3.1.5.8 Receiving a Data Transfer Message

All other messages received by either side of the connection are Data Transfer Messages.

The receiver of the message MUST verify:

  • The length of the received message is at least 20 bytes.

  • The received CreditsRequested field is at least 1.

  • The received DataOffset field is 8-byte aligned.

  • The sum of the received DataOffset and DataLength fields are less than or equal to the length of the received message.

  • The sum of the received DataLength and RemainingDataLength of the message is less than or equal to Connection.MaxFragmentSize.

If any of the preceding conditions are not satisfied, the receiver MUST terminate the connection and cease further processing.

The value of Connection.ReceiveCredits MUST be decremented by one.

If Connection.SendQueue is empty, the credit processing specified in section 3.1.5.9 MUST be performed. If the number of new credits returned is greater than zero, the receiver MUST promptly send a newly constructed Data Transfer message with its CreditsGranted field set to the number of new credits on the Connection, as specified in section 3.1.5.1.

The value of Connection.ReceiveCreditTarget MUST be set to the value of the received CreditsRequested field.

If the SMB_DIRECT_RESPONSE_REQUESTED flag is set in the received Flags field, then Connection.KeepaliveRequested MUST be set to "PENDING". The receiver MUST set Connection.SendImmediate to TRUE and promptly send a Data Transfer message on the Connection, as specified in section 3.1.5.1.

If the received CreditsGranted field is greater than zero, the receiver:

  • MUST increment Connection.SendCredits by the value of the received CreditsGranted field.

  • If the Connection.SendQueue is not empty, attempt to restart the send of any such messages as specified in section 3.1.5.1.

The contents of the incoming buffer, at the offset defined by DataOffset and the length defined by DataLength, MUST be appended to Connection.FragmentReassemblyBuffer.

If Connection.FragmentReassemblyRemaining is zero, Connection.FragmentReassemblyRemaining MUST be set to RemainingDataLength. Otherwise, Connection.FragmentReassemblyRemaining MUST be reduced by the received DataLength.

If the RDMA provider indicates that a local memory token was invalidated in the process of receiving the current segment, the receiver MUST set Connection.InvalidatedToken to the value of the token indicated by the RDMA provider, overwriting any previous value, if present.

If the received RemainingDataLength field of the message is zero, then:

  • If Connection.FragmentReassemblyRemaining is greater than zero, then the receiver MUST terminate the connection and cease further processing.

  • If the Connection.InvalidatedToken is not empty, it MUST be passed to the upper layer, and its contents MUST be cleared.

  • The Connection.FragmentReassemblyBuffer contents MUST be passed to the upper layer, and the Connection.FragmentReassemblyBuffer MUST be cleared.