From 47e2389596a84897327b7cfca84785f2dc8596bd Mon Sep 17 00:00:00 2001 From: Sebastian Vater Date: Thu, 10 Jul 2025 16:27:15 +0200 Subject: Added most login related text keys and fixed a few typos in iscsi.h. --- src/server/iscsi.h | 871 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 869 insertions(+), 2 deletions(-) diff --git a/src/server/iscsi.h b/src/server/iscsi.h index afbe60e..d0588e0 100644 --- a/src/server/iscsi.h +++ b/src/server/iscsi.h @@ -1070,6 +1070,771 @@ typedef struct __attribute__((packed)) iscsi_text_response_packet { // B and C: Random // D: Qualifier +/* Only the following keys are used during the SecurityNegotiation stage + of the Login Phase (other keys MUST NOT be used): +*/ +#define ISCSI_LOGIN_AUTH_TEXT_KEY_SESSION_TYPE "SessionType" // Use: LO, Declarative, Any-Stage + // Senders: Initiator + // Scope: SW + // SessionType= + // Default is Normal. + // The initiator indicates the type of session it wants to create. The + // target can either accept it or reject it. + // A Discovery session indicates to the target that the only purpose of + // this session is discovery. The only requests a target accepts in + // this type of session are a Text Request with a SendTargets key and a + // Logout Request with reason "close the session". + // The Discovery session implies MaxConnections = 1 and overrides both + // the default and an explicit setting. ErrorRecoveryLevel MUST be 0 + // (zero) for Discovery sessions. + // Depending on the type of session, a target may decide on resources to + // allocate, the security to enforce, etc., for the session. If the + // SessionType key is thus going to be offered as "Discovery", it SHOULD + // be offered in the initial Login Request by the initiator +#define ISCSI_LOGIN_AUTH_TEXT_KEY_INITIATOR_NAME "InitiatorName" // Use: IO, Declarative, Any-Stage + // Senders: Initiator + // Scope: SW + // InitiatorName= + // Examples: + // InitiatorName=iqn.1992-04.de.uni-freiburg.bwlehrpool:qcow2.5003 + // InitiatorName=iqn.2001-02.de.uni-freiburg.matrix:basty.eduroam + // InitiatorName=naa.52004567BA64678D + // The initiator of the TCP connection MUST provide this key to the + // remote endpoint at the first login of the Login Phase for every + // connection. The InitiatorName key enables the initiator to identify + // itself to the remote endpoint. + // The InitiatorName MUST NOT be redeclared within the Login Phase +#define ISCSI_LOGIN_AUTH_TEXT_KEY_TARGET_NAME "TargetName" // Use: IO by initiator, FFPO by target - only as response to a + // SendTargets, Declarative, Any-Stage + // Senders: Initiator and target + // Scope: SW + // TargetName= + // Examples: + // TargetName=iqn.1993-11.de.uni-freiburg:diskarrays.sn.5003 + // TargetName=eui.020000023B040506 + // TargetName=naa.62004567BA64678D0123456789ABCDEF + // The initiator of the TCP connection MUST provide this key to the + // remote endpoint in the first Login Request if the initiator is not + // establishing a Discovery session. The iSCSI Target Name specifies + // the worldwide unique name of the target. + // The TargetName key may also be returned by the SendTargets Text + // Request (which is its only use when issued by a target). + // The TargetName MUST NOT be redeclared within the Login Phase +#define ISCSI_LOGIN_AUTH_TEXT_KEY_TARGET_ADDRESS "TargetAddress" // Use: ALL, Declarative, Any-Stage + // Senders: Target + // Scope: SW + // TargetAddress=domainname[:port][,portal-group-tag] + // The domainname can be specified as either a DNS host name, a dotted- + // decimal IPv4 address, or a bracketed IPv6 address as specified in + // RFC3986. + // If the TCP port is not specified, it is assumed to be the IANA- + // assigned default port for iSCSI. + // If the TargetAddress is returned as the result of a redirect status + // in a Login Response, the comma and portal-group-tag MUST be omitted. + // If the TargetAddress is returned within a SendTargets response, the + // portal-group-tag MUST be included. + // Examples: + // TargetAddress=10.0.0.1:5003,1 + // TargetAddress=[1080:0:0:0:8:800:200C:417A],65 + // TargetAddress=[1080::8:800:200C:417A]:5003,1 + // TargetAddress=gitlab.uni-freiburg.de,443 + // The formats for the port and portal-group-tag are the same as the one + // specified in TargetPortalGroupTag +#define ISCSI_LOGIN_AUTH_TEXT_KEY_INITIATOR_ALIAS "InitiatorAlias" // Use: ALL, Declarative, Any-Stage + // Senders: Initiator + // Scope: SW + // InitiatorAlias= + // Examples: + // InitiatorAlias=Web Server 5 + // InitiatorAlias=matrix.uni-freiburg.de + // InitiatorAlias=Matrix Server + // If an initiator has been configured with a human-readable name or + // description, it SHOULD be communicated to the target during a Login + // Request PDU. If not, the host name can be used instead. This string + // is not used as an identifier, nor is it meant to be used for + // authentication or authorization decisions. It can be displayed by + // the target's user interface in a list of initiators to which it is + // connected +#define ISCSI_LOGIN_AUTH_TEXT_KEY_TARGET_ALIAS "TargetAlias" // Use: ALL, Declarative, Any-Stage + // Senders: Target + // Scope: SW + // TargetAlias= + // Examples: + // TargetAlias=Bob-s Disk + // TargetAlias=Database Server 1 Log Disk + // TargetAlias=Web Server 3 Disk 20 + // If a target has been configured with a human-readable name or + // description, this name SHOULD be communicated to the initiator during + // a Login Response PDU if SessionType=Normal. This string is not used + // as an identifier, nor is it meant to be used for authentication or + // authorization decisions. It can be displayed by the initiator's user + // interface in a list of targets to which it is connected +#define ISCSI_LOGIN_AUTH_TEXT_KEY_TARGET_PORTAL_GROUP_TAG "TargetPortalGroupTag" // Use: IO by target, Declarative, Any-Stage + // Senders: Target + // Scope: SW + // TargetPortalGroupTag=<16-bit-binary-value> + // Example: + // TargetPortalGroupTag=1 + // The TargetPortalGroupTag key is a 16-bit binary-value that uniquely + // identifies a portal group within an iSCSI target node. This key + // carries the value of the tag of the portal group that is servicing + // the Login Request. The iSCSI target returns this key to the + // initiator in the Login Response PDU to the first Login Request PDU + // that has the C bit set to 0 when TargetName is given by the + // initiator. + // SAM2 notes in its informative text that the TPGT value should be + // non-zero; note that this is incorrect. A zero value is allowed as a + // legal value for the TPGT. This discrepancy currently stands + // corrected in SAM4 +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD "AuthMethod" // Use: During Login - Security Negotiation + // Senders: Initiator and target + // Scope: connection + // AuthMethod = + // The main item of security negotiation is the authentication method + // (AuthMethod). + // The authentication methods that can be used (appear in the list-of- + // values) are either vendor-unique methods or those listed in the + // following table: + // +--------------------------------------------------------------+ + // | Name | Description | + // +--------------------------------------------------------------+ + // | KRB5 | Kerberos V5 - defined in RFC4120 | + // +--------------------------------------------------------------+ + // | SRP | Secure Remote Password - | + // | | defined in RFC2945 | + // +--------------------------------------------------------------+ + // | CHAP | Challenge Handshake Authentication Protocol - | + // | | defined in RFC1994 | + // +--------------------------------------------------------------+ + // | None | No authentication | + // +--------------------------------------------------------------+ + // The AuthMethod selection is followed by an "authentication exchange" + // specific to the authentication method selected. + // The authentication method proposal may be made by either the + // initiator or the target. However, the initiator MUST make the first + // step specific to the selected authentication method as soon as it is + // selected. It follows that if the target makes the authentication + // method proposal, the initiator sends the first key(s) of the exchange + // together with its authentication method selection. + // The authentication exchange authenticates the initiator to the target + // and, optionally, the target to the initiator. Authentication is + // OPTIONAL to use but MUST be supported by the target and initiator. + // The initiator and target MUST implement CHAP. All other + // authentication methods are OPTIONAL. + // Private or public extension algorithms MAY also be negotiated for + // authentication methods. Whenever a private or public extension + // algorithm is part of the default offer (the offer made in the absence + // of explicit administrative action), the implementer MUST ensure that + // CHAP is listed as an alternative in the default offer and "None" is + // not part of the default offer. + // Extension authentication methods MUST be named using one of the + // following two formats: + // 1) Z-reversed.vendor.dns_name.do_something= + // 2) New public key with no name prefix constraints + // Authentication methods named using the Z- format are used as private + // extensions. New public keys must be registered with IANA using the + // IETF Review process RFC5226. New public extensions for + // authentication methods MUST NOT use the Z# name prefix. + // For all of the public or private extension authentication methods, + // the method-specific keys MUST conform to the format specified for + // standard-label. + // To identify the vendor for private extension authentication methods, + // we suggest using the reversed DNS-name as a prefix to the proper + // digest names. + // The part of digest-name following Z- MUST conform to the format for + // standard-label. + // Support for public or private extension authentication methods is + // OPTIONAL + +/* Kerberos V5 (KRB5) related authentication keys: */ +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_KRB_AP_REQ "KRB_AP_REQ" // For KRB5 (Kerberos V5) (see RFC4120 and RFC1964), the initiator MUST use: + // KRB_AP_REQ= + // where KRB_AP_REQ is the client message as defined in RFC4120. + // The default principal name assumed by an iSCSI initiator or target + // (prior to any administrative configuration action) MUST be the iSCSI + // Initiator Name or iSCSI Target Name, respectively, prefixed by the + // string "iscsi/". + // If the initiator authentication fails, the target MUST respond with a + // Login reject with "Authentication Failure" status. Otherwise, if the + // initiator has selected the mutual authentication option (by setting + // MUTUAL-REQUIRED in the ap-options field of the KRB_AP_REQ), the + // target MUST reply with: +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_KRB_AP_REP "KRB_AP_REP" // KRB_AP_REP= + // where KRB_AP_REP is the server's response message as defined in + // RFC4120. + // If mutual authentication was selected and target authentication + // fails, the initiator MUST close the connection. + // KRB_AP_REQ and KRB_AP_REP are binary-values, and their binary length + // (not the length of the character string that represents them in + // encoded form) MUST NOT exceed 65536 bytes. Hex or Base64 encoding + // may be used for KRB_AP_REQ and KRB_AP_REP + +/* Secure Remote Password (SRP) related authentication keys: */ +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_SRP_SRP_U "SRP_U" // For SRP RFC2945, the initiator MUST use: + // SRP_U= TargetAuth=Yes or TargetAuth=No + // The target MUST answer with a Login reject with the "Authorization + // Failure" status or reply with: +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_SRP_SRP_GROUP "SRP_GROUP" // SRP_GROUP= SRP_s= + // where G1,G2... are proposed groups, in order of preference. +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_SRP_SRP_A "SRP_A" // The initiator MUST either close the connection or continue with: + // SRP_A= + // SRP_GROUP= + // where G is one of G1,G2... that were proposed by the target. + // The target MUST answer with a Login reject with the "Authentication + // Failure" status or reply with: +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_SRP_SRP_B "SRP_B" // SRP_B= + // The initiator MUST close the connection or continue with: +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_SRP_SRP_M "SRP_M" // SRP_M= + // If the initiator authentication fails, the target MUST answer with a + // Login reject with "Authentication Failure" status. Otherwise, if the + // initiator sent TargetAuth=Yes in the first message (requiring target + // authentication), the target MUST reply with: +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_SRP_SRP_HM "SRP_HM" // SRP_HM= + // If the target authentication fails, the initiator MUST close the + // connection: + // where U, s, A, B, M, and H(A | M | K) are defined in RFC2945 (using + // the SHA1 hash function, such as SRP-SHA1) and + // G,Gn ("Gn" stands for G1,G2...) are identifiers of SRP groups + // specified in RFC3723. + // G, Gn, and U are text strings; s,A,B,M, and H(A | M | K) are + // binary-values. The length of s,A,B,M and H(A | M | K) in binary form + // (not the length of the character string that represents them in + // encoded form) MUST NOT exceed 1024 bytes. Hex or Base64 encoding may + // be used for s,A,B,M and H(A | M | K). + // For the SRP_GROUP, all the groups specified in RFC3723 up to + // 1536 bits (i.e. SRP-768, SRP-1024, SRP-1280, SRP-1536) must be + // supported by initiators and targets. To guarantee interoperability, + // targets MUST always offer "SRP-1536" as one of the proposed groups + +/* Challenge Handshake Authentication Protocol (CHAP) related authentication keys: */ +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_A "CHAP_A" // For CHAP RFC1994, the initiator MUST use: + // CHAP_A= + // where A1,A2... are proposed algorithms, in order of preference. + // The target MUST answer with a Login reject with the "Authentication + // Failure" status or reply with: + // CHAP_A= +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_I "CHAP_I" // CHAP_I= +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_C "CHAP_C" // CHAP_C= + // where A is one of A1,A2... that were proposed by the initiator. + // The initiator MUST continue with: +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_N "CHAP_N" // CHAP_N= +#define ISCSI_LOGIN_AUTH_TEXT_KEY_AUTH_METHOD_CHAP_CHAP_R "CHAP_R" // CHAP_R= + // or, if it requires target authentication, with: + // CHAP_N= + // CHAP_R= + // CHAP_I= + // CHAP_C= + // If the initiator authentication fails, the target MUST answer with a + // Login reject with "Authentication Failure" status. Otherwise, if the + // initiator required target authentication, the target MUST either + // answer with a Login reject with "Authentication Failure" or reply + // with: + // CHAP_N= + // CHAP_R= + // If the target authentication fails, the initiator MUST close the + // connection: + // where N, (A,A1,A2), I, C, and R are (correspondingly) the Name, + // Algorithm, Identifier, Challenge, and Response as defined in + // RFC1994. + // N is a text string; A,A1,A2, and I are numbers; C and R are + // binary-values. Their binary length (not the length of the character + // string that represents them in encoded form) MUST NOT exceed + // 1024 bytes. Hex or Base64 encoding may be used for C and R. + // For the Algorithm, as stated in [RFC1994], one value is required to + // be implemented: + // 5 (CHAP with MD5) + // To guarantee interoperability, initiators MUST always offer it as one + // of the proposed algorithms + +/* Login/Text Operational Text Keys + + Some session-specific parameters MUST only be carried on the leading + connection and cannot be changed after the leading connection login + (e.g., MaxConnections - the maximum number of connections). This + holds for a single connection session with regard to connection + restart. The keys that fall into this category have the "use: LO" + (Leading Only). + + Keys that can only be used during login have the "use: IO" + (Initialize Only), while those that can be used in both the Login + Phase and Full Feature Phase have the "use: ALL". + + Keys that can only be used during the Full Feature Phase use FFPO + (Full Feature Phase Only). + + Keys marked as Any-Stage may also appear in the SecurityNegotiation + stage, while all other keys described in this section are + operational keys. + + Keys that do not require an answer are marked as Declarative. + + Key scope is indicated as session-wide (SW) or connection-only (CO). + + "Result function", wherever mentioned, states the function that can + be applied to check the validity of the responder selection. + "Minimum" means that the selected value cannot exceed the offered + value. "Maximum" means that the selected value cannot be lower than + the offered value. "AND" means that the selected value must be a + possible result of a Boolean "and" function with an arbitrary Boolean + value (e.g., if the offered value is No the selected value must be + No). "OR" means that the selected value must be a possible result of + a Boolean "or" function with an arbitrary Boolean value (e.g., if the + offered value is Yes the selected value must be Yes). +*/ +#define ISCSI_LOGIN_AUTH_TEXT_KEY_HEADER_DIGEST "HeaderDigest" // Use: IO +#define ISCSI_LOGIN_AUTH_TEXT_KEY_DATA_DIGEST "DataDigest" // Senders: Initiator and target + // Scope: CO + // HeaderDigest = + // DataDigest = + // Default is None for both HeaderDigest and DataDigest. + // Digests enable the checking of end-to-end, non-cryptographic data + // integrity beyond the integrity checks provided by the link layers and + // the covering of the whole communication path, including all elements + // that may change the network-level PDUs, such as routers, switches, + // and proxies. + // The following table lists cyclic integrity checksums that can be + // negotiated for the digests and MUST be implemented by every iSCSI + // initiator and target. These digest options only have error detection + // significance. + // +---------------------------------------------+ + // | Name | Description | Generator | + // +---------------------------------------------+ + // | CRC32C | 32-bit CRC |0x11edc6f41| + // +---------------------------------------------+ + // | None | no digest | + // +---------------------------------------------+ + // The generator polynomial G(x) for this digest is given in hexadecimal + // notation (e.g. "0x3b" stands for 0011 1011, and the polynomial is + // x**5 + x**4 + x**3 + x + 1). + // When the initiator and target agree on a digest, this digest MUST be + // used for every PDU in the Full Feature Phase. + // Padding bytes, when present in a segment covered by a CRC, SHOULD be + // set to 0 and are included in the CRC. + // The CRC MUST be calculated by a method that produces the same results + // as the following process: + // - The PDU bits are considered as the coefficients of a polynomial + // M(x) of degree n - 1; bit 7 of the lowest numbered byte is + // considered the most significant bit (x**n - 1), followed by bit 6 + // of the lowest numbered byte through bit 0 of the highest numbered + // byte (x**0). + // - The most significant 32 bits are complemented. + // - The polynomial is multiplied by x**32, then divided by G(x). The + // generator polynomial produces a remainder R(x) of degree <= 31. + // - The coefficients of R(x) are formed into a 32-bit sequence. + // - The bit sequence is complemented, and the result is the CRC. + // - The CRC bits are mapped into the digest word. The x**31 + // coefficient is mapped to bit 7 of the lowest numbered byte of the + // digest, and the mapping continues with successive coefficients and + // bits so that the x**24 coefficient is mapped to bit 0 of the lowest + // numbered byte. The mapping continues further with the x**23 + // coefficient mapped to bit 7 of the next byte in the digest until + // the x**0 coefficient is mapped to bit 0 of the highest numbered + // byte of the digest. + // - Computing the CRC over any segment (data or header) extended to + // include the CRC built using the generator 0x11edc6f41 will always + // get the value 0x1c2d19ed as its final remainder (R(x)). This value + // is given here in its polynomial form (i.e., not mapped as the + // digest word). + // For a discussion about selection criteria for the CRC, see RFC3385. + // For a detailed analysis of the iSCSI polynomial, see Castagnoli93. + // Private or public extension algorithms MAY also be negotiated for + // digests. Whenever a private or public digest extension algorithm is + // part of the default offer (the offer made in the absence of explicit + // administrative action), the implementer MUST ensure that CRC32C is + // listed as an alternative in the default offer and "None" is not part + // of the default offer. + // Extension digest algorithms MUST be named using one of the following + // two formats: + // 1) Y-reversed.vendor.dns_name.do_something= + // 2) New public key with no name prefix constraints + // Digests named using the Y- format are used for private purposes + // (unregistered). New public keys must be registered with IANA using + // the IETF Review process (RFC5226). New public extensions for + // digests MUST NOT use the Y# name prefix. + // For private extension digests, to identify the vendor we suggest + // using the reversed DNS-name as a prefix to the proper digest names. + // The part of digest-name following Y- MUST conform to the format for + // standard-label specified. + // Support for public or private extension digests is OPTIONA +#define ISCSI_LOGIN_AUTH_TEXT_KEY_MAX_CONNECTIONS "MaxConnections" // Use: LO + // Senders: Initiator and target + // Scope: SW + // Irrelevant when: SessionType=Discovery + // MaxConnections= + // Default is 1. + // Result function is Minimum. + // The initiator and target negotiate the maximum number of connections + // requested/acceptable +#define ISCSI_LOGIN_AUTH_TEXT_KEY_SEND_TARGETS "SendTargets" // Use: FFPO + // Senders: Initiator + // Scope: SW + // The text in this appendix is a normative part of this document. + // 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 (IP address-port + // pairs and Target Portal Group Tags) for the targets on the target + // Network Entity that 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 command 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 session or an 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. + // + // 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 been + // designated. + // + // 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. + // A Discovery session 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= + // followed by zero or more address keys of the form: + // TargetAddress=[:], + // + // The hostname-or-ipaddress contains a domain name, IPv4 address, or + // IPv6 address (RFC4291), as specified for the TargetAddress key. + // 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 Target Portal Group Tag. 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 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. + // The initiator sends a Text Request that contains: + // SendTargets=All + // The target sends a Text Response that contains: + // TargetName=iqn.1993-11.de.uni-freiburg:diskarray.sn.8675309 + // All the target had to return in this 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 those used on the current connection to + // the default iSCSI target. + // 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.de.uni-freiburg:diskarray.sn.8675309 + // TargetAddress=10.1.0.45:5300,1 + // TargetAddress=10.1.1.45:5300,2 + // TargetName=iqn.1993-11.de.uni-freiburg:diskarray.sn.1234567 + // TargetAddress=10.1.0.45:5300,1 + // TargetAddress=10.1.1.45:5300,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 Target Portal Group Tag; they do not support spanning multiple- + // connection sessions with each other. Keep in mind that the Target + // 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 + // Target Portal Group Tags: + // TargetName=iqn.1993-11.de.uni-freiburg:diskarray.sn.8675309 + // TargetAddress=10.1.0.45:5300,1 + // TargetAddress=10.1.1.46:5300,1 + // TargetAddress=10.1.0.47:5300,2 + // TargetAddress=10.1.1.48:5300,2 + // TargetAddress=10.1.1.49:5300,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 +#define ISCSI_LOGIN_AUTH_TEXT_KEY_INITIAL_R2T "InitialR2T" // Use: LO + // Senders: Initiator and target + // Scope: SW + // Irrelevant when: SessionType=Discovery + // InitialR2T= + // Examples: + // I->InitialR2T=No + // T->InitialR2T=No + // Default is Yes. + // Result function is OR. + // The InitialR2T key is used to turn off the default use of R2T for + // unidirectional operations and the output part of bidirectional + // commands, thus allowing an initiator to start sending data to a + // target as if it has received an initial R2T with Buffer + // Offset=Immediate Data Length and Desired Data Transfer + // Length=(min(FirstBurstLength, Expected Data Transfer Length) - + // Received Immediate Data Length). + // The default action is that R2T is required, unless both the initiator + // and the target send this key-pair attribute specifying InitialR2T=No. + // Only the first outgoing data burst (immediate data and/or separate + // PDUs) can be sent unsolicited (i.e., not requiring an explicit R2T) +#define ISCSI_LOGIN_AUTH_TEXT_KEY_IMMEDIATE_DATA "ImmediateData" // Use: LO + // Senders: Initiator and target + // Scope: SW + // Irrelevant when: SessionType=Discovery + // ImmediateData= + // Default is Yes. + // Result function is AND. + // The initiator and target negotiate support for immediate dataTo + // turn immediate data off, the initiator or target must state its + // desire to do soImmediateData can be turned on if both the + // initiator and target have ImmediateData=Yes. + // If ImmediateData is set to Yes and InitialR2T is set to Yes + // (default), then only immediate data are accepted in the first burst. + // If ImmediateData is set to No and InitialR2T is set to Yes, then the + // initiator MUST NOT send unsolicited data and the target MUST reject + // unsolicited data with the corresponding response code. + // If ImmediateData is set to No and InitialR2T is set to No, then the + // initiator MUST NOT send unsolicited immediate data but MAY send one + // unsolicited burst of Data-OUT PDUs. + // If ImmediateData is set to Yes and InitialR2T is set to No, then the + // initiator MAY send unsolicited immediate data and/or one unsolicited + // burst of Data-OUT PDUs. + // The following table is a summary of unsolicited data options: + // +----------+-------------+------------------+-------------+ + // |InitialR2T|ImmediateData| Unsolicited |ImmediateData| + // | | | Data-Out PDUs | | + // +----------+-------------+------------------+-------------+ + // | No | No | Yes | No | + // +----------+-------------+------------------+-------------+ + // | No | Yes | Yes | Yes | + // +----------+-------------+------------------+-------------+ + // | Yes | No | No | No | + // +----------+-------------+------------------+-------------+ + // | Yes | Yes | No | Yes | + // +----------+-------------+------------------+-------------+ +#define ISCSI_LOGIN_AUTH_TEXT_KEY_MAX_RECV_DS_LEN "MaxRecvDataSegmentLength" // Use: ALL, Declarative + // Senders: Initiator and target + // Scope: CO + // MaxRecvDataSegmentLength= + // Default is 8192 bytes. + // The initiator or target declares the maximum data segment length in + // bytes it can receive in an iSCSI PDU. + // The transmitter (initiator or target) is required to send PDUs with a + // data segment that does not exceed MaxRecvDataSegmentLength of the + // receiver. + // A target receiver is additionally limited by MaxBurstLength for + // solicited data and FirstBurstLength for unsolicited dataAn + // initiator MUST NOT send solicited PDUs exceeding MaxBurstLength nor + // unsolicited PDUs exceeding FirstBurstLength (or FirstBurstLength- + // Immediate Data Length if immediate data were sent) +#define ISCSI_LOGIN_AUTH_TEXT_KEY_MAX_BURST_LEN "MaxBurstLength" // Use: LO + // Senders: Initiator and target + // Scope: SW + // Irrelevant when: SessionType=Discovery + // MaxBurstLength= + // Default is 262144 (256 KB). + // Result function is Minimum. + // The initiator and target negotiate the maximum SCSI data payload in + // bytes in a Data-In or a solicited Data-Out iSCSI sequence. A + // sequence consists of one or more consecutive Data-In or Data-Out PDUs + // that end with a Data-In or Data-Out PDU with the F bit set to 1 +#define ISCSI_LOGIN_AUTH_TEXT_KEY_FIRST_BURST_LEN "FirstBurstLength" // Use: LO + // Senders: Initiator and target + // Scope: SW + // Irrelevant when: SessionType=Discovery + // Irrelevant when: ( InitialR2T=Yes and ImmediateData=No ) + // FirstBurstLength= + // Default is 65536 (64 KB). + // Result function is Minimum. + // The initiator and target negotiate the maximum amount in bytes of + // unsolicited data an iSCSI initiator may send to the target during the + // execution of a single SCSI command. This covers the immediate data + // (if any) and the sequence of unsolicited Data-Out PDUs (if any) that + // follow the command. + // FirstBurstLength MUST NOT exceed MaxBurstLength +#define ISCSI_LOGIN_AUTH_TEXT_KEY_DEFAULT_TIME_WAIT "DefaultTime2Wait" // Use: LO + // Senders: Initiator and target + // Scope: SW + // DefaultTime2Wait= + // Default is 2. + // Result function is Maximum. + // The initiator and target negotiate the minimum time, in seconds, to + // wait before attempting an explicit/implicit logout or an active task + // reassignment after an unexpected connection termination or a + // connection reset. + // A value of 0 indicates that logout or active task reassignment can be + // attempted immediately +#define ISCSI_LOGIN_AUTH_TEXT_KEY_DEFAULT_TIME_RETAIN "DefaultTime2Retain" // Use: LO + // Senders: Initiator and target + // Scope: SW + // DefaultTime2Retain= + // Default is 20. + // Result function is Minimum. + // The initiator and target negotiate the maximum time, in seconds, + // after an initial wait (Time2Wait), before which an active task + // reassignment is still possible after an unexpected connection + // termination or a connection reset. + // This value is also the session state timeout if the connection in + // question is the last LOGGED_IN connection in the session. + // A value of 0 indicates that connection/task state is immediately + // discarded by the target +#define ISCSI_LOGIN_AUTH_TEXT_KEY_MAX_OUTSTANDING_R2T "MaxOutstandingR2T" // Use: LO + // Senders: Initiator and target + // Scope: SW + // MaxOutstandingR2T= + // Irrelevant when: SessionType=Discovery + // Default is 1. + // Result function is Minimum. + // The initiator and target negotiate the maximum number of outstanding + // R2Ts per task, excluding any implied initial R2T that might be part + // of that task. An R2T is considered outstanding until the last data + // PDU (with the F bit set to 1) is transferred or a sequence reception + // timeout is encountered for that data sequence +#define ISCSI_LOGIN_AUTH_TEXT_KEY_DATA_PDU_IN_ORDER "DataPDUInOrder" // Use: LO + // Senders: Initiator and target + // Scope: SW + // Irrelevant when: SessionType=Discovery + // DataPDUInOrder= + // Default is Yes. + // Result function is OR. + // "No" is used by iSCSI to indicate that the data PDUs within sequences + // can be in any order. "Yes" is used to indicate that data PDUs within + // sequences have to be at continuously increasing addresses and + // overlays are forbidden +#define ISCSI_LOGIN_AUTH_TEXT_KEY_DATA_SEQ_IN_ORDER "DataSequenceInOrder" // Use: LO + // Senders: Initiator and target + // Scope: SW + // Irrelevant when: SessionType=Discovery + // DataSequenceInOrder= + // Default is Yes. + // Result function is OR. + // A data sequence is a sequence of Data-In or Data-Out PDUs that end + // with a Data-In or Data-Out PDU with the F bit set to 1. A Data-Out + // sequence is sent either unsolicited or in response to an R2T. + // Sequences cover an offset-range. + // If DataSequenceInOrder is set to No, data PDU sequences may be + // transferred in any order. + // If DataSequenceInOrder is set to Yes, data sequences MUST be + // transferred using continuously non-decreasing sequence offsets (R2T + // buffer offset for writes, or the smallest SCSI Data-In buffer offset + // within a read data sequence). + // If DataSequenceInOrder is set to Yes, a target may retry at most the + // last R2T, and an initiator may at most request retransmission for the + // last read data sequence. For this reason, if ErrorRecoveryLevel is + // not 0 and DataSequenceInOrder is set to Yes, then MaxOutstandingR2T + // MUST be set to 1 +#define ISCSI_LOGIN_AUTH_TEXT_KEY_ERR_RECOVERY_LEVEL "ErrorRecoveryLevel" // Use: LO + // Senders: Initiator and target + // Scope: SW + // ErrorRecoveryLevel= + // Default is 0. + // Result function is Minimum. + // The initiator and target negotiate the recovery level supported. + // Recovery levels represent a combination of recovery capabilities. + // Each recovery level includes all the capabilities of the lower + // recovery levels and adds some new ones to them. + // In the description of recovery mechanisms, certain recovery classes + // are specified +#define ISCSI_LOGIN_AUTH_TEXT_KEY_PRIV_EXT_KEY_FMT "X-reversed.vendor" // Use: ALL + // Senders: Initiator and target + // Scope: specific key dependent + // X-reversed.vendor.dns_name.do_something= + // Keys with this format are used for private extension purposes. These + // keys always start with X- if unregistered with IANA (private). New + // public keys (if registered with IANA via an IETF Review RFC5226) no + // longer have an X# name prefix requirement; implementers may propose + // any intuitive unique name. + // For unregistered keys, to identify the vendor we suggest using the + // reversed DNS-name as a prefix to the key-proper. + // The part of key-name following X- MUST conform to the format for + // key-name. + // Vendor-specific keys MUST ONLY be used in Normal sessions. + // Support for public or private extension keys is OPTIONAL +#define ISCSI_LOGIN_AUTH_TEXT_KEY_TASK_REPORTING "TaskReporting" // Use: LO + // Senders: Initiator and target + // Scope: SW + // Irrelevant when: SessionType=Discovery + // TaskReporting= + // Default is RFC3720. + // This key is used to negotiate the task completion reporting semantics + // from the SCSI target. The following table describes the semantics + // that an iSCSI target MUST support for respective negotiated key + // values. Whenever this key is negotiated, at least the RFC3720 and + // ResponseFence values MUST be offered as options by the negotiation + // originator. + // +--------------+------------------------------------------+ + // | Name | Description | + // +--------------+------------------------------------------+ + // | RFC3720 | RFC 3720-compliant semantics. Response | + // | | fencing is not guaranteed, and fast | + // | | completion of multi-task aborting is not | + // | | supported. | + // +--------------+------------------------------------------+ + // | ResponseFence| Response Fence | + // | | semantics MUST be supported in reporting | + // | | task completions. | + // +--------------+------------------------------------------+ + // | FastAbort | Updated fast multi-task abort semantics | + // | | defined in MUST be supported. Support | + // | | for the Response. Fence is implied - | + // | | i.e., semantics MUST be supported as | + // | | well. | + // +--------------+------------------------------------------+ + // When TaskReporting is not negotiated to FastAbort, the + // standard multi-task abort semantics MUST be used + /* This is an initiator-defined component of the session identifier and is structured as follows: @@ -1424,7 +2189,7 @@ typedef struct __attribute__((packed)) iscsi_login_response_packet { been delivered to SCSI because one or more commands with a smaller CmdSN have not been received by iSCSI. The resulting holes in the command sequence numbers will have to be handled by appropriate - recovery (see Section 7), unless the session is also closed. + recovery, unless the session is also closed. */ typedef struct __attribute__((packed)) iscsi_logout_req_packet { uint8_t opcode; // Always 0x06 according to specification (see above) @@ -1718,9 +2483,111 @@ typedef struct __attribute__((packed)) iscsi_reject_packet { // task, if any uint32_t reserved5[2]; // Reserved for future usage struct iscsi_header_digest hdr_digest; // Optional header digest - struct iscsi_bhs_packet bad_pdu_hdr; // Complete Header of Bad PDU + struct iscsi_bhs_packet bad_pdu_hdr; // Complete Header of Bad PDU. The target returns the + // header (not including the digest) of the PDU in error + // as the data of the response uint8_t vendor_data[0]; // Vendor-specific data (if any) struct iscsi_data_digest data_digest; // Optional data digest } iscsi_reject_packet; +/* NOP-Out may be used by an initiator as a "ping request" to verify + that a connection/session is still active and all its components are + operational. The NOP-In response is the "ping echo". + + A NOP-Out is also sent by an initiator in response to a NOP-In. + + A NOP-Out may also be used to confirm a changed ExpStatSN if another + PDU will not be available for a long time. + + Upon receipt of a NOP-In with the Target Transfer Tag set to a valid + value (not the reserved value 0xffffffff), the initiator MUST respond + with a NOP-Out. In this case, the NOP-Out Target Transfer Tag MUST + contain a copy of the NOP-In Target Transfer Tag. The initiator + + SHOULD NOT send a NOP-Out in response to any other received NOP-In, + in order to avoid lengthy sequences of NOP-In and NOP-Out PDUs sent + in response to each other. +*/ +typedef struct __attribute__((packed)) iscsi_nop_out { + uint8_t opcode; // Always 0x00 according to specification (see above) + uint8_t reserved[3]; // Reserved for future usage + uint8_t total_ahs_len; // TotalAHSLength + uint8_t ds_len[3]; // DataSegmentLength + uint64_t lun; // LUN or Reserved + uint32_t init_task_tag; // The NOP-Out MUST have the Initiator Task Tag set to a valid value + // only if a response in the form of a NOP-In is requested (i.e., the + // NOP-Out is used as a ping request). Otherwise, the Initiator Task + // Tag MUST be set to 0xFFFFFFFF. + // When a target receives the NOP-Out with a valid Initiator Task Tag, + // it MUST respond with a NOP-In Response. + // If the Initiator Task Tag contains 0xFFFFFFFF, the I bit MUST be set + // to 1, and the CmdSN is not advanced after this PDU is sent + uint32_t target_xfer_tag; // The Target Transfer Tag is a target-assigned identifier for the + // operation. + // The NOP-Out MUST only have the Target Transfer Tag set if it is + // issued in response to a NOP-In with a valid Target Transfer Tag. In + // this case, it copies the Target Transfer Tag from the NOP-In PDU. + // Otherwise, the Target Transfer Tag MUST be set to 0xFFFFFFFF. + // When the Target Transfer Tag is set to a value other than 0xFFFFFFFF, + // the LUN field MUST also be copied from the NOP-In + uint32_t cmd_sn; // CmdSN + uint32_t exp_stat_sn; // ExpStatSN + uint64_t reserved2[2]; // Reserved for future usage + struct iscsi_header_digest hdr_digest; // Optional header digest + struct iscsi_ds_cmd_data ds_ping_data; // DataSegment - Ping Data (optional) + // Ping data is reflected in the NOP-In Response. The length of the + // reflected data is limited to MaxRecvDataSegmentLength. The length of + // ping data is indicated by the DataSegmentLength. 0 is a valid value + // for the DataSegmentLength and indicates the absence of ping data + struct iscsi_data_digest data_digest; // Optional data digest +} iscsi_nop_out; + +/* NOP-In is sent by a target as either a response to a NOP-Out, a + "ping" to an initiator, or a means to carry a changed ExpCmdSN and/or + MaxCmdSN if another PDU will not be available for a long time (as + determined by the target). + + When a target receives the NOP-Out with a valid Initiator Task Tag + (not the reserved value 0xFFFFFFFF), it MUST respond with a NOP-In + with the same Initiator Task Tag that was provided in the NOP-Out + request. It MUST also duplicate up to the first + MaxRecvDataSegmentLength bytes of the initiator-provided Ping Data. + For such a response, the Target Transfer Tag MUST be 0xFFFFFFFF. The + + target SHOULD NOT send a NOP-In in response to any other received + NOP-Out in order to avoid lengthy sequences of NOP-In and NOP-Out + PDUs sent in response to each other. + + Otherwise, when a target sends a NOP-In that is not a response to a + NOP-Out received from the initiator, the Initiator Task Tag MUST be + set to 0xFFFFFFFF, and the data segment MUST NOT contain any data + (DataSegmentLength MUST be 0). +*/ + +typedef struct __attribute__((packed)) iscsi_nop_in { + uint8_t opcode; // Always 0x20 according to specification (see above) + uint8_t reserved[3]; // Reserved for future usage + uint8_t total_ahs_len; // TotalAHSLength + uint8_t ds_len[3]; // DataSegmentLength + uint64_t lun; // A LUN MUST be set to a correct value when the Target Transfer Tag is + // valid (not the reserved value 0xFFFFFFFF) + uint32_t init_task_tag; // Initiator task tag or 0xFFFFFFFF + uint32_t target_xfer_tag; // If the target is responding to a NOP-Out, this field is set to the + // reserved value 0xFFFFFFFF. + // If the target is sending a NOP-In as a ping (intending to receive a + // corresponding NOP-Out), this field is set to a valid value (not the + // reserved value 0xFFFFFFFF). + // If the target is initiating a NOP-In without wanting to receive a + // corresponding NOP-Out, this field MUST hold the reserved value + // 0xFFFFFFFF + uint32_t stat_sn; // The StatSN field will always contain the next StatSN. However, when + // the Initiator Task Tag is set to 0xFFFFFFFF, the StatSN for the + // connection is not advanced after this PDU is sent + uint32_t exp_cmd_sn; // ExpCmdSN + uint32_t max_cmd_sn; // MaxCmdSN + uint32_t reserved[3]; // Reserved for future usage + struct iscsi_header_digest hdr_digest; // Optional header digest + struct iscsi_ds_cmd_data ds_ping_data; // DataSegment - Return Ping Data + struct iscsi_data_digest data_digest; // Optional data digest +} iscsi_nop_in; #endif /* DNBD3_ISCSI_H_ */ -- cgit v1.2.3-55-g7522