Browse Source

Server: Bugfix: Some connection resources were not released after send error in some cases

Tal Aloni 7 years ago
parent
commit
89a9238d8a
2 changed files with 29 additions and 2 deletions
  1. 25 0
      SMBLibrary/Server/ConnectionManager.cs
  2. 4 2
      SMBLibrary/Server/SMBServer.cs

+ 25 - 0
SMBLibrary/Server/ConnectionManager.cs

@@ -6,6 +6,7 @@
  */
 using System;
 using System.Collections.Generic;
+using System.Net;
 using Utilities;
 
 namespace SMBLibrary.Server
@@ -44,6 +45,15 @@ namespace SMBLibrary.Server
             RemoveConnection(connection);
         }
 
+        public void ReleaseConnection(IPEndPoint clientEndPoint)
+        {
+            ConnectionState connection = FindConnection(clientEndPoint);
+            if (connection != null)
+            {
+                ReleaseConnection(connection);
+            }
+        }
+
         public void ReleaseAllConnections()
         {
             List<ConnectionState> connections = new List<ConnectionState>(m_activeConnections);
@@ -53,6 +63,21 @@ namespace SMBLibrary.Server
             }
         }
 
+        private ConnectionState FindConnection(IPEndPoint clientEndPoint)
+        {
+            lock (m_activeConnections)
+            {
+                for (int index = 0; index < m_activeConnections.Count; index++)
+                {
+                    if (m_activeConnections[index].ClientEndPoint.Equals(clientEndPoint))
+                    {
+                        return m_activeConnections[index];
+                    }
+                }
+            }
+            return null;
+        }
+
         public List<SessionInformation> GetSessionsInformation()
         {
             List<SessionInformation> result = new List<SessionInformation>();

+ 4 - 2
SMBLibrary/Server/SMBServer.cs

@@ -357,13 +357,15 @@ namespace SMBLibrary.Server
                 catch (SocketException ex)
                 {
                     state.LogToServer(Severity.Debug, "Failed to send packet. SocketException: {0}", ex.Message);
-                    m_connectionManager.ReleaseConnection(state);
+                    // Note: m_connectionManager contains SMB1ConnectionState or SMB2ConnectionState instances that were constructed from the initial
+                    // ConnectionState instance given to this method. for this reason, we must use state.ClientEndPoint to find and release the connection.
+                    m_connectionManager.ReleaseConnection(state.ClientEndPoint);
                     return;
                 }
                 catch (ObjectDisposedException)
                 {
                     state.LogToServer(Severity.Debug, "Failed to send packet. ObjectDisposedException.");
-                    m_connectionManager.ReleaseConnection(state);
+                    m_connectionManager.ReleaseConnection(state.ClientEndPoint);
                     return;
                 }
             }