Server, Client: Fix thread-safety violations related to NBTConnectionReceiveBuffer

This commit is contained in:
Tal Aloni 2024-06-02 10:11:09 +03:00
parent 1a8c94ba94
commit ac403baf41
5 changed files with 180 additions and 165 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2023 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2024 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -172,7 +172,10 @@ namespace SMBLibrary.Client
{ {
m_clientSocket.Disconnect(false); m_clientSocket.Disconnect(false);
m_clientSocket.Close(); m_clientSocket.Close();
lock (m_connectionState.ReceiveBuffer)
{
m_connectionState.ReceiveBuffer.Dispose(); m_connectionState.ReceiveBuffer.Dispose();
}
m_isConnected = false; m_isConnected = false;
m_userID = 0; m_userID = 0;
} }
@ -424,6 +427,8 @@ namespace SMBLibrary.Client
ConnectionState state = (ConnectionState)ar.AsyncState; ConnectionState state = (ConnectionState)ar.AsyncState;
Socket clientSocket = state.ClientSocket; Socket clientSocket = state.ClientSocket;
lock (state.ReceiveBuffer)
{
if (!clientSocket.Connected) if (!clientSocket.Connected)
{ {
state.ReceiveBuffer.Dispose(); state.ReceiveBuffer.Dispose();
@ -485,6 +490,7 @@ namespace SMBLibrary.Client
} }
} }
} }
}
private void ProcessConnectionBuffer(ConnectionState state) private void ProcessConnectionBuffer(ConnectionState state)
{ {

View file

@ -182,7 +182,10 @@ namespace SMBLibrary.Client
{ {
m_clientSocket.Disconnect(false); m_clientSocket.Disconnect(false);
m_clientSocket.Close(); m_clientSocket.Close();
lock (m_connectionState.ReceiveBuffer)
{
m_connectionState.ReceiveBuffer.Dispose(); m_connectionState.ReceiveBuffer.Dispose();
}
m_isConnected = false; m_isConnected = false;
m_messageID = 0; m_messageID = 0;
m_sessionID = 0; m_sessionID = 0;
@ -357,6 +360,8 @@ namespace SMBLibrary.Client
ConnectionState state = (ConnectionState)ar.AsyncState; ConnectionState state = (ConnectionState)ar.AsyncState;
Socket clientSocket = state.ClientSocket; Socket clientSocket = state.ClientSocket;
lock (state.ReceiveBuffer)
{
if (!clientSocket.Connected) if (!clientSocket.Connected)
{ {
state.ReceiveBuffer.Dispose(); state.ReceiveBuffer.Dispose();
@ -418,6 +423,7 @@ namespace SMBLibrary.Client
} }
} }
} }
}
private void ProcessConnectionBuffer(ConnectionState state) private void ProcessConnectionBuffer(ConnectionState state)
{ {

View file

@ -13,11 +13,11 @@ using Utilities;
namespace SMBLibrary.NetBios namespace SMBLibrary.NetBios
{ {
/// <remarks>
/// NBTConnectionReceiveBuffer is not thread-safe.
/// </remarks>
public class NBTConnectionReceiveBuffer : IDisposable public class NBTConnectionReceiveBuffer : IDisposable
{ {
#if NETSTANDARD2_0
private object m_bufferSyncLock = new object();
#endif
private byte[] m_buffer; private byte[] m_buffer;
private int m_readOffset = 0; private int m_readOffset = 0;
private int m_bytesInBuffer = 0; private int m_bytesInBuffer = 0;
@ -131,14 +131,11 @@ namespace SMBLibrary.NetBios
public void Dispose() public void Dispose()
{ {
#if NETSTANDARD2_0 #if NETSTANDARD2_0
lock (m_bufferSyncLock)
{
if (m_buffer != null) if (m_buffer != null)
{ {
ArrayPool<byte>.Shared.Return(m_buffer); ArrayPool<byte>.Shared.Return(m_buffer);
m_buffer = null; m_buffer = null;
} }
}
#else #else
m_buffer = null; m_buffer = null;
#endif #endif

View file

@ -42,7 +42,10 @@ namespace SMBLibrary.Server
connection.SendQueue.Stop(); connection.SendQueue.Stop();
SocketUtils.ReleaseSocket(connection.ClientSocket); SocketUtils.ReleaseSocket(connection.ClientSocket);
connection.CloseSessions(); connection.CloseSessions();
lock (connection.ReceiveBuffer)
{
connection.ReceiveBuffer.Dispose(); connection.ReceiveBuffer.Dispose();
}
RemoveConnection(connection); RemoveConnection(connection);
} }

View file

@ -230,6 +230,8 @@ namespace SMBLibrary.Server
ConnectionState state = (ConnectionState)result.AsyncState; ConnectionState state = (ConnectionState)result.AsyncState;
Socket clientSocket = state.ClientSocket; Socket clientSocket = state.ClientSocket;
lock (state.ReceiveBuffer)
{
if (!m_listening) if (!m_listening)
{ {
clientSocket.Close(); clientSocket.Close();
@ -290,6 +292,7 @@ namespace SMBLibrary.Server
} }
} }
} }
}
private void ProcessConnectionBuffer(ref ConnectionState state) private void ProcessConnectionBuffer(ref ConnectionState state)
{ {