*** empty log message ***

This commit is contained in:
eihrul 2006-07-06 21:22:41 +00:00
parent 1e2c45adf9
commit 1d6253cc3d
9 changed files with 579 additions and 345 deletions

View file

@ -1,5 +1,5 @@
AC_INIT(libenet, 1.0) AC_INIT(libenet, 7-6-2006)
AM_INIT_AUTOMAKE(libenet.a, 1.0) AM_INIT_AUTOMAKE(libenet.a, 7-6-2006)
AC_PROG_CC AC_PROG_CC
AC_PROG_RANLIB AC_PROG_RANLIB
@ -21,4 +21,16 @@ AC_CHECK_TYPE(socklen_t, [AC_DEFINE(HAS_SOCKLEN_T)], ,
AC_EGREP_HEADER(MSG_MAXIOVLEN, /usr/include/sys/socket.h, AC_DEFINE(ENET_BUFFER_MAXIMUM, [MSG_MAXIOVLEN])) AC_EGREP_HEADER(MSG_MAXIOVLEN, /usr/include/sys/socket.h, AC_DEFINE(ENET_BUFFER_MAXIMUM, [MSG_MAXIOVLEN]))
AC_EGREP_HEADER(MSG_MAXIOVLEN, socket.h, AC_DEFINE(ENET_BUFFER_MAXIMUM, [MSG_MAXIOVLEN])) AC_EGREP_HEADER(MSG_MAXIOVLEN, socket.h, AC_DEFINE(ENET_BUFFER_MAXIMUM, [MSG_MAXIOVLEN]))
AC_MSG_CHECKING(whether to use CRC32)
AC_ARG_ENABLE(crc32,
[ --enable-crc32 enable CRC32 packet verification ],
[if test "$enableval" = yes; then
AC_MSG_RESULT(yes)
AC_DEFINE(USE_CRC32)
else
AC_MSG_RESULT(no)
fi],
[AC_MSG_RESULT(no)])
AC_OUTPUT([Makefile include/Makefile include/enet/Makefile]) AC_OUTPUT([Makefile include/Makefile include/enet/Makefile])

26
host.c
View file

@ -30,6 +30,9 @@ enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 inc
ENetHost * host = (ENetHost *) enet_malloc (sizeof (ENetHost)); ENetHost * host = (ENetHost *) enet_malloc (sizeof (ENetHost));
ENetPeer * currentPeer; ENetPeer * currentPeer;
if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
return NULL;
host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer)); host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
memset (host -> peers, 0, peerCount * sizeof (ENetPeer)); memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
@ -135,7 +138,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
currentPeer -> address = * address; currentPeer -> address = * address;
currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
currentPeer -> channelCount = channelCount; currentPeer -> channelCount = channelCount;
currentPeer -> challenge = (enet_uint32) enet_rand (); currentPeer -> sessionID = (enet_uint32) enet_rand ();
if (host -> outgoingBandwidth == 0) if (host -> outgoingBandwidth == 0)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
@ -163,10 +166,8 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
enet_list_clear (& channel -> incomingUnreliableCommands); enet_list_clear (& channel -> incomingUnreliableCommands);
} }
command.header.command = ENET_PROTOCOL_COMMAND_CONNECT; command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF; command.header.channelID = 0xFF;
command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolConnect);
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
command.connect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu); command.connect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu);
command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize); command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
@ -176,6 +177,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
command.connect.sessionID = currentPeer -> sessionID;
enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0); enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
@ -243,7 +245,7 @@ enet_host_bandwidth_throttle (ENetHost * host)
peer < & host -> peers [host -> peerCount]; peer < & host -> peers [host -> peerCount];
++ peer) ++ peer)
{ {
if (peer -> state != ENET_PEER_STATE_CONNECTED) if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue; continue;
++ peersTotal; ++ peersTotal;
@ -276,7 +278,7 @@ enet_host_bandwidth_throttle (ENetHost * host)
{ {
enet_uint32 peerBandwidth; enet_uint32 peerBandwidth;
if (peer -> state != ENET_PEER_STATE_CONNECTED || if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> incomingBandwidth == 0 || peer -> incomingBandwidth == 0 ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent) peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue; continue;
@ -309,7 +311,7 @@ enet_host_bandwidth_throttle (ENetHost * host)
peer < & host -> peers [host -> peerCount]; peer < & host -> peers [host -> peerCount];
++ peer) ++ peer)
{ {
if (peer -> state != ENET_PEER_STATE_CONNECTED || if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent) peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue; continue;
@ -339,12 +341,12 @@ enet_host_bandwidth_throttle (ENetHost * host)
peer < & host -> peers [host -> peerCount]; peer < & host -> peers [host -> peerCount];
++ peer) ++ peer)
{ {
if (peer -> state != ENET_PEER_STATE_CONNECTED || if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> incomingBandwidthThrottleEpoch == timeCurrent) peer -> incomingBandwidthThrottleEpoch == timeCurrent)
continue; continue;
if (peer -> outgoingBandwidth > 0 && if (peer -> outgoingBandwidth > 0 &&
bandwidthLimit > peer -> outgoingBandwidth) peer -> outgoingBandwidth >= bandwidthLimit)
continue; continue;
peer -> incomingBandwidthThrottleEpoch = timeCurrent; peer -> incomingBandwidthThrottleEpoch = timeCurrent;
@ -359,13 +361,11 @@ enet_host_bandwidth_throttle (ENetHost * host)
peer < & host -> peers [host -> peerCount]; peer < & host -> peers [host -> peerCount];
++ peer) ++ peer)
{ {
if (peer -> state != ENET_PEER_STATE_CONNECTED) if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue; continue;
command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT; command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF; command.header.channelID = 0xFF;
command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolBandwidthLimit);
command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
if (peer -> incomingBandwidthThrottleEpoch == timeCurrent) if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)

View file

@ -80,7 +80,9 @@ typedef enum
/** packet will not be sequenced with other packets /** packet will not be sequenced with other packets
* not supported for reliable packets * not supported for reliable packets
*/ */
ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1) ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
/** packet will not allocate data, and user must supply it instead */
ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2)
} ENetPacketFlag; } ENetPacketFlag;
/** /**
@ -115,8 +117,8 @@ typedef struct _ENetAcknowledgement
typedef struct _ENetOutgoingCommand typedef struct _ENetOutgoingCommand
{ {
ENetListNode outgoingCommandList; ENetListNode outgoingCommandList;
enet_uint32 reliableSequenceNumber; enet_uint16 reliableSequenceNumber;
enet_uint32 unreliableSequenceNumber; enet_uint16 unreliableSequenceNumber;
enet_uint32 sentTime; enet_uint32 sentTime;
enet_uint32 roundTripTimeout; enet_uint32 roundTripTimeout;
enet_uint32 roundTripTimeoutLimit; enet_uint32 roundTripTimeoutLimit;
@ -129,8 +131,8 @@ typedef struct _ENetOutgoingCommand
typedef struct _ENetIncomingCommand typedef struct _ENetIncomingCommand
{ {
ENetListNode incomingCommandList; ENetListNode incomingCommandList;
enet_uint32 reliableSequenceNumber; enet_uint16 reliableSequenceNumber;
enet_uint32 unreliableSequenceNumber; enet_uint16 unreliableSequenceNumber;
ENetProtocol command; ENetProtocol command;
enet_uint32 fragmentCount; enet_uint32 fragmentCount;
enet_uint32 fragmentsRemaining; enet_uint32 fragmentsRemaining;
@ -144,10 +146,12 @@ typedef enum
ENET_PEER_STATE_CONNECTING = 1, ENET_PEER_STATE_CONNECTING = 1,
ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2, ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2,
ENET_PEER_STATE_CONNECTION_PENDING = 3, ENET_PEER_STATE_CONNECTION_PENDING = 3,
ENET_PEER_STATE_CONNECTED = 4, ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4,
ENET_PEER_STATE_DISCONNECTING = 5, ENET_PEER_STATE_CONNECTED = 5,
ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 6, ENET_PEER_STATE_DISCONNECT_LATER = 6,
ENET_PEER_STATE_ZOMBIE = 7 ENET_PEER_STATE_DISCONNECTING = 7,
ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8,
ENET_PEER_STATE_ZOMBIE = 9
} ENetPeerState; } ENetPeerState;
#ifndef ENET_BUFFER_MAXIMUM #ifndef ENET_BUFFER_MAXIMUM
@ -157,6 +161,7 @@ typedef enum
enum enum
{ {
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024, ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000, ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
ENET_HOST_DEFAULT_MTU = 1400, ENET_HOST_DEFAULT_MTU = 1400,
@ -197,7 +202,7 @@ typedef struct _ENetPeer
struct _ENetHost * host; struct _ENetHost * host;
enet_uint16 outgoingPeerID; enet_uint16 outgoingPeerID;
enet_uint16 incomingPeerID; enet_uint16 incomingPeerID;
enet_uint32 challenge; enet_uint32 sessionID;
ENetAddress address; /**< Internet address of the peer */ ENetAddress address; /**< Internet address of the peer */
void * data; /**< Application private data, may be freely modified */ void * data; /**< Application private data, may be freely modified */
ENetPeerState state; ENetPeerState state;
@ -234,14 +239,14 @@ typedef struct _ENetPeer
enet_uint16 mtu; enet_uint16 mtu;
enet_uint32 windowSize; enet_uint32 windowSize;
enet_uint32 reliableDataInTransit; enet_uint32 reliableDataInTransit;
enet_uint32 outgoingReliableSequenceNumber; enet_uint16 outgoingReliableSequenceNumber;
ENetList acknowledgements; ENetList acknowledgements;
ENetList sentReliableCommands; ENetList sentReliableCommands;
ENetList sentUnreliableCommands; ENetList sentUnreliableCommands;
ENetList outgoingReliableCommands; ENetList outgoingReliableCommands;
ENetList outgoingUnreliableCommands; ENetList outgoingUnreliableCommands;
enet_uint32 incomingUnsequencedGroup; enet_uint16 incomingUnsequencedGroup;
enet_uint32 outgoingUnsequencedGroup; enet_uint16 outgoingUnsequencedGroup;
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
enet_uint32 disconnectData; enet_uint32 disconnectData;
} ENetPeer; } ENetPeer;
@ -271,7 +276,9 @@ typedef struct _ENetHost
ENetPeer * peers; /**< array of peers allocated for this host */ ENetPeer * peers; /**< array of peers allocated for this host */
size_t peerCount; /**< number of peers allocated for this host */ size_t peerCount; /**< number of peers allocated for this host */
ENetPeer * lastServicedPeer; ENetPeer * lastServicedPeer;
int continueSending;
size_t packetSize; size_t packetSize;
enet_uint16 headerFlags;
ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS]; ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
size_t commandCount; size_t commandCount;
ENetBuffer buffers [ENET_BUFFER_MAXIMUM]; ENetBuffer buffers [ENET_BUFFER_MAXIMUM];
@ -337,7 +344,7 @@ typedef struct _ENetEvent
*/ */
ENET_API int enet_initialize (void); ENET_API int enet_initialize (void);
ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits); ENET_API int enet_initialize_with_callbacks (ENetVersion, const ENetCallbacks *);
/** /**
Shuts down ENet globally. Should be called when a program that has Shuts down ENet globally. Should be called when a program that has
@ -361,15 +368,14 @@ ENET_API void enet_time_set (enet_uint32);
/** @defgroup socket ENet socket functions /** @defgroup socket ENet socket functions
@{ @{
@ingroup private
*/ */
extern ENetSocket enet_socket_create (ENetSocketType, const ENetAddress *); ENET_API ENetSocket enet_socket_create (ENetSocketType, const ENetAddress *);
extern ENetSocket enet_socket_accept (ENetSocket, ENetAddress *); ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
extern int enet_socket_connect (ENetSocket, const ENetAddress *); ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
extern int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t); ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
extern int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t); ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
extern int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32); ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
extern void enet_socket_destroy (ENetSocket); ENET_API void enet_socket_destroy (ENetSocket);
/** @} */ /** @} */
@ -384,7 +390,7 @@ extern void enet_socket_destroy (ENetSocket);
@retval < 0 on failure @retval < 0 on failure
@returns the address of the given hostName in address on success @returns the address of the given hostName in address on success
*/ */
ENET_API int enet_address_set_host (ENetAddress *address, const char *hostName ); ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
/** Attempts to do a reserve lookup of the host field in the address parameter. /** Attempts to do a reserve lookup of the host field in the address parameter.
@param address address used for reverse lookup @param address address used for reverse lookup
@ -394,17 +400,18 @@ ENET_API int enet_address_set_host (ENetAddress *address, const char *hostName )
@retval 0 on success @retval 0 on success
@retval < 0 on failure @retval < 0 on failure
*/ */
ENET_API int enet_address_get_host (const ENetAddress *address, char *hostName, size_t nameLength ); ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
/** @} */ /** @} */
ENET_API ENetPacket * enet_packet_create (const void *dataContents, size_t dataLength, enet_uint32 flags); ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
ENET_API void enet_packet_destroy (ENetPacket *packet ); ENET_API void enet_packet_destroy (ENetPacket *);
ENET_API int enet_packet_resize (ENetPacket *packet, size_t dataLength ); ENET_API int enet_packet_resize (ENetPacket *, size_t);
extern enet_uint32 enet_crc32 (const ENetBuffer *, size_t);
ENET_API ENetHost * enet_host_create (const ENetAddress *address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth );
ENET_API void enet_host_destroy (ENetHost *host ); ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, enet_uint32, enet_uint32);
ENET_API ENetPeer * enet_host_connect (ENetHost *host, const ENetAddress *address, size_t channelCount ); ENET_API void enet_host_destroy (ENetHost *);
ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t);
ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32); ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
ENET_API void enet_host_flush (ENetHost *); ENET_API void enet_host_flush (ENetHost *);
ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *); ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
@ -417,12 +424,15 @@ ENET_API void enet_peer_ping (ENetPeer *);
ENET_API void enet_peer_reset (ENetPeer *); ENET_API void enet_peer_reset (ENetPeer *);
ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32); ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32);
ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32); ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32);
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 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 *, ENetPacket *, enet_uint32); extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32);
extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint32); extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
extern size_t enet_protocol_command_size (enet_uint8);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -15,7 +15,8 @@ enum
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096, ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768, ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768,
ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255 ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
ENET_PROTOCOL_MAXIMUM_PEER_ID = 0x7FFF,
}; };
typedef enum typedef enum
@ -29,41 +30,42 @@ typedef enum
ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6, ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7, ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8, ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 9, ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 10, ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 11 ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
ENET_PROTOCOL_COMMAND_COUNT = 12,
ENET_PROTOCOL_COMMAND_MASK = 0x0F,
} ENetProtocolCommand; } ENetProtocolCommand;
typedef enum typedef enum
{ {
ENET_PROTOCOL_FLAG_ACKNOWLEDGE = (1 << 0), ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
ENET_PROTOCOL_FLAG_UNSEQUENCED = (1 << 1) ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15),
ENET_PROTOCOL_HEADER_FLAG_MASK = 0x8000,
} ENetProtocolFlag; } ENetProtocolFlag;
typedef struct typedef struct
{ {
enet_uint32 checksum;
enet_uint16 peerID; enet_uint16 peerID;
enet_uint8 flags; enet_uint16 sentTime;
enet_uint8 commandCount;
enet_uint32 sentTime;
enet_uint32 challenge;
} ENetProtocolHeader; } ENetProtocolHeader;
typedef struct typedef struct
{ {
enet_uint8 command; enet_uint8 command;
enet_uint8 channelID; enet_uint8 channelID;
enet_uint8 flags; enet_uint16 reliableSequenceNumber;
enet_uint8 reserved;
enet_uint32 commandLength;
enet_uint32 reliableSequenceNumber;
} ENetProtocolCommandHeader; } ENetProtocolCommandHeader;
typedef struct typedef struct
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint32 receivedReliableSequenceNumber; enet_uint16 receivedReliableSequenceNumber;
enet_uint32 receivedSentTime; enet_uint16 receivedSentTime;
} ENetProtocolAcknowledge; } ENetProtocolAcknowledge;
typedef struct typedef struct
@ -78,6 +80,7 @@ typedef struct
enet_uint32 packetThrottleInterval; enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration; enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration; enet_uint32 packetThrottleDeceleration;
enet_uint32 sessionID;
} ENetProtocolConnect; } ENetProtocolConnect;
typedef struct typedef struct
@ -123,24 +126,28 @@ typedef struct
typedef struct typedef struct
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint16 dataLength;
} ENetProtocolSendReliable; } ENetProtocolSendReliable;
typedef struct typedef struct
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint32 unreliableSequenceNumber; enet_uint16 unreliableSequenceNumber;
enet_uint16 dataLength;
} ENetProtocolSendUnreliable; } ENetProtocolSendUnreliable;
typedef struct typedef struct
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint32 unsequencedGroup; enet_uint16 unsequencedGroup;
enet_uint16 dataLength;
} ENetProtocolSendUnsequenced; } ENetProtocolSendUnsequenced;
typedef struct typedef struct
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint32 startSequenceNumber; enet_uint16 startSequenceNumber;
enet_uint16 dataLength;
enet_uint32 fragmentCount; enet_uint32 fragmentCount;
enet_uint32 fragmentNumber; enet_uint32 fragmentNumber;
enet_uint32 totalLength; enet_uint32 totalLength;

