*** 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)
AM_INIT_AUTOMAKE(libenet.a, 1.0)
AC_INIT(libenet, 7-6-2006)
AM_INIT_AUTOMAKE(libenet.a, 7-6-2006)
AC_PROG_CC
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, 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])

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));
ENetPeer * currentPeer;
if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
return NULL;
host -> peers = (ENetPeer *) enet_malloc (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 -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
currentPeer -> channelCount = channelCount;
currentPeer -> challenge = (enet_uint32) enet_rand ();
currentPeer -> sessionID = (enet_uint32) enet_rand ();
if (host -> outgoingBandwidth == 0)
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);
}
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.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolConnect);
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
command.connect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu);
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.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
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);
@ -243,7 +245,7 @@ enet_host_bandwidth_throttle (ENetHost * host)
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED)
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
++ peersTotal;
@ -276,7 +278,7 @@ enet_host_bandwidth_throttle (ENetHost * host)
{
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 -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
@ -309,7 +311,7 @@ enet_host_bandwidth_throttle (ENetHost * host)
peer < & host -> peers [host -> peerCount];
++ 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)
continue;
@ -339,12 +341,12 @@ enet_host_bandwidth_throttle (ENetHost * host)
peer < & host -> peers [host -> peerCount];
++ 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)
continue;
if (peer -> outgoingBandwidth > 0 &&
bandwidthLimit > peer -> outgoingBandwidth)
peer -> outgoingBandwidth >= bandwidthLimit)
continue;
peer -> incomingBandwidthThrottleEpoch = timeCurrent;
@ -359,13 +361,11 @@ enet_host_bandwidth_throttle (ENetHost * host)
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED)
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
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.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolBandwidthLimit);
command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)

View file

@ -80,7 +80,9 @@ typedef enum
/** packet will not be sequenced with other 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;
/**
@ -115,8 +117,8 @@ typedef struct _ENetAcknowledgement
typedef struct _ENetOutgoingCommand
{
ENetListNode outgoingCommandList;
enet_uint32 reliableSequenceNumber;
enet_uint32 unreliableSequenceNumber;
enet_uint16 reliableSequenceNumber;
enet_uint16 unreliableSequenceNumber;
enet_uint32 sentTime;
enet_uint32 roundTripTimeout;
enet_uint32 roundTripTimeoutLimit;
@ -129,8 +131,8 @@ typedef struct _ENetOutgoingCommand
typedef struct _ENetIncomingCommand
{
ENetListNode incomingCommandList;
enet_uint32 reliableSequenceNumber;
enet_uint32 unreliableSequenceNumber;
enet_uint16 reliableSequenceNumber;
enet_uint16 unreliableSequenceNumber;
ENetProtocol command;
enet_uint32 fragmentCount;
enet_uint32 fragmentsRemaining;
@ -144,10 +146,12 @@ typedef enum
ENET_PEER_STATE_CONNECTING = 1,
ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2,
ENET_PEER_STATE_CONNECTION_PENDING = 3,
ENET_PEER_STATE_CONNECTED = 4,
ENET_PEER_STATE_DISCONNECTING = 5,
ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 6,
ENET_PEER_STATE_ZOMBIE = 7
ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4,
ENET_PEER_STATE_CONNECTED = 5,
ENET_PEER_STATE_DISCONNECT_LATER = 6,
ENET_PEER_STATE_DISCONNECTING = 7,
ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8,
ENET_PEER_STATE_ZOMBIE = 9
} ENetPeerState;
#ifndef ENET_BUFFER_MAXIMUM
@ -157,6 +161,7 @@ typedef enum
enum
{
ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024,
ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024,
ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000,
ENET_HOST_DEFAULT_MTU = 1400,
@ -197,7 +202,7 @@ typedef struct _ENetPeer
struct _ENetHost * host;
enet_uint16 outgoingPeerID;
enet_uint16 incomingPeerID;
enet_uint32 challenge;
enet_uint32 sessionID;
ENetAddress address; /**< Internet address of the peer */
void * data; /**< Application private data, may be freely modified */
ENetPeerState state;
@ -234,14 +239,14 @@ typedef struct _ENetPeer
enet_uint16 mtu;
enet_uint32 windowSize;
enet_uint32 reliableDataInTransit;
enet_uint32 outgoingReliableSequenceNumber;
enet_uint16 outgoingReliableSequenceNumber;
ENetList acknowledgements;
ENetList sentReliableCommands;
ENetList sentUnreliableCommands;
ENetList outgoingReliableCommands;
ENetList outgoingUnreliableCommands;
enet_uint32 incomingUnsequencedGroup;
enet_uint32 outgoingUnsequencedGroup;
enet_uint16 incomingUnsequencedGroup;
enet_uint16 outgoingUnsequencedGroup;
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
enet_uint32 disconnectData;
} ENetPeer;
@ -271,7 +276,9 @@ typedef struct _ENetHost
ENetPeer * peers; /**< array of peers allocated for this host */
size_t peerCount; /**< number of peers allocated for this host */
ENetPeer * lastServicedPeer;
int continueSending;
size_t packetSize;
enet_uint16 headerFlags;
ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
size_t commandCount;
ENetBuffer buffers [ENET_BUFFER_MAXIMUM];
@ -337,7 +344,7 @@ typedef struct _ENetEvent
*/
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
@ -361,15 +368,14 @@ ENET_API void enet_time_set (enet_uint32);
/** @defgroup socket ENet socket functions
@{
@ingroup private
*/
extern ENetSocket enet_socket_create (ENetSocketType, const ENetAddress *);
extern ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
extern int enet_socket_connect (ENetSocket, const ENetAddress *);
extern int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
extern int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
extern int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
extern void enet_socket_destroy (ENetSocket);
ENET_API ENetSocket enet_socket_create (ENetSocketType, const ENetAddress *);
ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *);
ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
ENET_API void enet_socket_destroy (ENetSocket);
/** @} */
@ -384,7 +390,7 @@ extern void enet_socket_destroy (ENetSocket);
@retval < 0 on failure
@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.
@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 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 void enet_packet_destroy (ENetPacket *packet );
ENET_API int enet_packet_resize (ENetPacket *packet, size_t dataLength );
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 ENetPeer * enet_host_connect (ENetHost *host, const ENetAddress *address, size_t channelCount );
ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
ENET_API void enet_packet_destroy (ENetPacket *);
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 *, size_t, enet_uint32, enet_uint32);
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 void enet_host_flush (ENetHost *);
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_disconnect (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);
extern int enet_peer_throttle (ENetPeer *, enet_uint32);
extern void enet_peer_reset_queues (ENetPeer *);
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 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
}

