/*****************************************************************************
* getaddrinfo.c: getaddrinfo/getnameinfo replacement functions
*****************************************************************************
- * Copyright (C) 2005 VideoLAN
+ * Copyright (C) 2005 VideoLAN (Centrale Réseaux) and its contributors
* Copyright (C) 2002-2004 Rémi Denis-Courmont
* $Id$
*
#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 INADDR_NONE 0xFFFFFFFF
+# define AF_UNSPEC 0
#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
addr.sin_port = port;
addr.sin_addr.s_addr = ip;
- return makeaddrinfo (PF_INET, type, proto,
+ return makeaddrinfo (AF_INET, type, proto,
(struct sockaddr*)&addr, sizeof (addr), name);
}
#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 )
if( val.b_bool )
hints.ai_family = AF_INET;
-#ifdef HAVE_INET_PTON
+#ifdef AF_INET6
var_Create( p_this, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Get( p_this, "ipv6", &val );
if( val.b_bool )
* - 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 *,
{
int i_ret;
- i_ret = ws2_getaddrinfo( psz_node, service, &hints, res );
+ i_ret = ws2_getaddrinfo( psz_node, psz_service, &hints, res );
FreeLibrary( wship6_module ); /* is this wise ? */
return i_ret;
}
}
#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;
}