mirror of
https://github.com/lsalzman/enet
synced 2024-11-21 14:29:05 -07:00
support for ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT
1.3.2 release prep
This commit is contained in:
parent
33e2fc6201
commit
f38c177db0
9 changed files with 258 additions and 34 deletions
16
ChangeLog
16
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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,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])
|
||||
|
||||
|
|
|
@ -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
host.c
1
host.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
123
peer.c
123
peer.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -550,7 +555,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 +568,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,29 +610,71 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
|
|||
void
|
||||
enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
|
||||
{
|
||||
ENetListIterator currentCommand;
|
||||
ENetListIterator startCommand, currentCommand;
|
||||
|
||||
for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands);
|
||||
for (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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
while (currentCommand != enet_list_begin (& channel -> incomingUnreliableCommands))
|
||||
{
|
||||
ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) enet_list_previous (currentCommand);
|
||||
|
||||
enet_list_remove (& incomingCommand -> incomingCommandList);
|
||||
|
||||
if (incomingCommand -> packet != NULL)
|
||||
{
|
||||
-- incomingCommand -> packet -> referenceCount;
|
||||
|
||||
if (incomingCommand -> packet -> referenceCount == 0)
|
||||
enet_packet_destroy (incomingCommand -> packet);
|
||||
}
|
||||
|
||||
if (incomingCommand -> fragments != NULL)
|
||||
enet_free (incomingCommand -> fragments);
|
||||
|
||||
enet_free (incomingCommand);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -640,6 +702,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 +748,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 +776,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)
|
||||
|
|
133
protocol.c
133
protocol.c
|
@ -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);
|
||||
|
@ -605,6 +607,132 @@ 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)
|
||||
{
|
||||
ENetProtocol hostCommand = * command;
|
||||
ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
|
||||
if (packet == NULL)
|
||||
return -1;
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
|
@ -986,6 +1114,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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue