diff --git a/ChangeLog b/ChangeLog index 6c71a58..b70a407 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ -ENet 1.3.9 (August 16, 2013): +ENet 1.3.9 (August 18, 2013): +* added duplicatePeers option to ENetHost which can limit the number of peers from duplicate IPs * added enet_socket_get_option() and ENET_SOCKOPT_ERROR * added enet_host_random_seed() platform stub diff --git a/host.c b/host.c index 8fdb160..fc57f74 100644 --- a/host.c +++ b/host.c @@ -99,6 +99,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL host -> connectedPeers = 0; host -> bandwidthLimitedPeers = 0; + host -> duplicatePeers = ENET_PROTOCOL_MAXIMUM_PEER_ID; host -> compressor.context = NULL; host -> compressor.compress = NULL; diff --git a/include/enet/enet.h b/include/enet/enet.h index 82ec73f..8d1c2c0 100644 --- a/include/enet/enet.h +++ b/include/enet/enet.h @@ -386,6 +386,7 @@ typedef struct _ENetHost ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */ size_t connectedPeers; size_t bandwidthLimitedPeers; + size_t duplicatePeers; /**< optional number of allowed peers from duplicate IPs, defaults to ENET_PROTOCOL_MAXIMUM_PEER_ID */ } ENetHost; /** diff --git a/protocol.c b/protocol.c index 1242cf6..3438a5d 100644 --- a/protocol.c +++ b/protocol.c @@ -277,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); @@ -287,59 +287,60 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) return NULL; - for (currentPeer = host -> peers; - 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 -> 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); + 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 ? currentPeer -> outgoingSessionID : command -> connect.incomingSessionID; + 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; @@ -362,27 +363,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; @@ -401,22 +402,22 @@ 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_32 (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