3.2.7.1 Handling a Network Disconnect
When the underlying transport indicates a disconnect, for each Session in Connection.SessionTable, the client MUST perform the following:
If Connection.Dialect belongs to the SMB 3.x dialect family, and the Session has more than one channel in Session.ChannelList, the client MUST perform the following actions:
The channel entry MUST be removed from the Session.ChannelList, where Channel.Connection matches the disconnected connection.
For each outstanding create request in Connection.OutstandingRequests containing SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 context, the client MUST replay the create request on an alternate channel by setting the SMB2_FLAGS_REPLAY_OPERATION bit in the SMB2 header.
Session.ChannelSequence MUST be incremented by 1.
If Session.Connection matches the disconnected connection, Session.Connection MUST be set to the first entry in Session.ChannelList.
Otherwise, the client MUST perform the following actions:
For each Open in Session.OpenTable:
If Connection.Dialect is not "2.0.2" and Connection.SupportsFileLeasing is TRUE, the client MUST locate the File in the GlobalFileTable by looking up Open.FileName. The client MUST delete the Open from the File.OpenTable.
If Connection.Dialect belongs to the SMB 3.x dialect family and if Connection.SupportsDirectoryLeasing is TRUE, and if all opens in File.OpenTable are deleted and if there is no entry in the GlobalFileTable whose name with its last component removed matches the Open.FileName, then the entry for the File MUST be deleted from the GlobalFileTable, and the File object MUST be freed.
Otherwise, if all opens in File.OpenTable are deleted, then the entry for this File MUST be deleted from the GlobalFileTable, and the File object MUST be freed.
If Open.Durable is not TRUE, the Open MUST be removed from the Session.OpenTable and freed, and the handle generated for the Open MUST be invalidated.
If Open.Durable is TRUE, the Open MUST be removed from the Session.OpenTable, the Open.Connection MUST be set to NULL, and the Open.TreeConnect MUST be set to NULL. The client SHOULD<205> attempt to re-establish the durable open as specified in section 3.2.4.4. If Connection.Dialect belongs to the SMB 3.x dialect family, Open.Durable is TRUE, and the client fails to re-establish the durable open within Open.DurableTimeout milliseconds, the Open MUST be freed and the handle generated for the Open MUST be invalidated.
If Open.ResilientHandle or Open.IsPersistent is TRUE, the client MUST perform the following steps:
Capture the current system time at which the disconnect occurred into Open.LastDisconnectTime.
Attempt to reestablish the durable open as specified in section 3.2.4.4.
If the reestablishment fails with a network error, the client MUST retry the reestablishment of the open for at least Open.ResilientTimeout milliseconds after Open.LastDisconnectTime, before giving up.
If the reestablishment of the durable handle fails, Open.Durable MUST be set to FALSE, Open.ResilientHandle MUST be set to FALSE, the Open MUST be removed from Session.OpenTable and the Open MUST be freed, and the handle generated for the Open MUST be invalidated.
Each TreeConnect in Session.TreeConnectTable MUST be freed, the handle generated for the TreeConnect MUST be invalidated, and the TreeConnect entry MUST be removed from Session.TreeConnectTable.
If Connection.Dialect belongs to the SMB 3.x dialect family, the client MUST free the channel and remove the channel entry in Session.ChannelList.
The client MUST free the Session and invalidate the session handle.
If Connection.Dialect belongs to the SMB 3.x dialect family and if Session.TreeConnectTable is empty in all sessions in the Connection.SessionTable for which Connection.ServerName matches the server name, the client SHOULD invoke the event as specified in [MS-SWN] section 3.2.4.3.
Finally, the connection MUST be removed from the ConnectionTable and freed.