]> git.sesse.net Git - vlc/blobdiff - src/network/getaddrinfo.c
playlist: Handle vlc_InputItemErrorWhenReadingChanged events.
[vlc] / src / network / getaddrinfo.c
index 35c584e9d4d46ae6983f844a8b4be9938ca56969..b57f8caf191196d409aa60891f8c7da5957b350b 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
 
 #include <stddef.h> /* size_t */
 #include <string.h> /* strlen(), memcpy(), memset(), strchr() */
 
 
 #ifndef HAVE_GAI_STRERROR
-static struct
+static const struct
 {
-    int code;
-    const char *msg;
-} const __gai_errlist[] =
+    int        code;
+    const char msg[41];
+} gai_errlist[] =
 {
     { 0,              "Error 0" },
     { EAI_BADFLAGS,   "Invalid flag used" },
@@ -75,21 +79,21 @@ static struct
     { EAI_MEMORY,     "Memory allocation failure" },
     { EAI_OVERFLOW,   "Buffer overflow" },
     { EAI_SYSTEM,     "System error" },
-    { 0,              NULL }
+    { 0,              "" },
 };
 
-static const char *__gai_unknownerr = "Unrecognized error number";
+static const char gai_unknownerr[] = "Unrecognized error number";
 
 /****************************************************************************
  * Converts an EAI_* error code into human readable english text.
  ****************************************************************************/
 const char *vlc_gai_strerror (int errnum)
 {
-    for (unsigned i = 0; __gai_errlist[i].msg != NULL; i++)
-        if (errnum == __gai_errlist[i].code)
-            return __gai_errlist[i].msg;
+    for (unsigned i = 0; *gai_errlist[i].msg; i++)
+        if (errnum == gai_errlist[i].code)
+            return gai_errlist[i].msg;
 
-    return __gai_unknownerr;
+    return gai_unknownerr;
 }
 #else /* ifndef HAVE_GAI_STRERROR */
 const char *vlc_gai_strerror (int errnum)
@@ -103,7 +107,7 @@ const char *vlc_gai_strerror (int errnum)
                   NI_DGRAM)
 /*
  * getnameinfo() non-thread-safe IPv4-only implementation,
- * Address-family-independant address to hostname translation
+ * Address-family-independent address to hostname translation
  * (reverse DNS lookup in case of IPv4).
  *
  * This is meant for use on old IP-enabled systems that are not IPv6-aware,
@@ -118,7 +122,7 @@ static int WSAAPI
 getnameinfo (const struct sockaddr *sa, socklen_t salen,
              char *host, DWORD hostlen, char *serv, DWORD servlen, int flags)
 #else
-static int 
+static int
 getnameinfo (const struct sockaddr *sa, socklen_t salen,
              char *host, int hostlen, char *serv, int servlen, int flags)
 #endif
@@ -277,7 +281,7 @@ makeipv4info (int type, int proto, u_long ip, u_short port, const char *name)
 
 /*
  * getaddrinfo() non-thread-safe IPv4-only implementation
- * Address-family-independant hostname to address resolution.
+ * Address-family-independent hostname to address resolution.
  *
  * This is meant for IPv6-unaware systems that do probably not provide
  * getaddrinfo(), but still have old function gethostbyname().
@@ -289,7 +293,7 @@ static int WSAAPI
 getaddrinfo (const char *node, const char *service,
              const struct addrinfo *hints, struct addrinfo **res)
 #else
-static int 
+static int
 getaddrinfo (const char *node, const char *service,
              const struct addrinfo *hints, struct addrinfo **res)
 #endif
@@ -398,7 +402,7 @@ getaddrinfo (const char *node, const char *service,
         port = 0;
     else
     {
-        long d;
+        unsigned long d;
         char *end;
 
         d = strtoul (service, &end, 0);
@@ -490,7 +494,7 @@ static WSAAPI int _ws2_getnameinfo_bind( const struct sockaddr FAR * sa, socklen
     if (entry == NULL)
     {
         /* not found, use replacement API instead */
-       entry = getnameinfo;
+    entry = getnameinfo;
 
     }
     /* call API before replacing function pointer to avoid crash */
@@ -514,8 +518,8 @@ static WSAAPI int _ws2_getaddrinfo_bind(const char FAR *node, const char FAR *se
     if ((entry == NULL) ||  (freentry == NULL))
     {
         /* not found, use replacement API instead */
-       entry = getaddrinfo;
-       freentry = freeaddrinfo;
+    entry = getaddrinfo;
+    freentry = freeaddrinfo;
     }
     /* call API before replacing function pointer to avoid crash */
     result = entry (node, service, hints, res);
@@ -583,31 +587,44 @@ int vlc_getaddrinfo( vlc_object_t *p_this, const char *node,
     memset (&hints, 0, sizeof (hints));
     if (p_hints != NULL)
     {
+        const int safe_flags =
+            AI_PASSIVE |
+            AI_CANONNAME |
+            AI_NUMERICHOST |
+            AI_NUMERICSERV |
+#ifdef AI_ALL
+            AI_ALL |
+#endif
+#ifdef AI_ADDRCONFIG
+            AI_ADDRCONFIG |
+#endif
+#ifdef AI_V4MAPPED
+            AI_V4MAPPED |
+#endif
+            0;
+
         hints.ai_family = p_hints->ai_family;
         hints.ai_socktype = p_hints->ai_socktype;
         hints.ai_protocol = p_hints->ai_protocol;
-        hints.ai_flags = p_hints->ai_flags & (AI_NUMERICHOST|AI_PASSIVE|AI_CANONNAME);
+        /* Unfortunately, some flags chang the layout of struct addrinfo, so
+         * they cannot be copied blindly from p_hints to &hints. Therefore, we
+         * only copy flags that we know for sure are "safe".
+         */
+        hints.ai_flags = p_hints->ai_flags & safe_flags;
     }
-#ifdef AI_NUMERICSERV
-    /* we only ever use port *numbers* */
+
+    /* We only ever use port *numbers* */
     hints.ai_flags |= AI_NUMERICSERV;
-#endif
 
     if( hints.ai_family == AF_UNSPEC )
     {
-        vlc_value_t val;
-
-        var_Create( p_this, "ipv4", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-        var_Get( p_this, "ipv4", &val );
-        if( val.b_bool )
-            hints.ai_family = AF_INET;
-
 #ifdef AF_INET6
-        var_Create( p_this, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-        var_Get( p_this, "ipv6", &val );
-        if( val.b_bool )
+        if (var_CreateGetBool (p_this, "ipv6"))
             hints.ai_family = AF_INET6;
+        else
 #endif
+        if (var_CreateGetBool (p_this, "ipv4"))
+            hints.ai_family = AF_INET;
     }
 
     /*
@@ -653,38 +670,17 @@ int vlc_getaddrinfo( vlc_object_t *p_this, const char *node,
         hints.ai_flags &= ~AI_NUMERICHOST;
     }
 #endif
-#if defined (HAVE_GETADDRINFO)
-# ifdef AI_IDN
+#ifdef AI_IDN
     /* Run-time I18n Domain Names support */
-    static vlc_bool_t b_idn = VLC_TRUE; /* beware of thread-safety */
-
-    if (b_idn)
-    {
-        hints.ai_flags |= AI_IDN;
-        int ret = getaddrinfo (psz_node, psz_service, &hints, res);
-
-        if (ret != EAI_BADFLAGS)
-            return ret;
-
-        /* IDN not available: disable and retry without it */
-        hints.ai_flags &= ~AI_IDN;
-        b_idn = VLC_FALSE;
-        msg_Info (p_this, "International Domain Names not supported");
-    }
-# endif
-    return getaddrinfo (psz_node, psz_service, &hints, res);
-#else
-    int ret;
-    vlc_value_t lock;
-
-    var_Create (p_this->p_libvlc, "getaddrinfo_mutex", VLC_VAR_MUTEX);
-    var_Get (p_this->p_libvlc, "getaddrinfo_mutex", &lock);
-    vlc_mutex_lock (lock.p_address);
+    hints.ai_flags |= AI_IDN;
+    int ret = getaddrinfo (psz_node, psz_service, &hints, res);
+    if (ret != EAI_BADFLAGS)
+        return ret;
 
-    ret = getaddrinfo (psz_node, psz_service, &hints, res);
-    vlc_mutex_unlock (lock.p_address);
-    return ret;
+    /* IDN not available: disable and retry without it */
+    hints.ai_flags &= ~AI_IDN;
 #endif
+    return getaddrinfo (psz_node, psz_service, &hints, res);
 }