tech-invite   World Map     

3GPP     Specs     Glossaries     Architecture     IMS     UICC       IETF     RFCs     Groups     SIP     ABNFs       Search

RFC 3720

 
 
 

Internet Small Computer Systems Interface (iSCSI)

Part 9 of 9, p. 219 to 257
Prev RFC Part

 


prevText      Top      Up      ToC       Page 219 
Appendix C.  Login Phase Examples

   In the first example, the initiator and target authenticate each
   other via Kerberos:

     I-> Login (CSG,NSG=0,1 T=1)
         InitiatorName=iqn.1999-07.com.os:hostid.77
         TargetName=iqn.1999-07.com.example:diskarray.sn.88
         AuthMethod=KRB5,SRP,None

     T-> Login (CSG,NSG=0,0 T=0)
         AuthMethod=KRB5

     I-> Login (CSG,NSG=0,1 T=1)
         KRB_AP_REQ=<krb_ap_req>

     (krb_ap_req contains the Kerberos V5 ticket and authenticator
        with MUTUAL-REQUIRED set in the ap-options field)

     If the authentication is successful, the target proceeds with:

     T-> Login (CSG,NSG=0,1 T=1)
         KRB_AP_REP=<krb_ap_rep>

     (krb_ap_rep is the Kerberos V5 mutual authentication reply)

     If the authentication is successful, the initiator may proceed
        with:

     I-> Login (CSG,NSG=1,0 T=0) FirstBurstLength=8192
     T-> Login (CSG,NSG=1,0 T=0) FirstBurstLength=4096
          MaxBurstLength=8192
     I-> Login (CSG,NSG=1,0 T=0) MaxBurstLength=8192
         ... more iSCSI Operational Parameters

     T-> Login (CSG,NSG=1,0 T=0)
         ... more iSCSI Operational Parameters

     And at the end:

     I-> Login (CSG,NSG=1,3 T=1)
         optional iSCSI parameters

     T-> Login (CSG,NSG=1,3 T=1) "login accept"

Top      Up      ToC       Page 220 
     If the initiator's authentication by the target is not
          successful, the target responds with:

     T-> Login "login reject"

     instead of the Login KRB_AP_REP message, and terminates the
        connection.

     If the target's authentication by the initiator is not
       successful, the initiator terminates the connection (without
       responding to the Login KRB_AP_REP message).

   In the next example only the initiator is authenticated by the
   target via Kerberos:

     I-> Login (CSG,NSG=0,1 T=1)
        InitiatorName=iqn.1999-07.com.os:hostid.77
        TargetName=iqn.1999-07.com.example:diskarray.sn.88
        AuthMethod=SRP,KRB5,None

     T-> Login-PR (CSG,NSG=0,0 T=0)
        AuthMethod=KRB5

     I-> Login (CSG,NSG=0,1 T=1)
         KRB_AP_REQ=krb_ap_req

     (MUTUAL-REQUIRED not set in the ap-options field of krb_ap_req)

     If the authentication is successful, the target proceeds with:

     T-> Login (CSG,NSG=0,1 T=1)

     I-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     T-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     . . .

     T-> Login (CSG,NSG=1,3 T=1)"login accept"

Top      Up      ToC       Page 221 
   In the next example, the initiator and target authenticate each
   other via SPKM1:

     I-> Login (CSG,NSG=0,1 T=1)
         InitiatorName=iqn.1999-07.com.os:hostid.77
         TargetName=iqn.1999-07.com.example:diskarray.sn.88
         AuthMethod=SPKM1,KRB5,None

     T-> Login (CSG,NSG=0,0 T=0)
         AuthMethod=SPKM1

     I-> Login (CSG,NSG=0,0 T=0)
         SPKM_REQ=<spkm-req>

     (spkm-req is the SPKM-REQ token with the mutual-state bit in the
       options field of the REQ-TOKEN set)

     T-> Login (CSG,NSG=0,0 T=0)
         SPKM_REP_TI=<spkm-rep-ti>

     If the authentication is successful, the initiator proceeds:

     I-> Login (CSG,NSG=0,1 T=1)
         SPKM_REP_IT=<spkm-rep-it>

     If the authentication is successful, the target proceeds with:

     T-> Login (CSG,NSG=0,1 T=1)

     The initiator may proceed:

     I-> Login  (CSG,NSG=1,0 T=0) ... iSCSI parameters
     T-> Login  (CSG,NSG=1,0 T=0) ... iSCSI parameters

     And at the end:

     I-> Login  (CSG,NSG=1,3 T=1)
         optional iSCSI parameters

     T-> Login (CSG,NSG=1,3 T=1) "login accept"


     If the target's authentication by the initiator is not
          successful, the initiator terminates the connection (without
          responding to the Login SPKM_REP_TI message).

Top      Up      ToC       Page 222 
     If the initiator's authentication by the target is not
          successful, the target responds with:

     T-> Login "login reject"

     instead of the Login "proceed and change stage" message, and
          terminates the connection.


   In the next example, the initiator and target authenticate each
   other via SPKM2:

     I-> Login (CSG,NSG=0,0 T=0)
         InitiatorName=iqn.1999-07.com.os:hostid.77
         TargetName=iqn.1999-07.com.example:diskarray.sn.88
               AuthMethod=SPKM1,SPKM2

     T-> Login-PR (CSG,NSG=0,0 T=0)
         AuthMethod=SPKM2

     I-> Login (CSG,NSG=0,1 T=1)
         SPKM_REQ=<spkm-req>

     (spkm-req is the SPKM-REQ token with the mutual-state bit in the
          options field of the REQ-TOKEN not set)

     If the authentication is successful, the target proceeds with:

     T-> Login (CSG,NSG=0,1 T=1)

     The initiator may proceed:

     I-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     T-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     And at the end:

     I-> Login  (CSG,NSG=1,3 T=1)
         optional iSCSI parameters

     T-> Login (CSG,NSG=1,3 T=1) "login accept"

Top      Up      ToC       Page 223 
   In the next example, the initiator and target authenticate each
   other via SRP:

     I-> Login (CSG,NSG=0,1 T=1)
         InitiatorName=iqn.1999-07.com.os:hostid.77
         TargetName=iqn.1999-07.com.example:diskarray.sn.88
         AuthMethod=KRB5,SRP,None

     T-> Login-PR (CSG,NSG=0,0 T=0)
         AuthMethod=SRP

     I-> Login (CSG,NSG=0,0 T=0)
         SRP_U=<user>
         TargetAuth=Yes

     T-> Login (CSG,NSG=0,0 T=0)
         SRP_GROUP=SRP-1536,SRP-1024
         SRP_s=<s>

     I-> Login (CSG,NSG=0,0 T=0)
         SRP_GROUP=SRP-1536
         SRP_A=<A>

     T-> Login (CSG,NSG=0,0 T=0)
         SRP_B=<B>

     I-> Login (CSG,NSG=0,1 T=1)
         SRP_M=<M>

     If the initiator authentication is successful, the target
       proceeds:

     T-> Login (CSG,NSG=0,1 T=1)
         SRP_HM=<H(A | M | K)>

      Where N, g, s, A, B, M, and H(A | M | K) are defined in [RFC2945].

     If the target authentication is not successful, the initiator
          terminates the connection; otherwise, it proceeds.

     I-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     T-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

Top      Up      ToC       Page 224 
     And at the end:

     I-> Login (CSG,NSG=1,3 T=1)
         optional iSCSI parameters

     T-> Login  (CSG,NSG=1,3 T=1) "login accept"

     If the initiator authentication is not successful, the target
          responds with:

     T-> Login "login reject"

     Instead of the T-> Login SRP_HM=<H(A | M | K)>  message and
          terminates the connection.

   In the next example, the initiator and target authenticate each
   other via SRP:

     I-> Login (CSG,NSG=0,1 T=1)
         InitiatorName=iqn.1999-07.com.os:hostid.77
         TargetName=iqn.1999-07.com.example:diskarray.sn.88
         AuthMethod=KRB5,SRP,None

     T-> Login-PR (CSG,NSG=0,0 T=0)
         AuthMethod=SRP

     I-> Login (CSG,NSG=0,0 T=0)
         SRP_U=<user>
         TargetAuth=No

      T-> Login (CSG,NSG=0,0 T=0)
          SRP_GROUP=SRP-1536
          SRP_s=<s>

     I-> Login (CSG,NSG=0,0 T=0)
         SRP_GROUP=SRP-1536
         SRP_A=<A>

     T-> Login (CSG,NSG=0,0 T=0)
         SRP_B=<B>

     I-> Login (CSG,NSG=0,1 T=1)
         SRP_M=<M>

     If the initiator authentication is successful, the target
          proceeds:

     T-> Login (CSG,NSG=0,1 T=1)

Top      Up      ToC       Page 225 
     I-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     T-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     And at the end:

     I-> Login (CSG,NSG=1,3 T=1)
         optional iSCSI parameters

     T-> Login (CSG,NSG=1,3 T=1) "login accept"

   In the next example the initiator and target authenticate each other
   via CHAP:

     I-> Login (CSG,NSG=0,0 T=0)
         InitiatorName=iqn.1999-07.com.os:hostid.77
         TargetName=iqn.1999-07.com.example:diskarray.sn.88
         AuthMethod=KRB5,CHAP,None

     T-> Login-PR (CSG,NSG=0,0 T=0)
         AuthMethod=CHAP

     I-> Login (CSG,NSG=0,0 T=0)
         CHAP_A=<A1,A2>

     T-> Login (CSG,NSG=0,0 T=0)
         CHAP_A=<A1>
         CHAP_I=<I>
         CHAP_C=<C>

     I-> Login (CSG,NSG=0,1 T=1)
         CHAP_N=<N>
         CHAP_R=<R>
         CHAP_I=<I>
         CHAP_C=<C>

Top      Up      ToC       Page 226 
     If the initiator authentication is successful, the target
       proceeds:

     T-> Login (CSG,NSG=0,1 T=1)
         CHAP_N=<N>
         CHAP_R=<R>

     If the target authentication is not successful, the initiator
       aborts the connection; otherwise, it proceeds.

     I-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters
     T-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     And at the end:

     I-> Login (CSG,NSG=1,3 T=1)
         optional iSCSI parameters

     T-> Login (CSG,NSG=1,3 T=1) "login accept"

     If the initiator authentication is not successful, the target
       responds with:

     T-> Login "login reject"

     Instead of the Login CHAP_R=<response> "proceed and change
       stage" message and terminates the connection.

   In the next example, only the initiator is authenticated by the
   target via CHAP:

     I-> Login (CSG,NSG=0,1 T=0)
         InitiatorName=iqn.1999-07.com.os:hostid.77
         TargetName=iqn.1999-07.com.example:diskarray.sn.88
         AuthMethod=KRB5,CHAP,None

     T-> Login-PR (CSG,NSG=0,0 T=0)
         AuthMethod=CHAP

     I-> Login (CSG,NSG=0,0 T=0)
         CHAP_A=<A1,A2>

Top      Up      ToC       Page 227 
     T-> Login (CSG,NSG=0,0 T=0)
         CHAP_A=<A1>
         CHAP_I=<I>
         CHAP_C=<C>

     I-> Login (CSG,NSG=0,1 T=1)
         CHAP_N=<N>
         CHAP_R=<R>

     If the initiator authentication is successful, the target
       proceeds:

     T-> Login (CSG,NSG=0,1 T=1)

     I-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     T-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     And at the end:

     I-> Login (CSG,NSG=1,3 T=1)
         optional iSCSI parameters

     T-> Login (CSG,NSG=1,3 T=1) "login accept"

   In the next example, the initiator does not offer any security
   parameters. It therefore may offer iSCSI parameters on the Login PDU
   with the T bit set to 1, and the target may respond with a final
   Login Response PDU immediately:

     I-> Login (CSG,NSG=1,3 T=1)
         InitiatorName=iqn.1999-07.com.os:hostid.77
         TargetName=iqn.1999-07.com.example:diskarray.sn.88
         ... iSCSI parameters

     T-> Login (CSG,NSG=1,3 T=1) "login accept"
         ... ISCSI parameters

     In the next example, the initiator does offer security
       parameters on the Login PDU, but the target does not choose
       any (i.e., chooses the "None" values):

     I-> Login (CSG,NSG=0,1 T=1)
         InitiatorName=iqn.1999-07.com.os:hostid.77
         TargetName=iqn.1999-07.com.example:diskarray.sn.88
         AuthMethod=KRB5,SRP,None

Top      Up      ToC       Page 228 
     T-> Login-PR (CSG,NSG=0,1 T=1)
         AuthMethod=None

     I-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     T-> Login (CSG,NSG=1,0 T=0)
         ... iSCSI parameters

     And at the end:

     I-> Login (CSG,NSG=1,3 T=1)
         optional iSCSI parameters

     T-> Login (CSG,NSG=1,3 T=1) "login accept"

Top      Up      ToC       Page 229 
Appendix D.  SendTargets Operation

   To reduce the amount of configuration required on an initiator, iSCSI
   provides the SendTargets text request.  The initiator uses the
   SendTargets request to get a list of targets to which it may have
   access, as well as the list of addresses (IP address and TCP port) on
   which these targets may be accessed.

   To make use of SendTargets, an initiator must first establish one of
   two types of sessions.  If the initiator establishes the session
   using the key "SessionType=Discovery", the session is a discovery
   session, and a target name does not need to be specified.  Otherwise,
   the session is a normal, operational session.  The SendTargets
   command MUST only be sent during the Full Feature Phase of a normal
   or discovery session.

   A system that contains targets MUST support discovery sessions on
   each of its iSCSI IP address-port pairs, and MUST support the
   SendTargets command on the discovery session.  In a discovery
   session, a target MUST return all path information (target name and
   IP address-port pairs and portal group tags) for the targets on the
   target network entity which the requesting initiator is authorized to
   access.

   A target MUST support the SendTargets command on operational
   sessions; these will only return path information about the target to
   which the session is connected, and do not need to return information
   about other target names that may be defined in the responding
   system.

   An initiator MAY make use of the SendTargets as it sees fit.

   A SendTargets command consists of a single Text request PDU.  This
   PDU contains exactly one text key and value.  The text key MUST be
   SendTargets.  The expected response depends upon the value, as well
   as whether the session is a discovery or operational session.

   The value must be one of:

     All

     The initiator is requesting that information on all relevant
       targets known to the implementation be returned.  This value
       MUST be supported on a discovery session, and MUST NOT be
       supported on an operational session.

Top      Up      ToC       Page 230 
     <iSCSI-target-name>

     If an iSCSI target name is specified, the session should respond
      with addresses for only the named target, if possible.  This
      value MUST be supported on discovery sessions.  A discovery
      session MUST be capable of returning addresses for those
      targets that would have been returned had value=All had been
      designated.

     <nothing>

     The session should only respond with addresses for the target to
       which the session is logged in.  This MUST be supported on
       operational sessions, and MUST NOT return targets other than
       the one to which the session is logged in.

   The response to this command is a text response that contains a list
   of zero or more targets and, optionally, their addresses.  Each
   target is returned as a target record.  A target record begins with
   the TargetName text key, followed by a list of TargetAddress text
   keys, and bounded by the end of the text response or the next
   TargetName key, which begins a new record.  No text keys other than
   TargetName and TargetAddress are permitted within a SendTargets
   response.

   For the format of the TargetName, see Section 12.4 TargetName.

   In a discovery session, a target MAY respond to a SendTargets request
   with its complete list of targets, or with a list of targets that is
   based on the name of the initiator logged in to the session.

   A SendTargets response MUST NOT contain target names if there are no
   targets for the requesting initiator to access.

   Each target record returned includes zero or more TargetAddress
   fields.

   Each target record starts with one text key of the form:

     TargetName=<target-name-goes-here>

   Followed by zero or more address keys of the form:

     TargetAddress=<hostname-or-ipaddress>[:<tcp-port>],
       <portal-group-tag>

   The hostname-or-ipaddress contains a domain name, IPv4 address, or
   IPv6 address, as specified for the TargetAddress key.

