📄 getaddrinfo.c
字号:
protocol = IPPROTO_TCP; break; case SOCK_DGRAM: protocol = IPPROTO_UDP; break;#ifndef SYS_BEOS case SOCK_RAW:#endif case 0: break; default: return EAI_SOCKTYPE; } if (hints->ai_protocol && protocol && (protocol != hints->ai_protocol)) return EAI_SERVICE; } *res = NULL; /* default values */ if (node == NULL) { if (flags & AI_PASSIVE) ip = htonl (INADDR_ANY); else ip = htonl (INADDR_LOOPBACK); } else if ((ip = inet_addr (node)) == INADDR_NONE) { struct hostent *entry = NULL; /* hostname resolution */ if (!(flags & AI_NUMERICHOST)) entry = gethostbyname (node); if (entry == NULL) return EAI_NONAME; if ((entry->h_length != 4) || (entry->h_addrtype != AF_INET)) return EAI_FAMILY; ip = *((u_long *) entry->h_addr); if (flags & AI_CANONNAME) name = entry->h_name; } if ((flags & AI_CANONNAME) && (name == NULL)) name = node; /* service resolution */ if (service == NULL) port = 0; else { long d; char *end; d = strtoul (service, &end, 0); if (end[0] /* service is not a number */ || (d > 65535)) { struct servent *entry; const char *protoname; switch (protocol) { case IPPROTO_TCP: protoname = "tcp"; break; case IPPROTO_UDP: protoname = "udp"; break; default: protoname = NULL; } entry = getservbyname (service, protoname); if (entry == NULL) return EAI_SERVICE; port = entry->s_port; } else port = htons ((u_short)d); } /* building results... */ if ((!protocol) || (protocol == IPPROTO_UDP)) { info = makeipv4info (SOCK_DGRAM, IPPROTO_UDP, ip, port, name); if (info == NULL) { errno = ENOMEM; return EAI_SYSTEM; } if (flags & AI_PASSIVE) info->ai_flags |= AI_PASSIVE; *res = info; } if ((!protocol) || (protocol == IPPROTO_TCP)) { info = makeipv4info (SOCK_STREAM, IPPROTO_TCP, ip, port, name); if (info == NULL) { errno = ENOMEM; return EAI_SYSTEM; } info->ai_next = *res; if (flags & AI_PASSIVE) info->ai_flags |= AI_PASSIVE; *res = info; } return 0;}#endif /* if !HAVE_GETADDRINFO */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;#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 ); HINSTANCE module; GETNAMEINFO ws2_getnameinfo;#endif flags |= NI_NUMERICSERV; if( portnum != NULL ) { psz_serv = psz_servbuf; i_servlen = sizeof( psz_servbuf ); } else { psz_serv = NULL; i_servlen = 0; }#if defined( WIN32 ) && !defined( UNDER_CE ) /* Production IPv6 stack releases are in WS2_32.DLL */ module = LoadLibrary( "ws2_32.dll" ); if( module != NULL ) { ws2_getnameinfo = (GETNAMEINFO)GetProcAddress( module, "getnameinfo" ); if( ws2_getnameinfo != NULL ) { i_val = ws2_getnameinfo( sa, salen, host, hostlen, psz_serv, i_servlen, flags ); FreeLibrary( module ); if( portnum != NULL ) *portnum = atoi( psz_serv ); return i_val; } FreeLibrary( module ); }#endif#if defined( HAVE_GETNAMEINFO ) || defined( UNDER_CE ) i_val = getnameinfo(sa, salen, host, hostlen, psz_serv, i_servlen, flags);#else {# 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 if( portnum != NULL ) *portnum = atoi( psz_serv ); return i_val;}/* 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 ){ struct addrinfo hints; 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 ) memset( &hints, 0, sizeof( hints ) ); else memcpy( &hints, p_hints, sizeof( hints ) ); 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 ) hints.ai_family = AF_INET6;#endif } /* * VLC extensions : * - accept "" as NULL * - ignore square brackets */ if( ( node == NULL ) || (node[0] == '\0' ) ) { psz_node = NULL; } else { strlcpy( psz_buf, node, NI_MAXHOST ); psz_node = psz_buf; if( psz_buf[0] == '[' ) { char *ptr; ptr = strrchr( psz_buf, ']' ); if( ( ptr != NULL ) && (ptr[1] == '\0' ) ) { *ptr = '\0'; psz_node++; } } }#if defined( WIN32 ) && !defined( UNDER_CE ) { typedef int (CALLBACK * GETADDRINFO) ( const char *, const char *, const struct addrinfo *, struct addrinfo ** ); HINSTANCE module; GETADDRINFO ws2_getaddrinfo; module = LoadLibrary( "ws2_32.dll" ); if( module != NULL ) { ws2_getaddrinfo = (GETADDRINFO)GetProcAddress( module, "getaddrinfo" ); if( ws2_getaddrinfo != NULL ) { int i_ret; i_ret = ws2_getaddrinfo( psz_node, psz_service, &hints, res ); FreeLibrary( module ); /* is this wise ? */ return i_ret; } FreeLibrary( module ); } }#endif#if defined( HAVE_GETADDRINFO ) || defined( UNDER_CE )# ifdef AI_IDN /* Run-time I18n Domain Names support */ { static vlc_bool_t i_idn = VLC_TRUE; /* beware of thread-safety */ if( i_idn ) { int i_ret; hints.ai_flags |= AI_IDN; i_ret = getaddrinfo( psz_node, psz_service, &hints, res ); if( i_ret != EAI_BADFLAGS ) return i_ret; /* libidn not available: disable and retry without it */ /* NOTE: Using i_idn here would not be thread-safe */ hints.ai_flags &= ~AI_IDN; i_idn = VLC_FALSE; msg_Dbg( p_this, "localized Domain Names not supported - " \ "disabled" ); } }# endif return getaddrinfo( psz_node, psz_service, &hints, res );#else{ int i_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 ); i_ret = __getaddrinfo( psz_node, psz_service, &hints, res ); vlc_mutex_unlock( lock.p_address ); return i_ret;}#endif}void vlc_freeaddrinfo( struct addrinfo *infos ){#if defined( WIN32 ) && !defined( UNDER_CE ) typedef void (CALLBACK * FREEADDRINFO) ( struct addrinfo * ); HINSTANCE module; FREEADDRINFO ws2_freeaddrinfo; module = LoadLibrary( "ws2_32.dll" ); if( module != NULL ) { ws2_freeaddrinfo = (FREEADDRINFO)GetProcAddress( module, "freeaddrinfo" ); /* * NOTE: it is assumed that ws2_32.dll defines either both or neither * getaddrinfo() and freeaddrinfo(). */ if( ws2_freeaddrinfo != NULL ) { ws2_freeaddrinfo( infos ); FreeLibrary( module ); return; } FreeLibrary( module ); }#endif#if defined( HAVE_GETADDRINFO ) || defined( UNDER_CE ) freeaddrinfo( infos );#else __freeaddrinfo( infos );#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -