]> git.sesse.net Git - vlc/blobdiff - src/network/getaddrinfo.c
Attempt to work-around the Winsock bug-of-the-day
[vlc] / src / network / getaddrinfo.c
index a6ff1fcb9e9d3ad66673ce8acc9ea096830cdef8..76d0f1c19f7818371105b661f17d5ece9016ea20 100644 (file)
@@ -25,7 +25,7 @@
 #include <vlc/vlc.h>
 
 #include <stddef.h> /* size_t */
-#include <string.h> /* strncpy(), strlen(), memcpy(), memset(), strchr() */
+#include <string.h> /* strlen(), memcpy(), memset(), strchr() */
 #include <stdlib.h> /* malloc(), free(), strtoul() */
 #include <errno.h>
 
@@ -175,8 +175,7 @@ __getnameinfo( const struct sockaddr *sa, socklen_t salen,
 
                 if (hent != NULL)
                 {
-                    strncpy (host, hent->h_name, hostlen);
-                    host[hostlen - 1] = '\0';
+                    strlcpy (host, hent->h_name, hostlen);
 
                     /*
                      * only keep first part of hostname
@@ -199,11 +198,8 @@ __getnameinfo( const struct sockaddr *sa, socklen_t salen,
             }
 
             if (!solved)
-            {
                 /* inet_ntoa() can't fail */
-                strncpy (host, inet_ntoa (addr->sin_addr), hostlen);
-                host[hostlen - 1] = '\0';
-            }
+                strlcpy (host, inet_ntoa (addr->sin_addr), hostlen);
         }
 
         if (serv != NULL)
@@ -222,8 +218,7 @@ __getnameinfo( const struct sockaddr *sa, socklen_t salen,
                                      ? "udp" : "tcp");
                 if (sent != NULL)
                 {
-                    strncpy (serv, sent->s_name, servlen);
-                    serv[servlen - 1] = 0;
+                    strlcpy (serv, sent->s_name, servlen);
                     solved = 1;
                 }
             }
