Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Randomized peerids #149

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ set(INCLUDE_FILES
${INCLUDE_FILES_PREFIX}/callbacks.h
${INCLUDE_FILES_PREFIX}/enet.h
${INCLUDE_FILES_PREFIX}/list.h
${INCLUDE_FILES_PREFIX}/map.h
${INCLUDE_FILES_PREFIX}/protocol.h
${INCLUDE_FILES_PREFIX}/time.h
${INCLUDE_FILES_PREFIX}/types.h
Expand All @@ -75,6 +76,7 @@ set(SOURCE_FILES
compress.c
host.c
list.c
map.c
packet.c
peer.c
protocol.c
Expand Down
13 changes: 12 additions & 1 deletion host.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
enet_peer_reset (currentPeer);
}

enet_map_init (& host -> peerIDMapping, host -> peerCount);
return host;
}

Expand Down Expand Up @@ -158,6 +159,7 @@ enet_host_destroy (ENetHost * host)

enet_free (host -> peers);
enet_free (host);
enet_map_free (& host -> peerIDMapping);
}

/** Initiates a connection to a foreign host.
Expand All @@ -182,12 +184,14 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;

int peerIndex = 0;
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
break;
peerIndex++;
}

if (currentPeer >= & host -> peers [host -> peerCount])
Expand Down Expand Up @@ -230,9 +234,16 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC
memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
}

// Generate a random peer ID and save it to the host's mapping so we can look it up later.
enet_uint16 randomValue = (enet_uint16) enet_host_random_seed ();
randomValue &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK);
if(enet_map_insert (& host -> peerIDMapping, randomValue, peerIndex) == 0)
return NULL;

command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
currentPeer -> incomingPeerID = randomValue;
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (randomValue);
command.connect.incomingSessionID = currentPeer -> incomingSessionID;
command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
Expand Down
2 changes: 2 additions & 0 deletions include/enet/enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extern "C"
#include "enet/types.h"
#include "enet/protocol.h"
#include "enet/list.h"
#include "enet/map.h"
#include "enet/callbacks.h"

#define ENET_VERSION_MAJOR 1
Expand Down Expand Up @@ -371,6 +372,7 @@ typedef struct _ENetHost
enet_uint32 randomSeed;
int recalculateBandwidthLimits;
ENetPeer * peers; /**< array of peers allocated for this host */
ENetMap peerIDMapping; /**< keep track of what peer ID belongs to what peer */
size_t peerCount; /**< number of peers allocated for this host */
size_t channelLimit; /**< maximum number of channels allowed for connected peers */
enet_uint32 serviceTime;
Expand Down
30 changes: 30 additions & 0 deletions include/enet/map.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
@file map.h
@brief ENet integer keyed hashmap implementation
*/
#ifndef __ENET_MAP_H__
#define __ENET_MAP_H__

#include <stdlib.h>

typedef struct _ENetMapDataItem {
enet_uint16 value;
enet_uint16 key;
} ENetMapDataItem;

typedef struct _ENetMap
{
ENetMapDataItem * hashArray;
enet_uint16 size;
} ENetMap;

// Init and delete map structs
extern void enet_map_init(ENetMap *map, enet_uint16 size);
extern void enet_map_free(ENetMap *map);

// Get, Insert, and Delete items into a map
extern enet_uint16 enet_map_get(ENetMap *map, enet_uint16 key);
extern int enet_map_insert(ENetMap *map, enet_uint16 key, enet_uint16 value);
extern void enet_map_delete(ENetMap *map, enet_uint16 key);

#endif /* __ENET_MAP_H__ */
77 changes: 77 additions & 0 deletions map.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
@file map.c
@brief ENet integer keyed hashmap implementation
*/
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"

enet_uint16 hashCode(ENetMap *map, enet_uint16 key) {
return key % map -> size;
}

void
enet_map_init(ENetMap *map, enet_uint16 size) {
map -> size = size;
map -> hashArray = (ENetMapDataItem *) enet_malloc( size * (sizeof(ENetMapDataItem)));
for (enet_uint16 i = 0; i < size; i++) {
map -> hashArray[i].key = -1;
map -> hashArray[i].value = -1;
}
}

void
enet_map_free(ENetMap *map) {
enet_free(map -> hashArray);
}


enet_uint16
enet_map_get(ENetMap *map, enet_uint16 key) {
enet_uint16 hashIndex = hashCode(map, key);

// Worst case scenario O(n) lookup. But the vast majority of lookups will
// hit on the first key in practice.
for (enet_uint16 i = 0; i < map -> size; i++) {
if (map -> hashArray[hashIndex].key == key) {
return map -> hashArray[hashIndex].value;
}
++hashIndex;
hashIndex %= map -> size;
}
return -1;
}

int
enet_map_insert(ENetMap *map, enet_uint16 key, enet_uint16 value) {
int hashIndex = hashCode(map, key);

// Start at hashIndex, and loop in array until we find an empty cell
for (enet_uint16 i = 0; i < map -> size; i++) {
if (map -> hashArray[hashIndex].key == (enet_uint16)(-1)) {
map -> hashArray[hashIndex].key = key;
map -> hashArray[hashIndex].value = value;
return 1;
}

++hashIndex;
hashIndex %= map -> size;
}
return 0;
}

void
enet_map_delete(ENetMap *map, enet_uint16 key) {
enet_uint16 hashIndex = hashCode(map, key);

// Worst case scenario O(n) lookup. But the vast majority of lookups will
// hit on the first key in practice.
for (enet_uint16 i = 0; i < map -> size; i++) {
if (map -> hashArray[hashIndex].key != key) {
map -> hashArray[hashIndex].key = -1;
map -> hashArray[hashIndex].value = -1;
return;
}
++hashIndex;
hashIndex %= map -> size;
}
}
2 changes: 2 additions & 0 deletions peer.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ enet_peer_on_disconnect (ENetPeer * peer)
-- peer -> host -> bandwidthLimitedPeers;

-- peer -> host -> connectedPeers;
enet_map_delete (& peer -> host -> peerIDMapping, peer -> outgoingPeerID);
}
}

Expand Down Expand Up @@ -514,6 +515,7 @@ enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data)

enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);

enet_map_delete (& peer -> host -> peerIDMapping, peer -> outgoingPeerID);
enet_host_flush (peer -> host);
}

Expand Down
33 changes: 24 additions & 9 deletions protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
size_t channelCount, duplicatePeers = 0;
ENetPeer * currentPeer, * peer = NULL;
ENetProtocol verifyCommand;
int peerIndex, i = 0;

channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount);

Expand All @@ -305,7 +306,10 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
{
if (peer == NULL)
{
peer = currentPeer;
peerIndex = i;
}
}
else
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
Expand All @@ -317,6 +321,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet

++ duplicatePeers;
}
++ i;
}

if (peer == NULL || duplicatePeers >= host -> duplicatePeers)
Expand Down Expand Up @@ -412,9 +417,16 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;

// Generate a random peer ID and save it to the host's mapping so we can look it up later.
enet_uint16 randomValue = (enet_uint16) enet_host_random_seed ();
randomValue &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK);
if(enet_map_insert (& host -> peerIDMapping, randomValue, peerIndex) == 0)
return NULL;

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 (peer -> incomingPeerID);
peer -> incomingPeerID = randomValue;
verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (randomValue);
verifyCommand.verifyConnect.incomingSessionID = incomingSessionID;
verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID;
verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32 (peer -> mtu);
Expand Down Expand Up @@ -1020,14 +1032,15 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
if (host -> checksum != NULL)
headerSize += sizeof (enet_uint32);

if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID)
peer = NULL;
else
if (peerID >= host -> peerCount)
return 0;
// Do a lookup of the peer ID. If we have that peer, then use it
enet_uint16 peerIndex = enet_map_get (& host -> peerIDMapping, peerID);
if (peerIndex == (enet_uint16)(-1))
{
peer = NULL;
}
else
{
peer = & host -> peers [peerID];
peer = & host -> peers [peerIndex];

if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
Expand Down Expand Up @@ -1572,7 +1585,8 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
ENetPeer * currentPeer;
int sentLength;
size_t shouldCompress = 0;

int peerIndex = 0;

host -> continueSending = 1;

while (host -> continueSending)
Expand Down Expand Up @@ -1668,7 +1682,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch

if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID)
host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT;
header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags);
header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID | host -> headerFlags);
if (host -> checksum != NULL)
{
enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength];
Expand All @@ -1695,6 +1709,7 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch

host -> totalSentData += sentLength;
host -> totalSentPackets ++;
++ peerIndex;
}

return 0;
Expand Down