Skip to content

Commit

Permalink
implement connect cookies for enet (protect against spoofed connect f…
Browse files Browse the repository at this point in the history
…lood), use enet_host_connect_cookies to activate
  • Loading branch information
pisto committed Sep 19, 2014
1 parent 5724545 commit c8e9316
Show file tree
Hide file tree
Showing 5 changed files with 405 additions and 48 deletions.
50 changes: 49 additions & 1 deletion enet/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ enet_host_destroy (ENetHost * host)
if (host -> compressor.context != NULL && host -> compressor.destroy)
(* host -> compressor.destroy) (host -> compressor.context);

enet_free (host -> connectsData);
enet_free (host -> idlePeersList);
enet_free (host -> peers);
enet_free (host);
}
Expand Down Expand Up @@ -489,5 +491,51 @@ enet_host_bandwidth_throttle (ENetHost * host)
}
}
}


int
enet_host_connect_cookies(ENetHost * host, const ENetRandom * randomFunction, enet_uint32 connectingPeerTimeout)
{
size_t iPeer;
if (host -> randomFunction.context && host -> randomFunction.destroy)
host -> randomFunction.destroy (host -> randomFunction.context);
memset (& host -> randomFunction, 0, sizeof (ENetRandom));
host -> connectingPeerTimeout = 0;
enet_free (host -> idlePeersList);
host -> idlePeersList = NULL;
host -> idlePeers = 0;
enet_free (host -> connectsData);
host -> connectsData = NULL;
host -> connectsInWindow = 0;
host -> connectsDataIndex = 0;
host -> connectsDataIndexTimestamp = 0;
host -> connectsWindow = 0;
for (iPeer = 0; iPeer < host -> peerCount; ++ iPeer)
{
enet_free (host -> peers [iPeer].connectingPeers);
host -> peers [iPeer].connectingPeers = NULL;
}

if (! randomFunction)
return 0;
host -> randomFunction = * randomFunction;
host -> connectingPeerTimeout = connectingPeerTimeout ? ((connectingPeerTimeout - 1) / ENET_HOST_CONNECTS_TIME_DELTA + 1) * ENET_HOST_CONNECTS_TIME_DELTA : ENET_HOST_DEFAULT_CONNECTING_PEER_TIMEOUT;
host -> idlePeersList = enet_malloc (sizeof (enet_uint16) * host -> peerCount);
host -> connectsData = enet_malloc (sizeof (enet_uint32) * (host -> connectingPeerTimeout / ENET_HOST_CONNECTS_TIME_DELTA + 1));
if (! host -> idlePeersList || ! host -> connectsData)
{
host -> connectingPeerTimeout = 0;
memset (& host -> randomFunction, 0, sizeof (ENetRandom));
enet_free (host -> idlePeersList);
host -> idlePeersList = NULL;
enet_free (host -> connectsData);
host -> connectsData = NULL;
return -1;
}
for (iPeer = 0; iPeer < host -> peerCount; ++ iPeer)
if (host -> peers [iPeer].state == ENET_PEER_STATE_DISCONNECTED)
host -> idlePeersList [host -> idlePeers ++] = host -> peers [iPeer].incomingPeerID;
memset (host -> connectsData, 0, sizeof (enet_uint32) * (host -> connectingPeerTimeout / ENET_HOST_CONNECTS_TIME_DELTA + 1));
return 0;
}

/** @} */
45 changes: 44 additions & 1 deletion enet/include/enet/enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ enum
ENET_HOST_DEFAULT_MTU = 1400,
ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE = 32 * 1024 * 1024,
ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA = 32 * 1024 * 1024,
ENET_HOST_DEFAULT_CONNECTING_PEER_TIMEOUT = 2000,
ENET_HOST_CONNECTS_TIME_DELTA = 100,
ENET_HOST_CONNECTS_CLEANUP_SIZE = 1024 * 1024,

ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500,
ENET_PEER_DEFAULT_PACKET_THROTTLE = 32,
Expand All @@ -232,7 +235,8 @@ enum
ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32,
ENET_PEER_RELIABLE_WINDOWS = 16,
ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000,
ENET_PEER_FREE_RELIABLE_WINDOWS = 8
ENET_PEER_FREE_RELIABLE_WINDOWS = 8,
ENET_PEER_MINIMUM_TIME_SENT_MASK = 3
};

