Browse Source

Merge pull request #22 from OptoCloud/master

Add packet clone, and improve IPv4/IPv6 handing
Vladyslav Hrytsenko 3 years ago
parent
commit
2c122c0ce2
1 changed files with 177 additions and 23 deletions
  1. 177 23
      include/enet.h

+ 177 - 23
include/enet.h

@@ -192,6 +192,15 @@
     #define ENET_SOCKETSET_CHECK(sockset, socket)  FD_ISSET(socket, &(sockset))
 #endif
 
+#ifdef __GNUC__
+#define ENET_DEPRECATED(func) func __attribute__ ((deprecated))
+#elif defined(_MSC_VER)
+#define ENET_DEPRECATED(func) __declspec(deprecated) func
+#else
+#pragma message("WARNING: Please ENET_DEPRECATED for this compiler")
+#define ENET_DEPRECATED(func) func
+#endif
+
 #ifndef ENET_BUFFER_MAXIMUM
 #define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
 #endif
@@ -202,6 +211,12 @@
 #define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
 
 #define ENET_IPV6           1
+const struct in6_addr enet_v4_anyaddr   = {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }}};
+const struct in6_addr enet_v4_noaddr    = {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}};
+const struct in6_addr enet_v4_localhost = {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01 }}};
+const struct in6_addr enet_v6_anyaddr   = {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}};
+const struct in6_addr enet_v6_noaddr    = {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}};
+const struct in6_addr enet_v6_localhost = {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}};
 #define ENET_HOST_ANY       in6addr_any
 #define ENET_HOST_BROADCAST 0xFFFFFFFFU
 #define ENET_PORT_ANY       0
