Sfoglia il codice sorgente

use getaddrinfo and getnameinfo where available

Lee Salzman 10 anni fa
parent
commit
5f476546ed
4 ha cambiato i file con 78 aggiunte e 13 eliminazioni
  1. 8 0
      CMakeLists.txt
  2. 2 0
      ChangeLog
  3. 2 0
      configure.ac
  4. 66 13
      unix.c

+ 8 - 0
CMakeLists.txt

@@ -8,6 +8,8 @@ include(CheckStructHasMember)
 include(CheckTypeSize)
 check_function_exists("fcntl" HAS_FCNTL)
 check_function_exists("poll" HAS_POLL)
+check_function_exists("getaddrinfo" HAS_GETADDRINFO)
+check_function_exists("getnameinfo" HAS_GETNAMEINFO)
 check_function_exists("gethostbyname_r" HAS_GETHOSTBYNAME_R)
 check_function_exists("gethostbyaddr_r" HAS_GETHOSTBYADDR_R)
 check_function_exists("inet_pton" HAS_INET_PTON)
@@ -23,6 +25,12 @@ endif()
 if(HAS_POLL)
     add_definitions(-DHAS_POLL=1)
 endif()
+if(HAS_GETNAMEINFO)
+    add_definitions(-DHAS_GETNAMEINFO=1)
+endif()
+if(HAS_GETADDRINFO)
+    add_definitions(-DHAS_GETADDRINFO=1)
+endif()
 if(HAS_GETHOSTBYNAME_R)
     add_definitions(-DHAS_GETHOSTBYNAME_R=1)
 endif()

+ 2 - 0
ChangeLog

@@ -1,3 +1,5 @@
+* use getaddrinfo and getnameinfo where available
+
 ENet 1.3.13 (April 30, 2015):
 
 * miscellaneous bug fixes

+ 2 - 0
configure.ac

@@ -7,6 +7,8 @@ AC_CONFIG_MACRO_DIR([m4])
 AC_PROG_CC
 AC_PROG_LIBTOOL
 
+AC_CHECK_FUNC(getaddrinfo, [AC_DEFINE(HAS_GETADDRINFO)])
+AC_CHECK_FUNC(getnameinfo, [AC_DEFINE(HAS_GETNAMEINFO)])
 AC_CHECK_FUNC(gethostbyaddr_r, [AC_DEFINE(HAS_GETHOSTBYADDR_R)])
 AC_CHECK_FUNC(gethostbyname_r, [AC_DEFINE(HAS_GETHOSTBYNAME_R)])
 AC_CHECK_FUNC(poll, [AC_DEFINE(HAS_POLL)])

+ 66 - 13
unix.c

@@ -38,6 +38,12 @@
 #ifndef HAS_SOCKLEN_T
 #define HAS_SOCKLEN_T 1
 #endif
+#ifndef HAS_GETADDRINFO
+#define HAS_GETADDRINFO 1
+#endif
+#ifndef HAS_GETNAMEINFO
+#define HAS_GETNAMEINFO 1
+#endif
 #endif
 
 #ifdef HAS_FCNTL
@@ -98,6 +104,32 @@ enet_time_set (enet_uint32 newTimeBase)
 int
 enet_address_set_host (ENetAddress * address, const char * name)
 {
+#ifdef HAS_GETADDRINFO
+    struct addrinfo hints, * resultList = NULL, * result = NULL;
+
+    memset (& hints, 0, sizeof (hints));
+    hints.ai_family = AF_INET;
+
+    if (getaddrinfo (name, NULL, NULL, & resultList) != 0)
+      return -1;
+
+    for (result = resultList; result != NULL; result = result -> ai_next)
+    {
+        if (result -> ai_family == AF_INET && result -> ai_addr != NULL && result -> ai_addrlen >= sizeof (struct sockaddr_in))
+        {
+            struct sockaddr_in * sin = (struct sockaddr_in *) result -> ai_addr;
+
+            address -> host = sin -> sin_addr.s_addr;
+
+            freeaddrinfo (resultList);
+
+            return 0;
+        }
+    }
+
+    if (resultList != NULL)
+      freeaddrinfo (resultList);
+#else
     struct hostent * hostEntry = NULL;
 #ifdef HAS_GETHOSTBYNAME_R
     struct hostent hostData;
@@ -113,19 +145,20 @@ enet_address_set_host (ENetAddress * address, const char * name)
     hostEntry = gethostbyname (name);
 #endif
 
-    if (hostEntry == NULL ||
-        hostEntry -> h_addrtype != AF_INET)
+    if (hostEntry != NULL && hostEntry -> h_addrtype == AF_INET)
     {
-#ifdef HAS_INET_PTON
-        if (! inet_pton (AF_INET, name, & address -> host))
-#else
-        if (! inet_aton (name, (struct in_addr *) & address -> host))
-#endif
-            return -1;
+        address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+
         return 0;
     }
+#endif
 
-    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+#ifdef HAS_INET_PTON
+    if (! inet_pton (AF_INET, name, & address -> host))
+#else
+    if (! inet_aton (name, (struct in_addr *) & address -> host))
+#endif
+        return -1;
 
     return 0;
 }
@@ -153,6 +186,26 @@ enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameL
 int
 enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
 {
+#ifdef HAS_GETNAMEINFO
+    struct sockaddr_in sin;
+    int err;
+
+    memset (& sin, 0, sizeof (struct sockaddr_in));
+
+    sin.sin_family = AF_INET;
+    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+    sin.sin_addr.s_addr = address -> host;
+
+    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 0;
+#else
     struct in_addr in;
     struct hostent * hostEntry = NULL;
 #ifdef HAS_GETHOSTBYADDR_R
@@ -173,17 +226,17 @@ enet_address_get_host (const ENetAddress * address, char * name, size_t nameLeng
     hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
 #endif
 
-    if (hostEntry == NULL)
-      return enet_address_get_host_ip (address, name, nameLength);
-    else
+    if (hostEntry != NULL)
     {
        size_t hostLen = strlen (hostEntry -> h_name);
        if (hostLen >= nameLength)
          return -1;
        memcpy (name, hostEntry -> h_name, hostLen + 1);
+       return 0;
     }
+#endif
 
-    return 0;
+    return enet_address_get_host_ip (address, name, nameLength);
 }
 
 int