diff options
Diffstat (limited to 'peer.c')
-rw-r--r-- | peer.c | 185 |
1 files changed, 100 insertions, 85 deletions
@@ -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); - - 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); + incomingCommand = (ENetIncomingCommand *) enet_list_front (& channel -> incomingReliableCommands); - 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; |