@@ -236,6 +251,7 @@ extern "C" {
     extern void *enet_malloc(size_t);
     extern void enet_free(void *);
     extern ENetPacket* enet_packet_create(const void*,size_t,enet_uint32);
+    extern ENetPacket* enet_packet_copy(ENetPacket*);
     extern void enet_packet_destroy(ENetPacket*);
 
 // =======================================================================//
@@ -885,7 +901,7 @@ extern "C" {
         @retval < 0 on failure
         @returns the address of the given hostName in address on success
     */
-    ENET_API int enet_address_set_host_ip(ENetAddress * address, const char * hostName);
+    ENET_DEPRECATED(ENET_API int enet_address_set_host_ip_old(ENetAddress * address, const char * hostName));
 
     /** Attempts to resolve the host named by the parameter hostName and sets
         the host field in the address parameter if successful.
@@ -895,7 +911,7 @@ extern "C" {
         @retval < 0 on failure
         @returns the address of the given hostName in address on success
     */
-    ENET_API int enet_address_set_host(ENetAddress * address, const char * hostName);
+    ENET_DEPRECATED(ENET_API int enet_address_set_host_old(ENetAddress * address, const char * hostName));
 
     /** Gives the printable form of the IP address specified in the address parameter.
         @param address    address printed
@@ -905,7 +921,7 @@ extern "C" {
         @retval 0 on success
         @retval < 0 on failure
     */
-    ENET_API int enet_address_get_host_ip(const ENetAddress * address, char * hostName, size_t nameLength);
+    ENET_DEPRECATED(ENET_API int enet_address_get_host_ip_old(const ENetAddress * address, char * hostName, size_t nameLength));
 
     /** Attempts to do a reverse lookup of the host field in the address parameter.
         @param address    address used for reverse lookup
@@ -915,7 +931,24 @@ extern "C" {
         @retval 0 on success
         @retval < 0 on failure
     */
-    ENET_API int enet_address_get_host(const ENetAddress * address, char * hostName, size_t nameLength);
+    ENET_DEPRECATED(ENET_API int enet_address_get_host_old(const ENetAddress * address, char * hostName, size_t nameLength));
+
+    ENET_API int enet_address_set_host_ip_new(ENetAddress * address, const char * hostName);
+    ENET_API int enet_address_set_host_new(ENetAddress * address, const char * hostName);
+    ENET_API int enet_address_get_host_ip_new(const ENetAddress * address, char * hostName, size_t nameLength);
+    ENET_API int enet_address_get_host_new(const ENetAddress * address, char * hostName, size_t nameLength);
+
+#ifdef ENET_FEATURE_ADDRESS_MAPPING
+#define enet_address_set_host_ip enet_address_set_host_ip_new
+#define enet_address_set_host    enet_address_set_host_new
+#define enet_address_get_host_ip enet_address_get_host_ip_new
+#define enet_address_get_host    enet_address_get_host_new
+#else
+#define enet_address_set_host_ip enet_address_set_host_ip_old
+#define enet_address_set_host    enet_address_set_host_old
+#define enet_address_get_host_ip enet_address_get_host_ip_old
+#define enet_address_get_host    enet_address_get_host_old
+#endif
 
     ENET_API enet_uint32 enet_host_get_peers_count(ENetHost *);
     ENET_API enet_uint32 enet_host_get_packets_sent(ENetHost *);
@@ -1197,7 +1230,6 @@ extern "C" {
 
 #endif /* defined(_MSC_VER) */
 
-
 // =======================================================================//
 // !
 // ! Callbacks
@@ -1388,6 +1420,10 @@ extern "C" {
         return packet;
     }
 
+    ENetPacket *enet_packet_copy(ENetPacket *packet) {
+        return enet_packet_create(packet->data, packet->dataLength, packet->flags);
+    }
+
     /**
      * Destroys the packet and deallocates its data.
      * @param packet packet to be destroyed
@@ -4970,6 +5006,131 @@ extern "C" {
         return (enet_uint32)(result_in_ns / ns_in_ms);
     }
 
+    void enet_inaddr_map4to6(struct in_addr in, struct in6_addr *out)
+    {
+        if (in.s_addr == 0x00000000) { /* 0.0.0.0 */
+            *out = enet_v6_anyaddr;
+        } else if (in.s_addr == 0xFFFFFFFF) { /* 255.255.255.255 */
+            *out = enet_v6_noaddr;
+        } else {
+            *out = enet_v4_anyaddr;
+            out->s6_addr[10] = 0xFF;
+            out->s6_addr[11] = 0xFF;
+            out->s6_addr[12] = ((uint8_t *)&in.s_addr)[0];
+            out->s6_addr[13] = ((uint8_t *)&in.s_addr)[1];
+            out->s6_addr[14] = ((uint8_t *)&in.s_addr)[2];
+            out->s6_addr[15] = ((uint8_t *)&in.s_addr)[3];
+        }
+    }
+    void enet_inaddr_map6to4(const struct in6_addr *in, struct in_addr *out)
+    {
+        memset(out, 0, sizeof(struct in_addr));
+        ((uint8_t *)&out->s_addr)[0] = in->s6_addr[12];
+        ((uint8_t *)&out->s_addr)[1] = in->s6_addr[13];
+        ((uint8_t *)&out->s_addr)[2] = in->s6_addr[14];
+        ((uint8_t *)&out->s_addr)[3] = in->s6_addr[15];
+    }
+
+    int enet_in6addr_lookup_host(const char *name, bool nodns, struct in6_addr *out) {
+        struct addrinfo hints, *resultList = NULL, *result = NULL;
+
+        memset(&hints, 0, sizeof(hints));
+        hints.ai_family = AF_UNSPEC;
+
+        if (nodns)
+        {
+            hints.ai_flags = AI_NUMERICHOST; /* prevent actual DNS lookups! */
+        }
+
+        if (getaddrinfo(name, NULL, &hints, &resultList) != 0) {
+            if (resultList != NULL) {
+                freeaddrinfo(resultList);
+            }
+
+            return -1;
+        }
+
+        for (result = resultList; result != NULL; result = result->ai_next) {
+            if (result->ai_addr != NULL) {
+                if (result->ai_family == AF_INET || (result->ai_family == AF_UNSPEC && result->ai_addrlen == sizeof(struct sockaddr_in))) {
+                    enet_inaddr_map4to6(((struct sockaddr_in*)result->ai_addr)->sin_addr, out);
+
+                    if (resultList != NULL) {
+                        freeaddrinfo(resultList);
+                    }
+
+                    return 0;
+                } else if (result->ai_family == AF_INET6 || (result->ai_family == AF_UNSPEC && result->ai_addrlen == sizeof(struct sockaddr_in6))) {
+                    memcpy(out, &((struct sockaddr_in6*)result->ai_addr)->sin6_addr, sizeof(struct in6_addr));
+
+                    if (resultList != NULL) {
+                        freeaddrinfo(resultList);
+                    }
+
+                    return 0;
+                }
+            }
+        }
+
+        if (resultList != NULL) {
+            freeaddrinfo(resultList);
+        }
+
+        return -1;
+    }
+
+    int enet_address_set_host_ip_new(ENetAddress *address, const char *name) {
+        return enet_in6addr_lookup_host(name, true, &address->host);
+    }
+
+    int enet_address_set_host_new(ENetAddress *address, const char *name) {
+        return enet_in6addr_lookup_host(name, false, &address->host);
+    }
+
+    int enet_address_get_host_ip_new(const ENetAddress *address, char *name, size_t nameLength) {
+        if (IN6_IS_ADDR_V4MAPPED(&address->host)) {
+            struct in_addr buf;
+            enet_inaddr_map6to4(&address->host, &buf);
+
+            if (inet_ntop(AF_INET, &buf, name, nameLength) == NULL) {
+                return -1;
+            }
+        }
+        else {
+            if (inet_ntop(AF_INET6, &address->host, name, nameLength) == NULL) {
+                return -1;
+            }
+        }
+
+        return 0;
+    } /* enet_address_get_host_ip_new */
+
+    int enet_address_get_host_new(const ENetAddress *address, char *name, size_t nameLength) {
+        struct sockaddr_in6 sin;
+        memset(&sin, 0, sizeof(struct sockaddr_in6));
+
+        int err;
+
+
+        sin.sin6_family = AF_INET6;
+        sin.sin6_port = ENET_HOST_TO_NET_16 (address->port);
+        sin.sin6_addr = address->host;
+        sin.sin6_scope_id = address->sin6_scope_id;
+
+        err = getnameinfo((struct sockaddr *) &sin, sizeof(sin), name, nameLength, NULL, 0, NI_NAMEREQD);
+        if (!err) {
+            if (name != NULL && nameLength > 0 && !memchr(name, '\0', nameLength)) {
+                return -1;
+            }
+            return 0;
+        }
+        if (err != EAI_NONAME) {
+            return -1;
+        }
+
+        return enet_address_get_host_ip_new(address, name, nameLength);
+    } /* enet_address_get_host_new */
+
 // =======================================================================//
 // !
 // ! Platform Specific (Unix)
@@ -5159,7 +5320,7 @@ extern "C" {
             }
         }
     #endif // __MINGW__
