diff --git a/ChangeLog b/ChangeLog
index 67edefd..e182076 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+ENet 1.3.17 (November 15, 2020):
+
+* fixes for sender getting too far ahead of receiver that can cause instability with reliable packets
+
+ENet 1.3.16 (September 8, 2020):
+
+* fix bug in unreliable fragment queuing
+* use single output queue for reliable and unreliable packets for saner ordering
+* revert experimental throttle changes that were less stable than prior algorithm
+
ENet 1.3.15 (April 20, 2020):
* quicker RTT initialization
@@ -9,7 +19,7 @@ ENet 1.3.14 (January 27, 2019):
* bug fix for enet_peer_disconnect_later()
* use getaddrinfo and getnameinfo where available
-* miscellenous cleanups
+* miscellaneous cleanups
ENet 1.3.13 (April 30, 2015):
diff --git a/Doxyfile b/Doxyfile
index 051279f..6b4d06f 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = "ENet"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = v1.3.15
+PROJECT_NUMBER = v1.3.17
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/Makefile.am b/Makefile.am
index d5f4bb7..d029ed1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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 7:3:0
+libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 7:5:0
AM_CPPFLAGS = -I$(top_srcdir)/include
ACLOCAL_AMFLAGS = -Im4
diff --git a/configure.ac b/configure.ac
index 2f282bc..e0c745d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([libenet], [1.3.15])
+AC_INIT([libenet], [1.3.17])
AC_CONFIG_SRCDIR([include/enet/enet.h])
AM_INIT_AUTOMAKE([foreign])
diff --git a/docs/mainpage.dox b/docs/mainpage.dox
index 06d62dc..a172dc8 100644
--- a/docs/mainpage.dox
+++ b/docs/mainpage.dox
@@ -36,7 +36,7 @@ portable, and easily embeddable.
You can retrieve the source to ENet by downloading it in either .tar.gz form
or accessing the github distribution directly.
-The most recent stable release (1.3.15) can be downloaded here.
+The most recent stable release (1.3.17) can be downloaded here.
The last release that is protocol compatible with the 1.2 series or earlier (1.2.5) can be downloaded here.
You can find the most recent ENet source at the github repository.
diff --git a/host.c b/host.c
index c51780b..ef36eb0 100644
--- a/host.c
+++ b/host.c
@@ -124,8 +124,7 @@ enet_host_create (int addressFamily, const ENetAddress * address, size_t peerCou
enet_list_clear (& currentPeer -> acknowledgements);
enet_list_clear (& currentPeer -> sentReliableCommands);
enet_list_clear (& currentPeer -> sentUnreliableCommands);
- enet_list_clear (& currentPeer -> outgoingReliableCommands);
- enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
+ enet_list_clear (& currentPeer -> outgoingCommands);
enet_list_clear (& currentPeer -> dispatchedCommands);
enet_peer_reset (currentPeer);
diff --git a/include/enet/enet.h b/include/enet/enet.h
index 7faa421..1b22b49 100644
--- a/include/enet/enet.h
+++ b/include/enet/enet.h
@@ -25,7 +25,7 @@ extern "C"
#define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3
-#define ENET_VERSION_PATCH 15
+#define ENET_VERSION_PATCH 17
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
@@ -302,12 +302,10 @@ typedef struct _ENetPeer
ENetList acknowledgements;
ENetList sentReliableCommands;
ENetList sentUnreliableCommands;
- ENetList outgoingReliableCommands;
- ENetList outgoingUnreliableCommands;
+ ENetList outgoingCommands;
ENetList dispatchedCommands;
enet_uint16 flags;
- enet_uint8 roundTripTimeRemainder;
- enet_uint8 roundTripTimeVarianceRemainder;
+ enet_uint16 reserved;
enet_uint16 incomingUnsequencedGroup;
enet_uint16 outgoingUnsequencedGroup;
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
@@ -553,8 +551,8 @@ extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetO
extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, const void *, size_t, enet_uint32, enet_uint32);
extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
-extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
-extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
+extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
+extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
extern void enet_peer_on_connect (ENetPeer *);
extern void enet_peer_on_disconnect (ENetPeer *);
diff --git a/peer.c b/peer.c
index 1278b85..9370ef4 100644
--- a/peer.c
+++ b/peer.c
@@ -76,7 +76,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
return 1;
}
else
- if (rtt >= peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
+ if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
{
if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
peer -> packetThrottle -= peer -> packetThrottleDeceleration;
@@ -268,7 +268,7 @@ enet_peer_reset_outgoing_commands (ENetList * queue)
}
static void
-enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand)
+enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand, ENetIncomingCommand * excludeCommand)
{
ENetListIterator currentCommand;
@@ -278,6 +278,9 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
currentCommand = enet_list_next (currentCommand);
+ if (incomingCommand == excludeCommand)
+ continue;
+
enet_list_remove (& incomingCommand -> incomingCommandList);
if (incomingCommand -> packet != NULL)
@@ -298,7 +301,7 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
static void
enet_peer_reset_incoming_commands (ENetList * queue)
{
- enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue));
+ enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue), NULL);
}
void
@@ -318,8 +321,7 @@ enet_peer_reset_queues (ENetPeer * peer)
enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
- enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
- enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
+ enet_peer_reset_outgoing_commands (& peer -> outgoingCommands);
enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
if (peer -> channels != NULL && peer -> channelCount > 0)
@@ -419,8 +421,6 @@ enet_peer_reset (ENetPeer * peer)
peer -> eventData = 0;
peer -> totalWaitingData = 0;
peer -> flags = 0;
- peer -> roundTripTimeRemainder = 0;
- peer -> roundTripTimeVarianceRemainder = 0;
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
@@ -573,8 +573,7 @@ void
enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
{
if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
- ! (enet_list_empty (& peer -> outgoingReliableCommands) &&
- enet_list_empty (& peer -> outgoingUnreliableCommands) &&
+ ! (enet_list_empty (& peer -> outgoingCommands) &&
enet_list_empty (& peer -> sentReliableCommands)))
{
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
@@ -676,10 +675,7 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
break;
}
- if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
- enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
- else
- enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
+ enet_list_insert (enet_list_end (& peer -> outgoingCommands), outgoingCommand);
}
ENetOutgoingCommand *
@@ -702,7 +698,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
}
void
-enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
+enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand)
{
ENetListIterator droppedCommand, startCommand, currentCommand;
@@ -781,11 +777,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
droppedCommand = currentCommand;
}
- enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand);
+ enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand, queuedCommand);
}
void
-enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
+enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel, ENetIncomingCommand * queuedCommand)
{
ENetListIterator currentCommand;
@@ -820,7 +816,7 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch
}
if (! enet_list_empty (& channel -> incomingUnreliableCommands))
- enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel, queuedCommand);
}
ENetIncomingCommand *
@@ -978,11 +974,11 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
{
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
- enet_peer_dispatch_incoming_reliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_reliable_commands (peer, channel, incomingCommand);
break;
default:
- enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel, incomingCommand);
break;
}
diff --git a/protocol.c b/protocol.c
index 2dc9119..4894ea4 100644
--- a/protocol.c
+++ b/protocol.c
@@ -188,8 +188,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
} while (! enet_list_empty (& peer -> sentUnreliableCommands));
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
- enet_list_empty (& peer -> outgoingReliableCommands) &&
- enet_list_empty (& peer -> outgoingUnreliableCommands) &&
+ enet_list_empty (& peer -> outgoingCommands) &&
enet_list_empty (& peer -> sentReliableCommands))
enet_peer_disconnect (peer, peer -> eventData);
}
@@ -215,12 +214,15 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
{
- for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
- currentCommand != enet_list_end (& peer -> outgoingReliableCommands);
+ for (currentCommand = enet_list_begin (& peer -> outgoingCommands);
+ currentCommand != enet_list_end (& peer -> outgoingCommands);
currentCommand = enet_list_next (currentCommand))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+ if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
+ continue;
+
if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
@@ -228,7 +230,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
break;
}
- if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
+ if (currentCommand == enet_list_end (& peer -> outgoingCommands))
return ENET_PROTOCOL_COMMAND_NONE;
wasSent = 0;
@@ -622,7 +624,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
fragmentLength);
if (startCommand -> fragmentsRemaining <= 0)
- enet_peer_dispatch_incoming_reliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_reliable_commands (peer, channel, NULL);
}
return 0;
@@ -740,7 +742,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
fragmentLength);
if (startCommand -> fragmentsRemaining <= 0)
- enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+ enet_peer_dispatch_incoming_unreliable_commands (peer, channel, NULL);
}
return 0;
@@ -855,19 +857,22 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
if (peer -> lastReceiveTime > 0)
{
- enet_uint32 accumRoundTripTime = (peer -> roundTripTime << 8) + peer -> roundTripTimeRemainder;
- enet_uint32 accumRoundTripTimeVariance = (peer -> roundTripTimeVariance << 8) + peer -> roundTripTimeVarianceRemainder;
-
enet_peer_throttle (peer, roundTripTime);
- roundTripTime <<= 8;
- accumRoundTripTimeVariance = (accumRoundTripTimeVariance * 3 + ENET_DIFFERENCE (roundTripTime, accumRoundTripTime)) / 4;
- accumRoundTripTime = (accumRoundTripTime * 7 + roundTripTime) / 8;
+ peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
- peer -> roundTripTime = accumRoundTripTime >> 8;
- peer -> roundTripTimeRemainder = accumRoundTripTime & 0xFF;
- peer -> roundTripTimeVariance = accumRoundTripTimeVariance >> 8;
- peer -> roundTripTimeVarianceRemainder = accumRoundTripTimeVariance & 0xFF;
+ if (roundTripTime >= peer -> roundTripTime)
+ {
+ enet_uint32 diff = roundTripTime - peer -> roundTripTime;
+ peer -> roundTripTimeVariance += diff / 4;
+ peer -> roundTripTime += diff / 8;
+ }
+ else
+ {
+ enet_uint32 diff = peer -> roundTripTime - roundTripTime;
+ peer -> roundTripTimeVariance += diff / 4;
+ peer -> roundTripTime -= diff / 8;
+ }
}
else
{
@@ -878,14 +883,14 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
if (peer -> roundTripTime < peer -> lowestRoundTripTime)
peer -> lowestRoundTripTime = peer -> roundTripTime;
- if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
+ if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance)
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
if (peer -> packetThrottleEpoch == 0 ||
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
{
peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
- peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 2);
+ peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 1);
peer -> lowestRoundTripTime = peer -> roundTripTime;
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
peer -> packetThrottleEpoch = host -> serviceTime;
@@ -915,8 +920,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
break;
case ENET_PEER_STATE_DISCONNECT_LATER:
- if (enet_list_empty (& peer -> outgoingReliableCommands) &&
- enet_list_empty (& peer -> outgoingUnreliableCommands) &&
+ if (enet_list_empty (& peer -> outgoingCommands) &&
enet_list_empty (& peer -> sentReliableCommands))
enet_peer_disconnect (peer, peer -> eventData);
break;
@@ -1322,108 +1326,6 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
host -> bufferCount = buffer - host -> buffers;
}
-static void
-enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
-{
- ENetProtocol * command = & host -> commands [host -> commandCount];
- ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
- ENetOutgoingCommand * outgoingCommand;
- ENetListIterator currentCommand;
-
- currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands);
-
- while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
- {
- size_t commandSize;
-
- outgoingCommand = (ENetOutgoingCommand *) currentCommand;
- 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 ||
- (outgoingCommand -> packet != NULL &&
- peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength))
- {
- host -> continueSending = 1;
-
- break;
- }
-
- currentCommand = enet_list_next (currentCommand);
-
- 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)
- {
- 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);
-
- 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;
- }
- }
-
- buffer -> data = command;
- buffer -> dataLength = commandSize;
-
- host -> packetSize += buffer -> dataLength;
-
- * command = outgoingCommand -> command;
-
- enet_list_remove (& outgoingCommand -> outgoingCommandList);
-
- if (outgoingCommand -> packet != NULL)
- {
- ++ buffer;
-
- buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
- buffer -> dataLength = outgoingCommand -> fragmentLength;
-
- host -> packetSize += buffer -> dataLength;
-
- enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
- }
- else
- enet_free (outgoingCommand);
-
- ++ command;
- ++ buffer;
- }
-
- host -> commandCount = command - host -> commands;
- host -> bufferCount = buffer - host -> buffers;
-
- if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
- enet_list_empty (& peer -> outgoingReliableCommands) &&
- enet_list_empty (& peer -> outgoingUnreliableCommands) &&
- enet_list_empty (& peer -> sentReliableCommands) &&
- enet_list_empty (& peer -> sentUnreliableCommands))
- enet_peer_disconnect (peer, peer -> eventData);
-}
-
static int
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
{
@@ -1431,7 +1333,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
ENetListIterator currentCommand, insertPosition;
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
- insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
+ insertPosition = enet_list_begin (& peer -> outgoingCommands);
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
{
@@ -1478,7 +1380,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
}
static int
-enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
+enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer)
{
ENetProtocol * command = & host -> commands [host -> commandCount];
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
@@ -1489,50 +1391,53 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
size_t commandSize;
int windowExceeded = 0, windowWrap = 0, canPing = 1;
- currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
+ currentCommand = enet_list_begin (& peer -> outgoingCommands);
- while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
+ while (currentCommand != enet_list_end (& peer -> outgoingCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
- 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)
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{
- 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_WINDOWS - reliableWindow)))))
- windowWrap = 1;
- if (windowWrap)
+ 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)
{
- currentCommand = enet_list_next (currentCommand);
+ 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 + 2)) - 1) << reliableWindow) |
+ (((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow)))))
+ windowWrap = 1;
+ if (windowWrap)
+ {
+ currentCommand = enet_list_next (currentCommand);
- continue;
+ continue;
+ }
}
- }
- if (outgoingCommand -> packet != NULL)
- {
- if (! windowExceeded)
+ if (outgoingCommand -> packet != NULL)
{
- enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
+ 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);
+ if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
+ windowExceeded = 1;
+ }
+ if (windowExceeded)
+ {
+ currentCommand = enet_list_next (currentCommand);
- continue;
+ continue;
+ }
}
+
+ canPing = 0;
}
- 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)] ||
@@ -1547,33 +1452,80 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
currentCommand = enet_list_next (currentCommand);
- if (channel != NULL && outgoingCommand -> sendAttempts < 1)
+ if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{
- channel -> usedReliableWindows |= 1 << reliableWindow;
- ++ channel -> reliableWindows [reliableWindow];
- }
+ if (channel != NULL && outgoingCommand -> sendAttempts < 1)
+ {
+ channel -> usedReliableWindows |= 1 << reliableWindow;
+ ++ channel -> reliableWindows [reliableWindow];
+ }
- ++ outgoingCommand -> sendAttempts;
+ ++ outgoingCommand -> sendAttempts;
- if (outgoingCommand -> roundTripTimeout == 0)
- {
- outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
- outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
+ if (outgoingCommand -> roundTripTimeout == 0)
+ {
+ outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
+ outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout;
+ }
+
+ if (enet_list_empty (& peer -> sentReliableCommands))
+ peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
+
+ enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
+ enet_list_remove (& outgoingCommand -> outgoingCommandList));
+
+ outgoingCommand -> sentTime = host -> serviceTime;
+
+ host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
+
+ peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
}
+ else
+ {
+ if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
+ {
+ peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
+ peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
- if (enet_list_empty (& peer -> sentReliableCommands))
- peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
+ if (peer -> packetThrottleCounter > peer -> packetThrottle)
+ {
+ enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber,
+ unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber;
+ for (;;)
+ {
+ -- outgoingCommand -> packet -> referenceCount;
- enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
- enet_list_remove (& outgoingCommand -> outgoingCommandList));
+ if (outgoingCommand -> packet -> referenceCount == 0)
+ enet_packet_destroy (outgoingCommand -> packet);
- outgoingCommand -> sentTime = host -> serviceTime;
+ enet_list_remove (& outgoingCommand -> outgoingCommandList);
+ enet_free (outgoingCommand);
+
+ if (currentCommand == enet_list_end (& peer -> outgoingCommands))
+ break;
+
+ outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+ if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber ||
+ outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber)
+ break;
+
+ currentCommand = enet_list_next (currentCommand);
+ }
+
+ continue;
+ }
+ }
+
+ enet_list_remove (& outgoingCommand -> outgoingCommandList);
+
+ if (outgoingCommand -> packet != NULL)
+ enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
+ }
buffer -> data = command;
buffer -> dataLength = commandSize;
host -> packetSize += buffer -> dataLength;
- host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
* command = outgoingCommand -> command;
@@ -1585,9 +1537,10 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
buffer -> dataLength = outgoingCommand -> fragmentLength;
host -> packetSize += outgoingCommand -> fragmentLength;
-
- peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
}
+ else
+ if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
+ enet_free (outgoingCommand);
++ peer -> packetsSent;
@@ -1598,6 +1551,12 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
host -> commandCount = command - host -> commands;
host -> bufferCount = buffer - host -> buffers;
+ if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
+ enet_list_empty (& peer -> outgoingCommands) &&
+ enet_list_empty (& peer -> sentReliableCommands) &&
+ enet_list_empty (& peer -> sentUnreliableCommands))
+ enet_peer_disconnect (peer, peer -> eventData);
+
return canPing;
}
@@ -1641,18 +1600,15 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
continue;
}
- if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) ||
- enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) &&
+ if ((enet_list_empty (& currentPeer -> outgoingCommands) ||
+ enet_protocol_check_outgoing_commands (host, currentPeer)) &&
enet_list_empty (& currentPeer -> sentReliableCommands) &&
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval &&
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
{
enet_peer_ping (currentPeer);
- enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
+ enet_protocol_check_outgoing_commands (host, currentPeer);
}
-
- if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
- enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
if (host -> commandCount == 0)
continue;
@@ -1666,7 +1622,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
#ifdef ENET_DEBUG
- printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
+ printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
#endif
currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4;