*****************************************************************************/
#include <vlc/vlc.h>
-#include "network.h"
#include <stddef.h> /* size_t */
#include <string.h> /* strncpy(), strlen(), memcpy(), memset(), strchr() */
#endif
#include <errno.h>
-#if defined (UNDER_CE)
-# include <winsock.h>
-#elif defined WIN32
-# include <winsock2.h>
-# include <ws2tcpip.h>
+#if defined( WIN32 ) || defined( UNDER_CE )
+# if defined(UNDER_CE) && defined(sockaddr_storage)
+# undef sockaddr_storage
+# endif
+# include <winsock2.h>
+# include <ws2tcpip.h>
#else
-# include <netdb.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+# endif
+# include <netdb.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
#endif
+#include "network.h"
+
#ifdef SYS_BEOS
-#define NO_ADDRESS NO_DATA
-#define PF_INET AF_INET
-#define INADDR_NONE 0xFFFFFFFF
-#define AF_UNSPEC 0
+# define NO_ADDRESS NO_DATA
+# define PF_INET AF_INET
+# define INADDR_NONE 0xFFFFFFFF
+# define AF_UNSPEC 0
+# define PF_UNSPEC AF_UNSPEC
#endif
-#define _NI_MASK (NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|\
- NI_DGRAM)
-# define _AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)
+#define _NI_MASK (NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|\
+ NI_DGRAM)
+#define _AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)
#ifndef HAVE_GAI_STRERROR
#endif /* if !HAVE_GETADDRINFO */
-int vlc_getnameinfo( vlc_object_t *p_this, const struct sockaddr *sa, int salen,
- char *host, int hostlen, char *serv, int servlen, int flags )
+int vlc_getnameinfo( const struct sockaddr *sa, int salen,
+ char *host, int hostlen, int *portnum, int flags )
{
+ char psz_servbuf[6], *psz_serv;
+ int i_servlen, i_val;
+
+ flags |= NI_NUMERICSERV;
+ if( portnum != NULL )
+ {
+ psz_serv = psz_servbuf;
+ i_servlen = sizeof( psz_servbuf );
+ }
+ else
+ {
+ psz_serv = NULL;
+ i_servlen = 0;
+ }
#ifdef WIN32
/*
* Here is the kind of kludge you need to keep binary compatibility among
if( ws2_getnameinfo != NULL )
{
- int i_val;
-
- i_val = ws2_getnameinfo( sa, salen, host, hostlen, serv, servlen,
- flags );
+ i_val = ws2_getnameinfo( sa, salen, host, hostlen, psz_serv,
+ i_servlen, flags );
FreeLibrary( wship6_module );
+
+ if( portnum != NULL )
+ *portnum = atoi( psz_serv );
return i_val;
}
}
#endif
#if HAVE_GETNAMEINFO
- return getnameinfo( sa, salen, host, hostlen, serv, servlen, flags );
+ i_val = getnameinfo( sa, salen, host, hostlen, psz_serv, i_servlen,
+ flags );
#else
-{
- vlc_value_t lock;
- int i_val;
+ {
+# 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 );
+#else
+# warning FIXME : This is not thread-safe!
+#endif
+ i_val = __getnameinfo( sa, salen, host, hostlen, psz_serv, i_servlen,
+ flags );
+# ifdef HAVE_USABLE_MUTEX_THAT_DONT_NEED_LIBVLC_POINTER
+ vlc_mutex_unlock( lock.p_address );
+# endif
+ }
+#endif
- /* my getnameinfo implementation is not thread-safe as it uses
- * gethostbyaddr and the likes */
- var_Create( p_this->p_libvlc, "getnameinfo_mutex", VLC_VAR_MUTEX );
- var_Get( p_this->p_libvlc, "getnameinfo_mutex", &lock );
- vlc_mutex_lock( lock.p_address );
+ if( portnum != NULL )
+ *portnum = atoi( psz_serv );
- i_val = __getnameinfo( sa, salen, host, hostlen, serv, servlen, flags );
- vlc_mutex_unlock( lock.p_address );
return i_val;
}
-#endif
-}
/* TODO: support for setting sin6_scope_id */
int vlc_getaddrinfo( vlc_object_t *p_this, const char *node,
- const char *service, const struct addrinfo *p_hints,
+ int i_port, const struct addrinfo *p_hints,
struct addrinfo **res )
{
struct addrinfo hints;
- char psz_buf[NI_MAXHOST], *psz_node;
+ char psz_buf[NI_MAXHOST], *psz_node, psz_service[6];
+
+ /*
+ * In VLC, we always use port number as integer rather than strings
+ * for historical reasons (and portability).
+ */
+ if( ( i_port > 65535 ) || ( i_port < 0 ) )
+ {
+ msg_Err( p_this, "invalid port number %d specified", i_port );
+ return EAI_SERVICE;
+ }
+
+ /* cannot overflow */
+ snprintf( psz_service, 6, "%d", i_port );
/* Check if we have to force ipv4 or ipv6 */
if( p_hints == NULL )
else
memcpy( &hints, p_hints, sizeof( hints ) );
- if( hints.ai_family == AF_UNSPEC )
+ if( hints.ai_family == PF_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;
+ hints.ai_family = PF_INET;
-#ifdef HAVE_INET_PTON
+#ifdef PF_INET6
var_Create( p_this, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Get( p_this, "ipv6", &val );
if( val.b_bool )
- hints.ai_family = AF_INET6;
+ hints.ai_family = PF_INET6;
#endif
}
* - ignore square brackets
*/
if( ( node == NULL ) || (node[0] == '\0' ) )
+ {
psz_node = NULL;
+ }
else
{
strncpy( psz_buf, node, NI_MAXHOST );
}
}
- if( ( service != NULL ) && ( *service == '\0' ) )
- /* We could put NULL, but you can't have both node and service NULL */
- service = "0";
-
#ifdef WIN32
- 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" );
-
- 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 )
{
- int i_ret;
+ ws2_getaddrinfo = (GETADDRINFO)GetProcAddress( wship6_module,
+ "getaddrinfo" );
- i_ret = ws2_getaddrinfo( psz_node, service, &hints, res );
- FreeLibrary( wship6_module ); /* is this wise ? */
- return i_ret;
- }
+ if( ws2_getaddrinfo != NULL )
+ {
+ int i_ret;
- FreeLibrary( wship6_module );
+ i_ret = ws2_getaddrinfo( psz_node, psz_service, &hints, res );
+ FreeLibrary( wship6_module ); /* is this wise ? */
+ return i_ret;
+ }
+
+ FreeLibrary( wship6_module );
+ }
}
#endif
#if HAVE_GETADDRINFO
- return getaddrinfo( psz_node, service, &hints, res );
+ return getaddrinfo( psz_node, psz_service, &hints, res );
#else
{
int i_ret;
var_Get( p_this->p_libvlc, "getaddrinfo_mutex", &lock );
vlc_mutex_lock( lock.p_address );
- i_ret = __getaddrinfo( psz_node, service, &hints, res );
+ i_ret = __getaddrinfo( psz_node, psz_service, &hints, res );
vlc_mutex_unlock( lock.p_address );
return i_ret;
}