summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/enet/CMakeLists.txt5
-rw-r--r--libs/enet/ChangeLog22
-rw-r--r--libs/enet/LICENSE2
-rw-r--r--libs/enet/host.c1
-rw-r--r--libs/enet/include/enet/enet.h8
-rw-r--r--libs/enet/include/enet/protocol.h3
-rw-r--r--libs/enet/list.c2
-rw-r--r--libs/enet/peer.c126
-rw-r--r--libs/enet/protocol.c248
9 files changed, 335 insertions, 82 deletions
diff --git a/libs/enet/CMakeLists.txt b/libs/enet/CMakeLists.txt
index 714d9c03..52895918 100644
--- a/libs/enet/CMakeLists.txt
+++ b/libs/enet/CMakeLists.txt
@@ -52,4 +52,7 @@ SET (SRCS
INCLUDE_DIRECTORIES("include")
ADD_LIBRARY(enet STATIC ${SRCS})
-SET_TARGET_PROPERTIES(enet PROPERTIES COMPILE_FLAGS "${FLAGS}") \ No newline at end of file
+IF (BEOS)
+ TARGET_LINK_LIBRARIES(enet network)
+ENDIF()
+SET_TARGET_PROPERTIES(enet PROPERTIES COMPILE_FLAGS "${FLAGS}")
diff --git a/libs/enet/ChangeLog b/libs/enet/ChangeLog
index 45f14db6..47c38adc 100644
--- a/libs/enet/ChangeLog
+++ b/libs/enet/ChangeLog
@@ -1,3 +1,16 @@
+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
+* reliable data window size now scales with the throttle
+* fixed bug in fragment length calculation when checksums are used
+
ENet 1.3.0 (June 5, 2010):
* enet_host_create() now requires the channel limit to be specified as
@@ -15,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
diff --git a/libs/enet/LICENSE b/libs/enet/LICENSE
index df0f91e9..357a4e5c 100644
--- a/libs/enet/LICENSE
+++ b/libs/enet/LICENSE
@@ -1,4 +1,4 @@
-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 "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
diff --git a/libs/enet/host.c b/libs/enet/host.c
index 8bb2433f..c44f2ed3 100644
--- a/libs/enet/host.c
+++ b/libs/enet/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);
diff --git a/libs/enet/include/enet/enet.h b/libs/enet/include/enet/enet.h
index 2f656d6c..02dc2c0a 100644
--- a/libs/enet/include/enet/enet.h
+++ b/libs/enet/include/enet/enet.h
@@ -25,7 +25,7 @@ extern "C"
#define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3
-#define ENET_VERSION_PATCH 0
+#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;
diff --git a/libs/enet/include/enet/protocol.h b/libs/enet/include/enet/protocol.h
index 19f7e45d..faef9179 100644
--- a/libs/enet/include/enet/protocol.h
+++ b/libs/enet/include/enet/protocol.h
@@ -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;
diff --git a/libs/enet/list.c b/libs/enet/list.c
index 8487200f..1c1a8dfa 100644
--- a/libs/enet/list.c
+++ b/libs/enet/list.c
@@ -3,7 +3,7 @@
@brief ENet linked list functions
*/
#define ENET_BUILDING_LIB 1
-#include "enet/list.h"
+#include "enet/enet.h"
/**
@defgroup list ENet linked list utility functions
diff --git a/libs/enet/peer.c b/libs/enet/peer.c
index d778ce1d..566f7978 100644
--- a/libs/enet/peer.c
+++ b/libs/enet/peer.c
@@ -108,16 +108,31 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
return -1;
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
+ if (peer -> host -> checksum != NULL)
+ fragmentLength -= sizeof(enet_uint32);
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,
@@ -145,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);
@@ -171,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);
@@ -192,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);
}
@@ -255,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;
@@ -278,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)
{
@@ -548,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;
@@ -560,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
@@ -588,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 (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands))
- return;
+ if (! peer -> needsDispatch)
+ {
+ enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
- enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand));
+ peer -> needsDispatch = 1;
+ }
- if (! peer -> needsDispatch)
+ droppedCommand = startCommand = enet_list_next (currentCommand);
+ }
+ }
+
+ 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
@@ -638,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)
@@ -682,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);
@@ -710,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)
diff --git a/libs/enet/protocol.c b/libs/enet/protocol.c
index 8e26dfb2..d7c3fede 100644
--- a/libs/enet/protocol.c
+++ b/libs/enet/protocol.c
@@ -23,6 +23,7 @@ static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
sizeof (ENetProtocolSendUnsequenced),
sizeof (ENetProtocolBandwidthLimit),
sizeof (ENetProtocolThrottleConfigure),
+ sizeof (ENetProtocolSendFragment)
};
size_t
@@ -172,6 +173,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
ENetOutgoingCommand * outgoingCommand;
ENetListIterator currentCommand;
ENetProtocolCommand commandNumber;
+ int wasSent = 1;
for (currentCommand = enet_list_begin (& peer -> sentReliableCommands);
currentCommand != enet_list_end (& peer -> sentReliableCommands);
@@ -201,6 +203,8 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
return ENET_PROTOCOL_COMMAND_NONE;
+
+ wasSent = 0;
}
if (channelID < peer -> channelCount)
@@ -221,7 +225,8 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
if (outgoingCommand -> packet != NULL)
{
- peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
+ if (wasSent)
+ peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
-- outgoingCommand -> packet -> referenceCount;
@@ -315,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);
@@ -569,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)
@@ -602,6 +602,124 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
}
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)
{
return 0;
@@ -848,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))
@@ -981,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;
}
@@ -1134,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;
@@ -1143,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;
-
- if (outgoingCommand -> packet -> referenceCount == 0)
- enet_packet_destroy (outgoingCommand -> packet);
+ enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
+ unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
+ for (;;)
+ {
+ -- outgoingCommand -> packet -> referenceCount;
+
+ 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;
}
@@ -1175,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;
@@ -1252,7 +1391,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
return 0;
}
-static void
+static int
enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
{
ENetProtocol * command = & host -> commands [host -> commandCount];
@@ -1262,6 +1401,7 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
ENetChannel *channel;
enet_uint16 reliableWindow;
size_t commandSize;
+ int windowExceeded = 0, windowWrap = 0, canPing = 1;
currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
@@ -1271,37 +1411,54 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
- if (channel != NULL &&
- outgoingCommand -> sendAttempts < 1 &&
- ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
- (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
- channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) |
- (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow)))))
- break;
-
+ if (channel != NULL)
+ {
+ if (! windowWrap &&
+ outgoingCommand -> sendAttempts < 1 &&
+ ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
+ (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
+ channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) |
+ (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow)))))
+ windowWrap = 1;
+ if (windowWrap)
+ {
+ currentCommand = enet_list_next (currentCommand);
+
+ continue;
+ }
+ }
+
+ if (outgoingCommand -> packet != NULL)
+ {
+ if (! windowExceeded)
+ {
+ enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
+
+ if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
+ windowExceeded = 1;
+ }
+ if (windowExceeded)
+ {
+ currentCommand = enet_list_next (currentCommand);
+
+ continue;
+ }
+ }
+
+ canPing = 0;
+
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
- peer -> mtu - host -> packetSize < commandSize)
+ peer -> mtu - host -> packetSize < commandSize ||
+ (outgoingCommand -> packet != NULL &&
+ (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength)))
{
host -> continueSending = 1;
break;
}
- if (outgoingCommand -> packet != NULL)
- {
- if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize)
- break;
-
- if ((enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))
- {
- host -> continueSending = 1;
-
- break;
- }
- }
-
currentCommand = enet_list_next (currentCommand);
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
@@ -1354,6 +1511,8 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
host -> commandCount = command - host -> commands;
host -> bufferCount = buffer - host -> buffers;
+
+ return canPing;
}
static int
@@ -1391,10 +1550,9 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
enet_protocol_check_timeouts (host, currentPeer, event) == 1)
return 1;
- if (! enet_list_empty (& currentPeer -> outgoingReliableCommands))
- enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
- else
- if (enet_list_empty (& currentPeer -> sentReliableCommands) &&
+ if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) ||
+ enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) &&
+ enet_list_empty (& currentPeer -> sentReliableCommands) &&
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= ENET_PEER_PING_INTERVAL &&
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
{