Top      Up      ToC       Page 231 
   A hostname-or-ipaddress duplicated in TargetAddress responses for a
   given node (the port is absent or equal) would probably indicate that
   multiple address families are in use at once (IPV6 and IPV4).

   Each TargetAddress belongs to a portal group, identified by its
   numeric portal group tag (as in Section 12.9 TargetPortalGroupTag).
   The iSCSI target name, together with this tag, constitutes the SCSI
   port identifier; the tag only needs to be unique within a given
   target's name list of addresses.

   Multiple-connection sessions can span iSCSI addresses that belong to
   the same portal group.

   Multiple-connection sessions cannot span iSCSI addresses that belong
   to different portal groups.

   If a SendTargets response reports an iSCSI address for a target, it
   SHOULD also report all other addresses in its portal group in the
   same response.

   A SendTargets text response can be longer than a single Text Response
   PDU, and makes use of the long text responses as specified.

   After obtaining a list of targets from the discovery target session,
   an iSCSI initiator may initiate new sessions to log in to the
   discovered targets for full operation.  The initiator MAY keep the
   discovery session open, and MAY send subsequent SendTargets commands
   to discover new targets.

   Examples:

   This example is the SendTargets response from a single target that
   has no other interface ports.

   Initiator sends text request that contains:

         SendTargets=All

   Target sends a text response that contains:

         TargetName=iqn.1993-11.com.example:diskarray.sn.8675309

   All the target had to return in the simple case was the target name.
   It is assumed by the initiator that the IP address and TCP port for
   this target are the same as used on the current connection to the
   default iSCSI target.

Top      Up      ToC       Page 232 
   The next example has two internal iSCSI targets, each accessible via
   two different ports with different IP addresses.  The following is
   the text response:

      TargetName=iqn.1993-11.com.example:diskarray.sn.8675309
      TargetAddress=10.1.0.45:3000,1 TargetAddress=10.1.1.45:3000,2
      TargetName=iqn.1993-11.com.example:diskarray.sn.1234567
      TargetAddress=10.1.0.45:3000,1 TargetAddress=10.1.1.45:3000,2

   Both targets share both addresses; the multiple addresses are likely
   used to provide multi-path support.  The initiator may connect to
   either target name on either address.  Each of the addresses has its
   own portal group tag; they do not support spanning
   multiple-connection sessions with each other.  Keep in mind that the
   portal group tags for the two named targets are independent of one
   another; portal group "1" on the first target is not necessarily the
   same as portal group "1" on the second target.

   In the above example, a DNS host name or an IPv6 address could have
   been returned instead of an IPv4 address.

   The next text response shows a target that supports spanning sessions
   across multiple addresses, and further illustrates the use of the
   portal group tags:

       TargetName=iqn.1993-11.com.example:diskarray.sn.8675309

      TargetAddress=10.1.0.45:3000,1 TargetAddress=10.1.1.46:3000,1
      TargetAddress=10.1.0.47:3000,2 TargetAddress=10.1.1.48:3000,2
      TargetAddress=10.1.1.49:3000,3

   In this example, any of the target addresses can be used to reach the
   same target.  A single-connection session can be established to any
   of these TCP addresses.  A multiple-connection session could span
   addresses .45 and .46 or .47 and .48, but cannot span any other
   combination.  A TargetAddress with its own tag (.49) cannot be
   combined with any other address within the same session.

   This SendTargets response does not indicate whether .49 supports
   multiple connections per session; it is communicated via the
   MaxConnections text key upon login to the target.

Top      Up      ToC       Page 233 
Appendix E.  Algorithmic Presentation of Error Recovery Classes

   This appendix illustrates the error recovery classes using a
   pseudo-programming-language.  The procedure names are chosen to be
   obvious to most implementers.  Each of the recovery classes described
   has initiator procedures as well as target procedures.  These
   algorithms focus on outlining the mechanics of error recovery
   classes, and do not exhaustively describe all other aspects/cases.
   Examples of this approach are:


      -  Handling for only certain Opcode types is shown.

      -  Only certain reason codes (e.g., Recovery in Logout command)
         are outlined.

      -  Resultant cases, such as recovery of Synchronization on a
         header digest error are considered out-of-scope in these
         algorithms.  In this particular example, a header digest error
         may lead to connection recovery if some type of sync and
         steering layer is not implemented.

   These algorithms strive to convey the iSCSI error recovery concepts
   in the simplest terms, and are not designed to be optimal.

E.1.  General Data Structure and Procedure Description

   This section defines the procedures and data structures that are
   commonly used by all the error recovery algorithms.  The structures
   may not be the exhaustive representations of what is required for a
   typical implementation.

   Data structure definitions -
   struct TransferContext {
           int TargetTransferTag;
           int ExpectedDataSN;
   };

   struct TCB {              /* task control block */
           Boolean SoFarInOrder;
           int ExpectedDataSN; /* used for both R2Ts, and Data */
           int MissingDataSNList[MaxMissingDPDU];
           Boolean FbitReceived;
           Boolean StatusXferd;
           Boolean CurrentlyAllegiant;
           int ActiveR2Ts;
           int Response;
           char *Reason;

Top      Up      ToC       Page 234 
           struct TransferContext
                       TransferContextList[MaxOutStandingR2T];
           int InitiatorTaskTag;
           int CmdSN;

           int SNACK_Tag;

   };

   struct Connection {
           struct Session SessionReference;
           Boolean SoFarInOrder;
           int CID;
           int State;

           int CurrentTimeout;
           int ExpectedStatSN;
           int MissingStatSNList[MaxMissingSPDU];
           Boolean PerformConnectionCleanup;
   };

   struct Session {
           int NumConnections;
           int CmdSN;
           int Maxconnections;
           int ErrorRecoveryLevel;
           struct iSCSIEndpoint OtherEndInfo;
           struct Connection ConnectionList[MaxSupportedConns];
   };

   Procedure descriptions -
   Receive-a-In-PDU(transport connection, inbound PDU);
   check-basic-validity(inbound PDU);
   Start-Timer(timeout handler, argument, timeout value);
   Build-And-Send-Reject(transport connection, bad PDU, reason code);

E.2.  Within-command Error Recovery Algorithms

E.2.1.  Procedure Descriptions

   Recover-Data-if-Possible(last required DataSN, task control
   block);
   Build-And-Send-DSnack(task control block);
   Build-And-Send-RDSnack(task control block);
   Build-And-Send-Abort(task control block);
   SCSI-Task-Completion(task control block);
   Build-And-Send-A-Data-Burst(transport connection, data-descriptor,
                                                 task control block);

Top      Up      ToC       Page 235 
   Build-And-Send-R2T(transport connection, data-descriptor,
                                                task control block);
   Build-And-Send-Status(transport connection, task control block);
   Transfer-Context-Timeout-Handler(transfer context);


   Notes:

      -  One procedure used in this section: Handle-Status-SNACK-
         request is defined in Within-connection recovery algorithms.

      -  The Response processing pseudo-code, shown in the target
         algorithms, applies to all solicited PDUs that carry StatSN -
         SCSI Response, Text Response etc.

E.2.2.  Initiator Algorithms

Recover-Data-if-Possible(LastRequiredDataSN, TCB)
{
  if (operational ErrorRecoveryLevel > 0) {
       if (# of missing PDUs is trackable) {
             Note the missing DataSNs in TCB.
             if (the task spanned a change in
                       MaxRecvDataSegmentLength) {
                  if (TCB.StatusXferd is TRUE)
                     drop the status PDU;
                  Build-And-Send-RDSnack(TCB);
             } else {
                  Build-And-Send-DSnack(TCB);
             }
       } else {
           TCB.Reason = "Protocol service CRC error";
           }
  } else {
        TCB.Reason = "Protocol service CRC error";
  }
  if (TCB.Reason == "Protocol service CRC error") {
        Clear the missing PDU list in the TCB.
        if (TCB.StatusXferd is not TRUE)
           Build-And-Send-Abort(TCB);
  }
}

Receive-a-In-PDU(Connection, CurrentPDU)
{
  check-basic-validity(CurrentPDU);
  if (Header-Digest-Bad) discard, return;
  Retrieve TCB for CurrentPDU.InitiatorTaskTag.

Top      Up      ToC       Page 236 
  if ((CurrentPDU.type == Data)
              or (CurrentPDU.type = R2T)) {
     if (Data-Digest-Bad for Data) {
           send-data-SNACK = TRUE;
       LastRequiredDataSN = CurrentPDU.DataSN;
         } else {
           if (TCB.SoFarInOrder = TRUE) {
               if (current DataSN is expected) {
                    Increment TCB.ExpectedDataSN.
               } else {

                    TCB.SoFarInOrder = FALSE;
                    send-data-SNACK = TRUE;
                   }
           } else {
                  if (current DataSN was considered missing) {
                      remove current DataSN from missing PDU list.
                  } else if (current DataSN is higher than expected)
{
                        send-data-SNACK = TRUE;
                   } else {
                         discard, return;
                   }
                   Adjust TCB.ExpectedDataSN if appropriate.
           }
           LastRequiredDataSN = CurrentPDU.DataSN - 1;
        }
        if (send-data-SNACK is TRUE and
               task is not already considered failed) {
           Recover-Data-if-Possible(LastRequiredDataSN, TCB);
     }
        if (missing data PDU list is empty) {
           TCB.SoFarInOrder = TRUE;
        }
     if (CurrentPDU.type == R2T) {
        Increment ActiveR2Ts for this task.

        Create a data-descriptor for the data burst.
        Build-And-Send-A-Data-Burst(Connection, data-descriptor,

                                                TCB);
     }
  } else if (CurrentPDU.type == Response) {
     if (Data-Digest-Bad) {
           send-status-SNACK = TRUE;
        } else {
        TCB.StatusXferd = TRUE;
        Store the status information in TCB.

Top      Up      ToC       Page 237 
        if (ExpDataSN does not match) {
             TCB.SoFarInOrder = FALSE;
             Recover-Data-if-Possible(current DataSN, TCB);
        }
           if (missing data PDU list is empty) {
                TCB.SoFarInOrder = TRUE;
           }
     }
  } else { /* REST UNRELATED TO WITHIN-COMMAND-RECOVERY, NOT
              SHOWN */
  }
  if ((TCB.SoFarInOrder == TRUE) and
                        (TCB.StatusXferd == TRUE)) {
     SCSI-Task-Completion(TCB);
  }
}

E.2.3.  Target Algorithms

Receive-a-In-PDU(Connection, CurrentPDU)
{
  check-basic-validity(CurrentPDU);
  if (Header-Digest-Bad) discard, return;
  Retrieve TCB for CurrentPDU.InitiatorTaskTag.
  if (CurrentPDU.type == Data) {
      Retrieve TContext from CurrentPDU.TargetTransferTag;
      if (Data-Digest-Bad) {
            Build-And-Send-Reject(Connection, CurrentPDU,
                              Payload-Digest-Error);
         Note the missing data PDUs in MissingDataRange[].
            send-recovery-R2T = TRUE;
         } else {
         if (current DataSN is not expected) {
             Note the missing data PDUs in MissingDataRange[].
                send-recovery-R2T = TRUE;
            }
         if (CurrentPDU.Fbit == TRUE) {
             if (current PDU is solicited) {
                    Decrement TCB.ActiveR2Ts.
             }
             if ((current PDU is unsolicited and
                    data received is less than I/O length and
                      data received is less than FirstBurstLength)
                 or (current PDU is solicited and the length of
                      this burst is less than expected)) {
                 send-recovery-R2T = TRUE;
                 Note the missing data in MissingDataRange[].
             }

Top      Up      ToC       Page 238 
            }
         }
         Increment TContext.ExpectedDataSN.
      if (send-recovery-R2T is TRUE  and
                task is not already considered failed) {
         if (operational ErrorRecoveryLevel > 0) {
             Increment TCB.ActiveR2Ts.
             Create a data-descriptor for the data burst
                        from MissingDataRange.
             Build-And-Send-R2T(Connection, data-descriptor, TCB);
         } else {
              if (current PDU is the last unsolicited)
                 TCB.Reason = "Not enough unsolicited data";
              else
                  TCB.Reason = "Protocol service CRC error";
         }
      }
      if (TCB.ActiveR2Ts == 0) {
         Build-And-Send-Status(Connection, TCB);
      }
  } else if (CurrentPDU.type == SNACK) {
      snack-failure = FALSE;
      if (operational ErrorRecoveryLevel > 0) {
         if (CurrentPDU.type == Data/R2T) {
              if (the request is satisfiable) {

                 if (request for Data) {
                    Create a data-descriptor for the data burst
                        from BegRun and RunLength.
                    Build-And-Send-A-Data-Burst(Connection,

                                  data-descriptor, TCB);
                 } else { /* R2T */
                    Create a data-descriptor for the data burst
                        from BegRun and RunLength.
                    Build-And-Send-R2T(Connection, data-descriptor,
                                   TCB);
                  }
              } else {
                    snack-failure = TRUE;
              }
         } else if (CurrentPDU.type == status) {
              Handle-Status-SNACK-request(Connection, CurrentPDU);
         } else if (CurrentPDU.type == DataACK) {
              Consider all data upto CurrentPDU.BegRun as
              acknowledged.
              Free up the retransmission resources for that data.
         } else if (CurrentPDU.type == R-Data SNACK) {

Top      Up      ToC       Page 239 
                 Create a data descriptor for a data burst covering
                 all unacknowledged data.
              Build-And-Send-A-Data-Burst(Connection,
                                  data-descriptor, TCB);
              TCB.SNACK_Tag = CurrentPDU.SNACK_Tag;
              if (there's no more data to send) {
                 Build-And-Send-Status(Connection, TCB);
              }
         }
      } else { /* operational ErrorRecoveryLevel = 0 */
              snack-failure = TRUE;

      }
      if (snack-failure == TRUE) {
          Build-And-Send-Reject(Connection, CurrentPDU,
                                                  SNACK-Reject);
          if (TCB.StatusXferd != TRUE) {
              TCB.Reason = "SNACK Rejected";
              Build-And-Send-Status(Connection, TCB);
          }
      }

  } else { /* REST UNRELATED TO WITHIN-COMMAND-RECOVERY, NOT SHOWN */
  }
}

Transfer-Context-Timeout-Handler(TContext)
{
  Retrieve TCB and Connection from TContext.
  Decrement TCB.ActiveR2Ts.
  if (operational ErrorRecoveryLevel > 0 and
                task is not already considered failed) {
      Note the missing data PDUs in MissingDataRange[].
      Create a data-descriptor for the data burst
                        from MissingDataRange[].
      Build-And-Send-R2T(Connection, data-descriptor, TCB);
  } else {
      TCB.Reason = "Protocol service CRC error";
      if (TCB.ActiveR2Ts = 0) {
         Build-And-Send-Status(Connection, TCB);
      }
  }
}

Top      Up      ToC       Page 240 
E.3.  Within-connection Recovery Algorithms

E.3.1.  Procedure Descriptions

Procedure descriptions:
Recover-Status-if-Possible(transport connection,
                                    currently received PDU);
Evaluate-a-StatSN(transport connection, currently received PDU);
Retransmit-Command-if-Possible(transport connection, CmdSN);
Build-And-Send-SSnack(transport connection);
Build-And-Send-Command(transport connection, task control block);
Command-Acknowledge-Timeout-Handler(task control block);
Status-Expect-Timeout-Handler(transport connection);
Build-And-Send-Nop-Out(transport connection);
Handle-Status-SNACK-request(transport connection, status SNACK
PDU);
Retransmit-Status-Burst(status SNACK, task control block);
Is-Acknowledged(beginning StatSN, run length);

Implementation-specific tunables:
InitiatorProactiveSNACKEnabled

   Notes:

      -  The initiator algorithms only deal with unsolicited Nop-In PDUs
         for generating status SNACKs.  A solicited Nop-In PDU has an
         assigned StatSN, which, when out of order, could trigger the
         out of order StatSN handling in Within-command algorithms,
         again leading to Recover-Status-if-Possible.


      -  The pseudo-code shown may result in the retransmission of
         unacknowledged commands in more cases than necessary.  This
         will not, however, affect the correctness of the operation
         because the target is required to discard the duplicate CmdSNs.

      -  The procedure Build-And-Send-Async is defined in the Connection
         recovery algorithms.

      -  The procedure Status-Expect-Timeout-Handler describes how
         initiators may proactively attempt to retrieve the Status if
         they so choose. This procedure is assumed to be triggered much
         before the standard ULP timeout.

Top      Up      ToC       Page 241 
E.3.2.  Initiator Algorithms

Recover-Status-if-Possible(Connection, CurrentPDU)
{
  if ((Connection.state == LOGGED_IN) and
                 connection is not already considered failed) {
     if (operational ErrorRecoveryLevel > 0) {
        if (# of missing PDUs is trackable) {
              Note the missing StatSNs in Connection
             that were not already requested with SNACK;
          Build-And-Send-SSnack(Connection);
            } else {
              Connection.PerformConnectionCleanup = TRUE;
        }
     } else {
            Connection.PerformConnectionCleanup = TRUE;
     }
     if (Connection.PerformConnectionCleanup == TRUE) {
        Start-Timer(Connection-Cleanup-Handler, Connection, 0);
         }
  }
}

Retransmit-Command-if-Possible(Connection, CmdSN)
{

  if (operational ErrorRecoveryLevel > 0) {
     Retrieve the InitiatorTaskTag, and thus TCB for the CmdSN.
     Build-And-Send-Command(Connection, TCB);
  }
}

Evaluate-a-StatSN(Connection, CurrentPDU)
{
  send-status-SNACK = FALSE;
  if (Connection.SoFarInOrder == TRUE) {
     if (current StatSN is the expected) {
          Increment Connection.ExpectedStatSN.
     } else {
              Connection.SoFarInOrder = FALSE;
              send-status-SNACK = TRUE;
         }
  } else {
     if (current StatSN was considered missing) {
          remove current StatSN from the missing list.
     } else {
              if (current StatSN is higher than expected){
                  send-status-SNACK = TRUE;

Top      Up      ToC       Page 242 
              } else {
                  send-status-SNACK = FALSE;
              discard the PDU;
          }
     }
     Adjust Connection.ExpectedStatSN if appropriate.
     if (missing StatSN list is empty) {
          Connection.SoFarInOrder = TRUE;
         }
  }
  return send-status-SNACK;
}

Receive-a-In-PDU(Connection, CurrentPDU)
{
  check-basic-validity(CurrentPDU);
  if (Header-Digest-Bad) discard, return;
  Retrieve TCB for CurrentPDU.InitiatorTaskTag.
  if (CurrentPDU.type == Nop-In) {
        if (the PDU is unsolicited) {
              if (current StatSN is not expected) {
                   Recover-Status-if-Possible(Connection,
                                CurrentPDU);
              }
              if (current ExpCmdSN is not Session.CmdSN) {
                  Retransmit-Command-if-Possible(Connection,
                                CurrentPDU.ExpCmdSN);
              }
        }
  } else if (CurrentPDU.type == Reject) {
        if (it is a data digest error on immediate data) {
              Retransmit-Command-if-Possible(Connection,
                                 CurrentPDU.BadPDUHeader.CmdSN);
        }
  } else if (CurrentPDU.type == Response) {
       send-status-SNACK = Evaluate-a-StatSN(Connection,
                                      CurrentPDU);
       if (send-status-SNACK == TRUE)
           Recover-Status-if-Possible(Connection, CurrentPDU);
  } else { /* REST UNRELATED TO WITHIN-CONNECTION-RECOVERY,
            * NOT SHOWN */
  }
}

Command-Acknowledge-Timeout-Handler(TCB)
{
  Retrieve the Connection for TCB.
  Retransmit-Command-if-Possible(Connection, TCB.CmdSN);

Top      Up      ToC       Page 243 
}

Status-Expect-Timeout-Handler(Connection)
{
  if (operational ErrorRecoveryLevel > 0) {
      Build-And-Send-Nop-Out(Connection);
  } else if (InitiatorProactiveSNACKEnabled){
      if ((Connection.state == LOGGED_IN) and
             connection is not already considered failed) {
           Build-And-Send-SSnack(Connection);
      }
  }
}

E.3.3.   Target Algorithms

Handle-Status-SNACK-request(Connection, CurrentPDU)
{
  if (operational ErrorRecoveryLevel > 0) {
     if (request for an acknowledged run) {
         Build-And-Send-Reject(Connection, CurrentPDU,
                                           Protocol-Error);
     } else if (request for an untransmitted run) {
         discard, return;
     } else {
         Retransmit-Status-Burst(CurrentPDU, TCB);
     } else {
        Build-And-Send-Async(Connection, DroppedConnection,
                                DefaultTime2Wait,
                                DefaultTime2Retain);
  }
}

E.4.  Connection Recovery Algorithms

E.4.1.  Procedure Descriptions

Build-And-Send-Async(transport connection, reason code,
                                   minimum time, maximum time);
Pick-A-Logged-In-Connection(session);
Build-And-Send-Logout(transport connection, logout connection
                  identifier, reason code);
PerformImplicitLogout(transport connection, logout connection
                  identifier, target information);
PerformLogin(transport connection, target information);
CreateNewTransportConnection(target information);
Build-And-Send-Command(transport connection, task control block);
Connection-Cleanup-Handler(transport connection);

Top      Up      ToC       Page 244 
Connection-Resource-Timeout-Handler(transport connection);
Quiesce-And-Prepare-for-New-Allegiance(session, task control
block);
Build-And-Send-Logout-Response(transport connection,
                         CID of connection in recovery, reason
code);
Build-And-Send-TaskMgmt-Response(transport connection,
                       task mgmt command PDU, response code);
Establish-New-Allegiance(task control block, transport
connection);
Schedule-Command-To-Continue(task control block);

Notes:
      - Transport exception conditions, such as unexpected connection
         termination, connection reset, and hung connection while the
         connection is in the full-feature phase, are all assumed to be
         asynchronously signaled to the iSCSI layer using the
         Transport_Exception_Handler procedure.

E.4.2.  Initiator Algorithms

         Receive-a-In-PDU(Connection, CurrentPDU) {
           check-basic-validity(CurrentPDU);
           if (Header-Digest-Bad) discard, return;

           Retrieve TCB from CurrentPDU.InitiatorTaskTag.
           if (CurrentPDU.type == Async) {
               if (CurrentPDU.AsyncEvent == ConnectionDropped) {
                  Retrieve the AffectedConnection for
         CurrentPDU.Parameter1.
                  AffectedConnection.CurrentTimeout =
         CurrentPDU.Parameter3;
                  AffectedConnection.State = CLEANUP_WAIT;
                  Start-Timer(Connection-Cleanup-Handler,
                               AffectedConnection,
         CurrentPDU.Parameter2);
               } else if (CurrentPDU.AsyncEvent == LogoutRequest)) {
                 AffectedConnection = Connection;
                 AffectedConnection.State = LOGOUT_REQUESTED;
                 AffectedConnection.PerformConnectionCleanup = TRUE;
                 AffectedConnection.CurrentTimeout =
         CurrentPDU.Parameter3;
                 Start-Timer(Connection-Cleanup-Handler,
                               AffectedConnection, 0);
               } else if (CurrentPDU.AsyncEvent == SessionDropped)) {
                 for (each Connection) {
                     Connection.State = CLEANUP_WAIT;
                     Connection.CurrentTimeout = CurrentPDU.Parameter3;

Top      Up      ToC       Page 245 
                     Start-Timer(Connection-Cleanup-Handler,
                               Connection, CurrentPDU.Parameter2);
                 }
                 Session.state = FAILED;
               }

           } else if (CurrentPDU.type == LogoutResponse) {
               Retrieve the CleanupConnection for CurrentPDU.CID.
               if (CurrentPDU.Response = failure) {
                  CleanupConnection.State = CLEANUP_WAIT;
               } else {
                   CleanupConnection.State = FREE;
               }
           } else if (CurrentPDU.type == LoginResponse) {
                if (this is a response to an implicit Logout) {
                   Retrieve the CleanupConnection.
                   if (successful) {
                       CleanupConnection.State = FREE;
                       Connection.State = LOGGED_IN;
                   } else {
                        CleanupConnection.State = CLEANUP_WAIT;
                        DestroyTransportConnection(Connection);
                   }
                }
           } else { /* REST UNRELATED TO CONNECTION-RECOVERY,

                     * NOT SHOWN */
           }
           if (CleanupConnection.State == FREE) {
              for (each command that was active on CleanupConnection) {
              /* Establish new connection allegiance */
                   NewConnection = Pick-A-Logged-In-Connection(Session);
                   Build-And-Send-Command(NewConnection, TCB);
               }
           } }

         Connection-Cleanup-Handler(Connection) {
           Retrieve Session from Connection.
           if (Connection can still exchange iSCSI PDUs) {
               NewConnection = Connection;
           } else {
               Start-Timer(Connection-Resource-Timeout-Handler,
                     Connection, Connection.CurrentTimeout);
               if (there are other logged-in connections) {
                    NewConnection = Pick-A-Logged-In-
         Connection(Session);
               } else {
                    NewConnection =

Top      Up      ToC       Page 246 
                      CreateTransportConnection(Session.OtherEndInfo);
                    Initiate an implicit Logout on NewConnection for
                                                      Connection.CID.
                    return;
               }
           }
           Build-And-Send-Logout(NewConnection, Connection.CID,
                                               RecoveryRemove); }

         Transport_Exception_Handler(Connection) {
           Connection.PerformConnectionCleanup = TRUE;
           if (the event is an unexpected transport disconnect) {
               Connection.State = CLEANUP_WAIT;

               Connection.CurrentTimeout = DefaultTime2Retain;
               Start-Timer(Connection-Cleanup-Handler, Connection,
                                                 DefaultTime2Wait);

           } else {
               Connection.State = FREE;
           } }

E.4.3.  Target Algorithms

         Receive-a-In-PDU(Connection, CurrentPDU)
         {
           check-basic-validity(CurrentPDU);
           if (Header-Digest-Bad) discard, return;
           else if (Data-Digest-Bad) {
                 Build-And-Send-Reject(Connection, CurrentPDU,
                                             Payload-Digest-Error);
                 discard, return;
           }
           Retrieve TCB and Session.
           if (CurrentPDU.type == Logout) {
              if (CurrentPDU.ReasonCode = RecoveryRemove) {
                  Retrieve the CleanupConnection from CurrentPDU.CID).
                  for (each command active on CleanupConnection) {
                       Quiesce-And-Prepare-for-New-Allegiance(Session,
                                           TCB);
                       TCB.CurrentlyAllegiant = FALSE;
                  }
                  Cleanup-Connection-State(CleanupConnection);
                  if ((quiescing successful) and (cleanup successful)) {
                       Build-And-Send-Logout-Response(Connection,
                                        CleanupConnection.CID, Success);
                  } else {
                       Build-And-Send-Logout-Response(Connection,

Top      Up      ToC       Page 247 
                                        CleanupConnection.CID, Failure);
                  }
              }
           } else if ((CurrentPDU.type == Login) and
                              operational ErrorRecoveryLevel == 2) {
                  Retrieve the CleanupConnection from CurrentPDU.CID).
                  for (each command active on CleanupConnection) {
                   Quiesce-And-Prepare-for-New-Allegiance(Session, TCB);
                       TCB.CurrentlyAllegiant = FALSE;
                  }
                  Cleanup-Connection-State(CleanupConnection);
                  if ((quiescing successful) and (cleanup successful)) {
                       Continue with the rest of the Login processing;
                  } else {
                       Build-And-Send-Login-Response(Connection,
                                  CleanupConnection.CID, Target Error);
                  }
              }

           } else if (CurrentPDU.type == TaskManagement) {
                if (CurrentPDU.function == "TaskReassign") {
                      if (Session.ErrorRecoveryLevel < 2) {
                         Build-And-Send-TaskMgmt-Response(Connection,
                              CurrentPDU, "Allegiance reassignment
                                                     not supported");
                      } else if (task is not found) {
                         Build-And-Send-TaskMgmt-Response(Connection,
                              CurrentPDU, "Task not in task set");
                      } else if (task is currently allegiant) {
                         Build-And-Send-TaskMgmt-Response(Connection,
                                   CurrentPDU, "Task still allegiant");
                      } else {
                         Establish-New-Allegiance(TCB, Connection);
                         TCB.CurrentlyAllegiant = TRUE;
                         Schedule-Command-To-Continue(TCB);
                      }
                }
           } else { /* REST UNRELATED TO CONNECTION-RECOVERY,
                     * NOT SHOWN */
           }
         }

         Transport_Exception_Handler(Connection)
         {
           Connection.PerformConnectionCleanup = TRUE;
           if (the event is an unexpected transport disconnect) {
               Connection.State = CLEANUP_WAIT;
               Start-Timer(Connection-Resource-Timeout-Handler,

Top      Up      ToC       Page 248 
               Connection,

         (DefaultTime2Wait+DefaultTime2Retain));
                 if (this Session has full-feature phase connections
                      left)
         {
                   DifferentConnection =
                      Pick-A-Logged-In-Connection(Session);
                    Build-And-Send-Async(DifferentConnection,
                          DroppedConnection, DefaultTime2Wait,
                            DefaultTime2Retain);
              }
           } else {
               Connection.State = FREE;
           }
         }

Top      Up      ToC       Page 249 
Appendix F.  Clearing Effects of Various Events on Targets