View file

@ -15,7 +15,8 @@ enum
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768,
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
@ -29,41 +30,42 @@ typedef enum
ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 9,
ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 10,
ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 11
ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
ENET_PROTOCOL_COMMAND_COUNT = 12,
ENET_PROTOCOL_COMMAND_MASK = 0x0F,
} ENetProtocolCommand;
typedef enum
{
ENET_PROTOCOL_FLAG_ACKNOWLEDGE = (1 << 0),
ENET_PROTOCOL_FLAG_UNSEQUENCED = (1 << 1)
ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15),
ENET_PROTOCOL_HEADER_FLAG_MASK = 0x8000,
} ENetProtocolFlag;
typedef struct
{
enet_uint32 checksum;
enet_uint16 peerID;
enet_uint8 flags;
enet_uint8 commandCount;
enet_uint32 sentTime;
enet_uint32 challenge;
enet_uint16 sentTime;
} ENetProtocolHeader;
typedef struct
{
enet_uint8 command;
enet_uint8 channelID;
enet_uint8 flags;
enet_uint8 reserved;
enet_uint32 commandLength;
enet_uint32 reliableSequenceNumber;
enet_uint16 reliableSequenceNumber;
} ENetProtocolCommandHeader;
typedef struct
{
ENetProtocolCommandHeader header;
enet_uint32 receivedReliableSequenceNumber;
enet_uint32 receivedSentTime;
enet_uint16 receivedReliableSequenceNumber;
enet_uint16 receivedSentTime;
} ENetProtocolAcknowledge;
typedef struct
@ -78,6 +80,7 @@ typedef struct
enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
enet_uint32 sessionID;
} ENetProtocolConnect;
typedef struct
@ -123,24 +126,28 @@ typedef struct
typedef struct
{
ENetProtocolCommandHeader header;
enet_uint16 dataLength;
} ENetProtocolSendReliable;
typedef struct
{
ENetProtocolCommandHeader header;
enet_uint32 unreliableSequenceNumber;
enet_uint16 unreliableSequenceNumber;
enet_uint16 dataLength;
} ENetProtocolSendUnreliable;
typedef struct
{
ENetProtocolCommandHeader header;
enet_uint32 unsequencedGroup;
enet_uint16 unsequencedGroup;
enet_uint16 dataLength;
} ENetProtocolSendUnsequenced;
typedef struct
{
ENetProtocolCommandHeader header;
enet_uint32 startSequenceNumber;
enet_uint16 startSequenceNumber;
enet_uint16 dataLength;
enet_uint32 fragmentCount;
enet_uint32 fragmentNumber;
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));
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)
memcpy (packet -> data, data, dataLength);
if (data != NULL)
memcpy (packet -> data, data, dataLength);
};
packet -> referenceCount = 0;
packet -> flags = flags;
@ -39,7 +44,8 @@ enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
void
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);
}
@ -54,7 +60,7 @@ enet_packet_resize (ENetPacket * packet, size_t dataLength)
{
enet_uint8 * newData;
if (dataLength <= packet -> dataLength)
if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
{
packet -> dataLength = dataLength;
@ -71,4 +77,53 @@ enet_packet_resize (ENetPacket * packet, size_t dataLength)
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 -> 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.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolThrottleConfigure);
command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval);
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)
{
enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
startSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingReliableSequenceNumber + 1),
fragmentNumber,
fragmentOffset;
@ -126,19 +124,18 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
++ fragmentNumber,
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.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolSendFragment);
command.sendFragment.startSequenceNumber = startSequenceNumber;
command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
command.sendFragment.fragmentCount = fragmentCount;
command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
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);
}
@ -149,24 +146,21 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE;
command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolSendReliable);
command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
}
else
if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED;
command.header.flags = ENET_PROTOCOL_FLAG_UNSEQUENCED;
command.header.commandLength = sizeof (ENetProtocolSendUnsequenced);
command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_32 (peer -> outgoingUnsequencedGroup + 1);
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
}
else
{
command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
command.header.flags = 0;
command.header.commandLength = sizeof (ENetProtocolSendUnreliable);
command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_32 (channel -> outgoingUnreliableSequenceNumber + 1);
command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (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;
ENetPacket * packet;
if (enet_list_empty (& channel -> incomingUnreliableCommands) == 0)
if (! enet_list_empty (& 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;
else
channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber;
@ -200,36 +194,12 @@ enet_peer_receive (ENetPeer * peer, enet_uint8 channelID)
}
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 ||
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)
if (incomingCommand -> fragmentsRemaining > 0 ||
incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber + 1)
return NULL;
channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
@ -260,7 +230,7 @@ enet_peer_reset_outgoing_commands (ENetList * queue)
{
ENetOutgoingCommand * outgoingCommand;
while (enet_list_empty (queue) == 0)
while (! enet_list_empty (queue))
{
outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
@ -281,7 +251,7 @@ enet_peer_reset_incoming_commands (ENetList * queue)
{
ENetIncomingCommand * incomingCommand;
while (enet_list_empty (queue) == 0)
while (! enet_list_empty (queue))
{
incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
@ -305,7 +275,7 @@ enet_peer_reset_queues (ENetPeer * peer)
{
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_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
@ -338,8 +308,8 @@ enet_peer_reset_queues (ENetPeer * peer)
void
enet_peer_reset (ENetPeer * peer)
{
peer -> outgoingPeerID = 0xFFFF;
peer -> challenge = 0;
peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
peer -> sessionID = 0;
peer -> address.host = ENET_HOST_ANY;
peer -> address.port = 0;
@ -402,10 +372,8 @@ enet_peer_ping (ENetPeer * peer)
if (peer -> state != ENET_PEER_STATE_CONNECTED)
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.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
command.header.commandLength = sizeof (ENetProtocolPing);
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);
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.flags = ENET_PROTOCOL_FLAG_UNSEQUENCED;
command.header.commandLength = sizeof (ENetProtocolDisconnect);
command.disconnect.data = data;
command.disconnect.data = ENET_HOST_TO_NET_32 (data);
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.channelID = 0xFF;
command.header.flags = ENET_PROTOCOL_FLAG_UNSEQUENCED;
command.header.commandLength = sizeof (ENetProtocolDisconnect);
command.disconnect.data = data;
command.disconnect.data = ENET_HOST_TO_NET_32 (data);
if (peer -> state == ENET_PEER_STATE_CONNECTED)
command.header.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
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);
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;
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 *
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;
@ -505,7 +492,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
ENetChannel * channel = & peer -> channels [command -> header.channelID];
ENetOutgoingCommand * outgoingCommand;
peer -> outgoingDataTotal += command -> header.commandLength + length;
peer -> outgoingDataTotal += enet_protocol_command_size (command -> header.command) + length;
outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
@ -517,7 +504,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
outgoingCommand -> unreliableSequenceNumber = 0;
}
else
if (command -> header.flags & ENET_PROTOCOL_FLAG_ACKNOWLEDGE)
if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
{
++ channel -> outgoingReliableSequenceNumber;
@ -525,7 +512,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
outgoingCommand -> unreliableSequenceNumber = 0;
}
else
if (command -> header.flags & ENET_PROTOCOL_FLAG_UNSEQUENCED)
if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
{
++ peer -> outgoingUnsequencedGroup;
@ -547,12 +534,12 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command,
outgoingCommand -> fragmentLength = length;
outgoingCommand -> packet = packet;
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)
++ 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);
else
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)
{
ENetChannel * channel = & peer -> channels [command -> header.channelID];
enet_uint32 unreliableSequenceNumber = 0;
enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber;
ENetIncomingCommand * incomingCommand;
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_RELIABLE:
if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
goto freePacket;
for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
currentCommand != enet_list_end (& channel -> incomingReliableCommands);
currentCommand = enet_list_previous (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;
goto freePacket;
@ -589,12 +597,13 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
break;
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)
goto freePacket;
if (unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber)
if (channel -> incomingUnreliableSequenceNumber >= 0xF000 && unreliableSequenceNumber < 0x1000)
unreliableSequenceNumber += 0x10000;
if (unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber ||
(channel -> incomingUnreliableSequenceNumber < 0x1000 && (unreliableSequenceNumber & 0xFFFF) >= 0xF000))
goto freePacket;
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;
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)
@ -624,7 +639,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber;
incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF;
incomingCommand -> command = * command;
incomingCommand -> fragmentCount = fragmentCount;
incomingCommand -> fragmentsRemaining = fragmentCount;

View file

@ -11,6 +11,28 @@
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
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)
{
case ENET_PEER_STATE_CONNECTION_PENDING:
case ENET_PEER_STATE_CONNECTION_SUCCEEDED:
currentPeer -> state = ENET_PEER_STATE_CONNECTED;
event -> type = ENET_EVENT_TYPE_CONNECT;
@ -82,7 +105,7 @@ enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * even
host -> recalculateBandwidthLimits = 1;
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
{
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)
host -> recalculateBandwidthLimits = 1;
if (peer -> state < ENET_PEER_STATE_CONNECTED)
if (peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED)
enet_peer_reset (peer);
else
if (event == NULL)
@ -118,7 +141,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
{
ENetOutgoingCommand * outgoingCommand;
while (enet_list_empty (& peer -> sentUnreliableCommands) == 0)
while (! enet_list_empty (& peer -> sentUnreliableCommands))
{
outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands);
@ -137,7 +160,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
}
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;
ENetListIterator currentCommand;
@ -157,7 +180,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint32 reliabl
if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
return ENET_PROTOCOL_COMMAND_NONE;
commandNumber = outgoingCommand -> command.header.command;
commandNumber = outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK;
enet_list_remove (& outgoingCommand -> outgoingCommandList);
@ -184,7 +207,7 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint32 reliabl
}
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_uint32 windowSize;
@ -193,9 +216,25 @@ enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header
ENetPeer * currentPeer;
ENetProtocol verifyCommand;
if (command -> header.commandLength < sizeof (ENetProtocolConnect))
return NULL;
#ifdef USE_CRC32
{
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);
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 &&
currentPeer -> address.host == host -> receivedAddress.host &&
currentPeer -> address.port == host -> receivedAddress.port &&
currentPeer -> challenge == header -> challenge)
currentPeer -> sessionID == command -> connect.sessionID)
return NULL;
}
@ -225,7 +264,7 @@ enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header
return NULL;
currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
currentPeer -> challenge = header -> challenge;
currentPeer -> sessionID = command -> connect.sessionID;
currentPeer -> address = host -> receivedAddress;
currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
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)
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.flags = ENET_PROTOCOL_FLAG_ACKNOWLEDGE;
verifyCommand.header.commandLength = sizeof (ENetProtocolVerifyConnect);
verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu);
verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize);
@ -307,38 +344,50 @@ enet_protocol_handle_connect (ENetHost * host, const ENetProtocolHeader * header
return currentPeer;
}
static void
enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
static int
enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
{
ENetPacket * packet;
size_t dataLength;
if (command -> header.commandLength <= sizeof (ENetProtocolSendReliable) ||
command -> header.channelID >= peer -> channelCount ||
peer -> state != ENET_PEER_STATE_CONNECTED)
return;
if (command -> header.channelID >= peer -> channelCount ||
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
return -1;
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),
command -> header.commandLength - sizeof (ENetProtocolSendReliable),
dataLength,
ENET_PACKET_FLAG_RELIABLE);
enet_peer_queue_incoming_command (peer, command, packet, 0);
return 0;
}
static void
enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
static int
enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
{
ENetPacket * packet;
enet_uint32 unsequencedGroup, index;
size_t dataLength;
if (command -> header.commandLength <= sizeof (ENetProtocolSendUnsequenced) ||
command -> header.channelID >= peer -> channelCount ||
peer -> state != ENET_PEER_STATE_CONNECTED)
return;
if (command -> header.channelID >= peer -> channelCount ||
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
return -1;
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;
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;
@ -347,37 +396,44 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E
else
if (unsequencedGroup < peer -> incomingUnsequencedGroup ||
peer -> unsequencedWindow [index / 32] & (1 << (index % 32)))
return;
return 0;
peer -> unsequencedWindow [index / 32] |= 1 << (index % 32);
packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced),
command -> header.commandLength - sizeof (ENetProtocolSendUnsequenced),
dataLength,
ENET_PACKET_FLAG_UNSEQUENCED);
enet_peer_queue_incoming_command (peer, command, packet, 0);
return 0;
}
static void
enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
static int
enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
{
ENetPacket * packet;
size_t dataLength;
if (command -> header.commandLength <= sizeof (ENetProtocolSendUnreliable) ||
command -> header.channelID >= peer -> channelCount ||
peer -> state != ENET_PEER_STATE_CONNECTED)
return;
if (command -> header.channelID >= peer -> channelCount ||
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
return -1;
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),
command -> header.commandLength - sizeof (ENetProtocolSendUnreliable),
dataLength,
0);
enet_peer_queue_incoming_command (peer, command, packet, 0);
return 0;
}
static void
enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
static int
enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
{
enet_uint32 fragmentNumber,
fragmentCount,
@ -389,36 +445,42 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
ENetListIterator currentCommand;
ENetIncomingCommand * startCommand;
if (command -> header.commandLength <= sizeof (ENetProtocolSendFragment) ||
command -> header.channelID >= peer -> channelCount ||
peer -> state != ENET_PEER_STATE_CONNECTED)
return;
if (command -> header.channelID >= peer -> channelCount ||
(peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
return -1;
fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
* currentData += fragmentLength;
if (* currentData > & host -> receivedData [host -> receivedDataLength])
return -1;
channel = & peer -> channels [command -> header.channelID];
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);
fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
fragmentLength = command -> header.commandLength - sizeof (ENetProtocolSendFragment);
if (fragmentOffset >= totalLength ||
fragmentOffset + fragmentLength > totalLength ||
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));
currentCommand != enet_list_end (& channel -> incomingReliableCommands);
currentCommand = enet_list_previous (currentCommand))
{
startCommand = (ENetIncomingCommand *) currentCommand;
if (startCommand -> command.header.command == ENET_PROTOCOL_COMMAND_SEND_FRAGMENT &&
startCommand -> command.sendFragment.startSequenceNumber == startSequenceNumber)
if ((startCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_FRAGMENT &&
startCommand -> command.sendFragment.startSequenceNumber == (startSequenceNumber & 0xFFFF))
break;
}
@ -428,6 +490,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
hostCommand.header.reliableSequenceNumber = startSequenceNumber;
hostCommand.sendFragment.startSequenceNumber = startSequenceNumber;
hostCommand.sendFragment.dataLength = fragmentLength;
hostCommand.sendFragment.fragmentNumber = fragmentNumber;
hostCommand.sendFragment.fragmentCount = fragmentCount;
hostCommand.sendFragment.fragmentOffset = fragmentOffset;
@ -441,7 +504,7 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
else
if (totalLength != startCommand -> packet -> dataLength ||
fragmentCount != startCommand -> fragmentCount)
return;
return -1;
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),
fragmentLength);
}
return 0;
}
static void
static int
enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
{
if (command -> header.commandLength < sizeof (ENetProtocolPing))
return;
return 0;
}
static void
static int
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 -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);
if (peer -> incomingBandwidth == 0 &&
host -> outgoingBandwidth == 0)
if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0)
peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
else
peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) /
@ -486,40 +546,42 @@ enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const EN
else
if (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)
{
if (command -> header.commandLength < sizeof (ENetProtocolThrottleConfigure))
return;
peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval);
peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration);
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)
{
if (command -> header.commandLength < sizeof (ENetProtocolDisconnect))
return;
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;
enet_peer_reset (peer);
}
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;
else
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
@ -530,10 +592,10 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
receivedReliableSequenceNumber;
ENetProtocolCommand commandNumber;
if (command -> header.commandLength < sizeof (ENetProtocolAcknowledge))
return 0;
receivedSentTime = ENET_NET_TO_HOST_32 (command -> acknowledge.receivedSentTime);
receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime);
receivedSentTime |= timeCurrent & 0xFFFF0000;
if ((receivedSentTime & 0x8000) > (timeCurrent & 0x8000))
receivedSentTime -= 0x10000;
if (ENET_TIME_LESS (timeCurrent, receivedSentTime))
return 0;
@ -574,7 +636,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
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);
@ -582,34 +644,37 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
{
case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT)
return 0;
return -1;
enet_protocol_notify_connect (host, peer, event);
return 1;
break;
case ENET_PEER_STATE_DISCONNECTING:
if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT)
return 0;
return -1;
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;
}
static void
static int
enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
{
enet_uint16 mtu;
enet_uint32 windowSize;
if (event == NULL ||
command -> header.commandLength < sizeof (ENetProtocolVerifyConnect) ||
peer -> state != ENET_PEER_STATE_CONNECTING)
return;
if (peer -> state != ENET_PEER_STATE_CONNECTING)
return -1;
if (ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount) != peer -> channelCount ||
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;
return;
return -1;
}
enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF);
peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID);
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);
enet_protocol_notify_connect (host, peer, event);
return 0;
}
static int
@ -658,135 +726,175 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
ENetProtocol * command;
ENetPeer * peer;
enet_uint8 * currentData;
size_t commandCount;
size_t headerSize;
enet_uint16 peerID, flags;
if (host -> receivedDataLength < sizeof (ENetProtocolHeader))
return 0;
header = (ENetProtocolHeader *) host -> receivedData;
header -> peerID = ENET_NET_TO_HOST_16 (header -> peerID);
header -> sentTime = ENET_NET_TO_HOST_32 (header -> sentTime);
peerID = ENET_NET_TO_HOST_16 (header -> peerID);
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;
else
if (header -> peerID >= host -> peerCount)
if (peerID >= host -> peerCount)
return 0;
else
{
peer = & host -> peers [header -> peerID];
peer = & host -> peers [peerID];
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
(host -> receivedAddress.host != peer -> address.host &&
peer -> address.host != ENET_HOST_BROADCAST) ||
header -> challenge != peer -> challenge)
peer -> address.host != ENET_HOST_BROADCAST))
return 0;
else
#ifdef USE_CRC32
{
peer -> address.host = host -> receivedAddress.host;
peer -> address.port = host -> receivedAddress.port;
enet_uint32 crc = header -> checksum;
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)
peer -> incomingDataTotal += host -> receivedDataLength;
commandCount = header -> commandCount;
currentData = host -> receivedData + sizeof (ENetProtocolHeader);
headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime);
currentData = host -> receivedData + headerSize;
while (commandCount > 0 &&
currentData < & host -> receivedData [host -> receivedDataLength])
while (currentData < & host -> receivedData [host -> receivedDataLength])
{
enet_uint8 commandNumber;
size_t commandSize;
command = (ENetProtocol *) currentData;
if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength])
break;
command -> header.commandLength = ENET_NET_TO_HOST_32 (command -> header.commandLength);
if (command -> header.commandLength <= 0 ||
command -> header.commandLength > & host -> receivedData [host -> receivedDataLength] - currentData)
commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK;
if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT)
break;
commandSize = commandSizes [commandNumber];
if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength])
break;
-- commandCount;
currentData += command -> header.commandLength;
currentData += commandSize;
if (peer == NULL && command -> header.command != ENET_PROTOCOL_COMMAND_CONNECT)
if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT)
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:
enet_protocol_handle_acknowledge (host, event, peer, command);
if (enet_protocol_handle_acknowledge (host, event, peer, command))
goto commandError;
break;
case ENET_PROTOCOL_COMMAND_CONNECT:
peer = enet_protocol_handle_connect (host, header, command);
if (peer == NULL)
goto commandError;
break;
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;
case ENET_PROTOCOL_COMMAND_DISCONNECT:
enet_protocol_handle_disconnect (host, peer, command);
if (enet_protocol_handle_disconnect (host, peer, command))
goto commandError;
break;
case ENET_PROTOCOL_COMMAND_PING:
enet_protocol_handle_ping (host, peer, command);
if (enet_protocol_handle_ping (host, peer, command))
goto commandError;
break;
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;
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;
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;
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;
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;
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;
default:
break;
goto commandError;
}
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)
{
case ENET_PEER_STATE_DISCONNECTING:
case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
break;
case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT:
if (command -> header.command != ENET_PROTOCOL_COMMAND_DISCONNECT)
break;
if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
enet_peer_queue_acknowledgement (peer, command, sentTime);
break;
default:
enet_peer_queue_acknowledgement (peer, command, header -> sentTime);
enet_peer_queue_acknowledgement (peer, command, sentTime);
break;
}
}
}
commandError:
if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
return 1;
@ -848,7 +956,11 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge))
break;
{
host -> continueSending = 1;
break;
}
acknowledgement = (ENetAcknowledgement *) currentAcknowledgement;
@ -861,12 +973,10 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE;
command -> header.channelID = acknowledgement -> command.header.channelID;
command -> header.flags = 0;
command -> header.commandLength = ENET_HOST_TO_NET_32 (sizeof (ENetProtocolAcknowledge));
command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_32 (acknowledgement -> command.header.reliableSequenceNumber);
command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_32 (acknowledgement -> sentTime);
command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber);
command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (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;
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))
{
size_t commandSize;
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength ||
peer -> mtu - host -> packetSize < commandSize ||
(outgoingCommand -> packet != NULL &&
peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength +
outgoingCommand -> packet -> dataLength))
break;
peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> packet -> dataLength))
{
host -> continueSending = 1;
break;
}
currentCommand = enet_list_next (currentCommand);
@ -924,7 +1040,7 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
}
buffer -> data = command;
buffer -> dataLength = outgoingCommand -> command.header.commandLength;
buffer -> dataLength = commandSize;
host -> packetSize += buffer -> dataLength;
@ -939,8 +1055,6 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
buffer -> data = outgoingCommand -> packet -> data;
buffer -> dataLength = outgoingCommand -> packet -> dataLength;
command -> header.commandLength += buffer -> dataLength;
host -> packetSize += buffer -> dataLength;
enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
@ -948,14 +1062,18 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee
else
enet_free (outgoingCommand);
command -> header.commandLength = ENET_HOST_TO_NET_32 (command -> header.commandLength);
++ command;
++ buffer;
}
host -> commandCount = command - host -> commands;
host -> bufferCount = buffer - host -> buffers;
if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER &&
enet_list_empty (& peer -> outgoingReliableCommands) &&
enet_list_empty (& peer -> outgoingUnreliableCommands) &&
enet_list_empty (& peer -> sentReliableCommands))
enet_peer_disconnect (peer, peer -> disconnectData);
}
static int
@ -1000,7 +1118,7 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even
enet_list_remove (& outgoingCommand -> outgoingCommandList));
if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
enet_list_empty (& peer -> sentReliableCommands) == 0)
! enet_list_empty (& peer -> sentReliableCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
@ -1023,22 +1141,33 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
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)] ||
buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength)
break;
peer -> mtu - host -> packetSize < commandSize)
{
host -> continueSending = 1;
break;
}
currentCommand = enet_list_next (currentCommand);
if (outgoingCommand -> packet != NULL)
{
if ((enet_uint16) (peer -> mtu - host -> packetSize) <
(enet_uint16) (outgoingCommand -> command.header.commandLength +
outgoingCommand -> fragmentLength) ||
peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize)
if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize)
break;
if ((enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))
{
host -> continueSending = 1;
break;
}
}
if (outgoingCommand -> roundTripTimeout == 0)
@ -1056,9 +1185,10 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
outgoingCommand -> sentTime = timeCurrent;
buffer -> data = command;
buffer -> dataLength = outgoingCommand -> command.header.commandLength;
buffer -> dataLength = commandSize;
host -> packetSize += buffer -> dataLength;
host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
* 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 -> dataLength = outgoingCommand -> fragmentLength;
command -> header.commandLength += outgoingCommand -> fragmentLength;
host -> packetSize += outgoingCommand -> fragmentLength;
peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
}
command -> header.commandLength = ENET_HOST_TO_NET_32 (command -> header.commandLength);
++ peer -> packetsSent;
++ command;
@ -1091,14 +1217,15 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
static int
enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts)
{
size_t packetsSent = 1;
ENetProtocolHeader header;
ENetPeer * currentPeer;
int sentLength;
while (packetsSent > 0)
for (currentPeer = host -> peers,
packetsSent = 0;
host -> continueSending = 1;
while (host -> continueSending)
for (host -> continueSending = 0,
currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
@ -1106,22 +1233,21 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
continue;
host -> headerFlags = 0;
host -> commandCount = 0;
host -> bufferCount = 1;
host -> packetSize = sizeof (ENetProtocolHeader);
if (enet_list_empty (& currentPeer -> acknowledgements) == 0)
if (! enet_list_empty (& currentPeer -> acknowledgements))
enet_protocol_send_acknowledgements (host, currentPeer);
if (host -> commandCount < sizeof (host -> commands) / sizeof (ENetProtocol))
{
if (checkForTimeouts != 0 &&
enet_list_empty (& currentPeer -> sentReliableCommands) == 0 &&
ENET_TIME_GREATER_EQUAL (timeCurrent, currentPeer -> nextTimeout) &&
enet_protocol_check_timeouts (host, currentPeer, event) == 1)
return 1;
}
if (enet_list_empty (& currentPeer -> outgoingReliableCommands) == 0)
if (checkForTimeouts != 0 &&
! enet_list_empty (& currentPeer -> sentReliableCommands) &&
ENET_TIME_GREATER_EQUAL (timeCurrent, currentPeer -> nextTimeout) &&
enet_protocol_check_timeouts (host, currentPeer, event) == 1)
return 1;
if (! enet_list_empty (& currentPeer -> outgoingReliableCommands))
enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
else
if (enet_list_empty (& currentPeer -> sentReliableCommands) &&
@ -1132,8 +1258,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
}
if (host -> commandCount < sizeof (host -> commands) / sizeof (ENetProtocol) &&
enet_list_empty (& currentPeer -> outgoingUnreliableCommands) == 0)
if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
if (host -> commandCount == 0)
@ -1174,19 +1299,25 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
currentPeer -> packetsLost = 0;
}
header.peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID);
header.flags = 0;
header.commandCount = host -> commandCount;
header.sentTime = ENET_HOST_TO_NET_32 (timeCurrent);
header.challenge = currentPeer -> challenge;
header.checksum = currentPeer -> sessionID;
header.peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags);
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;
++ packetsSent;
sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
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];
int errnum;
#ifdef linux
#if defined(linux) || defined(FREEBSD)
gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
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;
#ifdef linux
#if defined(linux) || defined(FREEBSD)
gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
#else
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);
int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE,
sendBufferSize = ENET_HOST_SEND_BUFFER_SIZE,
allowBroadcasting = 1;
#ifndef HAS_FCNTL
int nonBlocking = 1;
@ -171,6 +172,7 @@ enet_socket_create (ENetSocketType type, const ENetAddress * address)
#endif
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));
}

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);
u_long nonBlocking = 1;
int receiveBufferSize = ENET_HOST_RECEIVE_BUFFER_SIZE,
sendBufferSize = ENET_HOST_SEND_BUFFER_SIZE,
allowBroadcasting = 1;
struct sockaddr_in sin;
@ -113,6 +114,7 @@ enet_socket_create (ENetSocketType type, const ENetAddress * address)
ioctlsocket (newSocket, FIONBIO, & nonBlocking);
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));
}