Commit 8cec5b21 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

vlc_inet_pton: use getaddrinfo, should fix #1824

parent 95404003
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
# include "config.h" # include "config.h"
#endif #endif
#define _WIN32_WINNT 0x0501
#include <vlc_common.h> #include <vlc_common.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -558,62 +559,38 @@ ssize_t __net_vaPrintf( vlc_object_t *p_this, int fd, const v_socket_t *p_vs, ...@@ -558,62 +559,38 @@ ssize_t __net_vaPrintf( vlc_object_t *p_this, int fd, const v_socket_t *p_vs,
int vlc_inet_pton(int af, const char *src, void *dst) int vlc_inet_pton(int af, const char *src, void *dst)
{ {
#ifndef HAVE_INET_PTON #ifndef HAVE_INET_PTON
# ifdef WIN32 /* Windows Vista has inet_pton(), but not XP. */
/* As we already know, Microsoft always go its own way, so even if they do /* We have a pretty good example of abstraction inversion here... */
* provide IPv6, they don't provide the API. */ struct addrinfo hints = {
struct sockaddr_storage addr; .ai_family = af,
int len = sizeof( addr ); .ai_socktype = SOCK_DGRAM, /* make sure we have... */
.ai_protocol = IPPROTO_UDP, /* ...only one response */
/* Damn it, they didn't even put LPCSTR for the firs parameter!!! */ .ai_flags = AI_NUMERICHOST,
#ifdef UNICODE }, *res;
wchar_t *workaround_for_ill_designed_api =
malloc( MAX_PATH * sizeof(wchar_t) ); if (getaddrinfo (src, NULL, &hints, &res))
mbstowcs( workaround_for_ill_designed_api, src, MAX_PATH );
workaround_for_ill_designed_api[MAX_PATH-1] = 0;
#else
char *workaround_for_ill_designed_api = strdup( src );
#endif
if( WSAStringToAddress( workaround_for_ill_designed_api, af, NULL,
(LPSOCKADDR)&addr, &len ) )
{
free( workaround_for_ill_designed_api );
return -1; return -1;
}
free( workaround_for_ill_designed_api );
switch( af ) const void *data;
{ size_t len;
case AF_INET6:
memcpy( dst, &((struct sockaddr_in6 *)&addr)->sin6_addr, 16 );
break;
switch (af)
{
case AF_INET: case AF_INET:
memcpy( dst, &((struct sockaddr_in *)&addr)->sin_addr, 4 ); data = &((const struct sockaddr_in *)res->ai_addr)->sin_addr;
len = 4;
break; break;
#ifdef AF_INET6
case AF_INET6:
data = &((const struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
len = 16;
break;
#endif
default: default:
WSASetLastError( WSAEAFNOSUPPORT );
return -1;
}
# else
/* Assume IPv6 is not supported. */
/* Would be safer and more simpler to use inet_aton() but it is most
* likely not provided either. */
uint32_t ipv4;
if( af != AF_INET )
{
errno = EAFNOSUPPORT; errno = EAFNOSUPPORT;
return -1; return -1;
} }
memcpy (dst, data, len);
ipv4 = inet_addr( src );
if( ipv4 == INADDR_NONE )
return -1;
memcpy( dst, &ipv4, 4 );
# endif /* WIN32 */
return 0; return 0;
#else /* HAVE_INET_PTON */ #else /* HAVE_INET_PTON */
return inet_pton( af, src, dst ); return inet_pton( af, src, dst );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment