3.3.7.1 Handling Loss of a Connection

When the underlying transport indicates loss of a connection or after the server initiates a transport disconnect, for each session in Connection.SessionTable, the server MUST perform the following:

If Connection.Dialect belongs to the SMB 3.x dialect family and if the Session has more than one channel in Session.ChannelList, the server MUST perform the following action:

  • All requests in Session.Channel.Connection.RequestList MUST be canceled. The server SHOULD<436> pass the CancelRequestId to the object store to request cancellation of the pending operation.

  • The channel entry MUST be removed from the Session.ChannelList where Channel.Connection matches the disconnected connection.

  • If Session.Connection matches the disconnected connection, Session.Connection MUST be set to the first entry in Session.ChannelList.

Otherwise, the server MUST perform the following actions:

  • The server MUST iterate over the Session.OpenTable and determine whether each Open is to be preserved for reconnect. If any of the following conditions is satisfied, it indicates that the Open is to be preserved for reconnect.

    • Open.IsResilient is TRUE.

    • Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_BATCH and Open.OplockState is equal to Held, and Open.IsDurable is TRUE.

    • Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_LEASE, Lease.LeaseState contains SMB2_LEASE_HANDLE_CACHING, Open.OplockState is equal to Held, and Open.IsDurable is TRUE.

    • Open.IsPersistent is TRUE.

      If the Open is to be preserved for reconnect, perform the following actions:

    • Set Open.Connection to NULL, Open.Session to NULL, Open.TreeConnect to NULL.

    • If Open.IsResilient is TRUE, set Open.ResilientOpenTimeOut to the current time plus Open.ResiliencyTimeout. The server SHOULD<437> start or reset the Resilient Open Scavenger Timer, as specified in section 3.3.2.4, under the following conditions:

      • If the Resilient Open Scavenger Timer is not already active.

      • If the Resilient Open Scavenger Timer is active and ResilientOpenScavengerExpiryTime is greater than Open.ResilientOpenTimeOut.

        In both of the preceding cases, the server MUST set the timer to expire at Open.ResilientOpenTimeOut and MUST set ResilientOpenScavengerExpiryTime to Open.ResilientOpenTimeOut.

    • If Open.IsDurable is TRUE, the server MUST do the following:

      • The server MUST set Open.DurableOpenScavengerTimeout to the system time plus Open.DurableOpenTimeOut.

      • The server MUST start the durable open scavenger timer, as specified in sections 3.3.2.2.

        If the Open is not to be preserved for reconnect, the server MUST close the Open as specified in section 3.3.4.17.

  • The server MUST disconnect every TreeConnect in Session.TreeConnectTable and deregister the TreeConnect by invoking the event specified in [MS-SRVS] section 3.1.6.7, providing the tuple <TreeConnect.Share.ServerName, TreeConnect.Share.Name> and  TreeConnect.TreeGlobalId as the input parameters, and the TreeConnect MUST be removed from Session.TreeConnectTable and freed. For each deregistered TreeConnect, TreeConnect.Share.CurrentUses MUST be decreased by 1.

  • The server MUST deregister the Session by invoking the event specified in [MS-SRVS] section 3.1.6.3, providing Session.SessionGlobalId as the input parameter, and the Session MUST be removed from GlobalSessionTable and freed. ServerStatistics.sts0_sopens MUST be decreased by 1.

All requests in Connection.RequestList MUST be canceled. The server SHOULD<438> pass the CancelRequestId to the object store to request cancellation of the pending operation.

The server MUST invoke the event specified in [MS-SRVS] section 3.1.6.16 to update the connection count by providing the tuple <Connection.TransportName,FALSE>.

The connection MUST be removed from ConnectionList and MUST be freed.

If the server implements the SMB 3.x dialect family, the server MUST enumerate all connections in ConnectionList using the removed Connection.ClientGuid where Connection.Dialect is not “2.0.2”. If no Connection entry is found, the server MAY remove the Client entry identified by Connection.ClientGuid from GlobalClientTable.