Browse Source

Improved login logic, proper session / connection reinstatement is now performed during login

Tal Aloni 8 years ago
parent
commit
aea69662bb

+ 5 - 0
ISCSI/ISCSI.Server/ConnectionManager.cs

@@ -72,6 +72,11 @@ namespace ISCSI.Server
             }
         }
 
+        public List<ConnectionState> GetSessionConnections(ISCSISession session)
+        {
+            return GetSessionConnections(session.ISID, session.TSIH);
+        }
+
         public List<ConnectionState> GetSessionConnections(ulong isid, ushort tsih)
         {
             List<ConnectionState> result = new List<ConnectionState>();

+ 31 - 4
ISCSI/ISCSI.Server/ISCSIServer.Login.cs

@@ -76,26 +76,53 @@ namespace ISCSI.Server
             bool isNewSession = false;
             if (connection.Session == null)
             {
+                ISCSISession existingSession = m_sessionManager.FindSession(request.ISID);
                 if (request.TSIH == 0)
                 {
+                    if (existingSession != null)
+                    {
+                        // Do session reinstatement:
+                        List<ConnectionState> existingConnections = m_connectionManager.GetSessionConnections(existingSession);
+                        foreach (ConnectionState existingConnection in existingConnections)
+                        {
+                            m_connectionManager.ReleaseConnection(existingConnection);
+                        }
+                        m_sessionManager.RemoveSession(existingSession);
+                    }
                     // For a new session, the request TSIH is zero,
                     // As part of the response, the target generates a TSIH.
                     connection.Session = m_sessionManager.StartSession(request.ISID);
+                    connection.CID = request.CID;
                     Log(Severity.Verbose, "[{0}] Session has been started", connection.Session.SessionIdentifier);
                     connection.Session.CommandNumberingStarted = true;
                     connection.Session.ExpCmdSN = request.CmdSN;
                     isNewSession = true;
                 }
+                else if ((existingSession == null) ||
+                         (existingSession != null && request.TSIH != existingSession.TSIH))
+                {
+                    response.TSIH = request.TSIH;
+                    response.Status = LoginResponseStatusName.SessionDoesNotExist;
+                    return response;
+                }
                 else
                 {
-                    ISCSISession existingSession = m_sessionManager.FindSession(request.ISID, request.TSIH);
-                    if (existingSession == null)
+                    connection.Session = existingSession;
+                    connection.CID = request.CID;
+                    ConnectionState existingConnection = m_connectionManager.FindConnection(request.ISID, request.TSIH, request.CID);
+                    if (existingConnection != null)
+                    {
+                        // do connection reinstatement
+                        Log(Severity.Verbose, "[{0}] Initiating implicit logout", existingConnection.ConnectionIdentifier);
+                        m_connectionManager.ReleaseConnection(existingConnection);
+                    }
+                    else
                     {
+                        // add a new connection to the session
                         response.TSIH = request.TSIH;
-                        response.Status = LoginResponseStatusName.SessionDoesNotExist;
+                        response.Status = LoginResponseStatusName.TooManyConnections;
                         return response;
                     }
-                    connection.Session = existingSession;
                 }
                 isFirstLoginRequest = true;
             }

+ 0 - 14
ISCSI/ISCSI.Server/ISCSIServer.PDUProcessor.cs

@@ -62,23 +62,9 @@ namespace ISCSI.Server
                 {
                     LoginRequestPDU request = (LoginRequestPDU)pdu;
                     Log(Severity.Verbose, "[{0}] Login Request, current stage: {1}, next stage: {2}, parameters: {3}", state.ConnectionIdentifier, request.CurrentStage, request.NextStage, FormatNullDelimitedText(request.LoginParametersText));
-                    if (request.TSIH != 0)
-                    {
-                        // RFC 3720: A Login Request with a non-zero TSIH and a CID equal to that of an existing
-                        // connection implies a logout of the connection followed by a Login
-                        ConnectionState existingConnection = m_connectionManager.FindConnection(request.ISID, request.TSIH, request.CID);
-                        if (existingConnection != null)
-                        {
-                            // Perform implicit logout
-                            Log(Severity.Verbose, "[{0}] Initiating implicit logout", state.ConnectionIdentifier);
-                            m_connectionManager.ReleaseConnection(existingConnection);
-                            Log(Severity.Verbose, "[{0}] Implicit logout completed", state.ConnectionIdentifier);
-                        }
-                    }
                     LoginResponsePDU response = GetLoginResponsePDU(request, state.ConnectionParameters);
                     if (state.Session != null && state.Session.IsFullFeaturePhase)
                     {
-                        state.ConnectionParameters.CID = request.CID;
                         m_connectionManager.AddConnection(state);
                     }
                     Log(Severity.Verbose, "[{0}] Login Response parameters: {1}", state.ConnectionIdentifier, FormatNullDelimitedText(response.LoginParametersText));

+ 5 - 6
ISCSI/ISCSI.Server/SessionManager.cs

@@ -28,11 +28,11 @@ namespace ISCSI.Server
             return session;
         }
 
-        public ISCSISession FindSession(ulong isid, ushort tsih)
+        public ISCSISession FindSession(ulong isid)
         {
             lock (m_activeSessions)
             {
-                int index = GetSessionIndex(isid, tsih);
+                int index = GetSessionIndex(isid);
                 if (index >= 0)
                 {
                     return m_activeSessions[index];
@@ -45,7 +45,7 @@ namespace ISCSI.Server
         {
             lock (m_activeSessions)
             {
-                int index = GetSessionIndex(session.ISID, session.TSIH);
+                int index = GetSessionIndex(session.ISID);
                 m_activeSessions.RemoveAt(index);
             }
         }
@@ -68,12 +68,11 @@ namespace ISCSI.Server
             return false;
         }
 
-        private int GetSessionIndex(ulong isid, ushort tsih)
+        private int GetSessionIndex(ulong isid)
         {
             for (int index = 0; index < m_activeSessions.Count; index++)
             {
-                if (m_activeSessions[index].ISID == isid &&
-                    m_activeSessions[index].TSIH == tsih)
+                if (m_activeSessions[index].ISID == isid)
                 {
                     return index;
                 }