Ver Fonte

updated mingw support

Vladyslav Hrytsenko há 6 anos atrás
pai
commit
34076f8b3e
3 ficheiros alterados com 309 adições e 64 exclusões
  1. 70 6
      README.md
  2. 180 33
      include/enet.h
  3. 59 25
      test/build.c

+ 70 - 6
README.md

@@ -22,7 +22,8 @@
     Brought to you by
     <a href="https://github.com/lsalzman">@lsalzman</a>,
     <a href="https://github.com/inlife">@inlife</a>,
-    <a href="https://github.com/zaklaus">@zaklaus</a>
+    <a href="https://github.com/zaklaus">@zaklaus</a>,
+    <a href="https://github.com/inlife">@nxrighthere</a>
     and other contributors!
   </sub>
 </div>
@@ -34,11 +35,14 @@
 This is a fork of the original library [lsalzman/enet](https://github.com/lsalzman/enet). While original repo offers a stable, time-tested wonderful library,
 we are trying to change some things, things, which can't be reflected on the main repo, like:
 
+* integrated ipv6 support
+* added monotonic time
+* applied project-wide code style change
+* cleaned up project
+* single-header style code
 * NPM package distribution
-* Single-Header style code
-* Removed some config/make files
-* Project/Code cleanup
-* And other various changes
+* removed a lot of older methods
+* and many other various changes
 
 ## Description
 
@@ -64,7 +68,66 @@ Add include path to the library `node_modules/enet.c/include` to your makefile/
 
 Dowload file [include/enet.h](https://raw.githubusercontent.com/zpl-c/enet/master/include/enet.h) and just add to your project.
 
-## Usage
+## Usage (Shared library)
+
+Build the shared library:
+
+```sh
+$ mkdir build
+$ cd build
+$ cmake .. -DENET_SHARED=1 -DCMAKE_BUILD_TYPE=Release
+$ make
+```
+
+Use it:
+
+```c
+#define ENET_DLL
+#include <enet.h>
+#include <stdio.h>
+
+int main() {
+    if (enet_initialize () != 0) {
+        printf("An error occurred while initializing ENet.\n");
+        return 1;
+    }
+
+    enet_deinitialize();
+    return 0;
+}
+```
+
+## Usage (Static library)
+
+Build the static library:
+
+```sh
+$ mkdir build
+$ cd build
+$ cmake .. -DENET_STATIC=1 -DCMAKE_BUILD_TYPE=Release
+$ make
+```
+
+Use it:
+
+```c
+#include <enet.h>
+#include <stdio.h>
+
+int main() {
+    if (enet_initialize () != 0) {
+        printf("An error occurred while initializing ENet.\n");
+        return 1;
+    }
+
+    enet_deinitialize();
+    return 0;
+}
+```
+
+## Usage (Direct)
+
+In this case library will be built-in inside the project itself.
 
 Make sure you add a define for `ENET_IMPLEMENTATION` before including the `enet.h`.
 
@@ -73,6 +136,7 @@ Here is a simple server demo, it will wait 1 second for events, and then exit if
 ```c
 #define ENET_IMPLEMENTATION
 #include <enet.h>
+#include <stdio.h>
 
 int main() {
     if (enet_initialize () != 0) {

+ 180 - 33
include/enet.h

@@ -58,6 +58,13 @@
     #define NOT_UNDERSCORED_INTERLOCKED_EXCHANGE
     #endif
 
+    #ifdef __GNUC__
+    #if (_WIN32_WINNT < 0x0501)
+    #undef _WIN32_WINNT
+    #define _WIN32_WINNT 0x0501
+    #endif
+    #endif
+
     #include <winsock2.h>
     #include <ws2tcpip.h>
     #include <mmsystem.h>
@@ -5148,49 +5155,189 @@ extern "C" {
     #ifdef _WIN32
 
     #ifdef __MINGW32__
-    // inet_ntop/inet_pton for MinGW from http://mingw-users.1079350.n2.nabble.com/IPv6-getaddrinfo-amp-inet-ntop-td5891996.html
-    const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {
-        if (af == AF_INET) {
-            struct sockaddr_in in;
-            memset(&in, 0, sizeof(in));
-            in.sin_family = AF_INET;
-            memcpy(&in.sin_addr, src, sizeof(struct in_addr));
-            getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
-            return dst;
-        }
-        else if (af == AF_INET6) {
-            struct sockaddr_in6 in;
-            memset(&in, 0, sizeof(in));
-            in.sin6_family = AF_INET6;
-            memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
-            getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
-            return dst;
+        // inet_ntop/inet_pton for MinGW from http://mingw-users.1079350.n2.nabble.com/IPv6-getaddrinfo-amp-inet-ntop-td5891996.html
+        const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) {
+            if (af == AF_INET) {
+                struct sockaddr_in in;
+                memset(&in, 0, sizeof(in));
+                in.sin_family = AF_INET;
+                memcpy(&in.sin_addr, src, sizeof(struct in_addr));
+                getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
+                return dst;
+            }
+            else if (af == AF_INET6) {
+                struct sockaddr_in6 in;
+                memset(&in, 0, sizeof(in));
+                in.sin6_family = AF_INET6;
+                memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
+                getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
+                return dst;
+            }
+
+            return NULL;
         }
 
-        return NULL;
-    }
+        #define NS_INADDRSZ  4
+        #define NS_IN6ADDRSZ 16
+        #define NS_INT16SZ   2
 
-    int inet_pton(int af, const char *src, void *dst) {
-        struct addrinfo hints, *res, *ressave;
+        int inet_pton4(const char *src, char *dst)
+        {
+            uint8_t tmp[NS_INADDRSZ], *tp;
 
-        memset(&hints, 0, sizeof(struct addrinfo));
-        hints.ai_family = af;
+            int saw_digit = 0;
+            int octets = 0;
+            *(tp = tmp) = 0;
 
-        if (getaddrinfo(src, NULL, &hints, &res) != 0) {
-            return -1;
+            int ch;
+            while ((ch = *src++) != '\0')
+            {
+                if (ch >= '0' && ch <= '9')
+                {
+                    uint32_t n = *tp * 10 + (ch - '0');
+
+                    if (saw_digit && *tp == 0)
+                        return 0;
+
+                    if (n > 255)
+                        return 0;
+
+                    *tp = n;
+                    if (!saw_digit)
+                    {
+                        if (++octets > 4)
+                            return 0;
+                        saw_digit = 1;
+                    }
+                }
+                else if (ch == '.' && saw_digit)
+                {
+                    if (octets == 4)
+                        return 0;
+                    *++tp = 0;
+                    saw_digit = 0;
+                }
+                else
+                    return 0;
+            }
+            if (octets < 4)
+                return 0;
+
+            memcpy(dst, tmp, NS_INADDRSZ);
+
+            return 1;
         }
 
-        ressave = res;
+        int inet_pton6(const char *src, char *dst)
+        {
+            static const char xdigits[] = "0123456789abcdef";
+            uint8_t tmp[NS_IN6ADDRSZ];
+
+            uint8_t *tp = (uint8_t*) memset(tmp, '\0', NS_IN6ADDRSZ);
+            uint8_t *endp = tp + NS_IN6ADDRSZ;
+            uint8_t *colonp = NULL;
+
+            /* Leading :: requires some special handling. */
+            if (*src == ':')
+            {
+                if (*++src != ':')
+                    return 0;
+            }
+
+            const char *curtok = src;
+            int saw_xdigit = 0;
+            uint32_t val = 0;
+            int ch;
+            while ((ch = tolower(*src++)) != '\0')
+            {
+                const char *pch = strchr(xdigits, ch);
+                if (pch != NULL)
+                {
+                    val <<= 4;
+                    val |= (pch - xdigits);
+                    if (val > 0xffff)
+                        return 0;
+                    saw_xdigit = 1;
+                    continue;
+                }
+                if (ch == ':')
+                {
+                    curtok = src;
+                    if (!saw_xdigit)
+                    {
+                        if (colonp)
+                            return 0;
+                        colonp = tp;
+                        continue;
+                    }
+                    else if (*src == '\0')
+                    {
+                        return 0;
+                    }
+                    if (tp + NS_INT16SZ > endp)
+                        return 0;
+                    *tp++ = (uint8_t) (val >> 8) & 0xff;
+                    *tp++ = (uint8_t) val & 0xff;
+                    saw_xdigit = 0;
+                    val = 0;
+                    continue;
+                }
+                if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+                        inet_pton4(curtok, (char*) tp) > 0)
+                {
+                    tp += NS_INADDRSZ;
+                    saw_xdigit = 0;
+                    break; /* '\0' was seen by inet_pton4(). */
+                }
+                return 0;
+            }
+            if (saw_xdigit)
+            {
+                if (tp + NS_INT16SZ > endp)
+                    return 0;
+                *tp++ = (uint8_t) (val >> 8) & 0xff;
+                *tp++ = (uint8_t) val & 0xff;
+            }
+            if (colonp != NULL)
+            {
+                /*
+                 * Since some memmove()'s erroneously fail to handle
+                 * overlapping regions, we'll do the shift by hand.
+                 */
+                const int n = tp - colonp;
+
+                if (tp == endp)
+                    return 0;
 
-        while (res) {
-            memcpy(dst, res->ai_addr, res->ai_addrlen);
-            res = res->ai_next;
+                for (int i = 1; i <= n; i++)
+                {
+                    endp[-i] = colonp[n - i];
+                    colonp[n - i] = 0;
+                }
+                tp = endp;
+            }
+            if (tp != endp)
+                return 0;
+
+            memcpy(dst, tmp, NS_IN6ADDRSZ);
+
+            return 1;
         }
 
-        freeaddrinfo(ressave);
-        return 0;
-    }
-    #endif
+
+        int inet_pton(int af, const char *src, char *dst)
+        {
+            switch (af)
+            {
+            case AF_INET:
+                return inet_pton4(src, dst);
+            case AF_INET6:
+                return inet_pton6(src, dst);
+            default:
+                return -1;
+            }
+        }
+    #endif // __MINGW__
 
     int enet_initialize(void) {
         WORD versionRequested = MAKEWORD(1, 1);

+ 59 - 25
test/build.c

@@ -4,33 +4,14 @@
 #include "enet.h"
 #include <stdio.h>
 
-int main() {
-    if (enet_initialize () != 0) {
-        printf("An error occurred while initializing ENet.\n");
-        return 1;
-    }
-
-    ENetAddress address = {0};
-
-    address.host = ENET_HOST_ANY; /* Bind the server to the default localhost.     */
-    address.port = 7777; /* Bind the server to port 7777. */
-
-    #define MAX_CLIENTS 32
-
-    /* create a server */
-    ENetHost * server = enet_host_create(&address, MAX_CLIENTS, 2, 0, 0);
-
-    if (server == NULL) {
-        printf("An error occurred while trying to create an ENet server host.\n");
-        return 1;
-    }
-
-    printf("Started a server...\n");
+typedef struct {
+    ENetHost *host;
+    ENetPeer *peer;
+} Client;
 
+void host_server(ENetHost *server) {
     ENetEvent event;
-
-    /* Wait up to 1000 milliseconds for an event. (WARNING: blocking) */
-    while (enet_host_service(server, &event, 1000) > 0) {
+    while (enet_host_service(server, &event, 2) > 0) {
         switch (event.type) {
             case ENET_EVENT_TYPE_CONNECT:
                 printf("A new client connected from ::1:%u.\n", event.peer->address.port);
@@ -62,6 +43,59 @@ int main() {
             case ENET_EVENT_TYPE_NONE: break;
         }
     }
+}
+
+int main() {
+    if (enet_initialize() != 0) {
+        printf("An error occurred while initializing ENet.\n");
+        return 1;
+    }
+
+    #define MAX_CLIENTS 32
+
+    ENetHost *server;
+    Client clients[MAX_CLIENTS];
+    ENetAddress address = {0};
+
+    address.host = ENET_HOST_ANY; /* Bind the server to the default localhost. */
+    address.port = 7777; /* Bind the server to port 7777. */
+
+
+    /* create a server */
+    printf("starting server...\n");
+    server = enet_host_create(&address, MAX_CLIENTS, 2, 0, 0);
+    if (server == NULL) {
+        printf("An error occurred while trying to create an ENet server host.\n");
+        return 1;
+    }
+
+    printf("starting clients...\n");
+    for (int i = 0; i < MAX_CLIENTS; ++i) {
+        enet_address_set_host(&address, "::1");
+        clients[i].host = enet_host_create(NULL, 1, 2, 0, 0);
+        clients[i].peer = enet_host_connect(clients[i].host, &address, 2, 0);
+    }
+
+    // program will make N iterations, and then exit
+    static int counter = 1000;
+
+    do {
+        host_server(server);
+
+        ENetEvent event;
+        for (int i = 0; i < MAX_CLIENTS; ++i) {
+            enet_host_service(clients[i].host, &event, 0);
+        }
+
+        counter--;
+    } while (counter > 0);
+
+    for (int i = 0; i < MAX_CLIENTS; ++i) {
+        enet_peer_disconnect_now(clients[i].peer, 0);
+        enet_host_destroy(clients[i].host);
+    }
+
+    host_server(server);
 
     enet_host_destroy(server);
     enet_deinitialize();