diff options
Diffstat (limited to 'libs/enet/protocol.c')
-rw-r--r-- | libs/enet/protocol.c | 374 |
1 files changed, 229 insertions, 145 deletions
diff --git a/libs/enet/protocol.c b/libs/enet/protocol.c index da64e915..29d64873 100644 --- a/libs/enet/protocol.c +++ b/libs/enet/protocol.c @@ -32,6 +32,30 @@ enet_protocol_command_size (enet_uint8 commandNumber) return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK]; } +static void +enet_protocol_change_state (ENetHost * host, ENetPeer * peer, ENetPeerState state) +{ + if (state == ENET_PEER_STATE_CONNECTED || state == ENET_PEER_STATE_DISCONNECT_LATER) + enet_peer_on_connect (peer); + else + enet_peer_on_disconnect (peer); + + peer -> state = state; +} + +static void +enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state) +{ + enet_protocol_change_state (host, peer, state); + + if (! peer -> needsDispatch) + { + enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); + + peer -> needsDispatch = 1; + } +} + static int enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) { @@ -45,7 +69,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) { case ENET_PEER_STATE_CONNECTION_PENDING: case ENET_PEER_STATE_CONNECTION_SUCCEEDED: - peer -> state = ENET_PEER_STATE_CONNECTED; + enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED); event -> type = ENET_EVENT_TYPE_CONNECT; event -> peer = peer; @@ -83,6 +107,9 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) } return 1; + + default: + break; } } @@ -90,26 +117,13 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) } static void -enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state) -{ - peer -> state = state; - - if (! peer -> needsDispatch) - { - enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); - - peer -> needsDispatch = 1; - } -} - -static void enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event) { host -> recalculateBandwidthLimits = 1; if (event != NULL) { - peer -> state = ENET_PEER_STATE_CONNECTED; + enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED); event -> type = ENET_EVENT_TYPE_CONNECT; event -> peer = peer; @@ -160,7 +174,11 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) -- outgoingCommand -> packet -> referenceCount; if (outgoingCommand -> packet -> referenceCount == 0) - enet_packet_destroy (outgoingCommand -> packet); + { + outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT; + + enet_packet_destroy (outgoingCommand -> packet); + } } enet_free (outgoingCommand); @@ -170,7 +188,7 @@ enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) static ENetProtocolCommand enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) { - ENetOutgoingCommand * outgoingCommand; + ENetOutgoingCommand * outgoingCommand = NULL; ENetListIterator currentCommand; ENetProtocolCommand commandNumber; int wasSent = 1; @@ -207,6 +225,9 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl wasSent = 0; } + if (outgoingCommand == NULL) + return ENET_PROTOCOL_COMMAND_NONE; + if (channelID < peer -> channelCount) { ENetChannel * channel = & peer -> channels [channelID]; @@ -231,7 +252,11 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl -- outgoingCommand -> packet -> referenceCount; if (outgoingCommand -> packet -> referenceCount == 0) - enet_packet_destroy (outgoingCommand -> packet); + { + outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT; + + enet_packet_destroy (outgoingCommand -> packet); + } } enet_free (outgoingCommand); @@ -252,8 +277,8 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet enet_uint8 incomingSessionID, outgoingSessionID; enet_uint32 mtu, windowSize; ENetChannel * channel; - size_t channelCount; - ENetPeer * currentPeer; + size_t channelCount, duplicatePeers = 0; + ENetPeer * currentPeer, * peer = NULL; ENetProtocol verifyCommand; channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); @@ -266,55 +291,57 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet currentPeer < & host -> peers [host -> peerCount]; ++ currentPeer) { - if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED && - currentPeer -> address.host == host -> receivedAddress.host && - currentPeer -> address.port == host -> receivedAddress.port && - currentPeer -> connectID == command -> connect.connectID) - return NULL; - } - - for (currentPeer = host -> peers; - currentPeer < & host -> peers [host -> peerCount]; - ++ currentPeer) - { if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) - break; + { + if (peer == NULL) + peer = currentPeer; + } + else + if (currentPeer -> state != ENET_PEER_STATE_CONNECTING && + currentPeer -> address.host == host -> receivedAddress.host) + { + if (currentPeer -> address.port == host -> receivedAddress.port && + currentPeer -> connectID == command -> connect.connectID) + return NULL; + + ++ duplicatePeers; + } } - if (currentPeer >= & host -> peers [host -> peerCount]) + if (peer == NULL || duplicatePeers >= host -> duplicatePeers) return NULL; if (channelCount > host -> channelLimit) channelCount = host -> channelLimit; - currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); - if (currentPeer -> channels == NULL) + peer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); + if (peer -> channels == NULL) return NULL; - currentPeer -> channelCount = channelCount; - currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; - currentPeer -> connectID = command -> connect.connectID; - currentPeer -> address = host -> receivedAddress; - currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); - currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); - currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); - currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval); - currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration); - currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration); - currentPeer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data); - - incomingSessionID = command -> connect.incomingSessionID == 0xFF ? currentPeer -> outgoingSessionID : command -> connect.incomingSessionID; + peer -> channelCount = channelCount; + peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; + peer -> connectID = command -> connect.connectID; + peer -> address = host -> receivedAddress; + peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); + peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); + peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); + peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval); + peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration); + peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration); + peer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data); + + incomingSessionID = command -> connect.incomingSessionID == 0xFF ? peer -> outgoingSessionID : command -> connect.incomingSessionID; incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); - if (incomingSessionID == currentPeer -> outgoingSessionID) + if (incomingSessionID == peer -> outgoingSessionID) incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); - currentPeer -> outgoingSessionID = incomingSessionID; + peer -> outgoingSessionID = incomingSessionID; - outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? currentPeer -> incomingSessionID : command -> connect.outgoingSessionID; + outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? peer -> incomingSessionID : command -> connect.outgoingSessionID; outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); - if (outgoingSessionID == currentPeer -> incomingSessionID) + if (outgoingSessionID == peer -> incomingSessionID) outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); - currentPeer -> incomingSessionID = outgoingSessionID; + peer -> incomingSessionID = outgoingSessionID; - for (channel = currentPeer -> channels; - channel < & currentPeer -> channels [channelCount]; + for (channel = peer -> channels; + channel < & peer -> channels [channelCount]; ++ channel) { channel -> outgoingReliableSequenceNumber = 0; @@ -337,27 +364,27 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) mtu = ENET_PROTOCOL_MAXIMUM_MTU; - currentPeer -> mtu = mtu; + peer -> mtu = mtu; if (host -> outgoingBandwidth == 0 && - currentPeer -> incomingBandwidth == 0) - currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + peer -> incomingBandwidth == 0) + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; else if (host -> outgoingBandwidth == 0 || - currentPeer -> incomingBandwidth == 0) - currentPeer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / + peer -> incomingBandwidth == 0) + peer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, peer -> incomingBandwidth) / ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; else - currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / + peer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, peer -> incomingBandwidth) / ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) - currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; else - if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) - currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; if (host -> incomingBandwidth == 0) windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; @@ -376,28 +403,27 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; verifyCommand.header.channelID = 0xFF; - verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); + verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (peer -> incomingPeerID); verifyCommand.verifyConnect.incomingSessionID = incomingSessionID; verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID; - verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu); + verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32 (peer -> mtu); verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize); verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount); verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); - verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); - verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); - verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); - verifyCommand.verifyConnect.connectID = currentPeer -> connectID; + verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (peer -> packetThrottleInterval); + verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleAcceleration); + verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleDeceleration); + verifyCommand.verifyConnect.connectID = peer -> connectID; - enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0); + enet_peer_queue_outgoing_command (peer, & verifyCommand, NULL, 0, 0); - return currentPeer; + return peer; } 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.channelID >= peer -> channelCount || @@ -406,14 +432,12 @@ 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 > host -> maximumPacketSize || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; - packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), - dataLength, - ENET_PACKET_FLAG_RELIABLE); - if (packet == NULL || - enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) + if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), dataLength, ENET_PACKET_FLAG_RELIABLE, 0) == NULL) return -1; return 0; @@ -422,7 +446,6 @@ enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENet 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; @@ -432,7 +455,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 > host -> maximumPacketSize || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup); @@ -456,11 +481,7 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32))) return 0; - packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), - dataLength, - ENET_PACKET_FLAG_UNSEQUENCED); - if (packet == NULL || - enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) + if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), dataLength, ENET_PACKET_FLAG_UNSEQUENCED, 0) == NULL) return -1; peer -> unsequencedWindow [index / 32] |= 1 << (index % 32); @@ -471,7 +492,6 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E 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.channelID >= peer -> channelCount || @@ -480,14 +500,12 @@ 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 > host -> maximumPacketSize || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; - packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), - dataLength, - 0); - if (packet == NULL || - enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) + if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), dataLength, 0, 0) == NULL) return -1; return 0; @@ -513,7 +531,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 > host -> maximumPacketSize || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; channel = & peer -> channels [command -> header.channelID]; @@ -532,9 +552,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 > host -> maximumPacketSize || + fragmentOffset >= totalLength || + fragmentLength > totalLength - fragmentOffset) return -1; for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); @@ -570,13 +592,10 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet if (startCommand == NULL) { ENetProtocol hostCommand = * command; - ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE); - if (packet == NULL) - return -1; hostCommand.header.reliableSequenceNumber = startSequenceNumber; - startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount); + startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, NULL, totalLength, ENET_PACKET_FLAG_RELIABLE, fragmentCount); if (startCommand == NULL) return -1; } @@ -622,7 +641,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 > host -> maximumPacketSize || + * currentData < host -> receivedData || + * currentData > & host -> receivedData [host -> receivedDataLength]) return -1; channel = & peer -> channels [command -> header.channelID]; @@ -647,9 +668,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 > host -> maximumPacketSize || + fragmentOffset >= totalLength || + fragmentLength > totalLength - fragmentOffset) return -1; for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); @@ -690,11 +713,7 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, if (startCommand == NULL) { - ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); - if (packet == NULL) - return -1; - - startCommand = enet_peer_queue_incoming_command (peer, command, packet, fragmentCount); + startCommand = enet_peer_queue_incoming_command (peer, command, NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT, fragmentCount); if (startCommand == NULL) return -1; } @@ -722,18 +741,34 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, static int enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) { + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + return -1; + return 0; } static int enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) { + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + return -1; + + if (peer -> incomingBandwidth != 0) + -- host -> bandwidthLimitedPeers; + 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 -> bandwidthLimitedPeers; + if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0) peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; else + if (peer -> incomingBandwidth == 0 || host -> outgoingBandwidth == 0) + peer -> windowSize = (ENET_MAX (peer -> incomingBandwidth, host -> outgoingBandwidth) / + ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) / ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; @@ -749,6 +784,9 @@ enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const EN static int enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) { + if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) + return -1; + 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); @@ -759,12 +797,12 @@ enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const static int enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) { - if (peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT) + if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT) return 0; enet_peer_reset_queues (peer); - if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING) + if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING || peer -> state == ENET_PEER_STATE_CONNECTING) enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); else if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) @@ -775,7 +813,7 @@ enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetPro } else if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) - peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT; + enet_protocol_change_state (host, peer, ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT); else enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); @@ -793,6 +831,9 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * receivedReliableSequenceNumber; ENetProtocolCommand commandNumber; + if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE) + return 0; + receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime); receivedSentTime |= host -> serviceTime & 0xFFFF0000; if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000)) @@ -863,6 +904,9 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * enet_list_empty (& peer -> sentReliableCommands)) enet_peer_disconnect (peer, peer -> eventData); break; + + default: + break; } return 0; @@ -1042,7 +1086,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber); - switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) + switch (commandNumber) { case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: if (enet_protocol_handle_acknowledge (host, event, peer, command)) @@ -1050,6 +1094,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) break; case ENET_PROTOCOL_COMMAND_CONNECT: + if (peer != NULL) + goto commandError; peer = enet_protocol_handle_connect (host, header, command); if (peer == NULL) goto commandError; @@ -1123,6 +1169,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) { case ENET_PEER_STATE_DISCONNECTING: case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: + case ENET_PEER_STATE_DISCONNECTED: + case ENET_PEER_STATE_ZOMBIE: break; case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: @@ -1147,7 +1195,9 @@ commandError: static int enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) { - for (;;) + int packets; + + for (packets = 0; packets < 256; ++ packets) { int receivedLength; ENetBuffer buffer; @@ -1171,7 +1221,25 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) host -> totalReceivedData += receivedLength; host -> totalReceivedPackets ++; - + + if (host -> intercept != NULL) + { + switch (host -> intercept (host, event)) + { + case 1: + if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) + return 1; + + continue; + + case -1: + return -1; + + default: + break; + } + } + switch (enet_protocol_handle_incoming_commands (host, event)) { case 1: @@ -1195,7 +1263,8 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; ENetAcknowledgement * acknowledgement; ENetListIterator currentAcknowledgement; - + enet_uint16 reliableSequenceNumber; + currentAcknowledgement = enet_list_begin (& peer -> acknowledgements); while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements)) @@ -1217,10 +1286,13 @@ enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) buffer -> dataLength = sizeof (ENetProtocolAcknowledge); host -> packetSize += buffer -> dataLength; - + + reliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber); + command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; command -> header.channelID = acknowledgement -> command.header.channelID; - command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber); + command -> header.reliableSequenceNumber = reliableSequenceNumber; + command -> acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber; command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime); if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) @@ -1361,9 +1433,9 @@ enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * even peer -> earliestTimeout = outgoingCommand -> sentTime; if (peer -> earliestTimeout != 0 && - (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MAXIMUM || + (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum || (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit && - ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MINIMUM))) + ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum))) { enet_protocol_notify_disconnect (host, peer, event); @@ -1418,7 +1490,7 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | - (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow))))) + (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow))))) windowWrap = 1; if (windowWrap) { @@ -1472,7 +1544,7 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) if (outgoingCommand -> roundTripTimeout == 0) { outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; - outgoingCommand -> roundTripTimeoutLimit = ENET_PEER_TIMEOUT_LIMIT * outgoingCommand -> roundTripTimeout; + outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout; } if (enet_list_empty (& peer -> sentReliableCommands)) @@ -1548,12 +1620,17 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch ! enet_list_empty (& currentPeer -> sentReliableCommands) && ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) && enet_protocol_check_timeouts (host, currentPeer, event) == 1) - return 1; + { + if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) + return 1; + else + continue; + } if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) || enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) && enet_list_empty (& currentPeer -> sentReliableCommands) && - ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= ENET_PEER_PING_INTERVAL && + ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval && currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) { enet_peer_ping (currentPeer); @@ -1575,12 +1652,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; #ifdef ENET_DEBUG -#ifdef WIN32 - printf ( -#else - fprintf (stderr, -#endif - "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); + printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); #endif currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4; @@ -1625,12 +1697,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED; shouldCompress = compressedSize; #ifdef ENET_DEBUG_COMPRESS -#ifdef WIN32 - printf ( -#else - fprintf (stderr, -#endif - "peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize); + printf ("peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize); #endif } } @@ -1734,7 +1801,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) return 1; case -1: +#ifdef ENET_DEBUG perror ("Error dispatching incoming packets"); +#endif return -1; @@ -1758,7 +1827,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) return 1; case -1: +#ifdef ENET_DEBUG perror ("Error sending outgoing packets"); +#endif return -1; @@ -1772,7 +1843,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) return 1; case -1: +#ifdef ENET_DEBUG perror ("Error receiving incoming packets"); +#endif return -1; @@ -1786,7 +1859,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) return 1; case -1: +#ifdef ENET_DEBUG perror ("Error sending outgoing packets"); +#endif return -1; @@ -1802,7 +1877,9 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) return 1; case -1: +#ifdef ENET_DEBUG perror ("Error dispatching incoming packets"); +#endif return -1; @@ -1811,18 +1888,25 @@ enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) } } - host -> serviceTime = enet_time_get (); - if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout)) return 0; - waitCondition = ENET_SOCKET_WAIT_RECEIVE; + do + { + host -> serviceTime = enet_time_get (); + + if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout)) + return 0; + + waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT; + + if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0) + return -1; + } + while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT); - if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0) - return -1; - host -> serviceTime = enet_time_get (); - } while (waitCondition == ENET_SOCKET_WAIT_RECEIVE); + } while (waitCondition & ENET_SOCKET_WAIT_RECEIVE); return 0; } |