F.1.  Clearing Effects on iSCSI Objects

   The following tables describe the target behavior on receiving the
   events specified in the rows of the table.  The second table is  an
   extension of the first table and defines clearing actions for more
   objects on the same events.  The legend is:

      Y = Yes (cleared/discarded/reset on the event specified in the
          row).  Unless otherwise noted, the clearing action is only
          applicable for the issuing initiator port.
      N = No (not affected on the event specified in the row, i.e.,
          stays at previous value).
      NA = Not Applicable or Not Defined.

Top      Up      ToC       Page 250 
                         +-----+-----+-----+-----+-----+
                         |IT(1)|IC(2)|CT(5)|ST(6)|PP(7)|
   +---------------------+-----+-----+-----+-----+-----+
   |connection failure(8)|Y    |Y    |N    |N    |Y    |
   +---------------------+-----+-----+-----+-----+-----+
   |connection state     |NA   |NA   |Y    |N    |NA   |
   |timeout (9)          |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |session timeout/     |Y    |Y    |Y    |Y    |Y(14)|
   |closure/reinstatement|     |     |     |     |     |
   |(10)                 |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |session continuation |NA   |NA   |N(11)|N    |NA   |
   |(12)                 |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |successful connection|Y    |Y    |Y    |N    |Y(13)|
   |close logout         |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |session failure (18) |Y    |Y    |N    |N    |Y    |
   +---------------------+-----+-----+-----+-----+-----+
   |successful recovery  |Y    |Y    |N    |N    |Y(13)|
   |Logout               |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |failed Logout        |Y    |Y    |N    |N    |Y    |
   +---------------------+-----+-----+-----+-----+-----+
   |connection Login     |NA   |NA   |NA   |Y(15)|NA   |
   |(leading)            |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |connection Login     |NA   |NA   |N(11)|N    |Y    |
   |(non-leading)        |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |target cold reset(16)|Y    |Y    |Y    |Y    |Y    |
   +---------------------+-----+-----+-----+-----+-----+
   |target warm reset(16)|Y    |Y    |Y    |Y    |Y    |
   +---------------------+-----+-----+-----+-----+-----+
   |LU reset(19)         |Y    |Y    |Y    |Y    |Y    |
   +---------------------+-----+-----+-----+-----+-----+
   |powercycle(16)       |Y    |Y    |Y    |Y    |Y    |
   +---------------------+-----+-----+-----+-----+-----+

   1.  Incomplete TTTs - Target Transfer Tags on which the target is
   still  expecting PDUs to be received.  Examples include TTTs received
   via R2T, NOP-IN, etc.

   2.  Immediate Commands - immediate commands, but waiting for
   execution on a target.  For example, Abort Task Set.

Top      Up      ToC       Page 251 
   5.  Connection Tasks - tasks that are active on the iSCSI connection
   in question.

   6.  Session Tasks - tasks that are active on the entire iSCSI
   session.  A union of "connection tasks" on all participating
   connections.

   7.  Partial PDUs (if any) - PDUs that are partially sent and waiting
   for transport window credit to complete the transmission.

   8.  Connection failure is a connection exception condition - one of
   the transport connections shutdown, transport connections reset, or
   transport connections timed out, which abruptly terminated the iSCSI
   full-feature phase connection.  A connection failure always takes the
   connection state machine to the CLEANUP_WAIT state.

   9.  Connection state timeout happens if a connection spends more time
   that agreed upon during Login negotiation in the CLEANUP_WAIT state,
   and this takes the connection to the FREE state (M1 transition in
   connection cleanup state diagram).

   10.  These are defined in Section 5.3.5 Session Reinstatement,
   Closure, and Timeout.

   11.  This clearing effect is "Y" only if it is a connection
   reinstatement and the operational ErrorRecoveryLevel is less than 2.

   12.  Session continuation is defined in Section 5.3.6 Session
   Continuation and Failure.

   13.  This clearing effect is only valid if the connection is being
   logged out on a different connection and when the connection being
   logged out on the target may have some partial PDUs pending to be
   sent.  In all other cases, the effect is "NA".

   14.  This clearing effect is only valid for a "close the session"
   logout in a multi-connection session.  In all other cases, the effect
   is "NA".

   15.  Only applicable if this leading connection login is a session
   reinstatement.  If this is not the case, it is "NA".

   16.  This operation affects all logged-in initiators.

   18.  Session failure is defined in Section 5.3.6 Session Continuation
   and Failure.

