Merge pull request #11719 from AdmiralCurtiss/enet-update

Update ENet to 8ae0e85298fafdb20777b4eb4241218f52f775b0
This commit is contained in:
Pierre Bourdon 2023-04-04 22:00:45 +02:00 committed by GitHub
commit c71a4c2751
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 551 additions and 401 deletions

View file

@ -61,7 +61,20 @@ endif()
include_directories(${PROJECT_SOURCE_DIR}/include) include_directories(${PROJECT_SOURCE_DIR}/include)
add_library(enet STATIC set(INCLUDE_FILES_PREFIX include/enet)
set(INCLUDE_FILES
${INCLUDE_FILES_PREFIX}/callbacks.h
${INCLUDE_FILES_PREFIX}/enet.h
${INCLUDE_FILES_PREFIX}/list.h
${INCLUDE_FILES_PREFIX}/protocol.h
${INCLUDE_FILES_PREFIX}/time.h
${INCLUDE_FILES_PREFIX}/types.h
${INCLUDE_FILES_PREFIX}/unix.h
${INCLUDE_FILES_PREFIX}/utility.h
${INCLUDE_FILES_PREFIX}/win32.h
)
set(SOURCE_FILES
callbacks.c callbacks.c
compress.c compress.c
host.c host.c
@ -70,9 +83,22 @@ add_library(enet STATIC
peer.c peer.c
protocol.c protocol.c
unix.c unix.c
win32.c win32.c)
source_group(include FILES ${INCLUDE_FILES})
source_group(source FILES ${SOURCE_FILES})
add_library(enet STATIC
${INCLUDE_FILES}
${SOURCE_FILES}
) )
dolphin_disable_warnings_msvc(enet) dolphin_disable_warnings_msvc(enet)
if (MINGW)
target_link_libraries(enet winmm ws2_32)
endif()
if(HAIKU) if(HAIKU)
target_link_libraries(enet network) target_link_libraries(enet network)
endif(HAIKU) endif(HAIKU)

View file

@ -1,4 +1,25 @@
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
* use fractional precision for RTT calculations
* fixes for packet throttle with low RTT variance
* miscellaneous socket bug fixes
ENet 1.3.14 (January 27, 2019):
* bug fix for enet_peer_disconnect_later()
* use getaddrinfo and getnameinfo where available * use getaddrinfo and getnameinfo where available
* miscellaneous cleanups
ENet 1.3.13 (April 30, 2015): ENet 1.3.13 (April 30, 2015):

View file

@ -38,7 +38,7 @@ PROJECT_NAME = "ENet"
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = v1.3.13 PROJECT_NUMBER = v1.3.17
# Using the PROJECT_BRIEF tag one can provide an optional one line description # 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 # for a project that appears at the top of each page and should give viewer a

View file

@ -1,4 +1,4 @@
Copyright (c) 2002-2015 Lee Salzman Copyright (c) 2002-2020 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: 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:

View file

@ -16,7 +16,7 @@ enetinclude_HEADERS = \
lib_LTLIBRARIES = libenet.la 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 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 # see info '(libtool) Updating version info' before making a release
libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 7:1:0 libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 7:5:0
AM_CPPFLAGS = -I$(top_srcdir)/include AM_CPPFLAGS = -I$(top_srcdir)/include
ACLOCAL_AMFLAGS = -Im4 ACLOCAL_AMFLAGS = -Im4

View file

@ -1,4 +1,4 @@
Please visit the ENet homepage at http://enet.bespin.org for installation Please visit the ENet homepage at http://sauerbraten.org/enet/ for installation
and usage instructions. and usage instructions.
If you obtained this package from github, the quick description on how to build If you obtained this package from github, the quick description on how to build

View file

@ -1,4 +1,4 @@
AC_INIT([libenet], [1.3.13]) AC_INIT([libenet], [1.3.17])
AC_CONFIG_SRCDIR([include/enet/enet.h]) AC_CONFIG_SRCDIR([include/enet/enet.h])
AM_INIT_AUTOMAKE([foreign]) AM_INIT_AUTOMAKE([foreign])

View file

@ -1,7 +1,7 @@
/** /**
@page License License @page License License
Copyright (c) 2002-2015 Lee Salzman Copyright (c) 2002-2020 Lee Salzman
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

View file

@ -36,7 +36,7 @@ portable, and easily embeddable.
You can retrieve the source to ENet by downloading it in either .tar.gz form You can retrieve the source to ENet by downloading it in either .tar.gz form
or accessing the github distribution directly. or accessing the github distribution directly.
The most recent stable release (1.3.13) can be downloaded <a class="el" href="download/enet-1.3.13.tar.gz">here</a>. The most recent stable release (1.3.17) can be downloaded <a class="el" href="download/enet-1.3.17.tar.gz">here</a>.
The last release that is protocol compatible with the 1.2 series or earlier (1.2.5) can be downloaded <a class="el" href="download/enet-1.2.5.tar.gz">here</a>. The last release that is protocol compatible with the 1.2 series or earlier (1.2.5) can be downloaded <a class="el" href="download/enet-1.2.5.tar.gz">here</a>.
You can find the most recent ENet source at <a class="el" href="https://github.com/lsalzman/enet">the github repository</a>. You can find the most recent ENet source at <a class="el" href="https://github.com/lsalzman/enet">the github repository</a>.
@ -53,7 +53,7 @@ The <a class="el" href="http://lists.cubik.org/mailman/listinfo/enet-discuss">en
/** /**
@page IRCChannel IRC Channel @page IRCChannel IRC Channel
Join the \#enet channel on the <a class="el" href="http://freenode.net">freenode IRC network (irc.freenode.net)</a> for real-time discussion about the ENet library. Join the \#enet channel on the <a class="el" href="https://libera.chat">Libera Chat IRC network (irc.libera.chat)</a> for real-time discussion about the ENet library.
*/ */

View file

@ -102,8 +102,8 @@ may be simultaneously open.
client = enet_host_create (NULL /* create a client host */, client = enet_host_create (NULL /* create a client host */,
1 /* only allow 1 outgoing connection */, 1 /* only allow 1 outgoing connection */,
2 /* allow up 2 channels to be used, 0 and 1 */, 2 /* allow up 2 channels to be used, 0 and 1 */,
57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */, 0 /* assume any amount of incoming bandwidth */,
14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */); 0 /* assume any amount of outgoing bandwidth */);
if (client == NULL) if (client == NULL)
{ {

19
Externals/enet/host.c vendored
View file

@ -96,6 +96,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
host -> totalSentPackets = 0; host -> totalSentPackets = 0;
host -> totalReceivedData = 0; host -> totalReceivedData = 0;
host -> totalReceivedPackets = 0; host -> totalReceivedPackets = 0;
host -> totalQueued = 0;
host -> connectedPeers = 0; host -> connectedPeers = 0;
host -> bandwidthLimitedPeers = 0; host -> bandwidthLimitedPeers = 0;
@ -123,9 +124,8 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
enet_list_clear (& currentPeer -> acknowledgements); enet_list_clear (& currentPeer -> acknowledgements);
enet_list_clear (& currentPeer -> sentReliableCommands); enet_list_clear (& currentPeer -> sentReliableCommands);
enet_list_clear (& currentPeer -> sentUnreliableCommands); enet_list_clear (& currentPeer -> outgoingCommands);
enet_list_clear (& currentPeer -> outgoingReliableCommands); enet_list_clear (& currentPeer -> outgoingSendReliableCommands);
enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
enet_list_clear (& currentPeer -> dispatchedCommands); enet_list_clear (& currentPeer -> dispatchedCommands);
enet_peer_reset (currentPeer); enet_peer_reset (currentPeer);
@ -161,6 +161,16 @@ enet_host_destroy (ENetHost * host)
enet_free (host); enet_free (host);
} }
enet_uint32
enet_host_random (ENetHost * host)
{
/* Mulberry32 by Tommy Ettinger */
enet_uint32 n = (host -> randomSeed += 0x6D2B79F5U);
n = (n ^ (n >> 15)) * (n | 1U);
n ^= n + (n ^ (n >> 7)) * (n | 61U);
return n ^ (n >> 14);
}
/** Initiates a connection to a foreign host. /** Initiates a connection to a foreign host.
@param host host seeking the connection @param host host seeking the connection
@param address destination for the connection @param address destination for the connection
@ -200,7 +210,8 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
currentPeer -> channelCount = channelCount; currentPeer -> channelCount = channelCount;
currentPeer -> state = ENET_PEER_STATE_CONNECTING; currentPeer -> state = ENET_PEER_STATE_CONNECTING;
currentPeer -> address = * address; currentPeer -> address = * address;
currentPeer -> connectID = ++ host -> randomSeed; currentPeer -> connectID = enet_host_random (host);
currentPeer -> mtu = host -> mtu;
if (host -> outgoingBandwidth == 0) if (host -> outgoingBandwidth == 0)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;

View file

@ -25,7 +25,7 @@ extern "C"
#define ENET_VERSION_MAJOR 1 #define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3 #define ENET_VERSION_MINOR 3
#define ENET_VERSION_PATCH 13 #define ENET_VERSION_PATCH 17
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch)) #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_MAJOR(version) (((version)>>16)&0xFF)
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF) #define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
@ -62,7 +62,8 @@ typedef enum _ENetSocketOption
ENET_SOCKOPT_RCVTIMEO = 6, ENET_SOCKOPT_RCVTIMEO = 6,
ENET_SOCKOPT_SNDTIMEO = 7, ENET_SOCKOPT_SNDTIMEO = 7,
ENET_SOCKOPT_ERROR = 8, ENET_SOCKOPT_ERROR = 8,
ENET_SOCKOPT_NODELAY = 9 ENET_SOCKOPT_NODELAY = 9,
ENET_SOCKOPT_TTL = 10
} ENetSocketOption; } ENetSocketOption;
typedef enum _ENetSocketShutdown typedef enum _ENetSocketShutdown
@ -138,7 +139,11 @@ typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
* (not supported for reliable packets) * (not supported for reliable packets)
* *
* ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead * ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
*
* ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT - packet will be fragmented using unreliable
* (instead of reliable) sends if it exceeds the MTU
*
* ENET_PACKET_FLAG_SENT - whether the packet has been sent from all queues it has been entered into
@sa ENetPacketFlag @sa ENetPacketFlag
*/ */
typedef struct _ENetPacket typedef struct _ENetPacket
@ -165,7 +170,7 @@ typedef struct _ENetOutgoingCommand
enet_uint16 unreliableSequenceNumber; enet_uint16 unreliableSequenceNumber;
enet_uint32 sentTime; enet_uint32 sentTime;
enet_uint32 roundTripTimeout; enet_uint32 roundTripTimeout;
enet_uint32 roundTripTimeoutLimit; enet_uint32 queueTime;
enet_uint32 fragmentOffset; enet_uint32 fragmentOffset;
enet_uint16 fragmentLength; enet_uint16 fragmentLength;
enet_uint16 sendAttempts; enet_uint16 sendAttempts;
@ -246,6 +251,12 @@ typedef struct _ENetChannel
ENetList incomingUnreliableCommands; ENetList incomingUnreliableCommands;
} ENetChannel; } ENetChannel;
typedef enum _ENetPeerFlag
{
ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0),
ENET_PEER_FLAG_CONTINUE_SENDING = (1 << 1)
} ENetPeerFlag;
/** /**
* An ENet peer which data packets may be sent or received from. * An ENet peer which data packets may be sent or received from.
* *
@ -303,11 +314,11 @@ typedef struct _ENetPeer
enet_uint16 outgoingReliableSequenceNumber; enet_uint16 outgoingReliableSequenceNumber;
ENetList acknowledgements; ENetList acknowledgements;
ENetList sentReliableCommands; ENetList sentReliableCommands;
ENetList sentUnreliableCommands; ENetList outgoingSendReliableCommands;
ENetList outgoingReliableCommands; ENetList outgoingCommands;
ENetList outgoingUnreliableCommands;
ENetList dispatchedCommands; ENetList dispatchedCommands;
int needsDispatch; enet_uint16 flags;
enet_uint16 reserved;
enet_uint16 incomingUnsequencedGroup; enet_uint16 incomingUnsequencedGroup;
enet_uint16 outgoingUnsequencedGroup; enet_uint16 outgoingUnsequencedGroup;
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
@ -366,7 +377,7 @@ typedef struct _ENetHost
size_t channelLimit; /**< maximum number of channels allowed for connected peers */ size_t channelLimit; /**< maximum number of channels allowed for connected peers */
enet_uint32 serviceTime; enet_uint32 serviceTime;
ENetList dispatchQueue; ENetList dispatchQueue;
int continueSending; enet_uint32 totalQueued;
size_t packetSize; size_t packetSize;
enet_uint16 headerFlags; enet_uint16 headerFlags;
ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS]; ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
@ -405,7 +416,7 @@ typedef enum _ENetEventType
ENET_EVENT_TYPE_CONNECT = 1, ENET_EVENT_TYPE_CONNECT = 1,
/** a peer has disconnected. This event is generated on a successful /** a peer has disconnected. This event is generated on a successful
* completion of a disconnect initiated by enet_pper_disconnect, if * completion of a disconnect initiated by enet_peer_disconnect, if
* a peer has timed out, or if a connection request intialized by * a peer has timed out, or if a connection request intialized by
* enet_host_connect has timed out. The peer field contains the peer * enet_host_connect has timed out. The peer field contains the peer
* which disconnected. The data field contains user supplied data * which disconnected. The data field contains user supplied data
@ -505,6 +516,17 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
/** @defgroup Address ENet address functions /** @defgroup Address ENet address functions
@{ @{
*/ */
/** Attempts to parse the printable form of the IP address in the parameter hostName
and sets the host field in the address parameter if successful.
@param address destination to store the parsed IP address
@param hostName IP address to parse
@retval 0 on success
@retval < 0 on failure
@returns the address of the given hostName in address on success
*/
ENET_API int enet_address_set_host_ip (ENetAddress * address, const char * hostName);
/** Attempts to resolve the host named by the parameter hostName and sets /** Attempts to resolve the host named by the parameter hostName and sets
the host field in the address parameter if successful. the host field in the address parameter if successful.
@param address destination to store resolved address @param address destination to store resolved address
@ -555,6 +577,7 @@ ENET_API void enet_host_channel_limit (ENetHost *, size_t);
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32); ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
extern void enet_host_bandwidth_throttle (ENetHost *); extern void enet_host_bandwidth_throttle (ENetHost *);
extern enet_uint32 enet_host_random_seed (void); extern enet_uint32 enet_host_random_seed (void);
extern enet_uint32 enet_host_random (ENetHost *);
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *); ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID); ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
@ -568,12 +591,13 @@ ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32
ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32); ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
extern int enet_peer_throttle (ENetPeer *, enet_uint32); extern int enet_peer_throttle (ENetPeer *, enet_uint32);
extern void enet_peer_reset_queues (ENetPeer *); extern void enet_peer_reset_queues (ENetPeer *);
extern int enet_peer_has_outgoing_commands (ENetPeer *);
extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *); extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16); 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 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 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_unreliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *); extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *, ENetIncomingCommand *);
extern void enet_peer_on_connect (ENetPeer *); extern void enet_peer_on_connect (ENetPeer *);
extern void enet_peer_on_disconnect (ENetPeer *); extern void enet_peer_on_disconnect (ENetPeer *);

View file

@ -9,6 +9,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <unistd.h> #include <unistd.h>

View file

@ -7,6 +7,7 @@
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y)) #define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y)) #define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
#define ENET_DIFFERENCE(x, y) ((x) < (y) ? (y) - (x) : (x) - (y))
#endif /* __ENET_UTILITY_H__ */ #endif /* __ENET_UTILITY_H__ */

View file

@ -11,6 +11,8 @@
#pragma warning (disable: 4244) // 64bit to 32bit int #pragma warning (disable: 4244) // 64bit to 32bit int
#pragma warning (disable: 4018) // signed/unsigned mismatch #pragma warning (disable: 4018) // signed/unsigned mismatch
#pragma warning (disable: 4146) // unary minus operator applied to unsigned type #pragma warning (disable: 4146) // unary minus operator applied to unsigned type
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS
#endif #endif
#endif #endif

View file

@ -98,54 +98,47 @@ enet_packet_resize (ENetPacket * packet, size_t dataLength)
return 0; return 0;
} }
static int initializedCRC32 = 0; static const enet_uint32 crcTable [256] =
static enet_uint32 crcTable [256];
static enet_uint32
reflect_crc (int val, int bits)
{ {
int result = 0, bit; 0, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
for (bit = 0; bit < bits; bit ++) 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
{ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
if(val & 1) result |= 1 << (bits - 1 - bit); 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
val >>= 1; 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
} 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
return result; 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
} 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
static void 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
initialize_crc32 (void) 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
{ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
int byte; 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
for (byte = 0; byte < 256; ++ byte) 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
{ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
enet_uint32 crc = reflect_crc (byte, 8) << 24; 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
int offset; 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
for(offset = 0; offset < 8; ++ offset) 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
{ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
if (crc & 0x80000000) 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
crc = (crc << 1) ^ 0x04c11db7; 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x5005713,
else 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0xBDBDF21,
crc <<= 1; 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
} 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
crcTable [byte] = reflect_crc (crc, 32); 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
} 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
initializedCRC32 = 1; };
}
enet_uint32 enet_uint32
enet_crc32 (const ENetBuffer * buffers, size_t bufferCount) enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
{ {
enet_uint32 crc = 0xFFFFFFFF; enet_uint32 crc = 0xFFFFFFFF;
if (! initializedCRC32) initialize_crc32 ();
while (bufferCount -- > 0) while (bufferCount -- > 0)
{ {
const enet_uint8 * data = (const enet_uint8 *) buffers -> data, const enet_uint8 * data = (const enet_uint8 *) buffers -> data,

87
Externals/enet/peer.c vendored
View file

@ -66,7 +66,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
peer -> packetThrottle = peer -> packetThrottleLimit; peer -> packetThrottle = peer -> packetThrottleLimit;
} }
else else
if (rtt < peer -> lastRoundTripTime) if (rtt <= peer -> lastRoundTripTime)
{ {
peer -> packetThrottle += peer -> packetThrottleAcceleration; peer -> packetThrottle += peer -> packetThrottleAcceleration;
@ -90,6 +90,13 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
} }
/** Queues a packet to be sent. /** Queues a packet to be sent.
On success, ENet will assume ownership of the packet, and so enet_packet_destroy
should not be called on it thereafter. On failure, the caller still must destroy
the packet on its own as ENet has not queued the packet. The caller can also
check the packet's referenceCount field after sending to check if ENet queued
the packet and thus incremented the referenceCount.
@param peer destination for the packet @param peer destination for the packet
@param channelID channel on which to send @param channelID channel on which to send
@param packet packet to send @param packet packet to send
@ -99,7 +106,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
int int
enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
{ {
ENetChannel * channel = & peer -> channels [channelID]; ENetChannel * channel;
ENetProtocol command; ENetProtocol command;
size_t fragmentLength; size_t fragmentLength;
@ -108,6 +115,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
packet -> dataLength > peer -> host -> maximumPacketSize) packet -> dataLength > peer -> host -> maximumPacketSize)
return -1; return -1;
channel = & peer -> channels [channelID];
fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment); fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
if (peer -> host -> checksum != NULL) if (peer -> host -> checksum != NULL)
fragmentLength -= sizeof(enet_uint32); fragmentLength -= sizeof(enet_uint32);
@ -268,7 +276,7 @@ enet_peer_reset_outgoing_commands (ENetList * queue)
} }
static void 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; ENetListIterator currentCommand;
@ -278,6 +286,9 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
currentCommand = enet_list_next (currentCommand); currentCommand = enet_list_next (currentCommand);
if (incomingCommand == excludeCommand)
continue;
enet_list_remove (& incomingCommand -> incomingCommandList); enet_list_remove (& incomingCommand -> incomingCommandList);
if (incomingCommand -> packet != NULL) if (incomingCommand -> packet != NULL)
@ -298,7 +309,7 @@ enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startComm
static void static void
enet_peer_reset_incoming_commands (ENetList * queue) 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 void
@ -306,20 +317,19 @@ enet_peer_reset_queues (ENetPeer * peer)
{ {
ENetChannel * channel; ENetChannel * channel;
if (peer -> needsDispatch) if (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH)
{ {
enet_list_remove (& peer -> dispatchList); enet_list_remove (& peer -> dispatchList);
peer -> needsDispatch = 0; peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
} }
while (! enet_list_empty (& peer -> acknowledgements)) while (! enet_list_empty (& peer -> acknowledgements))
enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements))); enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands); enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands); enet_peer_reset_outgoing_commands (& peer -> outgoingCommands);
enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands); enet_peer_reset_outgoing_commands (& peer -> outgoingSendReliableCommands);
enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
enet_peer_reset_incoming_commands (& peer -> dispatchedCommands); enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
if (peer -> channels != NULL && peer -> channelCount > 0) if (peer -> channels != NULL && peer -> channelCount > 0)
@ -418,6 +428,7 @@ enet_peer_reset (ENetPeer * peer)
peer -> outgoingUnsequencedGroup = 0; peer -> outgoingUnsequencedGroup = 0;
peer -> eventData = 0; peer -> eventData = 0;
peer -> totalWaitingData = 0; peer -> totalWaitingData = 0;
peer -> flags = 0;
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
@ -560,6 +571,17 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
} }
} }
int
enet_peer_has_outgoing_commands (ENetPeer * peer)
{
if (enet_list_empty (& peer -> outgoingCommands) &&
enet_list_empty (& peer -> outgoingSendReliableCommands) &&
enet_list_empty (& peer -> sentReliableCommands))
return 0;
return 1;
}
/** Request a disconnection from a peer, but only after all queued outgoing packets are sent. /** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
@param peer peer to request a disconnection @param peer peer to request a disconnection
@param data data describing the disconnection @param data data describing the disconnection
@ -570,9 +592,7 @@ void
enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data) enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
{ {
if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) &&
! (enet_list_empty (& peer -> outgoingReliableCommands) && enet_peer_has_outgoing_commands (peer))
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
enet_list_empty (& peer -> sentReliableCommands)))
{ {
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER; peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
peer -> eventData = data; peer -> eventData = data;
@ -616,8 +636,6 @@ enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command,
void void
enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand) enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
{ {
ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength; peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
if (outgoingCommand -> command.header.channelID == 0xFF) if (outgoingCommand -> command.header.channelID == 0xFF)
@ -628,6 +646,9 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
outgoingCommand -> unreliableSequenceNumber = 0; outgoingCommand -> unreliableSequenceNumber = 0;
} }
else else
{
ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{ {
++ channel -> outgoingReliableSequenceNumber; ++ channel -> outgoingReliableSequenceNumber;
@ -652,12 +673,13 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
} }
}
outgoingCommand -> sendAttempts = 0; outgoingCommand -> sendAttempts = 0;
outgoingCommand -> sentTime = 0; outgoingCommand -> sentTime = 0;
outgoingCommand -> roundTripTimeout = 0; outgoingCommand -> roundTripTimeout = 0;
outgoingCommand -> roundTripTimeoutLimit = 0;
outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber); outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
outgoingCommand -> queueTime = ++ peer -> host -> totalQueued;
switch (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) switch (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK)
{ {
@ -673,10 +695,11 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin
break; break;
} }
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) if ((outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0 &&
enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand); outgoingCommand -> packet != NULL)
enet_list_insert (enet_list_end (& peer -> outgoingSendReliableCommands), outgoingCommand);
else else
enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand); enet_list_insert (enet_list_end (& peer -> outgoingCommands), outgoingCommand);
} }
ENetOutgoingCommand * ENetOutgoingCommand *
@ -699,7 +722,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
} }
void 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; ENetListIterator droppedCommand, startCommand, currentCommand;
@ -724,11 +747,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
{ {
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
if (! peer -> needsDispatch) if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{ {
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1; peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
} }
droppedCommand = currentCommand; droppedCommand = currentCommand;
@ -752,11 +775,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
{ {
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
if (! peer -> needsDispatch) if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{ {
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1; peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
} }
} }
} }
@ -768,21 +791,21 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
{ {
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
if (! peer -> needsDispatch) if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{ {
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1; peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
} }
droppedCommand = currentCommand; 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 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; ENetListIterator currentCommand;
@ -809,15 +832,15 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch
enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand)); enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
if (! peer -> needsDispatch) if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{ {
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1; peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
} }
if (! enet_list_empty (& channel -> incomingUnreliableCommands)) if (! enet_list_empty (& channel -> incomingUnreliableCommands))
enet_peer_dispatch_incoming_unreliable_commands (peer, channel); enet_peer_dispatch_incoming_unreliable_commands (peer, channel, queuedCommand);
} }
ENetIncomingCommand * ENetIncomingCommand *
@ -975,11 +998,11 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
{ {
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
enet_peer_dispatch_incoming_reliable_commands (peer, channel); enet_peer_dispatch_incoming_reliable_commands (peer, channel, incomingCommand);
break; break;
default: default:
enet_peer_dispatch_incoming_unreliable_commands (peer, channel); enet_peer_dispatch_incoming_unreliable_commands (peer, channel, incomingCommand);
break; break;
} }

View file

@ -9,7 +9,7 @@
#include "enet/time.h" #include "enet/time.h"
#include "enet/enet.h" #include "enet/enet.h"
static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = static const size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
{ {
0, 0,
sizeof (ENetProtocolAcknowledge), sizeof (ENetProtocolAcknowledge),
@ -48,11 +48,11 @@ enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState st
{ {
enet_protocol_change_state (host, peer, state); enet_protocol_change_state (host, peer, state);
if (! peer -> needsDispatch) if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{ {
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
peer -> needsDispatch = 1; peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
} }
} }
@ -63,7 +63,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
{ {
ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue)); ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue));
peer -> needsDispatch = 0; peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
switch (peer -> state) switch (peer -> state)
{ {
@ -101,7 +101,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
if (! enet_list_empty (& peer -> dispatchedCommands)) if (! enet_list_empty (& peer -> dispatchedCommands))
{ {
peer -> needsDispatch = 1; peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
} }
@ -159,13 +159,16 @@ enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * e
} }
static void static void
enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer, ENetList * sentUnreliableCommands)
{ {
ENetOutgoingCommand * outgoingCommand; ENetOutgoingCommand * outgoingCommand;
while (! enet_list_empty (& peer -> sentUnreliableCommands)) if (enet_list_empty (sentUnreliableCommands))
return;
do
{ {
outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands); outgoingCommand = (ENetOutgoingCommand *) enet_list_front (sentUnreliableCommands);
enet_list_remove (& outgoingCommand -> outgoingCommandList); enet_list_remove (& outgoingCommand -> outgoingCommandList);
@ -182,7 +185,36 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
} }
enet_free (outgoingCommand); enet_free (outgoingCommand);
} while (! enet_list_empty (sentUnreliableCommands));
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
! enet_peer_has_outgoing_commands (peer))
enet_peer_disconnect (peer, peer -> eventData);
} }
static ENetOutgoingCommand *
enet_protocol_find_sent_reliable_command (ENetList * list, enet_uint16 reliableSequenceNumber, enet_uint8 channelID)
{
ENetListIterator currentCommand;
for (currentCommand = enet_list_begin (list);
currentCommand != enet_list_end (list);
currentCommand = enet_list_next (currentCommand))
{
ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) currentCommand;
if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE))
continue;
if (outgoingCommand -> sendAttempts < 1)
break;
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
outgoingCommand -> command.header.channelID == channelID)
return outgoingCommand;
}
return NULL;
} }
static ENetProtocolCommand static ENetProtocolCommand
@ -206,21 +238,9 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl
if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
{ {
for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); outgoingCommand = enet_protocol_find_sent_reliable_command (& peer -> outgoingCommands, reliableSequenceNumber, channelID);
currentCommand != enet_list_end (& peer -> outgoingReliableCommands); if (outgoingCommand == NULL)
currentCommand = enet_list_next (currentCommand)) outgoingCommand = enet_protocol_find_sent_reliable_command (& peer -> outgoingSendReliableCommands, reliableSequenceNumber, channelID);
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
outgoingCommand -> command.header.channelID == channelID)
break;
}
if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
return ENET_PROTOCOL_COMMAND_NONE;
wasSent = 0; wasSent = 0;
} }
@ -320,6 +340,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
peer -> connectID = command -> connect.connectID; peer -> connectID = command -> connect.connectID;
peer -> address = host -> receivedAddress; peer -> address = host -> receivedAddress;
peer -> mtu = host -> mtu;
peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
@ -364,6 +385,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
mtu = ENET_PROTOCOL_MAXIMUM_MTU; mtu = ENET_PROTOCOL_MAXIMUM_MTU;
if (mtu < peer -> mtu)
peer -> mtu = mtu; peer -> mtu = mtu;
if (host -> outgoingBandwidth == 0 && if (host -> outgoingBandwidth == 0 &&
@ -531,7 +553,8 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
* currentData += fragmentLength; * currentData += fragmentLength;
if (fragmentLength > host -> maximumPacketSize || if (fragmentLength <= 0 ||
fragmentLength > host -> maximumPacketSize ||
* currentData < host -> receivedData || * currentData < host -> receivedData ||
* currentData > & host -> receivedData [host -> receivedDataLength]) * currentData > & host -> receivedData [host -> receivedDataLength])
return -1; return -1;
@ -555,6 +578,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
fragmentNumber >= fragmentCount || fragmentNumber >= fragmentCount ||
totalLength > host -> maximumPacketSize || totalLength > host -> maximumPacketSize ||
totalLength < fragmentCount ||
fragmentOffset >= totalLength || fragmentOffset >= totalLength ||
fragmentLength > totalLength - fragmentOffset) fragmentLength > totalLength - fragmentOffset)
return -1; return -1;
@ -614,7 +638,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
fragmentLength); fragmentLength);
if (startCommand -> fragmentsRemaining <= 0) if (startCommand -> fragmentsRemaining <= 0)
enet_peer_dispatch_incoming_reliable_commands (peer, channel); enet_peer_dispatch_incoming_reliable_commands (peer, channel, NULL);
} }
return 0; return 0;
@ -732,7 +756,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
fragmentLength); fragmentLength);
if (startCommand -> fragmentsRemaining <= 0) if (startCommand -> fragmentsRemaining <= 0)
enet_peer_dispatch_incoming_unreliable_commands (peer, channel); enet_peer_dispatch_incoming_unreliable_commands (peer, channel, NULL);
} }
return 0; return 0;
@ -842,24 +866,32 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime)) if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
return 0; return 0;
peer -> lastReceiveTime = host -> serviceTime;
peer -> earliestTimeout = 0;
roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime); roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
roundTripTime = ENET_MAX (roundTripTime, 1);
if (peer -> lastReceiveTime > 0)
{
enet_peer_throttle (peer, roundTripTime); enet_peer_throttle (peer, roundTripTime);
peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4; peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
if (roundTripTime >= peer -> roundTripTime) if (roundTripTime >= peer -> roundTripTime)
{ {
peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8; enet_uint32 diff = roundTripTime - peer -> roundTripTime;
peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4; peer -> roundTripTimeVariance += diff / 4;
peer -> roundTripTime += diff / 8;
} }
else else
{ {
peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8; enet_uint32 diff = peer -> roundTripTime - roundTripTime;
peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4; peer -> roundTripTimeVariance += diff / 4;
peer -> roundTripTime -= diff / 8;
}
}
else
{
peer -> roundTripTime = roundTripTime;
peer -> roundTripTimeVariance = (roundTripTime + 1) / 2;
} }
if (peer -> roundTripTime < peer -> lowestRoundTripTime) if (peer -> roundTripTime < peer -> lowestRoundTripTime)
@ -872,12 +904,15 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval) ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
{ {
peer -> lastRoundTripTime = peer -> lowestRoundTripTime; peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance; peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 1);
peer -> lowestRoundTripTime = peer -> roundTripTime; peer -> lowestRoundTripTime = peer -> roundTripTime;
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
peer -> packetThrottleEpoch = host -> serviceTime; peer -> packetThrottleEpoch = host -> serviceTime;
} }
peer -> lastReceiveTime = ENET_MAX (host -> serviceTime, 1);
peer -> earliestTimeout = 0;
receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber); receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID); commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
@ -899,9 +934,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
break; break;
case ENET_PEER_STATE_DISCONNECT_LATER: case ENET_PEER_STATE_DISCONNECT_LATER:
if (enet_list_empty (& peer -> outgoingReliableCommands) && if (! enet_peer_has_outgoing_commands (peer))
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
enet_list_empty (& peer -> sentReliableCommands))
enet_peer_disconnect (peer, peer -> eventData); enet_peer_disconnect (peer, peer -> eventData);
break; break;
@ -1253,7 +1286,7 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
} }
} }
return -1; return 0;
} }
static void static void
@ -1273,7 +1306,7 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge)) peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge))
{ {
host -> continueSending = 1; peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING;
break; break;
} }
@ -1309,36 +1342,177 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
host -> bufferCount = buffer - host -> buffers; host -> bufferCount = buffer - host -> buffers;
} }
static void static int
enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer) enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
{
ENetOutgoingCommand * outgoingCommand;
ENetListIterator currentCommand, insertPosition, insertSendReliablePosition;
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
insertPosition = enet_list_begin (& peer -> outgoingCommands);
insertSendReliablePosition = enet_list_begin (& peer -> outgoingSendReliableCommands);
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
currentCommand = enet_list_next (currentCommand);
if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout)
continue;
if (peer -> earliestTimeout == 0 ||
ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout))
peer -> earliestTimeout = outgoingCommand -> sentTime;
if (peer -> earliestTimeout != 0 &&
(ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum ||
((1 << (outgoingCommand -> sendAttempts - 1)) >= peer -> timeoutLimit &&
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum)))
{
enet_protocol_notify_disconnect (host, peer, event);
return 1;
}
++ peer -> packetsLost;
outgoingCommand -> roundTripTimeout *= 2;
if (outgoingCommand -> packet != NULL)
{
peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
enet_list_insert (insertSendReliablePosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
}
else
enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
! enet_list_empty (& peer -> sentReliableCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
}
}
return 0;
}
static int
enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer, ENetList * sentUnreliableCommands)
{ {
ENetProtocol * command = & host -> commands [host -> commandCount]; ENetProtocol * command = & host -> commands [host -> commandCount];
ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
ENetOutgoingCommand * outgoingCommand; ENetOutgoingCommand * outgoingCommand;
ENetListIterator currentCommand; ENetListIterator currentCommand, currentSendReliableCommand;
ENetChannel *channel = NULL;
currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands); enet_uint16 reliableWindow = 0;
while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
{
size_t commandSize; size_t commandSize;
int windowWrap = 0, canPing = 1;
currentCommand = enet_list_begin (& peer -> outgoingCommands);
currentSendReliableCommand = enet_list_begin (& peer -> outgoingSendReliableCommands);
for (;;)
{
if (currentCommand != enet_list_end (& peer -> outgoingCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand; outgoingCommand = (ENetOutgoingCommand *) currentCommand;
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands) &&
ENET_TIME_LESS (((ENetOutgoingCommand *) currentSendReliableCommand) -> queueTime, outgoingCommand -> queueTime))
goto useSendReliableCommand;
currentCommand = enet_list_next (currentCommand);
}
else
if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands))
{
useSendReliableCommand:
outgoingCommand = (ENetOutgoingCommand *) currentSendReliableCommand;
currentSendReliableCommand = enet_list_next (currentSendReliableCommand);
}
else
break;
if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{
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 (windowWrap)
continue;
else
if (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;
currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands);
continue;
}
}
if (outgoingCommand -> packet != NULL)
{
enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE;
if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu))
{
currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands);
continue;
}
}
canPing = 0;
}
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
peer -> mtu - host -> packetSize < commandSize || peer -> mtu - host -> packetSize < commandSize ||
(outgoingCommand -> packet != NULL && (outgoingCommand -> packet != NULL &&
peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength)) (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength)))
{ {
host -> continueSending = 1; peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING;
break; break;
} }
currentCommand = enet_list_next (currentCommand); if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{
if (channel != NULL && outgoingCommand -> sendAttempts < 1)
{
channel -> usedReliableWindows |= 1 << reliableWindow;
++ channel -> reliableWindows [reliableWindow];
}
++ outgoingCommand -> sendAttempts;
if (outgoingCommand -> roundTripTimeout == 0)
outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
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) if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0)
{ {
peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
@ -1358,7 +1532,7 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
enet_list_remove (& outgoingCommand -> outgoingCommandList); enet_list_remove (& outgoingCommand -> outgoingCommandList);
enet_free (outgoingCommand); enet_free (outgoingCommand);
if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands)) if (currentCommand == enet_list_end (& peer -> outgoingCommands))
break; break;
outgoingCommand = (ENetOutgoingCommand *) currentCommand; outgoingCommand = (ENetOutgoingCommand *) currentCommand;
@ -1373,193 +1547,16 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
} }
} }
buffer -> data = command;
buffer -> dataLength = commandSize;
host -> packetSize += buffer -> dataLength;
* command = outgoingCommand -> command;
enet_list_remove (& outgoingCommand -> outgoingCommandList); enet_list_remove (& outgoingCommand -> outgoingCommandList);
if (outgoingCommand -> packet != NULL) if (outgoingCommand -> packet != NULL)
{ enet_list_insert (enet_list_end (sentUnreliableCommands), outgoingCommand);
++ 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_peer_disconnect (peer, peer -> eventData);
}
static int
enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
{
ENetOutgoingCommand * outgoingCommand;
ENetListIterator currentCommand, insertPosition;
currentCommand = enet_list_begin (& peer -> sentReliableCommands);
insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
currentCommand = enet_list_next (currentCommand);
if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout)
continue;
if (peer -> earliestTimeout == 0 ||
ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout))
peer -> earliestTimeout = outgoingCommand -> sentTime;
if (peer -> earliestTimeout != 0 &&
(ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum ||
(outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit &&
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum)))
{
enet_protocol_notify_disconnect (host, peer, event);
return 1;
}
if (outgoingCommand -> packet != NULL)
peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
++ peer -> packetsLost;
outgoingCommand -> roundTripTimeout *= 2;
enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
! enet_list_empty (& peer -> sentReliableCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
}
}
return 0;
}
static int
enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
{
ENetProtocol * command = & host -> commands [host -> commandCount];
ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
ENetOutgoingCommand * outgoingCommand;
ENetListIterator currentCommand;
ENetChannel *channel;
enet_uint16 reliableWindow;
size_t commandSize;
int windowExceeded = 0, windowWrap = 0, canPing = 1;
currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
{
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 (! 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)
{
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 ||
(outgoingCommand -> packet != NULL &&
(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)
{
channel -> usedReliableWindows |= 1 << reliableWindow;
++ channel -> reliableWindows [reliableWindow];
}
++ outgoingCommand -> sendAttempts;
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;
buffer -> data = command; buffer -> data = command;
buffer -> dataLength = commandSize; buffer -> dataLength = commandSize;
host -> packetSize += buffer -> dataLength; host -> packetSize += buffer -> dataLength;
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
* command = outgoingCommand -> command; * command = outgoingCommand -> command;
@ -1571,9 +1568,10 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
buffer -> dataLength = outgoingCommand -> fragmentLength; buffer -> dataLength = outgoingCommand -> fragmentLength;
host -> packetSize += 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; ++ peer -> packetsSent;
@ -1584,6 +1582,11 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
host -> commandCount = command - host -> commands; host -> commandCount = command - host -> commands;
host -> bufferCount = buffer - host -> buffers; host -> bufferCount = buffer - host -> buffers;
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
! enet_peer_has_outgoing_commands (peer) &&
enet_list_empty (sentUnreliableCommands))
enet_peer_disconnect (peer, peer -> eventData);
return canPing; return canPing;
} }
@ -1592,22 +1595,24 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
{ {
enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)]; enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)];
ENetProtocolHeader * header = (ENetProtocolHeader *) headerData; ENetProtocolHeader * header = (ENetProtocolHeader *) headerData;
ENetPeer * currentPeer; int sentLength = 0;
int sentLength;
size_t shouldCompress = 0; size_t shouldCompress = 0;
ENetList sentUnreliableCommands;
host -> continueSending = 1; enet_list_clear (& sentUnreliableCommands);
while (host -> continueSending) for (int sendPass = 0, continueSending = 0; sendPass <= continueSending; ++ sendPass)
for (host -> continueSending = 0, for (ENetPeer * currentPeer = host -> peers;
currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount]; currentPeer < & host -> peers [host -> peerCount];
++ currentPeer) ++ currentPeer)
{ {
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED || if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
currentPeer -> state == ENET_PEER_STATE_ZOMBIE) currentPeer -> state == ENET_PEER_STATE_ZOMBIE ||
(sendPass > 0 && ! (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING)))
continue; continue;
currentPeer -> flags &= ~ ENET_PEER_FLAG_CONTINUE_SENDING;
host -> headerFlags = 0; host -> headerFlags = 0;
host -> commandCount = 0; host -> commandCount = 0;
host -> bufferCount = 1; host -> bufferCount = 1;
@ -1624,24 +1629,22 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
return 1; return 1;
else else
continue; goto nextPeer;
} }
if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) || if (((enet_list_empty (& currentPeer -> outgoingCommands) &&
enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) && enet_list_empty (& currentPeer -> outgoingSendReliableCommands)) ||
enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands)) &&
enet_list_empty (& currentPeer -> sentReliableCommands) && enet_list_empty (& currentPeer -> sentReliableCommands) &&
ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval && ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval &&
currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
{ {
enet_peer_ping (currentPeer); enet_peer_ping (currentPeer);
enet_protocol_send_reliable_outgoing_commands (host, currentPeer); enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands);
} }
if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
if (host -> commandCount == 0) if (host -> commandCount == 0)
continue; goto nextPeer;
if (currentPeer -> packetLossEpoch == 0) if (currentPeer -> packetLossEpoch == 0)
currentPeer -> packetLossEpoch = host -> serviceTime; currentPeer -> packetLossEpoch = host -> serviceTime;
@ -1652,21 +1655,11 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
#ifdef ENET_DEBUG #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) + enet_list_size (& currentPeer -> outgoingSendReliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
#endif #endif
currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4; currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4;
currentPeer -> packetLoss = (currentPeer -> packetLoss * 7 + packetLoss) / 8;
if (packetLoss >= currentPeer -> packetLoss)
{
currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8;
currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4;
}
else
{
currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8;
currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4;
}
currentPeer -> packetLossEpoch = host -> serviceTime; currentPeer -> packetLossEpoch = host -> serviceTime;
currentPeer -> packetsSent = 0; currentPeer -> packetsSent = 0;
@ -1724,13 +1717,17 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount); sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
enet_protocol_remove_sent_unreliable_commands (currentPeer); enet_protocol_remove_sent_unreliable_commands (currentPeer, & sentUnreliableCommands);
if (sentLength < 0) if (sentLength < 0)
return -1; return -1;
host -> totalSentData += sentLength; host -> totalSentData += sentLength;
host -> totalSentPackets ++; host -> totalSentPackets ++;
nextPeer:
if (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING)
continueSending = sendPass + 1;
} }
return 0; return 0;

42
Externals/enet/unix.c vendored
View file

@ -8,7 +8,6 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/time.h> #include <sys/time.h>
#include <arpa/inet.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netdb.h> #include <netdb.h>
#include <unistd.h> #include <unistd.h>
@ -51,10 +50,10 @@
#endif #endif
#ifdef HAS_POLL #ifdef HAS_POLL
#include <sys/poll.h> #include <poll.h>
#endif #endif
#ifndef HAS_SOCKLEN_T #if !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined)
typedef int socklen_t; typedef int socklen_t;
#endif #endif
@ -101,6 +100,19 @@ enet_time_set (enet_uint32 newTimeBase)
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase; timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
} }
int
enet_address_set_host_ip (ENetAddress * address, const char * name)
{
#ifdef HAS_INET_PTON
if (! inet_pton (AF_INET, name, & address -> host))
#else
if (! inet_aton (name, (struct in_addr *) & address -> host))
#endif
return -1;
return 0;
}
int int
enet_address_set_host (ENetAddress * address, const char * name) enet_address_set_host (ENetAddress * address, const char * name)
{ {
@ -136,7 +148,7 @@ enet_address_set_host (ENetAddress * address, const char * name)
char buffer [2048]; char buffer [2048];
int errnum; int errnum;
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__GNU__)
gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else #else
hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum); hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
@ -153,14 +165,7 @@ enet_address_set_host (ENetAddress * address, const char * name)
} }
#endif #endif
#ifdef HAS_INET_PTON return enet_address_set_host_ip (address, name);
if (! inet_pton (AF_INET, name, & address -> host))
#else
if (! inet_aton (name, (struct in_addr *) & address -> host))
#endif
return -1;
return 0;
} }
int int
@ -204,7 +209,7 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng
return 0; return 0;
} }
if (err != EAI_NONAME) if (err != EAI_NONAME)
return 0; return -1;
#else #else
struct in_addr in; struct in_addr in;
struct hostent * hostEntry = NULL; struct hostent * hostEntry = NULL;
@ -215,7 +220,7 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng
in.s_addr = address -> host; in.s_addr = address -> host;
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__GNU__)
gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else #else
hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum); hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
@ -343,6 +348,10 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int)); result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
break; break;
case ENET_SOCKOPT_TTL:
result = setsockopt (socket, IPPROTO_IP, IP_TTL, (char *) & value, sizeof (int));
break;
default: default:
break; break;
} }
@ -361,6 +370,11 @@ enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len); result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len);
break; break;
case ENET_SOCKOPT_TTL:
len = sizeof (int);
result = getsockopt (socket, IPPROTO_IP, IP_TTL, (char *) value, & len);
break;
default: default:
break; break;
} }

View file

@ -8,6 +8,7 @@
#include "enet/enet.h" #include "enet/enet.h"
#include <windows.h> #include <windows.h>
#include <mmsystem.h> #include <mmsystem.h>
#include <ws2ipdef.h>
static enet_uint32 timeBase = 0; static enet_uint32 timeBase = 0;
@ -59,6 +60,32 @@ enet_time_set (enet_uint32 newTimeBase)
timeBase = (enet_uint32) timeGetTime () - newTimeBase; timeBase = (enet_uint32) timeGetTime () - newTimeBase;
} }
int
enet_address_set_host_ip (ENetAddress * address, const char * name)
{
enet_uint8 vals [4] = { 0, 0, 0, 0 };
int i;
for (i = 0; i < 4; ++ i)
{
const char * next = name + 1;
if (* name != '0')
{
long val = strtol (name, (char **) & next, 10);
if (val < 0 || val > 255 || next == name || next - name > 3)
return -1;
vals [i] = (enet_uint8) val;
}
if (* next != (i < 3 ? '.' : '\0'))
return -1;
name = next + 1;
}
memcpy (& address -> host, vals, sizeof (enet_uint32));
return 0;
}
int int
enet_address_set_host (ENetAddress * address, const char * name) enet_address_set_host (ENetAddress * address, const char * name)
{ {
@ -67,13 +94,7 @@ enet_address_set_host (ENetAddress * address, const char * name)
hostEntry = gethostbyname (name); hostEntry = gethostbyname (name);
if (hostEntry == NULL || if (hostEntry == NULL ||
hostEntry -> h_addrtype != AF_INET) hostEntry -> h_addrtype != AF_INET)
{ return enet_address_set_host_ip (address, name);
unsigned long host = inet_addr (name);
if (host == INADDR_NONE)
return -1;
address -> host = host;
return 0;
}
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
@ -211,6 +232,10 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int)); result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
break; break;
case ENET_SOCKOPT_TTL:
result = setsockopt (socket, IPPROTO_IP, IP_TTL, (char *) & value, sizeof (int));
break;
default: default:
break; break;
} }
@ -228,6 +253,11 @@ enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len); result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len);
break; break;
case ENET_SOCKOPT_TTL:
len = sizeof(int);
result = getsockopt (socket, IPPROTO_IP, IP_TTL, (char *) value, & len);
break;
default: default:
break; break;
} }
@ -296,7 +326,7 @@ enet_socket_send (ENetSocket socket,
size_t bufferCount) size_t bufferCount)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
DWORD sentLength; DWORD sentLength = 0;
if (address != NULL) if (address != NULL)
{ {
@ -334,7 +364,7 @@ enet_socket_receive (ENetSocket socket,
{ {
INT sinLength = sizeof (struct sockaddr_in); INT sinLength = sizeof (struct sockaddr_in);
DWORD flags = 0, DWORD flags = 0,
recvLength; recvLength = 0;
struct sockaddr_in sin; struct sockaddr_in sin;
if (WSARecvFrom (socket, if (WSARecvFrom (socket,

View file

@ -333,6 +333,7 @@ bool EnsureTraversalClient(const std::string& server, u16 server_port, u16 liste
g_MainNetHost.reset(); g_MainNetHost.reset();
return false; return false;
} }
host->mtu = std::min(host->mtu, NetPlay::MAX_ENET_MTU);
g_MainNetHost.reset(host); g_MainNetHost.reset(host);
g_TraversalClient.reset(new TraversalClient(g_MainNetHost.get(), server, server_port)); g_TraversalClient.reset(new TraversalClient(g_MainNetHost.get(), server, server_port));
} }

View file

@ -144,6 +144,8 @@ NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlay
return; return;
} }
m_client->mtu = std::min(m_client->mtu, NetPlay::MAX_ENET_MTU);
ENetAddress addr; ENetAddress addr;
enet_address_set_host(&addr, address.c_str()); enet_address_set_host(&addr, address.c_str());
addr.port = port; addr.port = port;

View file

@ -220,6 +220,7 @@ enum class SyncCodeID : u8
constexpr u32 MAX_NAME_LENGTH = 30; constexpr u32 MAX_NAME_LENGTH = 30;
constexpr size_t CHUNKED_DATA_UNIT_SIZE = 16384; constexpr size_t CHUNKED_DATA_UNIT_SIZE = 16384;
constexpr u32 MAX_ENET_MTU = 1392; // see https://github.com/lsalzman/enet/issues/132
enum : u8 enum : u8
{ {

View file

@ -151,7 +151,10 @@ NetPlayServer::NetPlayServer(const u16 port, const bool forward_port, NetPlayUI*
serverAddr.port = port; serverAddr.port = port;
m_server = enet_host_create(&serverAddr, 10, CHANNEL_COUNT, 0, 0); m_server = enet_host_create(&serverAddr, 10, CHANNEL_COUNT, 0, 0);
if (m_server != nullptr) if (m_server != nullptr)
{
m_server->mtu = std::min(m_server->mtu, NetPlay::MAX_ENET_MTU);
m_server->intercept = ENetUtil::InterceptCallback; m_server->intercept = ENetUtil::InterceptCallback;
}
SetupIndex(); SetupIndex();
} }