mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-05-20 19:29:28 +02:00
Optimized connection receive buffer allocation
This commit is contained in:
parent
790f28704f
commit
eda010c37d
7 changed files with 47 additions and 8 deletions
|
@ -19,10 +19,10 @@ namespace SMBLibrary.Client
|
||||||
private Socket m_clientSocket;
|
private Socket m_clientSocket;
|
||||||
private NBTConnectionReceiveBuffer m_receiveBuffer;
|
private NBTConnectionReceiveBuffer m_receiveBuffer;
|
||||||
|
|
||||||
public ConnectionState(Socket clientSocket, bool isLargeMTU)
|
public ConnectionState(Socket clientSocket)
|
||||||
{
|
{
|
||||||
m_clientSocket = clientSocket;
|
m_clientSocket = clientSocket;
|
||||||
m_receiveBuffer = new NBTConnectionReceiveBuffer(isLargeMTU);
|
m_receiveBuffer = new NBTConnectionReceiveBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Socket ClientSocket
|
public Socket ClientSocket
|
||||||
|
|
|
@ -143,7 +143,7 @@ namespace SMBLibrary.Client
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionState state = new ConnectionState(m_clientSocket, false);
|
ConnectionState state = new ConnectionState(m_clientSocket);
|
||||||
NBTConnectionReceiveBuffer buffer = state.ReceiveBuffer;
|
NBTConnectionReceiveBuffer buffer = state.ReceiveBuffer;
|
||||||
m_clientSocket.BeginReceive(buffer.Buffer, buffer.WriteOffset, buffer.AvailableLength, SocketFlags.None, new AsyncCallback(OnClientSocketReceive), state);
|
m_clientSocket.BeginReceive(buffer.Buffer, buffer.WriteOffset, buffer.AvailableLength, SocketFlags.None, new AsyncCallback(OnClientSocketReceive), state);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -136,7 +136,7 @@ namespace SMBLibrary.Client
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionState state = new ConnectionState(m_clientSocket, true);
|
ConnectionState state = new ConnectionState(m_clientSocket);
|
||||||
NBTConnectionReceiveBuffer buffer = state.ReceiveBuffer;
|
NBTConnectionReceiveBuffer buffer = state.ReceiveBuffer;
|
||||||
m_clientSocket.BeginReceive(buffer.Buffer, buffer.WriteOffset, buffer.AvailableLength, SocketFlags.None, new AsyncCallback(OnClientSocketReceive), state);
|
m_clientSocket.BeginReceive(buffer.Buffer, buffer.WriteOffset, buffer.AvailableLength, SocketFlags.None, new AsyncCallback(OnClientSocketReceive), state);
|
||||||
return true;
|
return true;
|
||||||
|
@ -392,6 +392,21 @@ namespace SMBLibrary.Client
|
||||||
|
|
||||||
m_availableCredits += command.Header.Credits;
|
m_availableCredits += command.Header.Credits;
|
||||||
|
|
||||||
|
if (m_transport == SMBTransportType.DirectTCPTransport && command is NegotiateResponse)
|
||||||
|
{
|
||||||
|
NegotiateResponse negotiateResponse = (NegotiateResponse)command;
|
||||||
|
if ((negotiateResponse.Capabilities & Capabilities.LargeMTU) > 0)
|
||||||
|
{
|
||||||
|
// [MS-SMB2] 3.2.5.1 Receiving Any Message - If the message size received exceeds Connection.MaxTransactSize, the client MUST disconnect the connection.
|
||||||
|
// Note: Windows clients do not enforce the MaxTransactSize value, we add 256 bytes.
|
||||||
|
int maxPacketSize = SessionPacket.HeaderLength + (int)Math.Min(negotiateResponse.MaxTransactSize, ClientMaxTransactSize) + 256;
|
||||||
|
if (maxPacketSize > state.ReceiveBuffer.Buffer.Length)
|
||||||
|
{
|
||||||
|
state.ReceiveBuffer.IncreaseBufferSize(maxPacketSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// [MS-SMB2] 3.2.5.1.2 - If the MessageId is 0xFFFFFFFFFFFFFFFF, this is not a reply to a previous request,
|
// [MS-SMB2] 3.2.5.1.2 - If the MessageId is 0xFFFFFFFFFFFFFFFF, this is not a reply to a previous request,
|
||||||
// and the client MUST NOT attempt to locate the request, but instead process it as follows:
|
// and the client MUST NOT attempt to locate the request, but instead process it as follows:
|
||||||
// If the command field in the SMB2 header is SMB2 OPLOCK_BREAK, it MUST be processed as specified in 3.2.5.19.
|
// If the command field in the SMB2 header is SMB2 OPLOCK_BREAK, it MUST be processed as specified in 3.2.5.19.
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace SMBLibrary.NetBios
|
||||||
private int m_bytesInBuffer = 0;
|
private int m_bytesInBuffer = 0;
|
||||||
private int? m_packetLength;
|
private int? m_packetLength;
|
||||||
|
|
||||||
public NBTConnectionReceiveBuffer(bool isLargeMTU) : this(isLargeMTU ? SessionPacket.MaxDirectTcpPacketLength : SessionPacket.MaxSessionPacketLength)
|
public NBTConnectionReceiveBuffer() : this(SessionPacket.MaxSessionPacketLength)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,17 @@ namespace SMBLibrary.NetBios
|
||||||
m_buffer = new byte[bufferLength];
|
m_buffer = new byte[bufferLength];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void IncreaseBufferSize(int bufferLength)
|
||||||
|
{
|
||||||
|
byte[] buffer = new byte[bufferLength];
|
||||||
|
if (m_bytesInBuffer > 0)
|
||||||
|
{
|
||||||
|
Array.Copy(m_buffer, m_readOffset, buffer, 0, m_bytesInBuffer);
|
||||||
|
m_readOffset = 0;
|
||||||
|
}
|
||||||
|
m_buffer = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetNumberOfBytesReceived(int numberOfBytesReceived)
|
public void SetNumberOfBytesReceived(int numberOfBytesReceived)
|
||||||
{
|
{
|
||||||
m_bytesInBuffer += numberOfBytesReceived;
|
m_bytesInBuffer += numberOfBytesReceived;
|
||||||
|
|
|
@ -29,11 +29,11 @@ namespace SMBLibrary.Server
|
||||||
public SMBDialect Dialect;
|
public SMBDialect Dialect;
|
||||||
public GSSContext AuthenticationContext;
|
public GSSContext AuthenticationContext;
|
||||||
|
|
||||||
public ConnectionState(Socket clientSocket, IPEndPoint clientEndPoint, SMBTransportType transportType, LogDelegate logToServerHandler)
|
public ConnectionState(Socket clientSocket, IPEndPoint clientEndPoint, LogDelegate logToServerHandler)
|
||||||
{
|
{
|
||||||
m_clientSocket = clientSocket;
|
m_clientSocket = clientSocket;
|
||||||
m_clientEndPoint = clientEndPoint;
|
m_clientEndPoint = clientEndPoint;
|
||||||
m_receiveBuffer = new NBTConnectionReceiveBuffer(transportType == SMBTransportType.DirectTCPTransport);
|
m_receiveBuffer = new NBTConnectionReceiveBuffer();
|
||||||
m_sendQueue = new BlockingQueue<SessionPacket>();
|
m_sendQueue = new BlockingQueue<SessionPacket>();
|
||||||
m_creationDT = DateTime.UtcNow;
|
m_creationDT = DateTime.UtcNow;
|
||||||
m_lastReceiveDT = DateTime.UtcNow;
|
m_lastReceiveDT = DateTime.UtcNow;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using SMBLibrary.Authentication.GSSAPI;
|
using SMBLibrary.Authentication.GSSAPI;
|
||||||
|
using SMBLibrary.NetBios;
|
||||||
using SMBLibrary.SMB2;
|
using SMBLibrary.SMB2;
|
||||||
using Utilities;
|
using Utilities;
|
||||||
|
|
||||||
|
@ -53,6 +54,12 @@ namespace SMBLibrary.Server.SMB2
|
||||||
response.MaxTransactSize = ServerMaxTransactSizeLargeMTU;
|
response.MaxTransactSize = ServerMaxTransactSizeLargeMTU;
|
||||||
response.MaxReadSize = ServerMaxReadSizeLargeMTU;
|
response.MaxReadSize = ServerMaxReadSizeLargeMTU;
|
||||||
response.MaxWriteSize = ServerMaxWriteSizeLargeMTU;
|
response.MaxWriteSize = ServerMaxWriteSizeLargeMTU;
|
||||||
|
// [MS-SMB2] 3.3.5.2 Receiving Any Message - If the length of the message exceeds Connection.MaxTransactSize + 256, the server MUST disconnect the connection.
|
||||||
|
int maxPacketSize = SessionPacket.HeaderLength + (int)ServerMaxTransactSize + 256;
|
||||||
|
if (maxPacketSize > state.ReceiveBuffer.Buffer.Length)
|
||||||
|
{
|
||||||
|
state.ReceiveBuffer.IncreaseBufferSize(maxPacketSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -92,6 +99,12 @@ namespace SMBLibrary.Server.SMB2
|
||||||
response.MaxTransactSize = ServerMaxTransactSizeLargeMTU;
|
response.MaxTransactSize = ServerMaxTransactSizeLargeMTU;
|
||||||
response.MaxReadSize = ServerMaxReadSizeLargeMTU;
|
response.MaxReadSize = ServerMaxReadSizeLargeMTU;
|
||||||
response.MaxWriteSize = ServerMaxWriteSizeLargeMTU;
|
response.MaxWriteSize = ServerMaxWriteSizeLargeMTU;
|
||||||
|
// [MS-SMB2] 3.3.5.2 Receiving Any Message - If the length of the message exceeds Connection.MaxTransactSize + 256, the server MUST disconnect the connection.
|
||||||
|
int maxPacketSize = SessionPacket.HeaderLength + (int)ServerMaxTransactSize + 256;
|
||||||
|
if (maxPacketSize > state.ReceiveBuffer.Buffer.Length)
|
||||||
|
{
|
||||||
|
state.ReceiveBuffer.IncreaseBufferSize(maxPacketSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -160,7 +160,7 @@ namespace SMBLibrary.Server
|
||||||
|
|
||||||
if (acceptConnection)
|
if (acceptConnection)
|
||||||
{
|
{
|
||||||
ConnectionState state = new ConnectionState(clientSocket, clientEndPoint, m_transport, Log);
|
ConnectionState state = new ConnectionState(clientSocket, clientEndPoint, Log);
|
||||||
state.LogToServer(Severity.Verbose, "New connection request accepted");
|
state.LogToServer(Severity.Verbose, "New connection request accepted");
|
||||||
Thread senderThread = new Thread(delegate()
|
Thread senderThread = new Thread(delegate()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue