]> git.seodisparate.com - UDPConnection/commitdiff
More impl of UDPConnection
authorStephen Seo <seo.disparate@gmail.com>
Mon, 4 Mar 2019 06:04:16 +0000 (15:04 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Mon, 4 Mar 2019 06:04:16 +0000 (15:04 +0900)
Add client initiate connection.

src/UDPC_Defines.h
src/UDPConnection.c
src/UDPConnection.h

index c9bb2b8c77c0530ddca75e50ea1e62615295bdd5..68ded166b2e9c3b698ff314311de8d14d01e9a69 100644 (file)
@@ -37,6 +37,7 @@ static const char *UDPC_ERR_THREADFAIL_STR = "Failed to create thread";
 #define UDPC_BAD_MODE_SEND_INTERVAL (1.0f/10.0f)
 #define UDPC_TIMEOUT_SECONDS 10.0f
 #define UDPC_HEARTBEAT_PKT_INTERVAL (15.0f/100.0f)
+#define UDPC_INIT_PKT_INTERVAL 5.0f
 #define UDPC_PKT_PROTOCOL_ID 1357924680
 
 #define UDPC_ID_CONNECT        0x80000000
index 3448aa2972cf0c95b8366d93116b98ff8b55ff92..3fdc887215406a89d2da298f0c186badc968a28f 100644 (file)
@@ -190,16 +190,16 @@ void UDPC_INTERNAL_destroy_conMap(void *unused, uint32_t addr, char *data)
     }
     UDPC_Deque_destroy(cd->sendPktQueue);
 
-    for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < cd->resendPktQueue->size; ++x)
+    for(int x = 0; x * sizeof(UDPC_INTERNAL_PacketInfo) < cd->priorityPktQueue->size; ++x)
     {
         UDPC_INTERNAL_PacketInfo *pinfo = UDPC_Deque_index_ptr(
-            cd->resendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo), x);
+            cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo), x);
         if(pinfo->data)
         {
             free(pinfo->data);
         }
     }
-    UDPC_Deque_destroy(cd->resendPktQueue);
+    UDPC_Deque_destroy(cd->priorityPktQueue);
 }
 
 void UDPC_set_callback_connected(
@@ -289,6 +289,40 @@ void UDPC_check_events(UDPC_Context *ctx)
     }
 }
 
+void UDPC_client_initiate_connection(UDPC_Context *ctx, uint32_t addr, uint16_t port)
+{
+    if((ctx->flags & 0x2) == 0 || UDPC_HashMap_has(ctx->conMap, addr) != 0)
+    {
+        // must be client or no already-existing connection to same address
+        return;
+    }
+
+    UDPC_INTERNAL_ConnectionData cd = {
+        0x9,
+        0,
+        0,
+        0,
+        0xFFFFFFFF,
+        0.0f,
+        30.0f,
+        0.0f,
+        0.0f,
+        addr,
+        port,
+        UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SENT_PKTS_ALLOC_SIZE),
+        UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SEND_PKTS_ALLOC_SIZE),
+        UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_RESEND_PKTS_ALLOC_SIZE),
+        {0, 0},
+        {0, 0},
+        0.0f
+    };
+
+    timespec_get(&cd.received, TIME_UTC);
+    // only set "received" to now, since "sent" will be set after sending packet
+
+    UDPC_HashMap_insert(ctx->conMap, addr, &cd);
+}
+
 int UDPC_queue_send(UDPC_Context *ctx, uint32_t addr, uint32_t isChecked, void *data, uint32_t size)
 {
     UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, addr);
@@ -455,7 +489,8 @@ void UDPC_update(UDPC_Context *ctx)
 
     if(isConnect != 0 && (ctx->flags & 0x40) != 0)
     {
-        if(!UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr))
+        if((ctx->flags & 0x2) == 0
+            && !UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr))
         {
             UDPC_INTERNAL_log(ctx, 2, "Establishing connection with %s port %d",
                 UDPC_INTERNAL_atostr(ctx, receivedData.sin_addr.s_addr),
@@ -475,12 +510,10 @@ void UDPC_update(UDPC_Context *ctx)
                 UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SENT_PKTS_ALLOC_SIZE),
                 UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_SEND_PKTS_ALLOC_SIZE),
                 UDPC_Deque_init(sizeof(UDPC_INTERNAL_PacketInfo) * UDPC_RESEND_PKTS_ALLOC_SIZE),
-                {0, 0},
-                {0, 0},
+                us.tsNow,
+                us.tsNow,
                 0.0f
             };
-            newCD.received = us.tsNow;
-            newCD.sent = us.tsNow;
             UDPC_HashMap_insert(ctx->conMap, newCD.addr, &newCD);
             if(UDPC_Deque_get_available(ctx->connectedEvents) == 0)
             {
@@ -494,6 +527,16 @@ void UDPC_update(UDPC_Context *ctx)
                 UDPC_Deque_push_back(ctx->connectedEvents, &receivedData.sin_addr.s_addr, 4);
             }
         }
+        else if((ctx->flags & 0x2) != 0)
+        {
+            UDPC_INTERNAL_ConnectionData *cd = UDPC_HashMap_get(ctx->conMap, receivedData.sin_addr.s_addr);
+            if(!cd) { return; }
+
+            cd->flags &= 0xFFFFFFF7;
+            cd->id = conID;
+            UDPC_INTERNAL_log(ctx, 2, "Got id %u from server %s", conID,
+                UDPC_INTERNAL_atostr(ctx, receivedData.sin_addr.s_addr));
+        }
         return;
     }
     else if(isPing != 0)
@@ -722,7 +765,47 @@ void UDPC_INTERNAL_update_send(void *userData, uint32_t addr, char *data)
     }
 
     cd->flags = cd->flags & 0xFFFFFFFE;