Top      Up      ToC       Page 252 
   19.  This operation affects all logged-in initiators and the clearing
   effects are only applicable to the LU being reset.

                         +-----+-----+-----+-----+-----+
                         |DC(1)|DD(2)|SS(3)|CS(4)|DS(5)|
   +---------------------+-----+-----+-----+-----+-----+
   |connection failure   |N    |Y    |N    |N    |N    |
   +---------------------+-----+-----+-----+-----+-----+
   |connection state     |Y    |NA   |Y    |N    |NA   |
   |timeout              |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |session timeout/     |Y    |Y    |Y(7) |Y    |NA   |
   |closure/reinstatement|     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |session continuation |N(11)|NA*12|NA   |N    |NA*13|
   +---------------------+-----+-----+-----+-----+-----+
   |successful connection|Y    |Y    |Y    |N    |NA   |
   |close Logout         |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |session failure      |N    |Y    |N    |N    |N    |
   +---------------------+-----+-----+-----+-----+-----+
   |successful recovery  |Y    |Y    |Y    |N    |N    |
   |Logout               |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |failed Logout        |N    |Y(9) |N    |N    |N    |
   +---------------------+-----+-----+-----+-----+-----+
   |connection Login     |NA   |NA   |N(8) |N(8) |NA   |
   |(leading             |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |connection Login     |N(11)|NA*12|N(8) |N    |NA*13|
   |(non-leading)        |     |     |     |     |     |
   +---------------------+-----+-----+-----+-----+-----+
   |target cold reset    |Y    |Y    |Y    |Y(10)|NA   |
   +---------------------+-----+-----+-----+-----+-----+
   |target warm reset    |Y    |Y    |N    |N    |NA   |
   +---------------------+-----+-----+-----+-----+-----+
   |LU reset             |N    |Y    |N    |N    |N    |
   +---------------------+-----+-----+-----+-----+-----+
   |powercycle           |Y    |Y    |Y    |Y(10)|NA   |
   +---------------------+-----+-----+-----+-----+-----+

   1.  Discontiguous Commands - commands allegiant to the connection in
   question and waiting to be reordered in the iSCSI layer.  All "Y"s in
   this column assume that the task causing the event (if indeed the
   event is the result of a task) is issued as an immediate command,
   because the discontiguities can be ahead of the task.

Top      Up      ToC       Page 253 
   2.  Discontiguous Data - data PDUs received for the task in question
   and waiting to be reordered due to prior discontiguities in DataSN.

   3.  StatSN

   4.  CmdSN

   5.  DataSN

   7.  It clears the StatSN on all the connections.

   8.  This sequence number is instantiated on this event.

   9.  A logout failure drives the connection state machine to the
   CLEANUP_WAIT state, similar to the connection failure event.  Hence,
   it has a similar effect on this and several other protocol aspects.

   10.  This is cleared by virtue of the fact that all sessions with all
   initiators are terminated.

   11.  This clearing effect is "Y" if it is a connection reinstatement.

   12.  This clearing effect is "Y" only if it is a connection
   reinstatement and the operational ErrorRecoveryLevel is 2.

   13.  This clearing effect is "N" only if it is a connection
   reinstatement and the operational ErrorRecoveryLevel is 2.

F.2.  Clearing Effects on SCSI Objects

   The only iSCSI protocol action that can effect clearing actions on
   SCSI objects is the "I_T nexus loss" notification (Section 4.3.5.1
   Loss of Nexus notification).  [SPC3] describes the clearing effects
   of this notification on a variety of SCSI attributes.  In addition,
   SCSI standards documents (such as [SAM2] and [SBC]) define additional
   clearing actions that may take place for several SCSI objects on SCSI
   events such as LU resets and power-on resets.

   Since iSCSI defines a target cold reset as a protocol-equivalent to a
   target power-cycle, the iSCSI target cold reset must also be
   considered as the power-on reset event in interpreting the actions
   defined in the SCSI standards.

   When the iSCSI session is reconstructed (between the same SCSI ports
   with the same nexus identifier) reestablishing the same I_T nexus,
   all SCSI objects that are defined to not clear on the "I_T nexus
   loss" notification event, such as persistent reservations, are
   automatically associated to this new session.

Top      Up      ToC       Page 254 
Acknowledgements

   This protocol was developed by a design team that, in addition to the
   authors, included Daniel Smith, Ofer Biran, Jim Hafner and John
   Hufferd (IBM), Mark Bakke (Cisco), Randy Haagens (HP), Matt Wakeley
   (Agilent, now Sierra Logic), Luciano Dalle Ore (Quantum), and Paul
   Von Stamwitz (Adaptec, now TrueSAN Networks).

   Furthermore, a large group of people contributed to this work through
   their review, comments, and valuable insights.  We are grateful to
   all of them.  We especially thank those people who found the time and
   patience to take part in our weekly phone conferences and
   intermediate meetings in Almaden and Haifa, which helped shape this
   document: Prasenjit Sarkar, Meir Toledano, John Dowdy, Steve Legg,
   Alain Azagury (IBM), Dave Nagle (CMU), David Black (EMC), John Matze
   (Veritas - now Okapi Software), Steve DeGroote, Mark Schrandt
   (Cisco), Gabi Hecht (Gadzoox), Robert Snively and Brian Forbes
   (Brocade), Nelson Nachum (StorAge), and Uri Elzur (Broadcom).  Many
   others helped edit and improve this document within the IPS working
   group.  We are especially grateful to David Robinson and Raghavendra
   Rao (Sun), Charles Monia, Joshua Tseng (Nishan), Somesh Gupta
   (Silverback), Michael Krause, Pierre Labat, Santosh Rao, Matthew
   Burbridge, Bob Barry, Robert Elliott, Nick Martin (HP), Stephen
   Bailey (Sandburst), Steve Senum, Ayman Ghanem, Dave Peterson (Cisco),
   Barry Reinhold (Trebia Networks), Bob Russell (UNH), Eddy Quicksall
   (iVivity, Inc.), Bill Lynn and Michael Fischer (Adaptec), Vince
   Cavanna, Pat Thaler (Agilent), Jonathan Stone (Stanford), Luben
   Tuikov (Splentec), Paul Koning (EqualLogic), Michael Krueger
   (Windriver), Martins Krikis (Intel), Doug Otis (Sanlight), John
   Marberg (IBM), Robert Griswold and Bill Moody (Crossroads), Bill
   Studenmund (Wasabi Systems), Elizabeth Rodriguez (Brocade) and Yaron
   Klein (Sanrad).  The recovery chapter was enhanced with the help of
   Stephen Bailey (Sandburst), Somesh Gupta (Silverback), and Venkat
   Rangan (Rhapsody Networks).  Eddy Quicksall contributed some examples
   and began the Definitions section.  Michael Fischer and Bob Barry
   started the Acronyms section.  Last, but not least, we thank Ralph
   Weber for keeping us in line with T10 (SCSI) standardization.

   We would like to thank Steve Hetzler for his unwavering support and
   for coming up with such a good name for the protocol, and Micky
   Rodeh, Jai Menon, Clod Barrera, and Andy Bechtolsheim for helping
   make this work happen.

   In addition to this document, we recommend you acquaint yourself with
   the following in order to get a full understanding of the iSCSI
   specification: "iSCSI Naming & Discovery"[RFC3721], "Bootstrapping
   Clients using the iSCSI Protocol" [BOOT], "Securing Block Storage
   Protocols over IP" [RFC3723] documents, "iSCSI Requirements and

Top      Up      ToC       Page 255 
   Design Considerations" [RFC3347] and "SCSI Command Ordering
   Considerations with iSCSI" [CORD].

   The "iSCSI Naming & Discovery" document is authored by:

      Mark Bakke (Cisco), Jim Hafner, John Hufferd, Kaladhar Voruganti
         (IBM), and Marjorie Krueger (HP).

   The "Bootstrapping Clients using the iSCSI Protocol" document is
   authored by:

      Prasenjit Sarkar (IBM), Duncan Missimer (HP), and Costa
         Sapuntzakis (Cisco).

   The "Securing Block Storage Protocols over IP" document is authored
   by:

      Bernard Aboba (Microsoft), Joshua Tseng (Nishan), Jesse Walker
         (Intel), Venkat Rangan (Rhapsody Networks), and Franco
         Travostino (Nortel Networks).

   The "iSCSI Requirements and Design Considerations" document is
   authored by:

      Marjorie Krueger, Randy Haagens (HP), Costa Sapuntzakis, and Mark
      Bakke (Cisco).

   The "SCSI Command Ordering Considerations with iSCSI" document is
   authored by:

      Mallikarjun Chadalapaka, Rob Elliot (HP)

   We are grateful to all of them for their good work and for helping us
   correlate this document with the ones they produced.

Top      Up      ToC       Page 256 
Authors' Addresses

   Julian Satran
   IBM Research Laboratory in Haifa
   Haifa University Campus - Mount Carmel
   Haifa 31905, Israel

   Phone +972.4.829.6264
   EMail: Julian_Satran@il.ibm.com


   Kalman Meth
   IBM Research Laboratory in Haifa
   Haifa University Campus - Mount Carmel
   Haifa 31905, Israel

   Phone +972.4.829.6341
   EMail: meth@il.ibm.com


   Costa Sapuntzakis
   Stanford University
   353 Serra Mall Dr #407
   Stanford, CA 94305

   Phone: +1.650.723.2458
   EMail: csapuntz@alum.mit.edu


   Efri Zeidner
   XIV Ltd.
   1 Azrieli Center,
   Tel-Aviv 67021, Israel

   Phone: +972.3.607.4722
   EMail: efri@xiv.co.il


   Mallikarjun Chadalapaka
   Hewlett-Packard Company
   8000 Foothills Blvd.
   Roseville, CA 95747-5668, USA

   Phone: +1.916.785.5621
   EMail: cbm@rose.hp.com

Top      Up      ToC       Page 257 
Full Copyright Statement

   Copyright (C) The Internet Society (2004).  This document is subject
   to the rights, licenses and restrictions contained in BCP 78, and
   except as set forth therein, the authors retain all their rights.

   This document and the information contained herein are provided on an
   "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
   OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
   ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
   INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
   INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
   WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property

   The IETF takes no position regarding the validity or scope of any
   Intellectual Property Rights or other rights that might be claimed to
   pertain to the implementation or use of the technology described in
   this document or the extent to which any license under such rights
   might or might not be available; nor does it represent that it has
   made any independent effort to identify any such rights.  Information
   on the procedures with respect to rights in RFC documents can be
   found in BCP 78 and BCP 79.

   Copies of IPR disclosures made to the IETF Secretariat and any
   assurances of licenses to be made available, or the result of an
   attempt made to obtain a general license or permission for the use of
   such proprietary rights by implementers or users of this
   specification can be obtained from the IETF on-line IPR repository at
   http://www.ietf.org/ipr.

   The IETF invites any interested party to bring to its attention any
   copyrights, patents or patent applications, or other proprietary
   rights that may cover technology that may be required to implement
   this standard.  Please address the information to the IETF at ietf-
   ipr@ietf.org.

Acknowledgement

   Funding for the RFC Editor function is currently provided by the
   Internet Society.