diff --git a/source/enet/include/enet/enet.h b/source/enet/include/enet/enet.h index d73655f8..14f93820 100755 --- a/source/enet/include/enet/enet.h +++ b/source/enet/include/enet/enet.h @@ -50,7 +50,9 @@ typedef enum _ENetSocketOption ENET_SOCKOPT_BROADCAST = 2, ENET_SOCKOPT_RCVBUF = 3, ENET_SOCKOPT_SNDBUF = 4, - ENET_SOCKOPT_REUSEADDR = 5 + ENET_SOCKOPT_REUSEADDR = 5, + ENET_SOCKOPT_RCVTIMEO = 6, + ENET_SOCKOPT_SNDTIMEO = 7 } ENetSocketOption; enum diff --git a/source/enet/include/enet/protocol.h b/source/enet/include/enet/protocol.h index faef9179..f8a27d8e 100755 --- a/source/enet/include/enet/protocol.h +++ b/source/enet/include/enet/protocol.h @@ -16,7 +16,9 @@ enum ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768, ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255, - ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF + ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF, + ENET_PROTOCOL_MAXIMUM_PACKET_SIZE = 1024 * 1024 * 1024, + ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024 }; typedef enum _ENetProtocolCommand diff --git a/source/enet/packet.c b/source/enet/packet.c index 2fc9a10e..fd59b14c 100755 --- a/source/enet/packet.c +++ b/source/enet/packet.c @@ -26,6 +26,9 @@ enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags) if (flags & ENET_PACKET_FLAG_NO_ALLOCATE) packet -> data = (enet_uint8 *) data; else + if (dataLength <= 0) + packet -> data = NULL; + else { packet -> data = (enet_uint8 *) enet_malloc (dataLength); if (packet -> data == NULL) @@ -54,7 +57,8 @@ enet_packet_destroy (ENetPacket * packet) { if (packet -> freeCallback != NULL) (* packet -> freeCallback) (packet); - if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE)) + if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) && + packet -> data != NULL) enet_free (packet -> data); enet_free (packet); } diff --git a/source/enet/peer.c b/source/enet/peer.c index 44b0bc5a..38839b14 100755 --- a/source/enet/peer.c +++ b/source/enet/peer.c @@ -104,7 +104,8 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) size_t fragmentLength; if (peer -> state != ENET_PEER_STATE_CONNECTED || - channelID >= peer -> channelCount) + channelID >= peer -> channelCount || + packet -> dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE) return -1; fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment); @@ -113,7 +114,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) if (packet -> dataLength > fragmentLength) { - enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength), + enet_uint32 fragmentCount = (packet -> dataLength + fragmentLength - 1) / fragmentLength, fragmentNumber, fragmentOffset; enet_uint8 commandNumber; @@ -121,6 +122,9 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) ENetList fragments; ENetOutgoingCommand * fragment; + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) + return -1; + if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT && channel -> outgoingUnreliableSequenceNumber < 0xFFFF) { @@ -164,7 +168,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) fragment -> command.header.channelID = channelID; fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber; fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength); - fragment -> command.sendFragment.fragmentCount = fragmentCount; + fragment -> command.sendFragment.fragmentCount = ENET_HOST_TO_NET_32 (fragmentCount); fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber); fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength); fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset); @@ -832,7 +836,8 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, if (fragmentCount > 0) { - incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32)); + if (fragmentCount <= ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) + incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32)); if (incomingCommand -> fragments == NULL) { enet_free (incomingCommand); diff --git a/source/enet/protocol.c b/source/enet/protocol.c index 2e111a89..6d4618c7 100755 --- a/source/enet/protocol.c +++ b/source/enet/protocol.c @@ -406,7 +406,9 @@ enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENet dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength); * currentData += dataLength; - if (* currentData > & host -> receivedData [host -> receivedDataLength]) + if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), @@ -432,7 +434,9 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength); * currentData += dataLength; - if (* currentData > & host -> receivedData [host -> receivedDataLength]) + if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup); @@ -480,7 +484,9 @@ enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const EN dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength); * currentData += dataLength; - if (* currentData > & host -> receivedData [host -> receivedDataLength]) + if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), @@ -513,7 +519,9 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); * currentData += fragmentLength; - if (* currentData > & host -> receivedData [host -> receivedDataLength]) + if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; channel = & peer -> channels [command -> header.channelID]; @@ -532,9 +540,11 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); - if (fragmentOffset >= totalLength || - fragmentOffset + fragmentLength > totalLength || - fragmentNumber >= fragmentCount) + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || + fragmentNumber >= fragmentCount || + totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + fragmentOffset >= totalLength || + fragmentLength > totalLength - fragmentOffset) return -1; for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); @@ -622,7 +632,9 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); * currentData += fragmentLength; - if (* currentData > & host -> receivedData [host -> receivedDataLength]) + if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; channel = & peer -> channels [command -> header.channelID]; @@ -647,9 +659,11 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); - if (fragmentOffset >= totalLength || - fragmentOffset + fragmentLength > totalLength || - fragmentNumber >= fragmentCount) + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || + fragmentNumber >= fragmentCount || + totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + fragmentOffset >= totalLength || + fragmentLength > totalLength - fragmentOffset) return -1; for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); diff --git a/source/enet/unix.c b/source/enet/unix.c index 69715413..a225b57d 100755 --- a/source/enet/unix.c +++ b/source/enet/unix.c @@ -219,6 +219,14 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int)); break; + case ENET_SOCKOPT_RCVTIMEO: + result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_SNDTIMEO: + result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int)); + break; + default: break; } diff --git a/source/enet/win32.c b/source/enet/win32.c index 7b23cddc..0a213e7a 100755 --- a/source/enet/win32.c +++ b/source/enet/win32.c @@ -166,6 +166,14 @@ enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int)); break; + case ENET_SOCKOPT_RCVTIMEO: + result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int)); + break; + + case ENET_SOCKOPT_SNDTIMEO: + result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int)); + break; + default: break; } diff --git a/source/lib/enet.lib b/source/lib/enet.lib index 22d8c5b9..fd25efc8 100644 Binary files a/source/lib/enet.lib and b/source/lib/enet.lib differ