}
#endif
-#ifndef WIN32
-#if !(defined (HAVE_GETNAMEINFO) && defined (HAVE_GETADDRINFO))
-/*
- * Converts the current herrno error value into an EAI_* error code.
- * That error code is normally returned by getnameinfo() or getaddrinfo().
- */
-static int
-gai_error_from_herrno (void)
-{
- switch (h_errno)
- {
- case HOST_NOT_FOUND:
- return EAI_NONAME;
-
- case NO_ADDRESS:
-# if (NO_ADDRESS != NO_DATA)
- case NO_DATA:
-# endif
- return EAI_NODATA;
-
- case NO_RECOVERY:
- return EAI_FAIL;
-
- case TRY_AGAIN:
- return EAI_AGAIN;
- }
- return EAI_SYSTEM;
-}
-#endif /* if !(HAVE_GETNAMEINFO && HAVE_GETADDRINFO) */
-
#ifndef HAVE_GETNAMEINFO
/*
* getnameinfo() non-thread-safe IPv4-only implementation,
#endif /* if !HAVE_GETNAMEINFO */
#ifndef HAVE_GETADDRINFO
+/*
+ * Converts the current herrno error value into an EAI_* error code.
+ * That error code is normally returned by getnameinfo() or getaddrinfo().
+ */
+static int
+gai_error_from_herrno (void)
+{
+ switch (h_errno)
+ {
+ case HOST_NOT_FOUND:
+ return EAI_NONAME;
+
+ case NO_ADDRESS:
+# if (NO_ADDRESS != NO_DATA)
+ case NO_DATA:
+# endif
+ return EAI_NODATA;
+
+ case NO_RECOVERY:
+ return EAI_FAIL;
+
+ case TRY_AGAIN:
+ return EAI_AGAIN;
+ }
+ return EAI_SYSTEM;
+}
+
/*
* This functions must be used to free the memory allocated by getaddrinfo().
*/
entry = gethostbyname (node);
if (entry == NULL)
- return EAI_NONAME;
+ return gai_error_from_herrno ();
if ((entry->h_length != 4) || (entry->h_addrtype != AF_INET))
return EAI_FAMILY;
return 0;
}
#endif /* if !HAVE_GETADDRINFO */
-#endif
#if defined( WIN32 ) && !defined( UNDER_CE )
/*
* Here is the kind of kludge you need to keep binary compatibility among
* varying OS versions...
*/
-typedef int (CALLBACK * GETNAMEINFO) ( const struct sockaddr*, socklen_t,
- char*, DWORD, char*, DWORD, int );
-typedef int (CALLBACK * GETADDRINFO) (const char *, const char *,
- const struct addrinfo *,
- struct addrinfo **);
+typedef int (WSAAPI * GETNAMEINFO) ( const struct sockaddr FAR *, socklen_t,
+ char FAR *, DWORD, char FAR *, DWORD, int );
+typedef int (WSAAPI * GETADDRINFO) (const char FAR *, const char FAR *,
+ const struct addrinfo FAR *,
+ struct addrinfo FAR * FAR *);
-typedef void (CALLBACK * FREEADDRINFO) ( struct addrinfo * );
+typedef void (WSAAPI * FREEADDRINFO) ( struct addrinfo FAR * );
-
-static WINAPI int _ws2_getnameinfo_bind( const struct sockaddr *sa, socklen_t salen,
- char *host, DWORD hostlen, char *serv, DWORD servlen, int flags );
-
-static WINAPI int _ws2_getaddrinfo_bind(const char *node, const char *service,
- const struct addrinfo *hints, struct addrinfo **res);
-
-static WINAPI void _ws2_freeaddrinfo_bind( struct addrinfo *infos );
+static int WSAAPI _ws2_getnameinfo_bind ( const struct sockaddr FAR *, socklen_t,
+ char FAR *, DWORD, char FAR *, DWORD, int );
+static int WSAAPI _ws2_getaddrinfo_bind (const char FAR *, const char FAR *,
+ const struct addrinfo FAR *,
+ struct addrinfo FAR * FAR *);
static GETNAMEINFO ws2_getnameinfo = _ws2_getnameinfo_bind;
static GETADDRINFO ws2_getaddrinfo = _ws2_getaddrinfo_bind;
-static FREEADDRINFO ws2_freeaddrinfo = _ws2_freeaddrinfo_bind;
+static FREEADDRINFO ws2_freeaddrinfo;
-static int _ws2_find_ipv6_api(void)
+static FARPROC ws2_find_api (LPCTSTR name)
{
- /* For Windows XP and above, IPv6 stack is in WS2_32.DLL */
- HINSTANCE module = LoadLibrary( "ws2_32.dll" );
- if( module != NULL )
- {
- ws2_getnameinfo = (GETNAMEINFO)GetProcAddress( module, "getnameinfo" );
- ws2_getaddrinfo = (GETADDRINFO)GetProcAddress( module, "getaddrinfo" );
- ws2_freeaddrinfo = (FREEADDRINFO)GetProcAddress( module, "freeaddrinfo" );
- if( ws2_getnameinfo && ws2_getaddrinfo && ws2_freeaddrinfo )
- {
- /* got them */
- return 1;
- }
- FreeLibrary( module );
+ FARPROC f = NULL;
- /* For Windows 2000 and below, try IPv6 stack in in WSHIP6.DLL */
- module = LoadLibrary( "wship6.dll" );
- if( module != NULL )
- {
- ws2_getnameinfo = (GETNAMEINFO)GetProcAddress( module, "getnameinfo" );
- ws2_getaddrinfo = (GETADDRINFO)GetProcAddress( module, "getaddrinfo" );
- ws2_freeaddrinfo = (FREEADDRINFO)GetProcAddress( module, "freeaddrinfo" );
- if( ws2_getnameinfo && ws2_getaddrinfo && ws2_freeaddrinfo )
- {
- /* got them */
- return 1;
- }
- FreeLibrary( module );
- }
+ HMODULE m = GetModuleHandle (TEXT("WS2_32"));
+ if (m != NULL)
+ f = GetProcAddress (m, name);
+
+ if (f == NULL)
+ {
+ /* Windows 2K IPv6 preview */
+ m = LoadLibrary (TEXT("WSHIP6"));
+ if (m != NULL)
+ f = GetProcAddress (m, name);
}
- /* no API */
- return 0;
+
+ return f;
}
-static WINAPI int _ws2_getnameinfo_bind( const struct sockaddr *sa, socklen_t salen,
- char *host, DWORD hostlen, char *serv, DWORD servlen, int flags )
+static WSAAPI int _ws2_getnameinfo_bind( const struct sockaddr FAR * sa, socklen_t salen,
+ char FAR *host, DWORD hostlen, char FAR *serv, DWORD servlen, int flags )
{
- if( _ws2_find_ipv6_api() )
+ GETNAMEINFO entry = (GETNAMEINFO)ws2_find_api (TEXT("getnameinfo"));
+ if (entry != NULL)
{
- return ws2_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
+ /* call API before replacing function pointer to avoid crash */
+ int result = entry (sa, salen, host, hostlen, serv, servlen, flags);
+ ws2_getnameinfo = entry;
+ return result;
}
- /* return a possible error if API is not found */
- WSASetLastError(WSAHOST_NOT_FOUND);
- return WSAHOST_NOT_FOUND;
+ return getnameinfo (sa, salen, host, hostlen, serv, servlen, flags);
}
+#undef getnameinfo
+#define getnameinfo ws2_getnameinfo
-static WINAPI int _ws2_getaddrinfo_bind(const char *node, const char *service,
- const struct addrinfo *hints, struct addrinfo **res)
+/* So much for using different calling conventions */
+static WSAAPI void call_freeaddrinfo (struct addrinfo *infos)
{
- if( _ws2_find_ipv6_api() )
- {
- return ws2_getaddrinfo(node, service, hints, res);
- }
- /* return a possible error if API is not found */
- WSASetLastError(WSAHOST_NOT_FOUND);
- return WSAHOST_NOT_FOUND;
+ freeaddrinfo (infos);
}
-static WINAPI void _ws2_freeaddrinfo_bind( struct addrinfo *infos )
+static WSAAPI int _ws2_getaddrinfo_bind(const char FAR *node, const char FAR *service,
+ const struct addrinfo FAR *hints, struct addrinfo FAR * FAR *res)
{
- if( _ws2_find_ipv6_api() )
+ GETADDRINFO entry;
+ FREEADDRINFO freentry;
+
+ entry = (GETADDRINFO)ws2_find_api (TEXT("getaddrinfo"));
+ freentry = (FREEADDRINFO)ws2_find_api (TEXT("freeaddrinfo"));
+
+ if ((entry != NULL) && (freentry != NULL))
{
- ws2_freeaddrinfo(infos);
+ /* call API before replacing function pointer to avoid crash */
+ int result = entry (node, service, hints, res);
+ ws2_freeaddrinfo = freentry;
+ ws2_getaddrinfo = entry;
+ return result;
}
+ ws2_freeaddrinfo = call_freeaddrinfo;
+ return getaddrinfo (node, service, hints, res);
}
-
+#undef getaddrinfo
+#undef freeaddrinfo
+#define getaddrinfo ws2_getaddrinfo
+#define freeaddrinfo ws2_freeaddrinfo
+#define HAVE_GETADDRINFO
#endif
i_servlen = 0;
}
-#if defined (HAVE_GETNAMEINFO)
i_val = getnameinfo(sa, salen, host, hostlen, psz_serv, i_servlen, flags);
-#elif defined (WIN32)
- i_val = ws2_getnameinfo (sa, salen, host, hostlen, psz_serv, i_servlen, flags);
-#else
- i_val = __getnameinfo (sa, salen, host, hostlen, psz_serv, i_servlen, flags);
-#endif
if( portnum != NULL )
*portnum = atoi( psz_serv );
}
-/* TODO: support for setting sin6_scope_id */
int vlc_getaddrinfo( vlc_object_t *p_this, const char *node,
int i_port, const struct addrinfo *p_hints,
struct addrinfo **res )
#ifdef WIN32
/*
* Winsock tries to resolve numerical IPv4 addresses as AAAA
- * and IPv6 addresses as A... There comes the work around.
+ * and IPv6 addresses as A... There comes the bug-to-bug fix.
*/
if ((hints.ai_flags & AI_NUMERICHOST) == 0)
{
hints.ai_flags |= AI_NUMERICHOST;
- if (ws2_getaddrinfo (psz_node, psz_service, &hints, res) == 0)
+ if (getaddrinfo (psz_node, psz_service, &hints, res) == 0)
return 0;
hints.ai_flags &= ~AI_NUMERICHOST;
}
# endif
return getaddrinfo (psz_node, psz_service, &hints, res);
-#elif defined (WIN32)
- return ws2_getaddrinfo (psz_node, psz_service, &hints, res);
#else
int ret;
vlc_value_t lock;
var_Get (p_this->p_libvlc, "getaddrinfo_mutex", &lock);
vlc_mutex_lock (lock.p_address);
- int ret = __getaddrinfo (psz_node, psz_service, &hints, res);
+ ret = getaddrinfo (psz_node, psz_service, &hints, res);
vlc_mutex_unlock (lock.p_address);
return ret;
#endif
void vlc_freeaddrinfo( struct addrinfo *infos )
{
-#if defined (HAVE_GETADDRINFO)
freeaddrinfo (infos);
-#elif defined (WIN32)
- ws2_freeaddrinfo (infos);
-#else
- __freeaddrinfo( infos );
-#endif
}