-    
+
     int enet_initialize(void) {
         return 0;
     }
@@ -5170,7 +5331,7 @@ extern "C" {
         return (enet_uint64) time(NULL);
     }
 
-    int enet_address_set_host_ip(ENetAddress *address, const char *name) {
+    int enet_address_set_host_ip_old(ENetAddress *address, const char *name) {
         if (!inet_pton(AF_INET6, name, &address->host)) {
             return -1;
         }
@@ -5178,7 +5339,7 @@ extern "C" {
         return 0;
     }
 
-    int enet_address_set_host(ENetAddress *address, const char *name) {
+    int enet_address_set_host_old(ENetAddress *address, const char *name) {
         struct addrinfo hints, *resultList = NULL, *result = NULL;
 
         memset(&hints, 0, sizeof(hints));
@@ -5221,9 +5382,9 @@ extern "C" {
         }
 
         return enet_address_set_host_ip(address, name);
-    } /* enet_address_set_host */
+    } /* enet_address_set_host_old */
 
-    int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) {
+    int enet_address_get_host_ip_old(const ENetAddress *address, char *name, size_t nameLength) {
         if (inet_ntop(AF_INET6, &address->host, name, nameLength) == NULL) {
             return -1;
         }
@@ -5231,17 +5392,14 @@ extern "C" {
         return 0;
     }
 
-    int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLength) {
+    int enet_address_get_host_old(const ENetAddress *address, char *name, size_t nameLength) {
         struct sockaddr_in6 sin;
         int err;
-
         memset(&sin, 0, sizeof(struct sockaddr_in6));
-
         sin.sin6_family = AF_INET6;
         sin.sin6_port = ENET_HOST_TO_NET_16 (address->port);
         sin.sin6_addr = address->host;
         sin.sin6_scope_id = address->sin6_scope_id;
-
         err = getnameinfo((struct sockaddr *) &sin, sizeof(sin), name, nameLength, NULL, 0, NI_NAMEREQD);
         if (!err) {
             if (name != NULL && nameLength > 0 && !memchr(name, '\0', nameLength)) {
@@ -5252,9 +5410,8 @@ extern "C" {
         if (err != EAI_NONAME) {
             return -1;
         }
-
         return enet_address_get_host_ip(address, name, nameLength);
-    } /* enet_address_get_host */
+    } /* enet_address_get_host_old */
 
     int enet_socket_bind(ENetSocket socket, const ENetAddress *address) {
         struct sockaddr_in6 sin;
@@ -5579,7 +5736,7 @@ extern "C" {
         return (enet_uint64) timeGetTime();
     }
 
-    int enet_address_set_host_ip(ENetAddress *address, const char *name) {
+    int enet_address_set_host_ip_old(ENetAddress *address, const char *name) {
         enet_uint8 vals[4] = { 0, 0, 0, 0 };
         int i;
 
@@ -5603,7 +5760,7 @@ extern "C" {
         return 0;
     }
 
-    int enet_address_set_host(ENetAddress *address, const char *name) {
+    int enet_address_set_host_old(ENetAddress *address, const char *name) {
         struct hostent *hostEntry = NULL;
         hostEntry = gethostbyname(name);
 
@@ -5623,7 +5780,7 @@ extern "C" {
         return 0;
     }
 
-    int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) {
+    int enet_address_get_host_ip_old(const ENetAddress *address, char *name, size_t nameLength) {
         if (inet_ntop(AF_INET6, (PVOID)&address->host, name, nameLength) == NULL) {
             return -1;
         }
@@ -5631,13 +5788,11 @@ extern "C" {
         return 0;
     }
 
-    int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLength) {
+    int enet_address_get_host_old(const ENetAddress *address, char *name, size_t nameLength) {
         struct in6_addr in;
         struct hostent *hostEntry = NULL;
-
         in = address->host;
         hostEntry = gethostbyaddr((char *)&in, sizeof(struct in6_addr), AF_INET6);
-
         if (hostEntry == NULL) {
             return enet_address_get_host_ip(address, name, nameLength);
         } else {
@@ -5647,7 +5802,6 @@ extern "C" {
             }
             memcpy(name, hostEntry->h_name, hostLen + 1);
         }
-
         return 0;
     }