View file

@ -21,10 +21,15 @@ enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
{ {
ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket)); ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
packet -> data = (enet_uint8 *) enet_malloc (dataLength); if(flags & ENET_PACKET_FLAG_NO_ALLOCATE)
packet -> data = (enet_uint8 *) data;
else
{
packet -> data = (enet_uint8 *) enet_malloc (dataLength);
if (data != NULL) if (data != NULL)
memcpy (packet -> data, data, dataLength); memcpy (packet -> data, data, dataLength);
};
packet -> referenceCount = 0; packet -> referenceCount = 0;
packet -> flags = flags; packet -> flags = flags;
@ -39,7 +44,8 @@ enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
void void
enet_packet_destroy (ENetPacket * packet) enet_packet_destroy (ENetPacket * packet)
{ {
enet_free (packet -> data); if((packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) == 0)
enet_free (packet -> data);
enet_free (packet); enet_free (packet);
} }
@ -54,7 +60,7 @@ enet_packet_resize (ENetPacket * packet, size_t dataLength)
{ {
enet_uint8 * newData; enet_uint8 * newData;
if (dataLength <= packet -> dataLength) if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
{ {
packet -> dataLength = dataLength; packet -> dataLength = dataLength;
@ -71,4 +77,53 @@ enet_packet_resize (ENetPacket * packet, size_t dataLength)
return 0; return 0;
} }
static int initializedCRC32 = 0;
static enet_uint32 crcTable [256];
static void initialize_crc32 ()
{
int byte;
for (byte = 0; byte < 256; ++ byte)
{
enet_uint32 crc = byte << 24;
int offset;
for(offset = 0; offset < 8; ++ offset)
{
if (crc & 0x80000000)
crc = (crc << 1) ^ 0x04c11db7;
else
crc <<= 1;
}
crcTable [byte] = crc;
}
initializedCRC32 = 1;
}
enet_uint32
enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
{
enet_uint32 crc = 0xFFFFFFFF;
if (! initializedCRC32) initialize_crc32 ();
while (bufferCount -- > 0)
{
const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
* dataEnd = & data [buffers -> dataLength];
while (data < dataEnd)
{
crc = ((crc << 8) | * data ++) ^ crcTable [crc >> 24];
}
++ buffers;
}
return ENET_HOST_TO_NET_32 (~ crc);
}
/** @} */ /** @} */

185
peer.c
View file

@ -48,10 +48,8 @@ enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32
peer -> packetThrottleAcceleration = acceleration; peer -> packetThrottleAcceleration = acceleration;
peer -> packetThrottleDeceleration = deceleration; peer -> packetThrottleDeceleration = deceleration;
command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE; command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF; command.header.channelID = 0xFF;
command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolThrottleConfigure);
command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval); command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval);
command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration); command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration);
@ -113,8 +111,8 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
if (packet -> dataLength > fragmentLength) if (packet -> dataLength > fragmentLength)
{ {
enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength), enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
startSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingReliableSequenceNumber + 1),
fragmentNumber, fragmentNumber,
fragmentOffset; fragmentOffset;
@ -126,19 +124,18 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
++ fragmentNumber, ++ fragmentNumber,
fragmentOffset += fragmentLength) fragmentOffset += fragmentLength)
{ {
command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT; if (packet -> dataLength - fragmentOffset < fragmentLength)
fragmentLength = packet -> dataLength - fragmentOffset;
command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = channelID; command.header.channelID = channelID;
command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolSendFragment);
command.sendFragment.startSequenceNumber = startSequenceNumber; command.sendFragment.startSequenceNumber = startSequenceNumber;
command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
command.sendFragment.fragmentCount = fragmentCount; command.sendFragment.fragmentCount = fragmentCount;
command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber); command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength); command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset); command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
if (packet -> dataLength - fragmentOffset < fragmentLength)
fragmentLength = packet -> dataLength - fragmentOffset;
enet_peer_queue_outgoing_command (peer, & command, packet, fragmentOffset, fragmentLength); enet_peer_queue_outgoing_command (peer, & command, packet, fragmentOffset, fragmentLength);
} }
@ -149,24 +146,21 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
if (packet -> flags & ENET_PACKET_FLAG_RELIABLE) if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
{ {
command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE; command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE; command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
command.header.commandLength = sizeof (ENetProtocolSendReliable);
} }
else else
if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED) if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
{ {
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED; command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
command.header.flags = ENET_PROTOCOL_FLAG_UNSEQUENCED; command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
command.header.commandLength = sizeof (ENetProtocolSendUnsequenced); command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_32 (peer -> outgoingUnsequencedGroup + 1);
} }
else else
{ {
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE; command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
command.header.flags = 0; command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
command.header.commandLength = sizeof (ENetProtocolSendUnreliable); command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingUnreliableSequenceNumber + 1);
} }
enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength); enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength);
@ -186,13 +180,13 @@ enet_peer_receive (ENetPeer * peer, enet_uint8 channelID)
ENetIncomingCommand * incomingCommand = NULL; ENetIncomingCommand * incomingCommand = NULL;
ENetPacket * packet; ENetPacket * packet;
if (enet_list_empty (& channel -> incomingUnreliableCommands) == 0) if (! enet_list_empty (& channel -> incomingUnreliableCommands))
{ {
incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingUnreliableCommands); incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingUnreliableCommands);
if (incomingCommand -> unreliableSequenceNumber > 0) if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
{ {
if (incomingCommand -> reliableSequenceNumber > channel -> incomingReliableSequenceNumber) if (incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
incomingCommand = NULL; incomingCommand = NULL;
else else
channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber; channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber;
@ -200,36 +194,12 @@ enet_peer_receive (ENetPeer * peer, enet_uint8 channelID)
} }
if (incomingCommand == NULL && if (incomingCommand == NULL &&
enet_list_empty (& channel -> incomingReliableCommands) == 0) ! enet_list_empty (& channel -> incomingReliableCommands))
{ {
do incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingReliableCommands);
{
incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingReliableCommands);
if (incomingCommand -> fragmentsRemaining > 0 || if (incomingCommand -> fragmentsRemaining > 0 ||
incomingCommand -> reliableSequenceNumber > channel -> incomingReliableSequenceNumber + 1) incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber + 1)
return NULL;
if (incomingCommand -> reliableSequenceNumber <= channel -> incomingReliableSequenceNumber)
{
-- incomingCommand -> packet -> referenceCount;
if (incomingCommand -> packet -> referenceCount == 0)
enet_packet_destroy (incomingCommand -> packet);
if (incomingCommand -> fragments != NULL)
enet_free (incomingCommand -> fragments);
enet_list_remove (& incomingCommand -> incomingCommandList);
enet_free (incomingCommand);
incomingCommand = NULL;
}
} while (incomingCommand == NULL &&
enet_list_empty (& channel -> incomingReliableCommands) == 0);
if (incomingCommand == NULL)
return NULL; return NULL;
channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber; channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
@ -260,7 +230,7 @@ enet_peer_reset_outgoing_commands (ENetList * queue)
{ {
ENetOutgoingCommand * outgoingCommand; ENetOutgoingCommand * outgoingCommand;
while (enet_list_empty (queue) == 0) while (! enet_list_empty (queue))
{ {
outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue)); outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
@ -281,7 +251,7 @@ enet_peer_reset_incoming_commands (ENetList * queue)
{ {
ENetIncomingCommand * incomingCommand; ENetIncomingCommand * incomingCommand;
while (enet_list_empty (queue) == 0) while (! enet_list_empty (queue))
{ {
incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue)); incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
@ -305,7 +275,7 @@ enet_peer_reset_queues (ENetPeer * peer)
{ {
ENetChannel * channel; ENetChannel * channel;
while (enet_list_empty (& peer -> acknowledgements) == 0) 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);
@ -338,8 +308,8 @@ enet_peer_reset_queues (ENetPeer * peer)
void void
enet_peer_reset (ENetPeer * peer) enet_peer_reset (ENetPeer * peer)
{ {
peer -> outgoingPeerID = 0xFFFF; peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
peer -> challenge = 0; peer -> sessionID = 0;
peer -> address.host = ENET_HOST_ANY; peer -> address.host = ENET_HOST_ANY;
peer -> address.port = 0; peer -> address.port = 0;
@ -402,10 +372,8 @@ enet_peer_ping (ENetPeer * peer)
if (peer -> state != ENET_PEER_STATE_CONNECTED) if (peer -> state != ENET_PEER_STATE_CONNECTED)
return; return;
command.header.command = ENET_PROTOCOL_COMMAND_PING; command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF; command.header.channelID = 0xFF;
command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolPing);
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
} }
@ -430,11 +398,9 @@ enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data)
{ {
enet_peer_reset_queues (peer); enet_peer_reset_queues (peer);
command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT; command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
command.header.channelID = 0xFF; command.header.channelID = 0xFF;
command.header.flags = ENET_PROTOCOL_FLAG_UNSEQUENCED; command.disconnect.data = ENET_HOST_TO_NET_32 (data);
command.header.commandLength = sizeof (ENetProtocolDisconnect);
command.disconnect.data = data;
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
@ -464,16 +430,16 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT; command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
command.header.channelID = 0xFF; command.header.channelID = 0xFF;
command.header.flags = ENET_PROTOCOL_FLAG_UNSEQUENCED; command.disconnect.data = ENET_HOST_TO_NET_32 (data);
command.header.commandLength = sizeof (ENetProtocolDisconnect);
command.disconnect.data = data;
if (peer -> state == ENET_PEER_STATE_CONNECTED) if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE; command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
else
command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
if (peer -> state == ENET_PEER_STATE_CONNECTED) if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
peer -> state = ENET_PEER_STATE_DISCONNECTING; peer -> state = ENET_PEER_STATE_DISCONNECTING;
else else
{ {
@ -482,8 +448,29 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
} }
} }
/** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
@param peer peer to request a disconnection
@param data data describing the disconnection
@remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
once the disconnection is complete.
*/
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 -> sentReliableCommands)))
{
peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
peer -> disconnectData = data;
}
else
enet_peer_disconnect (peer, data);
}
ENetAcknowledgement * ENetAcknowledgement *
enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint32 sentTime) enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime)
{ {
ENetAcknowledgement * acknowledgement; ENetAcknowledgement * acknowledgement;
@ -505,7 +492,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
ENetChannel * channel = & peer -> channels [command -> header.channelID]; ENetChannel * channel = & peer -> channels [command -> header.channelID];
ENetOutgoingCommand * outgoingCommand; ENetOutgoingCommand * outgoingCommand;
peer -> outgoingDataTotal += command -> header.commandLength + length; peer -> outgoingDataTotal += enet_protocol_command_size (command -> header.command) + length;
outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand)); outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
@ -517,7 +504,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
outgoingCommand -> unreliableSequenceNumber = 0; outgoingCommand -> unreliableSequenceNumber = 0;
} }
else else
if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{ {
++ channel -> outgoingReliableSequenceNumber; ++ channel -> outgoingReliableSequenceNumber;
@ -525,7 +512,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
outgoingCommand -> unreliableSequenceNumber = 0; outgoingCommand -> unreliableSequenceNumber = 0;
} }
else else
if (command -> header.flags & ENET_PROTOCOL_FLAG_UNSEQUENCED) if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
{ {
++ peer -> outgoingUnsequencedGroup; ++ peer -> outgoingUnsequencedGroup;
@ -547,12 +534,12 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
outgoingCommand -> fragmentLength = length; outgoingCommand -> fragmentLength = length;
outgoingCommand -> packet = packet; outgoingCommand -> packet = packet;
outgoingCommand -> command = * command; outgoingCommand -> command = * command;
outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_32 (outgoingCommand -> reliableSequenceNumber); outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
if (packet != NULL) if (packet != NULL)
++ packet -> referenceCount; ++ packet -> referenceCount;
if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand); enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
else else
enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand); enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
@ -564,23 +551,44 @@ ENetIncomingCommand *
enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount) enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
{ {
ENetChannel * channel = & peer -> channels [command -> header.channelID]; ENetChannel * channel = & peer -> channels [command -> header.channelID];
enet_uint32 unreliableSequenceNumber = 0; enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber;
ENetIncomingCommand * incomingCommand; ENetIncomingCommand * incomingCommand;
ENetListIterator currentCommand; ENetListIterator currentCommand;
switch (command -> header.command) if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
goto freePacket;
if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
{
reliableSequenceNumber = command -> header.reliableSequenceNumber;
if (channel -> incomingReliableSequenceNumber >= 0xF000 && reliableSequenceNumber < 0x1000)
reliableSequenceNumber += 0x10000;
if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber ||
(channel -> incomingReliableSequenceNumber < 0x1000 && (reliableSequenceNumber & 0xFFFF) >= 0xF000))
goto freePacket;
}
switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
{ {
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
goto freePacket;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
currentCommand != enet_list_end (& channel -> incomingReliableCommands); currentCommand != enet_list_end (& channel -> incomingReliableCommands);
currentCommand = enet_list_previous (currentCommand)) currentCommand = enet_list_previous (currentCommand))
{ {
incomingCommand = (ENetIncomingCommand *) currentCommand; incomingCommand = (ENetIncomingCommand *) currentCommand;
if (incomingCommand -> reliableSequenceNumber <= command -> header.reliableSequenceNumber) if (reliableSequenceNumber >= 0x10000 && incomingCommand -> reliableSequenceNumber < 0xF000)
reliableSequenceNumber -= 0x10000;
if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber)
{ {
if (incomingCommand -> reliableSequenceNumber < command -> header.reliableSequenceNumber) if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
break; break;
goto freePacket; goto freePacket;
@ -589,12 +597,13 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
break; break;
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
unreliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> sendUnreliable.unreliableSequenceNumber); unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber);
if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber) if (channel -> incomingUnreliableSequenceNumber >= 0xF000 && unreliableSequenceNumber < 0x1000)
goto freePacket; unreliableSequenceNumber += 0x10000;
if (unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber) if (unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber ||
(channel -> incomingUnreliableSequenceNumber < 0x1000 && (unreliableSequenceNumber & 0xFFFF) >= 0xF000))
goto freePacket; goto freePacket;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
@ -603,6 +612,12 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
{ {
incomingCommand = (ENetIncomingCommand *) currentCommand; incomingCommand = (ENetIncomingCommand *) currentCommand;
if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
continue;
if (unreliableSequenceNumber >= 0x10000 && incomingCommand -> unreliableSequenceNumber < 0xF000)
unreliableSequenceNumber -= 0x10000;
if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber) if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
{ {
if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber) if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
@ -624,7 +639,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand)); incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber; incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber; incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF;
incomingCommand -> command = * command; incomingCommand -> command = * command;
incomingCommand -> fragmentCount = fragmentCount; incomingCommand -> fragmentCount = fragmentCount;
incomingCommand -> fragmentsRemaining = fragmentCount; incomingCommand -> fragmentsRemaining = fragmentCount;

View file

@ -11,6 +11,28 @@
static enet_uint32 timeCurrent; static enet_uint32 timeCurrent;
static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
{
0,
sizeof (ENetProtocolAcknowledge),
sizeof (ENetProtocolConnect),
sizeof (ENetProtocolVerifyConnect),
sizeof (ENetProtocolDisconnect),
sizeof (ENetProtocolPing),
sizeof (ENetProtocolSendReliable),
sizeof (ENetProtocolSendUnreliable),
sizeof (ENetProtocolSendFragment),
sizeof (ENetProtocolSendUnsequenced),
sizeof (ENetProtocolBandwidthLimit),
sizeof (ENetProtocolThrottleConfigure),
};
size_t
enet_protocol_command_size (enet_uint8 commandNumber)
{
return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK];
}
static int static int
enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
{ {
@ -27,6 +49,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
switch (currentPeer -> state) switch (currentPeer -> state)
{ {
case ENET_PEER_STATE_CONNECTION_PENDING: case ENET_PEER_STATE_CONNECTION_PENDING:
case ENET_PEER_STATE_CONNECTION_SUCCEEDED:
currentPeer -> state = ENET_PEER_STATE_CONNECTED; currentPeer -> state = ENET_PEER_STATE_CONNECTED;
event -> type = ENET_EVENT_TYPE_CONNECT; event -> type = ENET_EVENT_TYPE_CONNECT;
@ -82,7 +105,7 @@ enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * even
host -> recalculateBandwidthLimits = 1; host -> recalculateBandwidthLimits = 1;
if (event == NULL) if (event == NULL)
peer -> state = ENET_PEER_STATE_CONNECTION_PENDING; peer -> state = (peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING);
else else
{ {
peer -> state = ENET_PEER_STATE_CONNECTED; peer -> state = ENET_PEER_STATE_CONNECTED;
@ -98,7 +121,7 @@ enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * e
if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING) if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING)
host -> recalculateBandwidthLimits = 1; host -> recalculateBandwidthLimits = 1;
if (peer -> state < ENET_PEER_STATE_CONNECTED) if (peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED)
enet_peer_reset (peer); enet_peer_reset (peer);
else else
if (event == NULL) if (event == NULL)
@ -118,7 +141,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
{ {
ENetOutgoingCommand * outgoingCommand; ENetOutgoingCommand * outgoingCommand;
while (enet_list_empty (& peer -> sentUnreliableCommands) == 0) while (! enet_list_empty (& peer -> sentUnreliableCommands))
{ {
outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands); outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands);
@ -137,7 +160,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
} }
static ENetProtocolCommand static ENetProtocolCommand
enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint32 reliableSequenceNumber, enet_uint8 channelID) enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID)
{ {
ENetOutgoingCommand * outgoingCommand; ENetOutgoingCommand * outgoingCommand;
ENetListIterator currentCommand; ENetListIterator currentCommand;
@ -157,7 +180,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint32 reliabl
if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
return ENET_PROTOCOL_COMMAND_NONE; return ENET_PROTOCOL_COMMAND_NONE;
commandNumber = outgoingCommand -> command.header.command; commandNumber = outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK;
enet_list_remove (& outgoingCommand -> outgoingCommandList); enet_list_remove (& outgoingCommand -> outgoingCommandList);
@ -184,7 +207,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint32 reliabl
} }
static ENetPeer * static ENetPeer *
enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header, const ENetProtocol * command) enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command)
{ {
enet_uint16 mtu; enet_uint16 mtu;
enet_uint32 windowSize; enet_uint32 windowSize;
@ -193,9 +216,25 @@ enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header
ENetPeer * currentPeer; ENetPeer * currentPeer;
ENetProtocol verifyCommand; ENetProtocol verifyCommand;
if (command -> header.commandLength < sizeof (ENetProtocolConnect)) #ifdef USE_CRC32
return NULL; {
enet_uint32 crc = header -> checksum;
ENetBuffer buffer;
command -> header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (command -> header.reliableSequenceNumber);
header -> checksum = command -> connect.sessionID;
buffer.data = host -> receivedData;
buffer.dataLength = host -> receivedDataLength;
if (enet_crc32 (& buffer, 1) != crc)
return NULL;
command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber);
}
#endif
channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount);
if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT ||
@ -209,7 +248,7 @@ enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header
if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED && if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
currentPeer -> address.host == host -> receivedAddress.host && currentPeer -> address.host == host -> receivedAddress.host &&
currentPeer -> address.port == host -> receivedAddress.port && currentPeer -> address.port == host -> receivedAddress.port &&
currentPeer -> challenge == header -> challenge) currentPeer -> sessionID == command -> connect.sessionID)
return NULL; return NULL;
} }
@ -225,7 +264,7 @@ enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header
return NULL; return NULL;
currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
currentPeer -> challenge = header -> challenge; currentPeer -> sessionID = command -> connect.sessionID;
currentPeer -> address = host -> receivedAddress; currentPeer -> address = host -> receivedAddress;
currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
@ -288,10 +327,8 @@ enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header
if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT; verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
verifyCommand.header.channelID = 0xFF; verifyCommand.header.channelID = 0xFF;
verifyCommand.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
verifyCommand.header.commandLength = sizeof (ENetProtocolVerifyConnect);
verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu); verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu);
verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize); verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize);
@ -307,38 +344,50 @@ enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header
return currentPeer; return currentPeer;
} }
static void static int
enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
{ {
ENetPacket * packet; ENetPacket * packet;
size_t dataLength;
if (command -> header.commandLength <= sizeof (ENetProtocolSendReliable) || if (command -> header.channelID >= peer -> channelCount ||
command -> header.channelID >= peer -> channelCount || (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
peer -> state != ENET_PEER_STATE_CONNECTED) return -1;
return;
dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength);
* currentData += dataLength;
if (* currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable),
command -> header.commandLength - sizeof (ENetProtocolSendReliable), dataLength,
ENET_PACKET_FLAG_RELIABLE); ENET_PACKET_FLAG_RELIABLE);
enet_peer_queue_incoming_command (peer, command, packet, 0); enet_peer_queue_incoming_command (peer, command, packet, 0);
return 0;
} }
static void static int
enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
{ {
ENetPacket * packet; ENetPacket * packet;
enet_uint32 unsequencedGroup, index; enet_uint32 unsequencedGroup, index;
size_t dataLength;
if (command -> header.commandLength <= sizeof (ENetProtocolSendUnsequenced) || if (command -> header.channelID >= peer -> channelCount ||
command -> header.channelID >= peer -> channelCount || (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
peer -> state != ENET_PEER_STATE_CONNECTED) return -1;
return;
unsequencedGroup = ENET_NET_TO_HOST_32 (command -> sendUnsequenced.unsequencedGroup); dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength);
* currentData += dataLength;
if (* currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup);
index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE; index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE;
if (unsequencedGroup >= peer -> incomingUnsequencedGroup + ENET_PEER_UNSEQUENCED_WINDOW_SIZE) if (unsequencedGroup >= peer -> incomingUnsequencedGroup + ENET_PEER_UNSEQUENCED_WINDOW_SIZE ||
peer -> incomingUnsequencedGroup >= 0xF000 && unsequencedGroup < 0x1000)
{ {
peer -> incomingUnsequencedGroup = unsequencedGroup - index; peer -> incomingUnsequencedGroup = unsequencedGroup - index;
@ -347,37 +396,44 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E
else else
if (unsequencedGroup < peer -> incomingUnsequencedGroup || if (unsequencedGroup < peer -> incomingUnsequencedGroup ||
peer -> unsequencedWindow [index / 32] & (1 << (index % 32))) peer -> unsequencedWindow [index / 32] & (1 << (index % 32)))
return; return 0;
peer -> unsequencedWindow [index / 32] |= 1 << (index % 32); peer -> unsequencedWindow [index / 32] |= 1 << (index % 32);
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced),
command -> header.commandLength - sizeof (ENetProtocolSendUnsequenced), dataLength,
ENET_PACKET_FLAG_UNSEQUENCED); ENET_PACKET_FLAG_UNSEQUENCED);
enet_peer_queue_incoming_command (peer, command, packet, 0); enet_peer_queue_incoming_command (peer, command, packet, 0);
return 0;
} }
static void static int
enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
{ {
ENetPacket * packet; ENetPacket * packet;
size_t dataLength;
if (command -> header.commandLength <= sizeof (ENetProtocolSendUnreliable) || if (command -> header.channelID >= peer -> channelCount ||
command -> header.channelID >= peer -> channelCount || (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
peer -> state != ENET_PEER_STATE_CONNECTED) return -1;
return;
dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength);
* currentData += dataLength;
if (* currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable),
command -> header.commandLength - sizeof (ENetProtocolSendUnreliable), dataLength,
0); 0);
enet_peer_queue_incoming_command (peer, command, packet, 0); enet_peer_queue_incoming_command (peer, command, packet, 0);
return 0;
} }
static void static int
enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
{ {
enet_uint32 fragmentNumber, enet_uint32 fragmentNumber,
fragmentCount, fragmentCount,
@ -389,36 +445,42 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
ENetListIterator currentCommand; ENetListIterator currentCommand;
ENetIncomingCommand * startCommand; ENetIncomingCommand * startCommand;
if (command -> header.commandLength <= sizeof (ENetProtocolSendFragment) || if (command -> header.channelID >= peer -> channelCount ||
command -> header.channelID >= peer -> channelCount || (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
peer -> state != ENET_PEER_STATE_CONNECTED) return -1;
return;
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
* currentData += fragmentLength;
if (* currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
channel = & peer -> channels [command -> header.channelID];
startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber);
if (channel -> incomingReliableSequenceNumber >= 0xF000 && startSequenceNumber < 0x1000)
startSequenceNumber += 0x10000;
if (startSequenceNumber < channel -> incomingReliableSequenceNumber ||
(channel -> incomingReliableSequenceNumber < 0x1000 && (startSequenceNumber & 0xFFFF) >= 0xF000))
return 0;
startSequenceNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.startSequenceNumber);
fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber); fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber);
fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount); fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
fragmentLength = command -> header.commandLength - sizeof (ENetProtocolSendFragment);
if (fragmentOffset >= totalLength || if (fragmentOffset >= totalLength ||
fragmentOffset + fragmentLength > totalLength || fragmentOffset + fragmentLength > totalLength ||
fragmentNumber >= fragmentCount) fragmentNumber >= fragmentCount)
return; return -1;
channel = & peer -> channels [command -> header.channelID];
if (startSequenceNumber <= channel -> incomingReliableSequenceNumber)
return;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
currentCommand != enet_list_end (& channel -> incomingReliableCommands); currentCommand != enet_list_end (& channel -> incomingReliableCommands);
currentCommand = enet_list_previous (currentCommand)) currentCommand = enet_list_previous (currentCommand))
{ {
startCommand = (ENetIncomingCommand *) currentCommand; startCommand = (ENetIncomingCommand *) currentCommand;
if (startCommand -> command.header.command == ENET_PROTOCOL_COMMAND_SEND_FRAGMENT && if ((startCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_FRAGMENT &&
startCommand -> command.sendFragment.startSequenceNumber == startSequenceNumber) startCommand -> command.sendFragment.startSequenceNumber == (startSequenceNumber & 0xFFFF))
break; break;
} }
@ -428,6 +490,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
hostCommand.header.reliableSequenceNumber = startSequenceNumber; hostCommand.header.reliableSequenceNumber = startSequenceNumber;
hostCommand.sendFragment.startSequenceNumber = startSequenceNumber; hostCommand.sendFragment.startSequenceNumber = startSequenceNumber;
hostCommand.sendFragment.dataLength = fragmentLength;
hostCommand.sendFragment.fragmentNumber = fragmentNumber; hostCommand.sendFragment.fragmentNumber = fragmentNumber;
hostCommand.sendFragment.fragmentCount = fragmentCount; hostCommand.sendFragment.fragmentCount = fragmentCount;
hostCommand.sendFragment.fragmentOffset = fragmentOffset; hostCommand.sendFragment.fragmentOffset = fragmentOffset;
@ -441,7 +504,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
else else
if (totalLength != startCommand -> packet -> dataLength || if (totalLength != startCommand -> packet -> dataLength ||
fragmentCount != startCommand -> fragmentCount) fragmentCount != startCommand -> fragmentCount)
return; return -1;
if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0)
{ {
@ -456,26 +519,23 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
(enet_uint8 *) command + sizeof (ENetProtocolSendFragment), (enet_uint8 *) command + sizeof (ENetProtocolSendFragment),
fragmentLength); fragmentLength);
} }
return 0;
} }
static void static int
enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{ {
if (command -> header.commandLength < sizeof (ENetProtocolPing)) return 0;
return;
} }
static void static int
enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{ {
if (command -> header.commandLength < sizeof (ENetProtocolBandwidthLimit))
return;
peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth); peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth);
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth); peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);
if (peer -> incomingBandwidth == 0 && if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0)
host -> outgoingBandwidth == 0)
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
else else
peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) / peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) /
@ -486,40 +546,42 @@ enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const EN
else else
if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
return 0;
} }
static void static int
enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{ {
if (command -> header.commandLength < sizeof (ENetProtocolThrottleConfigure))
return;
peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval); peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval);
peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration); peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration);
peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration); peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration);
return 0;
} }
static void static int
enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{ {
if (command -> header.commandLength < sizeof (ENetProtocolDisconnect))
return;
enet_peer_reset_queues (peer); enet_peer_reset_queues (peer);
if (peer -> state != ENET_PEER_STATE_CONNECTED) if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED)
peer -> state = ENET_PEER_STATE_ZOMBIE;
else
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
{ {
if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1; if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1;
enet_peer_reset (peer); enet_peer_reset (peer);
} }
else else
if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT; peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT;
else else
peer -> state = ENET_PEER_STATE_ZOMBIE; peer -> state = ENET_PEER_STATE_ZOMBIE;
peer -> disconnectData = command -> disconnect.data; peer -> disconnectData = ENET_NET_TO_HOST_32 (command -> disconnect.data);
return 0;
} }
static int static int
@ -530,10 +592,10 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
receivedReliableSequenceNumber; receivedReliableSequenceNumber;
ENetProtocolCommand commandNumber; ENetProtocolCommand commandNumber;
if (command -> header.commandLength < sizeof (ENetProtocolAcknowledge)) receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime);
return 0; receivedSentTime |= timeCurrent & 0xFFFF0000;
if ((receivedSentTime & 0x8000) > (timeCurrent & 0x8000))
receivedSentTime = ENET_NET_TO_HOST_32 (command -> acknowledge.receivedSentTime); receivedSentTime -= 0x10000;
if (ENET_TIME_LESS (timeCurrent, receivedSentTime)) if (ENET_TIME_LESS (timeCurrent, receivedSentTime))
return 0; return 0;
@ -574,7 +636,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
peer -> packetThrottleEpoch = timeCurrent; peer -> packetThrottleEpoch = timeCurrent;
} }
receivedReliableSequenceNumber = ENET_NET_TO_HOST_32 (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);
@ -582,34 +644,37 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
{ {
case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT)
return 0; return -1;
enet_protocol_notify_connect (host, peer, event); enet_protocol_notify_connect (host, peer, event);
break;
return 1;
case ENET_PEER_STATE_DISCONNECTING: case ENET_PEER_STATE_DISCONNECTING:
if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT)
return 0; return -1;
enet_protocol_notify_disconnect (host, peer, event); enet_protocol_notify_disconnect (host, peer, event);
break;
return 1; case ENET_PEER_STATE_DISCONNECT_LATER:
if (enet_list_empty (& peer -> outgoingReliableCommands) &&
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
enet_list_empty (& peer -> sentReliableCommands))
enet_peer_disconnect (peer, peer -> disconnectData);
break;
} }
return 0; return 0;
} }
static void static int
enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
{ {
enet_uint16 mtu; enet_uint16 mtu;
enet_uint32 windowSize; enet_uint32 windowSize;
if (event == NULL || if (peer -> state != ENET_PEER_STATE_CONNECTING)
command -> header.commandLength < sizeof (ENetProtocolVerifyConnect) || return -1;
peer -> state != ENET_PEER_STATE_CONNECTING)
return;
if (ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount) != peer -> channelCount || if (ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount) != peer -> channelCount ||
ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval || ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval ||
@ -618,9 +683,11 @@ enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPee
{ {
peer -> state = ENET_PEER_STATE_ZOMBIE; peer -> state = ENET_PEER_STATE_ZOMBIE;
return; return -1;
} }
enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF);
peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID); peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID);
mtu = ENET_NET_TO_HOST_16 (command -> verifyConnect.mtu); mtu = ENET_NET_TO_HOST_16 (command -> verifyConnect.mtu);
@ -649,6 +716,7 @@ enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPee
peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth); peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth);
enet_protocol_notify_connect (host, peer, event); enet_protocol_notify_connect (host, peer, event);
return 0;
} }
static int static int
@ -658,135 +726,175 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
ENetProtocol * command; ENetProtocol * command;
ENetPeer * peer; ENetPeer * peer;
enet_uint8 * currentData; enet_uint8 * currentData;
size_t commandCount; size_t headerSize;
enet_uint16 peerID, flags;
if (host -> receivedDataLength < sizeof (ENetProtocolHeader)) if (host -> receivedDataLength < sizeof (ENetProtocolHeader))
return 0; return 0;
header = (ENetProtocolHeader *) host -> receivedData; header = (ENetProtocolHeader *) host -> receivedData;
header -> peerID = ENET_NET_TO_HOST_16 (header -> peerID); peerID = ENET_NET_TO_HOST_16 (header -> peerID);
header -> sentTime = ENET_NET_TO_HOST_32 (header -> sentTime); flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK;
peerID &= ~ ENET_PROTOCOL_HEADER_FLAG_MASK;
if (header -> peerID == 0xFFFF) if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID)
peer = NULL; peer = NULL;
else else
if (header -> peerID >= host -> peerCount) if (peerID >= host -> peerCount)
return 0; return 0;
else else
{ {
peer = & host -> peers [header -> peerID]; peer = & host -> peers [peerID];
if (peer -> state == ENET_PEER_STATE_DISCONNECTED || if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ZOMBIE ||
(host -> receivedAddress.host != peer -> address.host && (host -> receivedAddress.host != peer -> address.host &&
peer -> address.host != ENET_HOST_BROADCAST) || peer -> address.host != ENET_HOST_BROADCAST))
header -> challenge != peer -> challenge)
return 0; return 0;
else
#ifdef USE_CRC32
{ {
peer -> address.host = host -> receivedAddress.host; enet_uint32 crc = header -> checksum;
peer -> address.port = host -> receivedAddress.port; ENetBuffer buffer;
header -> checksum = peer -> sessionID;
buffer.data = host -> receivedData;
buffer.dataLength = host -> receivedDataLength;
if (enet_crc32 (& buffer, 1) != crc)
return 0;
} }
#else
if (header -> checksum != peer -> sessionID)
return 0;
#endif
peer -> address.host = host -> receivedAddress.host;
peer -> address.port = host -> receivedAddress.port;
peer -> incomingDataTotal += host -> receivedDataLength;
} }
if (peer != NULL) headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime);
peer -> incomingDataTotal += host -> receivedDataLength; currentData = host -> receivedData + headerSize;
commandCount = header -> commandCount;
currentData = host -> receivedData + sizeof (ENetProtocolHeader);
while (commandCount > 0 && while (currentData < & host -> receivedData [host -> receivedDataLength])
currentData < & host -> receivedData [host -> receivedDataLength])
{ {
enet_uint8 commandNumber;
size_t commandSize;
command = (ENetProtocol *) currentData; command = (ENetProtocol *) currentData;
if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength]) if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength])
break; break;
command -> header.commandLength = ENET_NET_TO_HOST_32 (command -> header.commandLength); commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK;
if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT)
if (command -> header.commandLength <= 0 || break;
command -> header.commandLength > & host -> receivedData [host -> receivedDataLength] - currentData)
commandSize = commandSizes [commandNumber];
if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength])
break; break;
-- commandCount; currentData += commandSize;
currentData += command -> header.commandLength;
if (peer == NULL && command -> header.command != ENET_PROTOCOL_COMMAND_CONNECT) if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT)
break; break;
command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> header.reliableSequenceNumber); command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber);
switch (command -> header.command) switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
{ {
case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE:
enet_protocol_handle_acknowledge (host, event, peer, command); if (enet_protocol_handle_acknowledge (host, event, peer, command))
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_CONNECT: case ENET_PROTOCOL_COMMAND_CONNECT:
peer = enet_protocol_handle_connect (host, header, command); peer = enet_protocol_handle_connect (host, header, command);
if (peer == NULL)
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT: case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT:
enet_protocol_handle_verify_connect (host, event, peer, command); if (enet_protocol_handle_verify_connect (host, event, peer, command))
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_DISCONNECT: case ENET_PROTOCOL_COMMAND_DISCONNECT:
enet_protocol_handle_disconnect (host, peer, command); if (enet_protocol_handle_disconnect (host, peer, command))
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_PING: case ENET_PROTOCOL_COMMAND_PING:
enet_protocol_handle_ping (host, peer, command); if (enet_protocol_handle_ping (host, peer, command))
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
enet_protocol_handle_send_reliable (host, peer, command); if (enet_protocol_handle_send_reliable (host, peer, command, & currentData))
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
enet_protocol_handle_send_unreliable (host, peer, command); if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData))
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
enet_protocol_handle_send_unsequenced (host, peer, command); if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData))
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
enet_protocol_handle_send_fragment (host, peer, command); if (enet_protocol_handle_send_fragment (host, peer, command, & currentData))
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT: case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT:
enet_protocol_handle_bandwidth_limit (host, peer, command); if (enet_protocol_handle_bandwidth_limit (host, peer, command))
goto commandError;
break; break;
case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE: case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE:
enet_protocol_handle_throttle_configure (host, peer, command); if (enet_protocol_handle_throttle_configure (host, peer, command))
goto commandError;
break; break;
default: default:
break; goto commandError;
} }
if (peer != NULL && if (peer != NULL &&
(command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE) != 0) (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0)
{ {
enet_uint16 sentTime;
if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME))
break;
sentTime = ENET_NET_TO_HOST_16 (header -> sentTime);
switch (peer -> state) switch (peer -> state)
{ {
case ENET_PEER_STATE_DISCONNECTING: case ENET_PEER_STATE_DISCONNECTING:
case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
break; break;
case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT:
if (command -> header.command != ENET_PROTOCOL_COMMAND_DISCONNECT) if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
break; enet_peer_queue_acknowledgement (peer, command, sentTime);
break;
default: default:
enet_peer_queue_acknowledgement (peer, command, header -> sentTime); enet_peer_queue_acknowledgement (peer, command, sentTime);
break; break;
} }
} }
} }
commandError:
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
return 1; return 1;
@ -848,7 +956,11 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
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))
break; {
host -> continueSending = 1;
break;
}
acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; acknowledgement = (ENetAcknowledgement *) currentAcknowledgement;
@ -861,12 +973,10 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE;
command -> header.channelID = acknowledgement -> command.header.channelID; command -> header.channelID = acknowledgement -> command.header.channelID;
command -> header.flags = 0; command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber);
command -> header.commandLength = ENET_HOST_TO_NET_32 (sizeof (ENetProtocolAcknowledge)); command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime);
command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_32 (acknowledgement -> command.header.reliableSequenceNumber);
command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_32 (acknowledgement -> sentTime);
if (acknowledgement -> command.header.command == ENET_PROTOCOL_COMMAND_DISCONNECT) if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
peer -> state = ENET_PEER_STATE_ZOMBIE; peer -> state = ENET_PEER_STATE_ZOMBIE;
enet_list_remove (& acknowledgement -> acknowledgementList); enet_list_remove (& acknowledgement -> acknowledgementList);
@ -892,15 +1002,21 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands)) while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
{ {
size_t commandSize;
outgoingCommand = (ENetOutgoingCommand *) currentCommand; outgoingCommand = (ENetOutgoingCommand *) currentCommand;
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 < outgoingCommand -> command.header.commandLength || peer -> mtu - host -> packetSize < commandSize ||
(outgoingCommand -> packet != NULL && (outgoingCommand -> packet != NULL &&
peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength + peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> packet -> dataLength))
outgoingCommand -> packet -> dataLength)) {
break; host -> continueSending = 1;
break;
}
currentCommand = enet_list_next (currentCommand); currentCommand = enet_list_next (currentCommand);
@ -924,7 +1040,7 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
} }
buffer -> data = command; buffer -> data = command;
buffer -> dataLength = outgoingCommand -> command.header.commandLength; buffer -> dataLength = commandSize;
host -> packetSize += buffer -> dataLength; host -> packetSize += buffer -> dataLength;
@ -939,8 +1055,6 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
buffer -> data = outgoingCommand -> packet -> data; buffer -> data = outgoingCommand -> packet -> data;
buffer -> dataLength = outgoingCommand -> packet -> dataLength; buffer -> dataLength = outgoingCommand -> packet -> dataLength;
command -> header.commandLength += buffer -> dataLength;
host -> packetSize += buffer -> dataLength; host -> packetSize += buffer -> dataLength;
enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
@ -948,14 +1062,18 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
else else
enet_free (outgoingCommand); enet_free (outgoingCommand);
command -> header.commandLength = ENET_HOST_TO_NET_32 (command -> header.commandLength);
++ command; ++ command;
++ buffer; ++ buffer;
} }
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_list_empty (& peer -> outgoingReliableCommands) &&
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
enet_list_empty (& peer -> sentReliableCommands))
enet_peer_disconnect (peer, peer -> disconnectData);
} }
static int static int
@ -1000,7 +1118,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
enet_list_remove (& outgoingCommand -> outgoingCommandList)); enet_list_remove (& outgoingCommand -> outgoingCommandList));
if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) && if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
enet_list_empty (& peer -> sentReliableCommands) == 0) ! enet_list_empty (& peer -> sentReliableCommands))
{ {
outgoingCommand = (ENetOutgoingCommand *) currentCommand; outgoingCommand = (ENetOutgoingCommand *) currentCommand;
@ -1023,22 +1141,33 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
{ {
outgoingCommand = (ENetOutgoingCommand *) currentCommand; 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)] || 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 < outgoingCommand -> command.header.commandLength) peer -> mtu - host -> packetSize < commandSize)
break; {
host -> continueSending = 1;
break;
}
currentCommand = enet_list_next (currentCommand); currentCommand = enet_list_next (currentCommand);
if (outgoingCommand -> packet != NULL) if (outgoingCommand -> packet != NULL)
{ {
if ((enet_uint16) (peer -> mtu - host -> packetSize) < if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize)
(enet_uint16) (outgoingCommand -> command.header.commandLength +
outgoingCommand -> fragmentLength) ||
peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize)
break; break;
if ((enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))
{
host -> continueSending = 1;
break;
}
} }
if (outgoingCommand -> roundTripTimeout == 0) if (outgoingCommand -> roundTripTimeout == 0)
@ -1056,9 +1185,10 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
outgoingCommand -> sentTime = timeCurrent; outgoingCommand -> sentTime = timeCurrent;
buffer -> data = command; buffer -> data = command;
buffer -> dataLength = outgoingCommand -> command.header.commandLength; 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;
@ -1069,15 +1199,11 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
buffer -> dataLength = outgoingCommand -> fragmentLength; buffer -> dataLength = outgoingCommand -> fragmentLength;
command -> header.commandLength += outgoingCommand -> fragmentLength;
host -> packetSize += outgoingCommand -> fragmentLength; host -> packetSize += outgoingCommand -> fragmentLength;
peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
} }
command -> header.commandLength = ENET_HOST_TO_NET_32 (command -> header.commandLength);
++ peer -> packetsSent; ++ peer -> packetsSent;
++ command; ++ command;
@ -1091,14 +1217,15 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
static int static int
enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts) enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts)
{ {
size_t packetsSent = 1;
ENetProtocolHeader header; ENetProtocolHeader header;
ENetPeer * currentPeer; ENetPeer * currentPeer;
int sentLength; int sentLength;
while (packetsSent > 0) host -> continueSending = 1;
for (currentPeer = host -> peers,
packetsSent = 0; while (host -> continueSending)
for (host -> continueSending = 0,
currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount]; currentPeer < & host -> peers [host -> peerCount];
++ currentPeer) ++ currentPeer)
{ {
@ -1106,22 +1233,21 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
currentPeer -> state == ENET_PEER_STATE_ZOMBIE) currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
continue; continue;
host -> headerFlags = 0;
host -> commandCount = 0; host -> commandCount = 0;
host -> bufferCount = 1; host -> bufferCount = 1;
host -> packetSize = sizeof (ENetProtocolHeader); host -> packetSize = sizeof (ENetProtocolHeader);
if (enet_list_empty (& currentPeer -> acknowledgements) == 0) if (! enet_list_empty (& currentPeer -> acknowledgements))
enet_protocol_send_acknowledgements (host, currentPeer); enet_protocol_send_acknowledgements (host, currentPeer);
if (host -> commandCount < sizeof (host -> commands) / sizeof (ENetProtocol)) if (checkForTimeouts != 0 &&
{ ! enet_list_empty (& currentPeer -> sentReliableCommands) &&
if (checkForTimeouts != 0 && ENET_TIME_GREATER_EQUAL (timeCurrent, currentPeer -> nextTimeout) &&
enet_list_empty (& currentPeer -> sentReliableCommands) == 0 && enet_protocol_check_timeouts (host, currentPeer, event) == 1)
ENET_TIME_GREATER_EQUAL (timeCurrent, currentPeer -> nextTimeout) && return 1;
enet_protocol_check_timeouts (host, currentPeer, event) == 1)
return 1; if (! enet_list_empty (& currentPeer -> outgoingReliableCommands))
}
if (enet_list_empty (& currentPeer -> outgoingReliableCommands) == 0)
enet_protocol_send_reliable_outgoing_commands (host, currentPeer); enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
else else
if (enet_list_empty (& currentPeer -> sentReliableCommands) && if (enet_list_empty (& currentPeer -> sentReliableCommands) &&
@ -1132,8 +1258,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
enet_protocol_send_reliable_outgoing_commands (host, currentPeer); enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
} }
if (host -> commandCount < sizeof (host -> commands) / sizeof (ENetProtocol) && if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
enet_list_empty (& currentPeer -> outgoingUnreliableCommands) == 0)
enet_protocol_send_unreliable_outgoing_commands (host, currentPeer); enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
if (host -> commandCount == 0) if (host -> commandCount == 0)
@ -1174,19 +1299,25 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
currentPeer -> packetsLost = 0; currentPeer -> packetsLost = 0;
} }
header.peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID); header.checksum = currentPeer -> sessionID;
header.flags = 0; header.peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags);
header.commandCount = host -> commandCount;
header.sentTime = ENET_HOST_TO_NET_32 (timeCurrent);
header.challenge = currentPeer -> challenge;
host -> buffers -> data = & header; host -> buffers -> data = & header;
host -> buffers -> dataLength = sizeof (ENetProtocolHeader); if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)
{
header.sentTime = ENET_HOST_TO_NET_16 (timeCurrent & 0xFFFF);
host -> buffers -> dataLength = sizeof (ENetProtocolHeader);
}
else
host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime;
#ifdef USE_CRC32
header.checksum = enet_crc32 (host -> buffers, host -> bufferCount);
#endif
currentPeer -> lastSendTime = timeCurrent; currentPeer -> lastSendTime = timeCurrent;
++ packetsSent;
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);