@@ -517,7 +512,7 @@ int vlc_getnameinfo( const struct sockaddr *sa, int salen,
      */
     typedef int (CALLBACK * GETNAMEINFO) ( const struct sockaddr*, socklen_t,
                                            char*, DWORD, char*, DWORD, int );
-    HINSTANCE wship6_module;
+    HINSTANCE module;
     GETNAMEINFO ws2_getnameinfo;
 #endif
 
@@ -533,24 +528,24 @@ int vlc_getnameinfo( const struct sockaddr *sa, int salen,
         i_servlen = 0;
     }
 #if defined( WIN32 ) && !defined( UNDER_CE )
-    wship6_module = LoadLibrary( "wship6.dll" );
-    if( wship6_module != NULL )
+    /* Production IPv6 stack releases are in WS2_32.DLL */
+    module = LoadLibrary( "ws2_32.dll" );
+    if( module != NULL )
     {
-        ws2_getnameinfo = (GETNAMEINFO)GetProcAddress( wship6_module,
-                                                       "getnameinfo" );
+        ws2_getnameinfo = (GETNAMEINFO)GetProcAddress( module, "getnameinfo" );
 
         if( ws2_getnameinfo != NULL )
         {
             i_val = ws2_getnameinfo( sa, salen, host, hostlen, psz_serv,
                                      i_servlen, flags );
-            FreeLibrary( wship6_module );
+            FreeLibrary( module );
 
             if( portnum != NULL )
                 *portnum = atoi( psz_serv );
             return i_val;
         }
-            
-        FreeLibrary( wship6_module );
+
+        FreeLibrary( module );
     }
 #endif
 #if defined( HAVE_GETNAMEINFO ) || defined( UNDER_CE )
@@ -559,7 +554,7 @@ int vlc_getnameinfo( const struct sockaddr *sa, int salen,
     {
 # ifdef HAVE_USABLE_MUTEX_THAT_DONT_NEED_LIBVLC_POINTER
         static vlc_value_t lock;
-    
+
         /* my getnameinfo implementation is not thread-safe as it uses
          * gethostbyaddr and the likes */
         vlc_mutex_lock( lock.p_address );
@@ -625,7 +620,7 @@ int vlc_getaddrinfo( vlc_object_t *p_this, const char *node,
 #endif
     }
 
-    /* 
+    /*
      * VLC extensions :
      * - accept "" as NULL
      * - ignore square brackets
@@ -636,8 +631,7 @@ int vlc_getaddrinfo( vlc_object_t *p_this, const char *node,
     }
     else
     {
-        strncpy( psz_buf, node, NI_MAXHOST );
-        psz_buf[NI_MAXHOST - 1] = '\0';
+        strlcpy( psz_buf, node, NI_MAXHOST );
 
         psz_node = psz_buf;
 
@@ -655,30 +649,40 @@ int vlc_getaddrinfo( vlc_object_t *p_this, const char *node,
     }
 
 #if defined( WIN32 ) && !defined( UNDER_CE )
+    typedef int (CALLBACK * GETADDRINFO) (const char *, const char *,
+                                          const struct addrinfo *,
+                                          struct addrinfo **);
+    static GETADDRINFO ws2_getaddrinfo = NULL;
+
+    if (ws2_getaddrinfo == NULL)
     {
-        typedef int (CALLBACK * GETADDRINFO) ( const char *, const char *,
-                                            const struct addrinfo *,
-                                            struct addrinfo ** );
-        HINSTANCE wship6_module;
-        GETADDRINFO ws2_getaddrinfo;
-
-        wship6_module = LoadLibrary( "wship6.dll" );
-        if( wship6_module != NULL )
-        {
-            ws2_getaddrinfo = (GETADDRINFO)GetProcAddress( wship6_module,
-                                                        "getaddrinfo" );
+        static HINSTANCE module = NULL;
 
-            if( ws2_getaddrinfo != NULL )
-            {
-                int i_ret;
+        if (module == NULL)
+            module = LoadLibrary( "ws2_32.dll" );
 
-                i_ret = ws2_getaddrinfo( psz_node, psz_service, &hints, res );
-                FreeLibrary( wship6_module ); /* is this wise ? */
-                return i_ret;
-            }
+        if (module != NULL)
+            ws2_getaddrinfo =
+                    (GETADDRINFO)GetProcAddress (module, "getaddrinfo");
+    }
 
-            FreeLibrary( wship6_module );
+    if (ws2_getaddrinfo != NULL)
+    {
+        /*
+         * Winsock tries to resolve numerical IPv4 addresses as AAAA
+         * and IPv6 addresses as A... There comes the work around.
+         */
+        if ((hints.ai_flags & AI_NUMERICHOST) == 0)
+        {
+            hints.ai_flags |= AI_NUMERICHOST;
+
+            if (ws2_getaddrinfo (psz_node, psz_service, &hints, res) == 0)
+                return 0;
+
+            hints.ai_flags &= ~AI_NUMERICHOST;
         }
+
+        return ws2_getaddrinfo (psz_node, psz_service, &hints, res);
     }
 #endif
 #if defined( HAVE_GETADDRINFO ) || defined( UNDER_CE )
@@ -702,7 +706,8 @@ int vlc_getaddrinfo( vlc_object_t *p_this, const char *node,
             /* NOTE: Using i_idn here would not be thread-safe */
             hints.ai_flags &= ~AI_IDN;
             i_idn = VLC_FALSE;
-            msg_Dbg( p_this, "I18n Domain Names not supported - disabled" );
+            msg_Dbg( p_this, "localized Domain Names not supported - " \
+                "disabled" );
         }
     }
 # endif
@@ -729,27 +734,26 @@ void vlc_freeaddrinfo( struct addrinfo *infos )
 {
 #if defined( WIN32 ) && !defined( UNDER_CE )
     typedef void (CALLBACK * FREEADDRINFO) ( struct addrinfo * );
-    HINSTANCE wship6_module;
+    HINSTANCE module;
     FREEADDRINFO ws2_freeaddrinfo;
      
-    wship6_module = LoadLibrary( "wship6.dll" );
-    if( wship6_module != NULL )
+    module = LoadLibrary( "ws2_32.dll" );
+    if( module != NULL )
     {
-        ws2_freeaddrinfo = (FREEADDRINFO)GetProcAddress( wship6_module,
-                                                         "freeaddrinfo" );
+        ws2_freeaddrinfo = (FREEADDRINFO)GetProcAddress( module, "freeaddrinfo" );
 
         /*
-         * NOTE: it is assumed that wship6.dll defines either both
-         * getaddrinfo and freeaddrinfo or none of them.
+         * NOTE: it is assumed that ws2_32.dll defines either both or neither
+         * getaddrinfo() and freeaddrinfo().
          */
         if( ws2_freeaddrinfo != NULL )
         {
             ws2_freeaddrinfo( infos );
-            FreeLibrary( wship6_module );
+            FreeLibrary( module );
             return;
         }
 
-        FreeLibrary( wship6_module );
+        FreeLibrary( module );
     }
 #endif
 #if defined( HAVE_GETADDRINFO ) || defined( UNDER_CE )