Skip to content

Commit

Permalink
Rework MARSConnection state machine (#933)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wraith2 authored Jul 23, 2021
1 parent 6a5a670 commit ad31bb8
Show file tree
Hide file tree
Showing 11 changed files with 679 additions and 386 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIMarsQueuedPacket.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SNINpHandle.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIPacket.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIPacket.Debug.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIPacketPool.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIPhysicalHandle.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIProxy.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,63 +35,94 @@ internal enum SNIProviders
/// <summary>
/// SMUX packet header
/// </summary>
internal sealed class SNISMUXHeader
internal struct SNISMUXHeader
{
public const int HEADER_LENGTH = 16;

public byte SMID;
public byte flags;
public ushort sessionId;
public uint length;
public uint sequenceNumber;
public uint highwater;
public byte SMID { get; private set; }
public byte Flags { get; private set; }
public ushort SessionId { get; private set; }
public uint Length { get; private set; }
public uint SequenceNumber { get; private set; }
public uint Highwater { get; private set; }

public void Set(byte smid, byte flags, ushort sessionID, uint length, uint sequenceNumber, uint highwater)
{
SMID = smid;
Flags = flags;
SessionId = sessionID;
Length = length;
SequenceNumber = sequenceNumber;
Highwater = highwater;
}

public void Read(byte[] bytes)
{
SMID = bytes[0];
flags = bytes[1];
sessionId = BitConverter.ToUInt16(bytes, 2);
length = BitConverter.ToUInt32(bytes, 4) - SNISMUXHeader.HEADER_LENGTH;
sequenceNumber = BitConverter.ToUInt32(bytes, 8);
highwater = BitConverter.ToUInt32(bytes, 12);
Flags = bytes[1];
SessionId = BitConverter.ToUInt16(bytes, 2);
Length = BitConverter.ToUInt32(bytes, 4) - SNISMUXHeader.HEADER_LENGTH;
SequenceNumber = BitConverter.ToUInt32(bytes, 8);
Highwater = BitConverter.ToUInt32(bytes, 12);
}

public void Write(Span<byte> bytes)
{
uint value = highwater;
uint value = Highwater;
// access the highest element first to cause the largest range check in the jit, then fill in the rest of the value and carry on as normal
bytes[15] = (byte)((value >> 24) & 0xff);
bytes[12] = (byte)(value & 0xff); // BitConverter.GetBytes(_currentHeader.highwater).CopyTo(headerBytes, 12);
bytes[13] = (byte)((value >> 8) & 0xff);
bytes[14] = (byte)((value >> 16) & 0xff);

bytes[0] = SMID; // BitConverter.GetBytes(_currentHeader.SMID).CopyTo(headerBytes, 0);
bytes[1] = flags; // BitConverter.GetBytes(_currentHeader.flags).CopyTo(headerBytes, 1);
bytes[1] = Flags; // BitConverter.GetBytes(_currentHeader.flags).CopyTo(headerBytes, 1);

value = sessionId;
value = SessionId;
bytes[2] = (byte)(value & 0xff); // BitConverter.GetBytes(_currentHeader.sessionId).CopyTo(headerBytes, 2);
bytes[3] = (byte)((value >> 8) & 0xff);

value = length;
value = Length;
bytes[4] = (byte)(value & 0xff); // BitConverter.GetBytes(_currentHeader.length).CopyTo(headerBytes, 4);
bytes[5] = (byte)((value >> 8) & 0xff);
bytes[6] = (byte)((value >> 16) & 0xff);
bytes[7] = (byte)((value >> 24) & 0xff);

value = sequenceNumber;
value = SequenceNumber;
bytes[8] = (byte)(value & 0xff); // BitConverter.GetBytes(_currentHeader.sequenceNumber).CopyTo(headerBytes, 8);
bytes[9] = (byte)((value >> 8) & 0xff);
bytes[10] = (byte)((value >> 16) & 0xff);
bytes[11] = (byte)((value >> 24) & 0xff);

}

public SNISMUXHeader Clone()
{
SNISMUXHeader copy = new SNISMUXHeader();
copy.SMID = SMID;
copy.Flags = Flags;
copy.SessionId = SessionId;
copy.Length = Length;
copy.SequenceNumber = SequenceNumber;
copy.Highwater = Highwater;
return copy;
}

public void Clear()
{
SMID = 0;
Flags = 0;
SessionId = 0;
Length = 0;
SequenceNumber = 0;
Highwater = 0;
}
}

/// <summary>
/// SMUX packet flags
/// </summary>
[Flags]
internal enum SNISMUXFlags
internal enum SNISMUXFlags : uint
{
SMUX_SYN = 1, // Begin SMUX connection
SMUX_ACK = 2, // Acknowledge SMUX packets
Expand Down
Loading

0 comments on commit ad31bb8

Please sign in to comment.