typedef struct _ENetChannel
Expand All @@ -247,6 +251,26 @@ typedef struct _ENetChannel
ENetList incomingUnreliableCommands;
} ENetChannel;

typedef struct _ENetConnectingPeer
{
ENetAddress address;
ENetAddress localAddress;
enet_uint32 realTimeSent;
enet_uint32 connectID;
enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth;
enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration;
enet_uint32 packetThrottleInterval;
enet_uint32 eventData;
enet_uint32 mtu;
enet_uint16 windowSize;
enet_uint16 randomTimeSent;
enet_uint16 outgoingPeerID;
enet_uint8 channelCount;
enet_uint8 outgoingSessionID;
} ENetConnectingPeer;

/**
* An ENet peer which data packets may be sent or received from.
*
Expand All @@ -256,6 +280,8 @@ typedef struct _ENetPeer
{
ENetListNode dispatchList;
struct _ENetHost * host;
ENetConnectingPeer (* connectingPeers) [ENET_PROTOCOL_TOTAL_SESSIONS];
enet_uint32 connectingPeersTimeMask;
enet_uint16 outgoingPeerID;
enet_uint16 incomingPeerID;
enet_uint32 connectID;
Expand Down Expand Up @@ -337,6 +363,13 @@ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * b
/** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */
typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, struct _ENetEvent * event);

typedef struct _ENetRandom
{
void * context;
enet_uint32 (ENET_CALLBACK * generate) (void * context);
void (ENET_CALLBACK * destroy) (void * context);
} ENetRandom;

/** An ENet host for communicating with peers.
*
* No fields should be modified unless otherwise stated.
Expand Down Expand Up @@ -365,6 +398,15 @@ typedef struct _ENetHost
int recalculateBandwidthLimits;
ENetPeer * peers; /**< array of peers allocated for this host */
size_t peerCount; /**< number of peers allocated for this host */
enet_uint32 connectingPeerTimeout;
enet_uint32 connectsWindow;
enet_uint32 * connectsData;
size_t connectsDataIndex;
enet_uint32 connectsDataIndexTimestamp;
enet_uint32 connectsInWindow;
enet_uint16 * idlePeersList;
size_t idlePeers;
ENetRandom randomFunction;
size_t channelLimit; /**< maximum number of channels allowed for connected peers */
enet_uint32 serviceTime;
ENetList dispatchQueue;
Expand Down Expand Up @@ -558,6 +600,7 @@ ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *);
ENET_API int enet_host_compress_with_range_coder (ENetHost * host);
ENET_API void enet_host_channel_limit (ENetHost *, size_t);
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
ENET_API int enet_host_connect_cookies(ENetHost *, const ENetRandom *, enet_uint32);
extern void enet_host_bandwidth_throttle (ENetHost *);
extern enet_uint32 enet_host_random_seed (void);

Expand Down
3 changes: 2 additions & 1 deletion enet/include/enet/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ typedef enum _ENetProtocolFlag
ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,

ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12),
ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12
ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12,
ENET_PROTOCOL_TOTAL_SESSIONS = (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT) + 1
} ENetProtocolFlag;

#ifdef _MSC_VER
Expand Down
16 changes: 16 additions & 0 deletions enet/peer.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,22 @@ enet_peer_on_disconnect (ENetPeer * peer)
void
enet_peer_reset (ENetPeer * peer)
{
if (peer -> host -> connectingPeerTimeout)
{
size_t i;
ENetHost * host = peer -> host;
if (peer -> connectingPeers)
{
enet_free(peer -> connectingPeers);
peer -> connectingPeers = NULL;
peer -> host -> connectsWindow -= ENET_PROTOCOL_TOTAL_SESSIONS * (peer -> connectingPeersTimeMask + 1);
}
for (i = 0; i < host -> idlePeers; ++ i)
if (host -> idlePeersList [i] == peer -> incomingPeerID)
break;
if (i == host -> idlePeers)
host -> idlePeersList [host -> idlePeers ++] = peer -> incomingPeerID;
}
enet_peer_on_disconnect (peer);

peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
Expand Down
Loading

0 comments on commit c8e9316

Please sign in to comment.