X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fnetwork%2Fudp.c;h=5af1c0b634774a0851d4bc9b8acf7156dee058fb;hb=4d636fa3a74924691b0bb1e26e600f7657e0af5c;hp=8f6a18f499d88591a0e38ce8c78f815bda576f71;hpb=3c56e7abe9f8ab23ffd69bd8c1a2d38ce9efa6b6;p=vlc diff --git a/src/network/udp.c b/src/network/udp.c index 8f6a18f499..5af1c0b634 100644 --- a/src/network/udp.c +++ b/src/network/udp.c @@ -35,10 +35,6 @@ #include -#ifdef HAVE_SYS_TIME_H -# include -#endif - #include #ifdef WIN32 @@ -146,18 +142,20 @@ static int net_ListenSingle (vlc_object_t *obj, const char *host, int port, memset (&hints, 0, sizeof( hints )); hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = protocol; hints.ai_flags = AI_PASSIVE; if (host && !*host) host = NULL; - msg_Dbg (obj, "net: opening %s datagram port %d", host ?: "any", port); + msg_Dbg (obj, "net: opening %s datagram port %d", + host ? host : "any", port); int val = vlc_getaddrinfo (obj, host, port, &hints, &res); if (val) { msg_Err (obj, "Cannot resolve %s port %d : %s", host, port, - vlc_gai_strerror (val)); + gai_strerror (val)); return -1; } @@ -166,24 +164,28 @@ static int net_ListenSingle (vlc_object_t *obj, const char *host, int port, for (const struct addrinfo *ptr = res; ptr != NULL; ptr = ptr->ai_next) { int fd = net_Socket (obj, ptr->ai_family, ptr->ai_socktype, - protocol ?: ptr->ai_protocol); + ptr->ai_protocol); if (fd == -1) { msg_Dbg (obj, "socket error: %m"); continue; } - if (ptr->ai_next != NULL) - { #ifdef IPV6_V6ONLY - if ((ptr->ai_family != AF_INET6) - || setsockopt (fd, SOL_IPV6, IPV6_V6ONLY, &(int){ 0 }, - sizeof (int))) + /* If IPv6 was forced, set IPv6-only mode. + * If IPv4 was forced, do nothing extraordinary. + * If nothing was forced, try dual-mode IPv6. */ + if (ptr->ai_family == AF_INET6) + { + int on = (family == AF_INET6); + setsockopt (fd, SOL_IPV6, IPV6_V6ONLY, &on, sizeof (on)); + } + if (ptr->ai_family == AF_INET) #endif - { - msg_Err (obj, "Multiple network protocols present"); - msg_Err (obj, "Please select network protocol manually"); - } + if (family == AF_UNSPEC && ptr->ai_next != NULL) + { + msg_Warn (obj, "ambiguous network protocol specification"); + msg_Warn (obj, "please select IP version explicitly"); } fd = net_SetupDgramSocket( obj, fd, ptr ); @@ -201,7 +203,7 @@ static int net_ListenSingle (vlc_object_t *obj, const char *host, int port, break; } - vlc_freeaddrinfo (res); + freeaddrinfo (res); return val; } @@ -242,9 +244,13 @@ static int net_SetMcastHopLimit( vlc_object_t *p_this, /* BSD compatibility */ unsigned char buf; + msg_Dbg( p_this, "cannot set hop limit (%d): %m", hlim ); buf = (unsigned char)(( hlim > 255 ) ? 255 : hlim); if( setsockopt( fd, proto, cmd, &buf, sizeof( buf ) ) ) + { + msg_Err( p_this, "cannot set hop limit (%d): %m", hlim ); return VLC_EGENERIC; + } } return VLC_SUCCESS; @@ -628,25 +634,26 @@ static int net_SetDSCP( int fd, uint8_t dscp ) return setsockopt( fd, level, cmd, &(int){ dscp }, sizeof (int)); } - +#undef net_ConnectDgram /***************************************************************************** - * __net_ConnectDgram: + * net_ConnectDgram: ***************************************************************************** * Open a datagram socket to send data to a defined destination, with an * optional hop limit. *****************************************************************************/ -int __net_ConnectDgram( vlc_object_t *p_this, const char *psz_host, int i_port, - int i_hlim, int proto ) +int net_ConnectDgram( vlc_object_t *p_this, const char *psz_host, int i_port, + int i_hlim, int proto ) { struct addrinfo hints, *res, *ptr; int i_val, i_handle = -1; bool b_unreach = false; - if( i_hlim < 1 ) + if( i_hlim < 0 ) i_hlim = var_CreateGetInteger( p_this, "ttl" ); memset( &hints, 0, sizeof( hints ) ); hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = proto; msg_Dbg( p_this, "net: connecting to [%s]:%d", psz_host, i_port ); @@ -654,7 +661,7 @@ int __net_ConnectDgram( vlc_object_t *p_this, const char *psz_host, int i_port, if( i_val ) { msg_Err( p_this, "cannot resolve [%s]:%d : %s", psz_host, i_port, - vlc_gai_strerror( i_val ) ); + gai_strerror( i_val ) ); return -1; } @@ -662,7 +669,7 @@ int __net_ConnectDgram( vlc_object_t *p_this, const char *psz_host, int i_port, { char *str; int fd = net_Socket (p_this, ptr->ai_family, ptr->ai_socktype, - proto ?: ptr->ai_protocol); + ptr->ai_protocol); if (fd == -1) continue; @@ -676,7 +683,7 @@ int __net_ConnectDgram( vlc_object_t *p_this, const char *psz_host, int i_port, setsockopt (fd, SOL_SOCKET, SO_BROADCAST, &(int){ 1 }, sizeof (int)); #endif - if( i_hlim > 0 ) + if( i_hlim >= 0 ) net_SetMcastHopLimit( p_this, fd, ptr->ai_family, i_hlim ); str = var_CreateGetNonEmptyString (p_this, "miface"); @@ -716,7 +723,7 @@ int __net_ConnectDgram( vlc_object_t *p_this, const char *psz_host, int i_port, } } - vlc_freeaddrinfo( res ); + freeaddrinfo( res ); if( i_handle == -1 ) { @@ -729,15 +736,15 @@ int __net_ConnectDgram( vlc_object_t *p_this, const char *psz_host, int i_port, return i_handle; } - +#undef net_OpenDgram /***************************************************************************** - * __net_OpenDgram: + * net_OpenDgram: ***************************************************************************** * OpenDgram a datagram socket and return a handle *****************************************************************************/ -int __net_OpenDgram( vlc_object_t *obj, const char *psz_bind, int i_bind, - const char *psz_server, int i_server, - int family, int protocol ) +int net_OpenDgram( vlc_object_t *obj, const char *psz_bind, int i_bind, + const char *psz_server, int i_server, + int family, int protocol ) { if ((psz_server == NULL) || (psz_server[0] == '\0')) return net_ListenSingle (obj, psz_bind, i_bind, family, protocol); @@ -751,12 +758,13 @@ int __net_OpenDgram( vlc_object_t *obj, const char *psz_bind, int i_bind, memset (&hints, 0, sizeof (hints)); hints.ai_family = family; hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = protocol; val = vlc_getaddrinfo (obj, psz_server, i_server, &hints, &rem); if (val) { msg_Err (obj, "cannot resolve %s port %d : %s", psz_bind, i_bind, - vlc_gai_strerror (val)); + gai_strerror (val)); return -1; } @@ -765,15 +773,15 @@ int __net_OpenDgram( vlc_object_t *obj, const char *psz_bind, int i_bind, if (val) { msg_Err (obj, "cannot resolve %s port %d : %s", psz_bind, i_bind, - vlc_gai_strerror (val)); - vlc_freeaddrinfo (rem); + gai_strerror (val)); + freeaddrinfo (rem); return -1; } for (struct addrinfo *ptr = loc; ptr != NULL; ptr = ptr->ai_next) { int fd = net_Socket (obj, ptr->ai_family, ptr->ai_socktype, - protocol ?: ptr->ai_protocol); + ptr->ai_protocol); if (fd == -1) continue; // usually, address family not supported @@ -809,8 +817,8 @@ int __net_OpenDgram( vlc_object_t *obj, const char *psz_bind, int i_bind, net_Close (fd); } - vlc_freeaddrinfo (rem); - vlc_freeaddrinfo (loc); + freeaddrinfo (rem); + freeaddrinfo (loc); return val; }