Skip to content

Commit

Permalink
feat: Added bit-acks (#4)
Browse files Browse the repository at this point in the history
* feat: Added fragmentation

* Added fragmented channel

* fix: Fixed various fragmentation issues

* Finalized ReliableSequencedFragmented channel

* Pooled pointer arrays

* Fixed fragment resending

* Added unit tests

* Adjusted defaults and added validation to SocketConfig

* Updated readme

* Removed old comment

* Added print when an invalid channel got a message

* fix: Fixes hashcash difficulty

* Updated socketConfig to use more reasonable defaults

* Reduced example difficulty

* feat: Added unconnected messages

* feat: Added bit-acks

* feat: Added bit-ack to ReliableChannel

* refactor: Removed duplicate configs

* doc(xml): Added xml documentation for config
  • Loading branch information
TwoTenPvP authored Sep 3, 2019
1 parent cf57557 commit 7d9f3ad
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 5 deletions.
46 changes: 44 additions & 2 deletions Ruffles/Channeling/Channels/ReliableChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,33 @@ public void HandleAck(ArraySegment<byte> payload)
// Read the sequence number
ushort sequence = (ushort)(payload.Array[payload.Offset] | (ushort)(payload.Array[payload.Offset + 1] << 8));

// Handle the base ack
HandleAck(sequence);

if ((payload.Count - 2) > 0)
{
// There is more data. This has to be ack bits

// Calculate the amount of ack bits
int bits = (payload.Count - 2) * 8;

// Iterate ack bits
for (byte i = 0; i < bits; i++)
{
// Get the ack for the current bit
bool isAcked = ((payload.Array[payload.Offset + 2 + (i / 8)] & ((byte)Math.Pow(2, (7 - (i % 8))))) >> (7 - (i % 8))) == 1;

if (isAcked)
{
// Handle the bit ack
HandleAck((ushort)(sequence - i));
}
}
}
}

private void HandleAck(ushort sequence)
{
if (_sendSequencer[sequence].Alive)
{
// Dealloc the memory held by the sequencer
Expand Down Expand Up @@ -233,7 +260,7 @@ public void Reset()
private void SendAck(ushort sequence)
{
// Alloc ack memory
HeapMemory ackMemory = memoryManager.AllocHeapMemory(4);
HeapMemory ackMemory = memoryManager.AllocHeapMemory(4 + (uint)(config.EnableMergedAcks ? config.MergedAckBytes : 0));

// Write header
ackMemory.Buffer[0] = HeaderPacker.Pack((byte)MessageType.Ack, false);
Expand All @@ -243,8 +270,23 @@ private void SendAck(ushort sequence)
ackMemory.Buffer[2] = (byte)sequence;
ackMemory.Buffer[3] = (byte)(sequence >> 8);

if (config.EnableMergedAcks)
{
// Reset the memory
for (int i = 0; i < config.MergedAckBytes; i++)
{
ackMemory.Buffer[4 + i] = 0;
}

// Set the bit fields
for (byte i = 0; i < config.MergedAckBytes * 8; i++)
{
ackMemory.Buffer[(i / 8)] |= (byte)(((SequencingUtils.Distance(((ushort)(sequence - (i + 1))), _incomingLowestAckedSequence, sizeof(ushort)) <= 0 || _incomingAckedPackets.Contains(((ushort)(sequence - (i + 1))))) ? 1 : 0) << (7 - (i % 8)));
}
}

// Send ack
connection.SendRaw(new ArraySegment<byte>(ackMemory.Buffer, 0, 4), false);
connection.SendRaw(new ArraySegment<byte>(ackMemory.Buffer, 0, 4 + (config.EnableMergedAcks ? config.MergedAckBytes : 0)), false);

// Return memory
memoryManager.DeAlloc(ackMemory);
Expand Down
46 changes: 44 additions & 2 deletions Ruffles/Channeling/Channels/ReliableSequencedChannel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,33 @@ public void HandleAck(ArraySegment<byte> payload)
// Read the sequence number
ushort sequence = (ushort)(payload.Array[payload.Offset] | (ushort)(payload.Array[payload.Offset + 1] << 8));

// Handle the base ack
HandleAck(sequence);

if ((payload.Count - 2) > 0)
{
// There is more data. This has to be ack bits

// Calculate the amount of ack bits
int bits = (payload.Count - 2) * 8;

// Iterate ack bits
for (byte i = 0; i < bits; i++)
{
// Get the ack for the current bit
bool isAcked = ((payload.Array[payload.Offset + 2 + (i / 8)] & ((byte)Math.Pow(2, (7 - (i % 8))))) >> (7 - (i % 8))) == 1;

if (isAcked)
{
// Handle the bit ack
HandleAck((ushort)(sequence - i));
}
}
}
}

private void HandleAck(ushort sequence)
{
if (_sendSequencer[sequence].Alive)
{
// Dealloc the memory held by the sequencer for the packet
Expand Down Expand Up @@ -242,7 +269,7 @@ public void Reset()
private void SendAck(ushort sequence)
{
// Alloc ack memory
HeapMemory ackMemory = memoryManager.AllocHeapMemory(4);
HeapMemory ackMemory = memoryManager.AllocHeapMemory(4 + (uint)(config.EnableMergedAcks ? config.MergedAckBytes : 0));

// Write header
ackMemory.Buffer[0] = HeaderPacker.Pack((byte)MessageType.Ack, false);
Expand All @@ -252,8 +279,23 @@ private void SendAck(ushort sequence)
ackMemory.Buffer[2] = (byte)sequence;
ackMemory.Buffer[3] = (byte)(sequence >> 8);

if (config.EnableMergedAcks)
{
// Reset the memory
for (int i = 0; i < config.MergedAckBytes; i++)
{
ackMemory.Buffer[4 + i] = 0;
}

// Set the bit fields
for (byte i = 0; i < config.MergedAckBytes * 8; i++)
{
ackMemory.Buffer[(i / 8)] |= (byte)(((SequencingUtils.Distance(((ushort)(sequence - (i + 1))), _incomingLowestAckedSequence, sizeof(ushort)) <= 0 || _receiveSequencer[((ushort)(sequence - (i + 1)))].Alive) ? 1 : 0) << (7 - (i % 8)));
}
}

// Send ack
connection.SendRaw(new ArraySegment<byte>(ackMemory.Buffer, 0, 4), false);
connection.SendRaw(new ArraySegment<byte>(ackMemory.Buffer, 0, 4 + (config.EnableMergedAcks ? config.MergedAckBytes : 0)), false);

// Return memory
memoryManager.DeAlloc(ackMemory);
Expand Down
10 changes: 9 additions & 1 deletion Ruffles/Configuration/SocketConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,15 @@ public class SocketConfig
/// <summary>
/// The maximum delay before merged packets are sent.
/// </summary>
public ulong MaxMergeDelay = 250;
public ulong MaxMergeDelay = 250;
/// <summary>
/// Whether or not to enable merged acks for non fragmented channels.
/// </summary>
public bool EnableMergedAcks = true;
/// <summary>
/// The amount of bytes to use for merged acks.
/// </summary>
public byte MergedAckBytes = 8;

// Fragmentation
/// <summary>
Expand Down

0 comments on commit 7d9f3ad

Please sign in to comment.