6
unix.c
View file

@ -80,7 +80,7 @@ enet_address_set_host (ENetAddress * address, const char * name)
char buffer [2048]; char buffer [2048];
int errnum; int errnum;
#ifdef linux #if defined(linux) || defined(FREEBSD)
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);
@ -118,7 +118,7 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng
in.s_addr = address -> host; in.s_addr = address -> host;
#ifdef linux #if defined(linux) || defined(FREEBSD)
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);
@ -153,6 +153,7 @@ enet_socket_create (ENetSocketType type, const ENetAddress * address)
{ {
ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE, int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE,
sendBufferSize = ENET_HOST_SEND_BUFFER_SIZE,
allowBroadcasting = 1; allowBroadcasting = 1;
#ifndef HAS_FCNTL #ifndef HAS_FCNTL
int nonBlocking = 1; int nonBlocking = 1;
@ -171,6 +172,7 @@ enet_socket_create (ENetSocketType type, const ENetAddress * address)
#endif #endif
setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int)); setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
setsockopt (newSocket, SOL_SOCKET, SO_SNDBUF, (char *) & sendBufferSize, sizeof (int));
setsockopt (newSocket, SOL_SOCKET, SO_BROADCAST, (char *) & allowBroadcasting, sizeof (int)); setsockopt (newSocket, SOL_SOCKET, SO_BROADCAST, (char *) & allowBroadcasting, sizeof (int));
} }

View file

@ -102,6 +102,7 @@ enet_socket_create (ENetSocketType type, const ENetAddress * address)
ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
u_long nonBlocking = 1; u_long nonBlocking = 1;
int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE, int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE,
sendBufferSize = ENET_HOST_SEND_BUFFER_SIZE,
allowBroadcasting = 1; allowBroadcasting = 1;
struct sockaddr_in sin; struct sockaddr_in sin;
@ -113,6 +114,7 @@ enet_socket_create (ENetSocketType type, const ENetAddress * address)
ioctlsocket (newSocket, FIONBIO, & nonBlocking); ioctlsocket (newSocket, FIONBIO, & nonBlocking);
setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int)); setsockopt (newSocket, SOL_SOCKET, SO_RCVBUF, (char *) & receiveBufferSize, sizeof (int));
setsockopt (newSocket, SOL_SOCKET, SO_SNDBUF, (char *) & sendBufferSize, sizeof (int));
setsockopt (newSocket, SOL_SOCKET, SO_BROADCAST, (char *) & allowBroadcasting, sizeof (int)); setsockopt (newSocket, SOL_SOCKET, SO_BROADCAST, (char *) & allowBroadcasting, sizeof (int));
} }