[ENet-discuss] Adding invitation support

Benoit Germain bgermain at ubisoft.fr
Wed Oct 20 08:20:50 PDT 2004


Hi,

I am an ENet-newbie, in the sense that I just downloaded it and I am trying
to use it for a simple connecting scheme.

I want to add an invitation scheme to ENet, so that the real work will only
begin for peers that have been "invited" by the host. You can have a look at
the attached patch file to see what I changed.

What is supposed to happen is the following:

1 - The host is created with reservation for a given number of peers, and
may at any time reserve some peers for friends or any other purpose. By this
I mean: compute some unique keys, use them to reserve a peer, and give the
keys to some account on a matchmaking system using that system's API.
2 - The peer can then join the matchmaking system's session, retrieve the
keys, and use them to connect to the host.

The idea is that I can take advantage of the number of created peers inside
the ENet host to limit the number of connections that I'll be handling. 
So now my questions:

- Is there anything potentially wrong with the way I did it ?
- In the event it is useful to the community, can this be integrated in the
main version ?

Also, I scanned the mailing-list archives and found out about two bugs whose
fixes weren't included in the tarball that can be downloaded as of now (they
appear in the diff file as well as my changes). Related threads are "Bug in
fragmented reliable packet reassembly" (October 5th) and "Bug in
enet_peer_disconnect_now" (April 30th)
So, how old exactly is that tarball, and what other fixes are missing from
it ?


Regards,

 <<patch.txt>> 

__________________________________
Benoit Germain
][ Engineer
+33 4 50 10 93 52
<mailto:bgermain at ubisoft.fr>
__________________________________

-------------- next part --------------
--- enet_orig/include/enet/enet.h	2004-01-06 02:54:12.000000000 +0100
+++ enet/include/enet/enet.h	2004-10-20 16:47:16.486414500 +0200
@@ -197,6 +197,8 @@
    enet_uint16   outgoingPeerID;
    enet_uint16   incomingPeerID;
    enet_uint32   challenge;
+   enet_uint32   invite_challenge1;
+   enet_uint32   invite_challenge2;
    ENetAddress   address;            /**< Internet address of the peer */
    void *        data;               /**< Application private data, may be freely modified */
    ENetPeerState state;
@@ -394,7 +396,8 @@
 
 ENET_API ENetHost * enet_host_create (const ENetAddress *address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth );
 ENET_API void       enet_host_destroy (ENetHost *host );
-ENET_API ENetPeer * enet_host_connect (ENetHost *host, const ENetAddress *address, size_t channelCount );
+ENET_API ENetPeer * enet_host_reserve (ENetHost *host, enet_uint32 invite_challenge1, enet_uint32 invite_challenge2 );
+ENET_API ENetPeer * enet_host_connect (ENetHost *host, const ENetAddress *address, size_t channelCount, enet_uint32 invite_challenge1 , enet_uint32 invite_challenge2);
 ENET_API int        enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
 ENET_API void       enet_host_flush (ENetHost *);
 ENET_API void       enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);


--- enet_orig/host.c	2003-11-16 19:18:18.000000000 +0100
+++ enet/host.c	2004-10-20 16:47:14.080118300 +0200
@@ -98,6 +98,36 @@
     enet_free (host);
 }
 
+/** Reserve a peer so that not everyone can connect to the host
+    @param invite_challenge1 a value to identify the reservation
+    @param invite_challenge2 a value to identify the reservation
+    @returns the peer that has been reserved, NULL on failure
+    @remarks Failure happens either because no peer is available for reservation, or some peer was already reserved with the same values
+*/
+ENetPeer *
+enet_host_reserve (ENetHost *host, enet_uint32 invite_challenge1, enet_uint32 invite_challenge2 )
+{
+    ENetPeer * currentPeer;
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED &&
+           currentPeer -> invite_challenge1 != invite_challenge1 &&
+           currentPeer -> invite_challenge2 != invite_challenge2)
+         break;
+    }
+
+    if (currentPeer >= & host -> peers [host -> peerCount])
+      return NULL;
+
+    currentPeer -> invite_challenge1 = invite_challenge1;
+    currentPeer -> invite_challenge2 = invite_challenge2;
+
+    return currentPeer;
+}
+
 /** Initiates a connection to a foreign host.
     @param host host seeking the connection
     @param address destination for the connection
@@ -107,7 +137,7 @@
     notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
 */
 ENetPeer *
-enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount)
+enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 invite_challenge1 , enet_uint32 invite_challenge2)
 {
     ENetPeer * currentPeer;
     ENetChannel * channel;
@@ -135,6 +165,8 @@
     currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
     currentPeer -> channelCount = channelCount;
     currentPeer -> challenge = (enet_uint32) rand ();
+    currentPeer -> invite_challenge1 = invite_challenge1;
+    currentPeer -> invite_challenge2 = invite_challenge2;
 
     if (host -> outgoingBandwidth == 0)
       currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
--- enet_orig/peer.c	2003-12-22 04:09:26.000000000 +0100
+++ enet/peer.c	2004-10-20 16:26:35.759468000 +0200
@@ -325,6 +325,8 @@
 {
     peer -> outgoingPeerID = 0xFFFF;
     peer -> challenge = 0;
+    peer -> invite_challenge1 = 0;
+    peer -> invite_challenge2 = 0;
 
     peer -> address.host = ENET_HOST_ANY;
     peer -> address.port = 0;
@@ -400,7 +402,7 @@
 {
     ENetProtocol command;
 
-    if (peer -> state != ENET_PEER_STATE_DISCONNECTED)
+    if (peer -> state == ENET_PEER_STATE_DISCONNECTED)
       return;
 
     if (peer -> state != ENET_PEER_STATE_ZOMBIE &&
--- enet_orig/protocol.c	2004-01-18 17:13:58.000000000 +0100
+++ enet/protocol.c	2004-10-20 16:43:47.013642700 +0200
@@ -156,6 +156,7 @@
         channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
       return NULL;
 
+    /* ignore reception of connect commands from an already known peer */
     for (currentPeer = host -> peers;
          currentPeer < & host -> peers [host -> peerCount];
          ++ currentPeer)
@@ -167,14 +168,19 @@
           return NULL;
     }
 
+    /* find a peer in our list that is suitable to establish a connection with the command's sender */
     for (currentPeer = host -> peers;
          currentPeer < & host -> peers [host -> peerCount];
          ++ currentPeer)
     {
-        if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
+        /* peer is suitable if not already connected, and invite challenge matches the reservation */
+        if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED &&
+            currentPeer -> invite_challenge1 == command -> connect.invite_challenge1 &&
+            currentPeer -> invite_challenge2 == command -> connect.invite_challenge2)
           break;
     }
 
+    /* no suitable peer found: ignore connect command (-> the peer's attempt will fail) */
     if (currentPeer >= & host -> peers [host -> peerCount])
       return NULL;
 
@@ -252,6 +258,8 @@
     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.invite_challenge1 = currentPeer -> invite_challenge1 ;
+    verifyCommand.verifyConnect.invite_challenge2 = currentPeer -> invite_challenge2 ;
     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);
@@ -344,7 +352,7 @@
     if (currentCommand == enet_list_end (& channel -> incomingReliableCommands))
     {
        ENetProtocol hostCommand = * command;
-       
+       hostCommand.header.reliableSequenceNumber = startSequenceNumber;
        hostCommand.sendFragment.startSequenceNumber = startSequenceNumber;
        hostCommand.sendFragment.fragmentNumber = fragmentNumber;
        hostCommand.sendFragment.fragmentCount = fragmentCount;
@@ -535,7 +543,9 @@
     if (ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount) != peer -> channelCount ||
         ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval ||
         ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration ||
-        ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration)
+        ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration ||
+        command -> verifyConnect.invite_challenge1 != peer -> invite_challenge1 ||
+        command -> verifyConnect.invite_challenge2 != peer -> invite_challenge2)
     {
         peer -> state = ENET_PEER_STATE_ZOMBIE;
 
--- enet_orig/include/enet/protocol.h	2003-10-30 16:55:32.000000000 +0100
+++ enet/include/enet/protocol.h	2004-10-20 16:38:44.398457600 +0200
@@ -73,6 +73,8 @@
    enet_uint32 channelCount;
    enet_uint32 incomingBandwidth;
    enet_uint32 outgoingBandwidth;
+   enet_uint32 invite_challenge1;
+   enet_uint32 invite_challenge2;
    enet_uint32 packetThrottleInterval;
    enet_uint32 packetThrottleAcceleration;
    enet_uint32 packetThrottleDeceleration;
@@ -87,6 +89,8 @@
    enet_uint32 channelCount;
    enet_uint32 incomingBandwidth;
    enet_uint32 outgoingBandwidth;
+   enet_uint32 invite_challenge1;
+   enet_uint32 invite_challenge2;
    enet_uint32 packetThrottleInterval;
    enet_uint32 packetThrottleAcceleration;
    enet_uint32 packetThrottleDeceleration;


More information about the ENet-discuss mailing list