small fix for duplicate peers

This commit is contained in:
Lee Salzman 2013-08-18 17:20:17 +03:00
parent dc48f76192
commit 4d7b80152b
4 changed files with 59 additions and 55 deletions

View file

@ -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_socket_get_option() and ENET_SOCKOPT_ERROR
* added enet_host_random_seed() platform stub * added enet_host_random_seed() platform stub

1
host.c
View file

@ -99,6 +99,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
host -> connectedPeers = 0; host -> connectedPeers = 0;
host -> bandwidthLimitedPeers = 0; host -> bandwidthLimitedPeers = 0;
host -> duplicatePeers = ENET_PROTOCOL_MAXIMUM_PEER_ID;
host -> compressor.context = NULL; host -> compressor.context = NULL;
host -> compressor.compress = NULL; host -> compressor.compress = NULL;

View file

@ -386,6 +386,7 @@ typedef struct _ENetHost
ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */ ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */
size_t connectedPeers; size_t connectedPeers;
size_t bandwidthLimitedPeers; size_t bandwidthLimitedPeers;
size_t duplicatePeers; /**< optional number of allowed peers from duplicate IPs, defaults to ENET_PROTOCOL_MAXIMUM_PEER_ID */
} ENetHost; } ENetHost;
/** /**

View file

@ -277,8 +277,8 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
enet_uint8 incomingSessionID, outgoingSessionID; enet_uint8 incomingSessionID, outgoingSessionID;
enet_uint32 mtu, windowSize; enet_uint32 mtu, windowSize;
ENetChannel * channel; ENetChannel * channel;
size_t channelCount; size_t channelCount, duplicatePeers = 0;
ENetPeer * currentPeer; ENetPeer * currentPeer, * peer = NULL;
ENetProtocol verifyCommand; ENetProtocol verifyCommand;
channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); 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) channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
return NULL; 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; for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount]; currentPeer < & host -> peers [host -> peerCount];
++ currentPeer) ++ currentPeer)
{ {
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) 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; return NULL;
if (channelCount > host -> channelLimit) if (channelCount > host -> channelLimit)
channelCount = host -> channelLimit; channelCount = host -> channelLimit;
currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); peer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
if (currentPeer -> channels == NULL) if (peer -> channels == NULL)
return NULL; return NULL;
currentPeer -> channelCount = channelCount; peer -> channelCount = channelCount;
currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
currentPeer -> connectID = command -> connect.connectID; peer -> connectID = command -> connect.connectID;
currentPeer -> address = host -> receivedAddress; peer -> address = host -> receivedAddress;
currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval); peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval);
currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration); peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration);
currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration); peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration);
currentPeer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data); 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); 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); 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); 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); outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
currentPeer -> incomingSessionID = outgoingSessionID; peer -> incomingSessionID = outgoingSessionID;
for (channel = currentPeer -> channels; for (channel = peer -> channels;
channel < & currentPeer -> channels [channelCount]; channel < & peer -> channels [channelCount];
++ channel) ++ channel)
{ {
channel -> outgoingReliableSequenceNumber = 0; channel -> outgoingReliableSequenceNumber = 0;
@ -362,27 +363,27 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
mtu = ENET_PROTOCOL_MAXIMUM_MTU; mtu = ENET_PROTOCOL_MAXIMUM_MTU;
currentPeer -> mtu = mtu; peer -> mtu = mtu;
if (host -> outgoingBandwidth == 0 && if (host -> outgoingBandwidth == 0 &&
currentPeer -> incomingBandwidth == 0) peer -> incomingBandwidth == 0)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
else else
if (host -> outgoingBandwidth == 0 || if (host -> outgoingBandwidth == 0 ||
currentPeer -> incomingBandwidth == 0) peer -> incomingBandwidth == 0)
currentPeer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / peer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, peer -> incomingBandwidth) /
ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PEER_WINDOW_SIZE_SCALE) *
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
else else
currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / peer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, peer -> incomingBandwidth) /
ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PEER_WINDOW_SIZE_SCALE) *
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
else else
if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
if (host -> incomingBandwidth == 0) if (host -> incomingBandwidth == 0)
windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 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.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
verifyCommand.header.channelID = 0xFF; 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.incomingSessionID = incomingSessionID;
verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID; 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.windowSize = ENET_HOST_TO_NET_32 (windowSize);
verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount); verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (peer -> packetThrottleInterval);
verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleAcceleration);
verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleDeceleration);
verifyCommand.verifyConnect.connectID = currentPeer -> connectID; 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 static int