]> git.seodisparate.com - UDPConnection/commitdiff
Impl create id with hostname
authorStephen Seo <seo.disparate@gmail.com>
Sun, 26 Apr 2020 09:36:49 +0000 (18:36 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Sun, 26 Apr 2020 09:52:06 +0000 (18:52 +0900)
Previously, ids could only be created with an ip address. Now they can
be made with a hostname, which will be looked up by UDPC.

Also fix client still requesting connections even if
accept-new-connections flag is false.

src/UDPC.h
src/UDPC_Defines.hpp
src/UDPConnection.cpp
src/test/TestUDPC.cpp
src/test/UDPC_NetworkTest.c

index 2e6f45114eb4d79d09b849a842f935e93511be87..89e67e5508359f2665e33ca90d5125d310b8c8ad 100644 (file)
@@ -281,6 +281,8 @@ UDPC_ConnectionId UDPC_create_id_anyaddr(uint16_t port);
  */
 UDPC_ConnectionId UDPC_create_id_easy(const char *addrString, uint16_t port);
 
+UDPC_ConnectionId UDPC_create_id_hostname(const char *hostname, uint16_t port);
+
 /*!
  * \brief Creates an UDPC_HContext that holds state for connections
  *
@@ -678,6 +680,8 @@ UDPC_IPV6_ADDR_TYPE UDPC_strtoa(const char *addrStr);
 
 UDPC_IPV6_ADDR_TYPE UDPC_strtoa_link(const char *addrStr, uint32_t *linkId_out);
 
+UDPC_IPV6_ADDR_TYPE UDPC_a4toa6(uint32_t a4_be);
+
 int UDPC_is_big_endian();
 uint16_t UDPC_no16i(uint16_t i);
 uint32_t UDPC_no32i(uint32_t i);
index f97dc12285081d33b96c74dd84ca4cc615d224ca..ff572011b550815a0ad971cea59ac3880f001009 100644 (file)
 # include <sodium.h>
 #endif
 
+#if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS
+# include <ws2tcpip.h>
+#elif UDPC_PLATFORM == UDPC_PLATFORM_MAC || UDPC_PLATFORM_LINUX
+# include <netdb.h>
+#endif
+
 #define UDPC_MIN_HEADER_SIZE 20
 #define UDPC_CON_HEADER_SIZE (UDPC_MIN_HEADER_SIZE+4)
 #define UDPC_CCL_HEADER_SIZE (UDPC_MIN_HEADER_SIZE+4+crypto_sign_PUBLICKEYBYTES+12)
index 39ff0acf5b58fb86598bf91e14d33a48d8828db7..0829ed24a106ffa3ed6fa0f6a87939d410cab20f 100644 (file)
 
 #if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS
 #include <netioapi.h>
-
-static const UDPC_IPV6_ADDR_TYPE in6addr_any = UDPC_IPV6_ADDR_TYPE{{
-    0, 0, 0, 0,
-    0, 0, 0, 0,
-    0, 0, 0, 0,
-    0, 0, 0, 0
-}};
-static const UDPC_IPV6_ADDR_TYPE in6addr_loopback = UDPC_IPV6_ADDR_TYPE{{
-    0, 0, 0, 0,
-    0, 0, 0, 0,
-    0, 0, 0, 0,
-    0, 0, 0, 1
-}};
-
 typedef int socklen_t;
+
 #elif UDPC_PLATFORM == UDPC_PLATFORM_MAC || UDPC_PLATFORM == UDPC_PLATFORM_LINUX
 #include <sys/ioctl.h>
 #include <net/if.h>
@@ -319,6 +306,12 @@ void UDPC::Context::update_impl() {
             switch(event.type) {
             case UDPC_ET_REQUEST_CONNECT:
             {
+                if(!isAcceptNewConnections.load()) {
+                    UDPC_CHECK_LOG(this, UDPC_LoggingType::UDPC_WARNING,
+                        "Ignoring connection request because "
+                        "accept-new-connections flag is false");
+                    break;
+                }
                 unsigned char *sk = nullptr;
                 unsigned char *pk = nullptr;
                 if(keysSet.load()) {
@@ -1942,6 +1935,51 @@ UDPC_ConnectionId UDPC_create_id_easy(const char *addrString, uint16_t port) {
     return result;
 }
 
+UDPC_ConnectionId UDPC_create_id_hostname(const char *hostname, uint16_t port) {
+    UDPC_ConnectionId result;
+    std::memset(&result, 0, sizeof(UDPC_ConnectionId));
+    result.port = port;
+
+#if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS
+    WORD wVersionRequested = MAKEWORD(2, 2);
+    WSADATA wsaData;
+    if(WSAStartup(wVersionRequested, &wsaData) != 0) {
+        fprintf(stderr, "Failed to initialize Winsock\n");
+        return result;
+    }
+#elif UDPC_PLATFORM == UDPC_PLATFORM_MAC || UDPC_PLATFORM == UDPC_PLATFORM_LINUX
+#endif
+    addrinfo hints;
+    std::memset(&hints, 0, sizeof(addrinfo));
+
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_DGRAM;
+
+    addrinfo *lookupResult;
+    int error = getaddrinfo(hostname, nullptr, &hints, &lookupResult);
+
+    if(error == 0) {
+        if(lookupResult->ai_family == AF_INET) {
+            sockaddr_in *a4 = (sockaddr_in*)lookupResult->ai_addr;
+            result.addr = UDPC_a4toa6(a4->sin_addr.s_addr);
+        } else if(lookupResult->ai_family == AF_INET6) {
+            sockaddr_in6 *a6 = (sockaddr_in6*)lookupResult->ai_addr;
+            result.addr = a6->sin6_addr;
+        } else {
+            result.addr = in6addr_loopback;
+        }
+        freeaddrinfo(lookupResult);
+    } else {
+        result.addr = in6addr_loopback;
+    }
+
+#if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS
+    WSACleanup();
+#endif
+
+    return result;
+}
+
 UDPC_HContext UDPC_init(UDPC_ConnectionId listenId, int isClient, int isUsingLibsodium) {
     UDPC::Context *ctx = new UDPC::Context(false);
     ctx->flags.set(1, isClient != 0);
@@ -3013,6 +3051,31 @@ UDPC_IPV6_ADDR_TYPE UDPC_strtoa_link(const char *addrStr, uint32_t *linkId_out)
     return result;
 }
 
+UDPC_IPV6_ADDR_TYPE UDPC_a4toa6(uint32_t a4_be) {
+    if(a4_be == 0) {
+        return in6addr_any;
+    }
+
+    uint32_t a4 = ntohl(a4_be);
+
+    if(a4 == 0x7F000001) {
+        return in6addr_loopback;
+    }
+
+    UDPC_IPV6_ADDR_TYPE result;
+    for(unsigned int i = 0; i < 10; ++i) {
+        UDPC_IPV6_ADDR_SUB(result)[i] = 0;
+    }
+    UDPC_IPV6_ADDR_SUB(result)[10] = 0xFF;
+    UDPC_IPV6_ADDR_SUB(result)[11] = 0xFF;
+
+    for(unsigned int i = 0; i < 4; ++i) {
+        UDPC_IPV6_ADDR_SUB(result)[12 + i] = *((uint8_t*)&a4 + (3 - i));
+    }
+
+    return result;
+}
+
 int UDPC_is_big_endian() {
     return UDPC::isBigEndian() ? 1 : 0;
 }
index 6c7ecd6f0e21e113be2eaea91c5673c4f54f19f1..e0e0f7669c95a3503c6f9089d4d04b64a9e2439e 100644 (file)
@@ -318,3 +318,13 @@ TEST(UDPC, NetworkOrderEndianness) {
         EXPECT_EQ(ll, 0x4000001010008040);
     }
 }
+
+TEST(UDPC, a4toa6) {
+    EXPECT_EQ(UDPC_a4toa6(0), in6addr_any);
+    uint32_t a4 = htonl(0x7F000001);
+    EXPECT_EQ(UDPC_a4toa6(a4), in6addr_loopback);
+
+    UDPC_IPV6_ADDR_TYPE a6 = UDPC_strtoa("::FFFF:0102:0304");
+    a4 = htonl(0x01020304);
+    EXPECT_EQ(UDPC_a4toa6(a4), a6);
+}
index 7b6c2db342f68b13db83d9c2597484b9e7f88717..b6d2cbc551c02d86a58f992b3b77267e5a901614 100644 (file)
@@ -19,6 +19,7 @@ void usage() {
     puts("-ll <addr> - listen addr");
     puts("-lp <port> - listen port");
     puts("-cl <addr> - connection addr (client only)");
+    puts("-clh <hostname> - connection hostname (client only)");
     puts("-cp <port> - connection port (client only)");
     puts("-t <tick_count>");
     puts("-n - do not add payload to packets");
@@ -28,6 +29,7 @@ void usage() {
     puts("-ck <pubkey_file> - add pubkey to whitelist");
     puts("-sk <pubkey> <seckey> - start with pub/sec key pair");
     puts("-p <\"fallback\" or \"strict\"> - set auth policy");
+    puts("--hostname <hostname> - dont run test, just lookup hostname");
 }
 
 void sleep_seconds(unsigned int seconds) {
@@ -48,6 +50,7 @@ int main(int argc, char **argv) {
     const char *listenAddr = NULL;
     const char *listenPort = NULL;
     const char *connectionAddr = NULL;
+    const char *connectionHostname = NULL;
     const char *connectionPort = NULL;
     unsigned int tickLimit = 15;
     int noPayload = 0;
@@ -77,6 +80,9 @@ int main(int argc, char **argv) {
         } else if(strcmp(argv[0], "-cl") == 0 && argc > 1) {
             --argc; ++argv;
             connectionAddr = argv[0];
+        } else if(strcmp(argv[0], "-clh") == 0 && argc > 1) {
+            --argc; ++argv;
+            connectionHostname = argv[0];
         } else if(strcmp(argv[0], "-cp") == 0 && argc > 1) {
             --argc; ++argv;
             connectionPort = argv[0];
@@ -137,6 +143,16 @@ int main(int argc, char **argv) {
                 usage();
                 return 1;
             }
+        } else if(strcmp(argv[0], "--hostname") == 0 && argc > 1) {
+            --argc; ++argv;
+            UDPC_ConnectionId id = UDPC_create_id_hostname(argv[0], 9000);
+
+            UDPC_HContext ctx = UDPC_init(UDPC_create_id_easy("::1", 9000), 0, 0);
+            const char *str = UDPC_atostr(ctx, id.addr);
+            printf("Got addr \"%s\" for hostname \"%s\"\n", str, argv[0]);
+            UDPC_destroy(ctx);
+
+            return 0;
         } else {
             printf("ERROR: invalid argument \"%s\"\n", argv[0]);
             usage();
@@ -204,8 +220,8 @@ int main(int argc, char **argv) {
     } else if(!listenPort) {
         puts("ERROR: listenPort was not specified");
         return 1;
-    } else if(isClient && !connectionAddr) {
-        puts("ERROR: connectionAddr was not specified");
+    } else if(isClient && !connectionAddr && !connectionHostname) {
+        puts("ERROR: connectionAddr or connectionHostname was not specified");
         return 1;
     } else if(isClient && !connectionPort) {
         puts("ERROR: connectionPort was not specified");
@@ -220,7 +236,15 @@ int main(int argc, char **argv) {
         listenId = UDPC_create_id_easy(listenAddr, atoi(listenPort));
     }
     if(isClient) {
-        connectionId = UDPC_create_id_easy(connectionAddr, atoi(connectionPort));
+        if(connectionAddr) {
+            connectionId = UDPC_create_id_easy(connectionAddr, atoi(connectionPort));
+        } else /* if(connectionHostname) */ {
+            connectionId = UDPC_create_id_hostname(connectionHostname, atoi(connectionPort));
+            if(memcmp(&connectionId.addr, &in6addr_loopback, 16) == 0) {
+                puts("ERROR: Failed to resolve hostname");
+                return 1;
+            }
+        }
     }
     UDPC_HContext context = UDPC_init(listenId, isClient, isLibSodiumEnabled);
     if(!context) {