4 Commits

Author SHA1 Message Date
eihrul cfb05d051b unreliable fragment fixes 2011-05-31 09:44:09 +00:00
eihrul f38c177db0 support for ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT
1.3.2 release prep
2011-05-31 07:48:27 +00:00
eihrul 33e2fc6201 check received port 2011-05-30 19:00:26 +00:00
eihrul 620e92fa66 updated copyright 2011-03-25 19:41:01 +00:00
10 changed files with 275 additions and 56 deletions
+16
View File
@@ -1,3 +1,10 @@
ENet 1.3.2 (May 31, 2011):
* added support for unreliable packet fragmenting via the packet flag
ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT
* fixed regression in unreliable packet queuing
* added check against received port to limit some forms of IP-spoofing
ENet 1.3.1 (February 10, 2011):
* fixed bug in tracking of reliable data in transit
@@ -21,6 +28,15 @@ Caveats: This version is not protocol compatible with the 1.2 series or
earlier. The enet_host_connect and enet_host_create API functions require
supplying additional parameters.
ENet 1.2.4 (May 31, 2011):
* fixed regression in unreliable packet queuing
* added check against received port to limit some forms of IP-spoofing
ENet 1.2.3 (February 10, 2011):
* fixed bug in tracking reliable data in transit
ENet 1.2.2 (June 5, 2010):
* checksum functionality is now enabled by setting a checksum callback
+1 -1
View File
@@ -16,7 +16,7 @@ enetinclude_HEADERS = \
lib_LTLIBRARIES = libenet.la
libenet_la_SOURCES = callbacks.c compress.c host.c list.c packet.c peer.c protocol.c unix.c win32.c
# see info '(libtool) Updating version info' before making a release
libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:1:0
libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:2:0
INCLUDES = -Iinclude
ACLOCAL_AMFLAGS = -Im4
+1 -1
View File
@@ -1,4 +1,4 @@
AC_INIT([libenet], [1.3.1])
AC_INIT([libenet], [1.3.2])
AC_CONFIG_SRCDIR([include/enet/enet.h])
AM_INIT_AUTOMAKE([foreign])
+1 -1
View File
@@ -1,7 +1,7 @@
/**
@page License License
Copyright (c) 2002-2010 Lee Salzman
Copyright (c) 2002-2011 Lee Salzman
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
+2 -2
View File
@@ -36,8 +36,8 @@ portable, and easily embeddable.
You can retrieve the source to ENet by downloading it in either .tar.gz form
or accessing the cvs distribution directly.
The most recent stable release (1.3.1) can be downloaded <a href="http://enet.bespin.org/download/enet-1.3.1.tar.gz">here</a>.
The last release that is protocol compatible with the 1.2 series or earlier (1.2.3) can be downloaded <a href="http://enet.bespin.org/download/enet-1.2.3.tar.gz">here</a>
The most recent stable release (1.3.2) can be downloaded <a href="http://enet.bespin.org/download/enet-1.3.2.tar.gz">here</a>.
The last release that is protocol compatible with the 1.2 series or earlier (1.2.4) can be downloaded <a href="http://enet.bespin.org/download/enet-1.2.4.tar.gz">here</a>
To access ENet via anonymous CVS, you must use the CVSROOT
:pserver:anonymous\@bespin.org:/var/lib/cvs/enet with an empty
+1
View File
@@ -210,6 +210,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
channel -> outgoingReliableSequenceNumber = 0;
channel -> outgoingUnreliableSequenceNumber = 0;
channel -> incomingReliableSequenceNumber = 0;
channel -> incomingUnreliableSequenceNumber = 0;
enet_list_clear (& channel -> incomingReliableCommands);
enet_list_clear (& channel -> incomingUnreliableCommands);
+6 -2
View File
@@ -25,7 +25,7 @@ extern "C"
#define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3
#define ENET_VERSION_PATCH 1
#define ENET_VERSION_PATCH 2
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
@@ -96,7 +96,10 @@ typedef enum _ENetPacketFlag
*/
ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
/** packet will not allocate data, and user must supply it instead */
ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2)
ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2),
/** packet will be fragmented using unreliable (instead of reliable) sends
* if it exceeds the MTU */
ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3)
} ENetPacketFlag;
struct _ENetPacket;
@@ -218,6 +221,7 @@ typedef struct _ENetChannel
enet_uint16 usedReliableWindows;
enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS];
enet_uint16 incomingReliableSequenceNumber;
enet_uint16 incomingUnreliableSequenceNumber;
ENetList incomingReliableCommands;
ENetList incomingUnreliableCommands;
} ENetChannel;
+2 -1
View File
@@ -33,7 +33,8 @@ typedef enum _ENetProtocolCommand
ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
ENET_PROTOCOL_COMMAND_COUNT = 12,
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12,
ENET_PROTOCOL_COMMAND_COUNT = 13,
ENET_PROTOCOL_COMMAND_MASK = 0x0F
} ENetProtocolCommand;
+94 -32
View File
@@ -113,13 +113,26 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
if (packet -> dataLength > fragmentLength)
{
enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
fragmentNumber,
fragmentOffset;
enet_uint8 commandNumber;
enet_uint16 startSequenceNumber;
ENetList fragments;
ENetOutgoingCommand * fragment;
if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT &&
channel -> outgoingUnreliableSequenceNumber < 0xFFFF)
{
commandNumber = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT;
startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
}
else
{
commandNumber = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
}
enet_list_clear (& fragments);
for (fragmentNumber = 0,
@@ -147,7 +160,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
fragment -> fragmentOffset = fragmentOffset;
fragment -> fragmentLength = fragmentLength;
fragment -> packet = packet;
fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
fragment -> command.header.command = commandNumber;
fragment -> command.header.channelID = channelID;
fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
@@ -173,20 +186,13 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
command.header.channelID = channelID;
if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
}
else
if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNSEQUENCED)) == ENET_PACKET_FLAG_UNSEQUENCED)
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
}
else
if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
if (packet -> flags & ENET_PACKET_FLAG_RELIABLE || channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
@@ -194,7 +200,6 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
else
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
}
@@ -257,14 +262,18 @@ enet_peer_reset_outgoing_commands (ENetList * queue)
}
static void
enet_peer_reset_incoming_commands (ENetList * queue)
enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand)
{
ENetIncomingCommand * incomingCommand;
while (! enet_list_empty (queue))
ENetListIterator currentCommand;
for (currentCommand = startCommand; currentCommand != endCommand; )
{
incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
currentCommand = enet_list_next (currentCommand);
enet_list_remove (& incomingCommand -> incomingCommandList);
if (incomingCommand -> packet != NULL)
{
-- incomingCommand -> packet -> referenceCount;
@@ -280,6 +289,12 @@ enet_peer_reset_incoming_commands (ENetList * queue)
}
}
static void
enet_peer_reset_incoming_commands (ENetList * queue)
{
enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end(queue));
}
void
enet_peer_reset_queues (ENetPeer * peer)
{
@@ -550,7 +565,8 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
}
else
{
++ channel -> outgoingUnreliableSequenceNumber;
if (outgoingCommand -> fragmentOffset == 0)
++ channel -> outgoingUnreliableSequenceNumber;
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
@@ -562,6 +578,20 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
outgoingCommand -> roundTripTimeoutLimit = 0;
outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
switch (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK)
{
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
outgoingCommand -> command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> unreliableSequenceNumber);
break;
case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
outgoingCommand -> command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup);
break;
default:
break;
}
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
else
@@ -590,30 +620,55 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
void
enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
{
ENetListIterator currentCommand;
ENetListIterator droppedCommand, startCommand, currentCommand;
for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands);
for (droppedCommand = startCommand = currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands);
currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
currentCommand = enet_list_next (currentCommand))
{
ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE &&
incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
continue;
else
if (incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
break;
else
if (incomingCommand -> fragmentsRemaining <= 0)
channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber;
else
if (startCommand == currentCommand)
startCommand = enet_list_next (currentCommand);
else
{
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
if (! peer -> needsDispatch)
{
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1;
}
droppedCommand = startCommand = enet_list_next (currentCommand);
}
}
if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands))
return;
enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand));
if (! peer -> needsDispatch)
if (startCommand != currentCommand)
{
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
peer -> needsDispatch = 1;
if (! peer -> needsDispatch)
{
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1;
}
droppedCommand = startCommand = enet_list_next (currentCommand);
}
enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand);
}
void
@@ -640,6 +695,8 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch
if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands))
return;
channel -> incomingUnreliableSequenceNumber = 0;
enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
if (! peer -> needsDispatch)
@@ -684,7 +741,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
goto freePacket;
goto freePacket;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
currentCommand != enet_list_end (& channel -> incomingReliableCommands);
@@ -712,15 +769,20 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
break;
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT:
unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber);
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber &&
unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber)
goto freePacket;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
currentCommand = enet_list_previous (currentCommand))
{
incomingCommand = (ENetIncomingCommand *) currentCommand;
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
continue;
if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+151 -16
View File
@@ -23,6 +23,7 @@ static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
sizeof (ENetProtocolSendUnsequenced),
sizeof (ENetProtocolBandwidthLimit),
sizeof (ENetProtocolThrottleConfigure),
sizeof (ENetProtocolSendFragment)
};
size_t
@@ -319,6 +320,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
channel -> outgoingReliableSequenceNumber = 0;
channel -> outgoingUnreliableSequenceNumber = 0;
channel -> incomingReliableSequenceNumber = 0;
channel -> incomingUnreliableSequenceNumber = 0;
enet_list_clear (& channel -> incomingReliableCommands);
enet_list_clear (& channel -> incomingUnreliableCommands);
@@ -573,12 +575,6 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
return -1;
hostCommand.header.reliableSequenceNumber = startSequenceNumber;
hostCommand.sendFragment.startSequenceNumber = startSequenceNumber;
hostCommand.sendFragment.dataLength = fragmentLength;
hostCommand.sendFragment.fragmentNumber = fragmentNumber;
hostCommand.sendFragment.fragmentCount = fragmentCount;
hostCommand.sendFragment.fragmentOffset = fragmentOffset;
hostCommand.sendFragment.totalLength = totalLength;
startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount);
if (startCommand == NULL)
@@ -605,6 +601,124 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
return 0;
}
static int
enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
{
enet_uint32 fragmentNumber,
fragmentCount,
fragmentOffset,
fragmentLength,
reliableSequenceNumber,
startSequenceNumber,
totalLength;
enet_uint16 reliableWindow, currentWindow;
ENetChannel * channel;
ENetListIterator currentCommand;
ENetIncomingCommand * startCommand = NULL;
if (command -> header.channelID >= peer -> channelCount ||
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
return -1;
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
* currentData += fragmentLength;
if (* currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
channel = & peer -> channels [command -> header.channelID];
reliableSequenceNumber = command -> header.reliableSequenceNumber;
startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber);
reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
return 0;
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber &&
startSequenceNumber <= channel -> incomingUnreliableSequenceNumber)
return 0;
fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber);
fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
if (fragmentOffset >= totalLength ||
fragmentOffset + fragmentLength > totalLength ||
fragmentNumber >= fragmentCount)
return -1;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
currentCommand = enet_list_previous (currentCommand))
{
ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
{
if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
continue;
}
else
if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
break;
if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
break;
if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
continue;
if (incomingCommand -> unreliableSequenceNumber <= startSequenceNumber)
{
if (incomingCommand -> unreliableSequenceNumber < startSequenceNumber)
break;
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT ||
totalLength != incomingCommand -> packet -> dataLength ||
fragmentCount != incomingCommand -> fragmentCount)
return -1;
startCommand = incomingCommand;
break;
}
}
if (startCommand == NULL)
{
ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
if (packet == NULL)
return -1;
startCommand = enet_peer_queue_incoming_command (peer, command, packet, fragmentCount);
if (startCommand == NULL)
return -1;
}
if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0)
{
-- startCommand -> fragmentsRemaining;
startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32));
if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength)
fragmentLength = startCommand -> packet -> dataLength - fragmentOffset;
memcpy (startCommand -> packet -> data + fragmentOffset,
(enet_uint8 *) command + sizeof (ENetProtocolSendFragment),
fragmentLength);
if (startCommand -> fragmentsRemaining <= 0)
enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
}
return 0;
}
static int
enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
@@ -852,7 +966,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
(host -> receivedAddress.host != peer -> address.host &&
((host -> receivedAddress.host != peer -> address.host ||
host -> receivedAddress.port != peer -> address.port) &&
peer -> address.host != ENET_HOST_BROADCAST) ||
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
sessionID != peer -> incomingSessionID))
@@ -985,6 +1100,11 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
goto commandError;
break;
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT:
if (enet_protocol_handle_send_unreliable_fragment (host, peer, command, & currentData))
goto commandError;
break;
default:
goto commandError;
}
@@ -1138,7 +1258,7 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
peer -> mtu - host -> packetSize < commandSize ||
(outgoingCommand -> packet != NULL &&
peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> packet -> dataLength))
peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength))
{
host -> continueSending = 1;
@@ -1147,20 +1267,35 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
currentCommand = enet_list_next (currentCommand);
if (outgoingCommand -> packet != NULL)
if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
{
peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
if (peer -> packetThrottleCounter > peer -> packetThrottle)
{
-- outgoingCommand -> packet -> referenceCount;
enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
for (;;)
{
-- outgoingCommand -> packet -> referenceCount;
if (outgoingCommand -> packet -> referenceCount == 0)
enet_packet_destroy (outgoingCommand -> packet);
if (outgoingCommand -> packet -> referenceCount == 0)
enet_packet_destroy (outgoingCommand -> packet);
enet_list_remove (& outgoingCommand -> outgoingCommandList);
enet_free (outgoingCommand);
enet_list_remove (& outgoingCommand -> outgoingCommandList);
enet_free (outgoingCommand);
if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands))
break;
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
break;
currentCommand = enet_list_next (currentCommand);
}
continue;
}
@@ -1179,8 +1314,8 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
{
++ buffer;
buffer -> data = outgoingCommand -> packet -> data;
buffer -> dataLength = outgoingCommand -> packet -> dataLength;
buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
buffer -> dataLength = outgoingCommand -> fragmentLength;
host -> packetSize += buffer -> dataLength;