-    if(cd->sendPktQueue->size == 0 && cd->resendPktQueue->size == 0)
+
+    if((cd->flags & 0x8) != 0)
+    {
+        // initiate connection to server
+        if(UDPC_INTERNAL_ts_diff(&us->tsNow, &cd->sent) < UDPC_INIT_PKT_INTERVAL)
+        {
+            return;
+        }
+        cd->sent = us->tsNow;
+
+        char *data = malloc(20);
+        UDPC_INTERNAL_prepare_pkt(
+            data,
+            UDPC_ID_CONNECT,
+            0,
+            0xFFFFFFFF,
+            NULL,
+            0);
+
+        struct sockaddr_in destinationInfo;
+        destinationInfo.sin_family = AF_INET;
+        destinationInfo.sin_addr.s_addr = addr;
+        destinationInfo.sin_port = htons(cd->port);
+        long int sentBytes = sendto(
+            us->ctx->socketHandle,
+            data,
+            20,
+            0,
+            (struct sockaddr*) &destinationInfo,
+            sizeof(struct sockaddr_in));
+        if(sentBytes != 20)
+        {
+            UDPC_INTERNAL_log(us->ctx, 0, "Failed to send init packet to %s "
+                "port %d", UDPC_INTERNAL_atostr(us->ctx, addr), cd->port);
+            free(data);
+            return;
+        }
+        return;
+    }
+
+    if(cd->sendPktQueue->size == 0 && cd->priorityPktQueue->size == 0)
     {
         // send and resend packet queue is empty, send heartbeat packet
         if(UDPC_INTERNAL_ts_diff(&us->tsNow, &cd->sent) < UDPC_HEARTBEAT_PKT_INTERVAL)
@@ -775,15 +858,15 @@ void UDPC_INTERNAL_update_send(void *userData, uint32_t addr, char *data)
         }
         free(data);
     }
-    else // sendPktQueue or resendPktQueue not empty
+    else // sendPktQueue or priorityPktQueue not empty
     {
         UDPC_INTERNAL_PacketInfo *pinfo;
         int isResendingPkt = 0;
 
-        if(cd->resendPktQueue->size != 0)
+        if(cd->priorityPktQueue->size != 0)
         {
             pinfo = UDPC_Deque_get_front_ptr(
-                cd->resendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo));
+                cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo));
             isResendingPkt = 1;
         }
         else
@@ -820,7 +903,7 @@ void UDPC_INTERNAL_update_send(void *userData, uint32_t addr, char *data)
             free(pinfo->data);
             if(isResendingPkt != 0)
             {
-                UDPC_Deque_pop_front(cd->resendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo));
+                UDPC_Deque_pop_front(cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo));
             }
             else
             {
@@ -871,7 +954,7 @@ void UDPC_INTERNAL_update_send(void *userData, uint32_t addr, char *data)
         free(pinfo->data);
         if(isResendingPkt != 0)
         {
-            UDPC_Deque_pop_front(cd->resendPktQueue, sizeof(UDPC_INTERNAL_PacketInfo));
+            UDPC_Deque_pop_front(cd->priorityPktQueue, sizeof(UDPC_INTERNAL_PacketInfo));
         }
         else
         {
@@ -973,7 +1056,7 @@ void UDPC_INTERNAL_check_pkt_timeout(
                     pinfo->data = NULL;
                     pinfo->size = 0;
                     UDPC_Deque_push_back(
-                        cd->resendPktQueue,
+                        cd->priorityPktQueue,
                         &newPkt,
                         sizeof(UDPC_INTERNAL_PacketInfo));
                 }
@@ -1091,8 +1174,17 @@ void UDPC_INTERNAL_prepare_pkt(
         temp = htonl(conID | ((flags & 0x2) != 0 ? UDPC_ID_RESENDING : 0));
         memcpy(&d[4], &temp, 4);
     }
-    temp = htonl(*seqID);
-    ++(*seqID);
+
+    if(seqID)
+    {
+        temp = htonl(*seqID);
+        ++(*seqID);
+    }
+    else
+    {
+        temp = 0;
+    }
+
     memcpy(&d[8], &temp, 4);
     temp = htonl(rseq);
     memcpy(&d[12], &temp, 4);
index 920ab3c180aed1c98f0ea7431487fc2726e09ae7..c4728ba042ba3d9a0202e1df6c6f85e55d9b6ea0 100644 (file)
@@ -56,6 +56,7 @@ typedef struct {
      * 0x1 - is resending
      * 0x2 - is check received packet
      * 0x4 - has been re-sent
+     * 0x8 - initiate connection packet
      */
     uint32_t flags;
     char *data; // no-header in sendPktQueue and receivedPackets, header in sentPkts
@@ -69,6 +70,7 @@ typedef struct {
      * 0x1 - trigger send
      * 0x2 - is good mode
      * 0x4 - is good rtt
+     * 0x8 - is id not set yet / initiating connection to server
      */
     uint32_t flags;
     uint32_t id;
@@ -83,7 +85,7 @@ typedef struct {
     uint16_t port;
     UDPC_Deque *sentPkts;
     UDPC_Deque *sendPktQueue;
-    UDPC_Deque *resendPktQueue;
+    UDPC_Deque *priorityPktQueue;
     struct timespec received;
     struct timespec sent;
     float rtt;
@@ -154,6 +156,8 @@ void UDPC_set_callback_received(
 
 void UDPC_check_events(UDPC_Context *ctx);
 
+void UDPC_client_initiate_connection(UDPC_Context *ctx, uint32_t addr, uint16_t port);
+
 /*!
  * \brief Queues a packet to send to a connected peer
  * Note addr is expected to be in network-byte-order (big-endian).