X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=include%2Fnetwork.h;h=f49dd60a4e279a9d05e873f949653ba6d6676aca;hb=33bd93a1e8c5f139d4d3e8a13111e1ecc7adb710;hp=f726f482df3de6bb9d2715a993edbc1ec474bb3d;hpb=ecac4600297d2c79d17320eae529861994ebd671;p=vlc diff --git a/include/network.h b/include/network.h index f726f482df..f49dd60a4e 100644 --- a/include/network.h +++ b/include/network.h @@ -20,7 +20,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #ifndef __VLC_NETWORK_H @@ -30,8 +30,16 @@ # if defined(UNDER_CE) && defined(sockaddr_storage) # undef sockaddr_storage # endif +# if defined(UNDER_CE) +# define HAVE_STRUCT_ADDRINFO +# else +# include +# endif # include # include +# define ENETUNREACH WSAENETUNREACH +# define net_errno (WSAGetLastError()) +extern const char *net_strerror( int val ); #else # if HAVE_SYS_SOCKET_H # include @@ -45,8 +53,13 @@ # include # endif # include +# define net_errno errno +# define net_strerror strerror #endif +# ifdef __cplusplus +extern "C" { +# endif /***************************************************************************** * network_socket_t: structure passed to a network plug-in to define the @@ -62,267 +75,17 @@ struct network_socket_t int i_ttl; + int v6only; + /* Return values */ int i_handle; size_t i_mtu; }; -typedef struct -{ - char *psz_protocol; - char *psz_username; - char *psz_password; - char *psz_host; - int i_port; - - char *psz_path; - - char *psz_option; - - char *psz_buffer; /* to be freed */ -} vlc_url_t; - -/***************************************************************************** - * vlc_UrlParse: - ***************************************************************************** - * option : if != 0 then path is split at this char - * - * format [protocol://[login[:password]@]][host[:port]]/path[OPTIONoption] - *****************************************************************************/ -static inline void vlc_UrlParse( vlc_url_t *url, const char *psz_url, - char option ) -{ - char *psz_dup; - char *psz_parse; - char *p; - - url->psz_protocol = NULL; - url->psz_username = NULL; - url->psz_password = NULL; - url->psz_host = NULL; - url->i_port = 0; - url->psz_path = NULL; - url->psz_option = NULL; - - if( psz_url == NULL ) - { - url->psz_buffer = NULL; - return; - } - url->psz_buffer = psz_parse = psz_dup = strdup( psz_url ); - - p = strstr( psz_parse, ":/" ); - if( p != NULL ) - { - /* we have a protocol */ - - /* skip :// */ - *p++ = '\0'; - if( p[1] == '/' ) - p += 2; - url->psz_protocol = psz_parse; - psz_parse = p; - } - p = strchr( psz_parse, '@' ); - if( p != NULL ) - { - /* We have a login */ - url->psz_username = psz_parse; - *p++ = '\0'; - - psz_parse = strchr( psz_parse, ':' ); - if( psz_parse != NULL ) - { - /* We have a password */ - *psz_parse++ = '\0'; - url->psz_password = psz_parse; - } - - psz_parse = p; - } - - p = strchr( psz_parse, '/' ); - if( !p || psz_parse < p ) - { - char *p2; - - /* We have a host[:port] */ - url->psz_host = strdup( psz_parse ); - if( p ) - { - url->psz_host[p - psz_parse] = '\0'; - } - - if( *url->psz_host == '[' ) - { - /* Ipv6 address */ - p2 = strchr( url->psz_host, ']' ); - if( p2 ) - { - p2 = strchr( p2, ':' ); - } - } - else - { - p2 = strchr( url->psz_host, ':' ); - } - if( p2 ) - { - *p2++ = '\0'; - url->i_port = atoi( p2 ); - } - } - psz_parse = p; - - /* Now parse psz_path and psz_option */ - if( psz_parse ) - { - url->psz_path = psz_parse; - if( option != '\0' ) - { - p = strchr( url->psz_path, option ); - if( p ) - { - *p++ = '\0'; - url->psz_option = p; - } - } - } -} - -/***************************************************************************** - * vlc_UrlClean: - ***************************************************************************** - * - *****************************************************************************/ -static inline void vlc_UrlClean( vlc_url_t *url ) -{ - if( url->psz_buffer ) free( url->psz_buffer ); - if( url->psz_host ) free( url->psz_host ); - - url->psz_protocol = NULL; - url->psz_username = NULL; - url->psz_password = NULL; - url->psz_host = NULL; - url->i_port = 0; - url->psz_path = NULL; - url->psz_option = NULL; - - url->psz_buffer = NULL; -} - -/***************************************************************************** - * vlc_UrlEncode: - ***************************************************************************** - * perform URL encoding - * (you do NOT want to do URL decoding - it is not reversible - do NOT do it) - *****************************************************************************/ -static inline char *vlc_UrlEncode( const char *psz_url ) -{ - char *psz_enc, *out; - const char *in; - - psz_enc = (char *)malloc( 3 * strlen( psz_url ) + 1 ); - if( psz_enc == NULL ) - return NULL; - - out = psz_enc; - for( in = psz_url; *in; in++ ) - { - char c = *in; - - if( ( c <= 32 ) || ( c == '%' ) || ( c == '?' ) || ( c == '&' ) - || ( c == '+' ) ) - { - *out++ = '%'; - *out++ = ( ( c >> 4 ) >= 0xA ) ? 'A' + ( c >> 4 ) - 0xA - : '0' + ( c >> 4 ); - *out++ = ( ( c & 0xf ) >= 0xA ) ? 'A' + ( c & 0xf ) - 0xA - : '0' + ( c & 0xf ); - } - else - *out++ = c; - } - *out++ = '\0'; - - return (char *)realloc( psz_enc, out - psz_enc ); -} - -/***************************************************************************** - * vlc_UrlIsNotEncoded: - ***************************************************************************** - * check if given string is not a valid URL and must hence be encoded - *****************************************************************************/ -#include - -static inline int vlc_UrlIsNotEncoded( const char *psz_url ) -{ - const char *ptr; - - for( ptr = psz_url; *ptr; ptr++ ) - { - char c = *ptr; - - if( c == '%' ) - { - if( !isxdigit( ptr[1] ) || !isxdigit( ptr[2] ) ) - return 1; /* not encoded */ - ptr += 2; - } - else - if( c == ' ' ) - return 1; - } - return 0; /* looks fine - but maybe it is not encoded */ -} - -/***************************************************************************** - * vlc_b64_encode: - ***************************************************************************** - * - *****************************************************************************/ -static inline char *vlc_b64_encode( char *src ) -{ - static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - char *dst = (char *)malloc( strlen( src ) * 4 / 3 + 12 ); - char *ret = dst; - unsigned i_bits = 0; - unsigned i_shift = 0; - - for( ;; ) - { - if( *src ) - { - i_bits = ( i_bits << 8 )|( *src++ ); - i_shift += 8; - } - else if( i_shift > 0 ) - { - i_bits <<= 6 - i_shift; - i_shift = 6; - } - else - { - *dst++ = '='; - break; - } - - while( i_shift >= 6 ) - { - i_shift -= 6; - *dst++ = b64[(i_bits >> i_shift)&0x3f]; - } - } - - *dst++ = '\0'; - - return ret; -} - /* Portable networking layer communication */ -#define net_OpenTCP(a, b, c) __net_OpenTCP(VLC_OBJECT(a), b, c) -VLC_EXPORT( int, __net_OpenTCP, ( vlc_object_t *p_this, const char *psz_host, int i_port ) ); +#define net_ConnectTCP(a, b, c) __net_ConnectTCP(VLC_OBJECT(a), b, c) +#define net_OpenTCP(a, b, c) __net_ConnectTCP(VLC_OBJECT(a), b, c) +VLC_EXPORT( int, __net_ConnectTCP, ( vlc_object_t *p_this, const char *psz_host, int i_port ) ); #define net_ListenTCP(a, b, c) __net_ListenTCP(VLC_OBJECT(a), b, c) VLC_EXPORT( int *, __net_ListenTCP, ( vlc_object_t *, const char *, int ) ); @@ -330,12 +93,16 @@ VLC_EXPORT( int *, __net_ListenTCP, ( vlc_object_t *, const char *, int ) ); #define net_Accept(a, b, c) __net_Accept(VLC_OBJECT(a), b, c) VLC_EXPORT( int, __net_Accept, ( vlc_object_t *, int *, mtime_t ) ); +#define net_ConnectUDP(a, b, c, d ) __net_ConnectUDP(VLC_OBJECT(a), b, c, d) +VLC_EXPORT( int, __net_ConnectUDP, ( vlc_object_t *p_this, const char *psz_host, int i_port, int hlim ) ); + #define net_OpenUDP(a, b, c, d, e ) __net_OpenUDP(VLC_OBJECT(a), b, c, d, e) VLC_EXPORT( int, __net_OpenUDP, ( vlc_object_t *p_this, const char *psz_bind, int i_bind, const char *psz_server, int i_server ) ); VLC_EXPORT( void, net_Close, ( int fd ) ); VLC_EXPORT( void, net_ListenClose, ( int *fd ) ); +VLC_EXPORT( int, net_SetDSCP, ( int fd, uint8_t dscp ) ); /* Functions to read from or write to the networking layer */ struct virtual_socket_t @@ -346,24 +113,24 @@ struct virtual_socket_t }; #define net_Read(a,b,c,d,e,f) __net_Read(VLC_OBJECT(a),b,c,d,e,f) -VLC_EXPORT( int, __net_Read, ( vlc_object_t *p_this, int fd, v_socket_t *, uint8_t *p_data, int i_data, vlc_bool_t b_retry ) ); +VLC_EXPORT( int, __net_Read, ( vlc_object_t *p_this, int fd, const v_socket_t *, uint8_t *p_data, int i_data, vlc_bool_t b_retry ) ); #define net_ReadNonBlock(a,b,c,d,e,f) __net_ReadNonBlock(VLC_OBJECT(a),b,c,d,e,f) -VLC_EXPORT( int, __net_ReadNonBlock, ( vlc_object_t *p_this, int fd, v_socket_t *, uint8_t *p_data, int i_data, mtime_t i_wait ) ); +VLC_EXPORT( int, __net_ReadNonBlock, ( vlc_object_t *p_this, int fd, const v_socket_t *, uint8_t *p_data, int i_data, mtime_t i_wait ) ); #define net_Select(a,b,c,d,e,f,g) __net_Select(VLC_OBJECT(a),b,c,d,e,f,g) -VLC_EXPORT( int, __net_Select, ( vlc_object_t *p_this, int *pi_fd, v_socket_t **, int i_fd, uint8_t *p_data, int i_data, mtime_t i_wait ) ); +VLC_EXPORT( int, __net_Select, ( vlc_object_t *p_this, const int *pi_fd, const v_socket_t *const *, int i_fd, uint8_t *p_data, int i_data, mtime_t i_wait ) ); #define net_Write(a,b,c,d,e) __net_Write(VLC_OBJECT(a),b,c,d,e) -VLC_EXPORT( int, __net_Write, ( vlc_object_t *p_this, int fd, v_socket_t *, uint8_t *p_data, int i_data ) ); +VLC_EXPORT( int, __net_Write, ( vlc_object_t *p_this, int fd, const v_socket_t *, const uint8_t *p_data, int i_data ) ); #define net_Gets(a,b,c) __net_Gets(VLC_OBJECT(a),b,c) -VLC_EXPORT( char *, __net_Gets, ( vlc_object_t *p_this, int fd, v_socket_t * ) ); +VLC_EXPORT( char *, __net_Gets, ( vlc_object_t *p_this, int fd, const v_socket_t * ) ); -VLC_EXPORT( int, net_Printf, ( vlc_object_t *p_this, int fd, v_socket_t *, const char *psz_fmt, ... ) ); +VLC_EXPORT( int, net_Printf, ( vlc_object_t *p_this, int fd, const v_socket_t *, const char *psz_fmt, ... ) ); #define net_vaPrintf(a,b,c,d,e) __net_vaPrintf(VLC_OBJECT(a),b,c,d,e) -VLC_EXPORT( int, __net_vaPrintf, ( vlc_object_t *p_this, int fd, v_socket_t *, const char *psz_fmt, va_list args ) ); +VLC_EXPORT( int, __net_vaPrintf, ( vlc_object_t *p_this, int fd, const v_socket_t *, const char *psz_fmt, va_list args ) ); #if !HAVE_INET_PTON @@ -386,7 +153,9 @@ int inet_pton(int af, const char *src, void *dst); # define net_StopSend( fd ) (void)shutdown( fd, SD_SEND ) # define net_StopRecv( fd ) (void)shutdown( fd, SD_RECEIVE ) #else -# warning FIXME: implement shutdown on your platform! +# ifndef SYS_BEOS /* R5 just doesn't have a working shutdown() */ +# warning FIXME: implement shutdown on your platform! +# endif # define net_StopSend( fd ) (void)0 # define net_StopRecv( fd ) (void)0 #endif @@ -460,12 +229,6 @@ struct addrinfo # define AI_NUMERICHOST 4 # endif /* if !HAVE_STRUCT_ADDRINFO */ -/*** libidn support ***/ -# ifndef AI_IDN -# define AI_IDN 0 -# define AI_CANONIDN 0 -# endif - VLC_EXPORT( const char *, vlc_gai_strerror, ( int ) ); VLC_EXPORT( int, vlc_getnameinfo, ( const struct sockaddr *, int, char *, int, int *, int ) ); VLC_EXPORT( int, vlc_getaddrinfo, ( vlc_object_t *, const char *, int, const struct addrinfo *, struct addrinfo ** ) ); @@ -475,7 +238,7 @@ VLC_EXPORT( void, vlc_freeaddrinfo, ( struct addrinfo * ) ); * net_AddressIsMulticast: This function returns VLC_FALSE if the psz_addr does * not specify a multicast address or if the address is not a valid address. *****************************************************************************/ -static inline vlc_bool_t net_AddressIsMulticast( vlc_object_t *p_object, char *psz_addr ) +static inline vlc_bool_t net_AddressIsMulticast( vlc_object_t *p_object, const char *psz_addr ) { struct addrinfo hints, *res; vlc_bool_t b_multicast = VLC_FALSE; @@ -489,11 +252,11 @@ static inline vlc_bool_t net_AddressIsMulticast( vlc_object_t *p_object, char *p &hints, &res ); if( i ) { - msg_Err( p_object, "Invalid node for net_AddressIsMulticast: %s : %s", + msg_Err( p_object, "invalid address for net_AddressIsMulticast: %s : %s", psz_addr, vlc_gai_strerror( i ) ); return VLC_FALSE; } - + if( res->ai_family == AF_INET ) { #if !defined( SYS_BEOS ) @@ -502,14 +265,14 @@ static inline vlc_bool_t net_AddressIsMulticast( vlc_object_t *p_object, char *p && ( ntohl( v4->sin_addr.s_addr ) <= 0xefffffff ); #endif } +#if defined( WIN32 ) || defined( HAVE_GETADDRINFO ) else if( res->ai_family == AF_INET6 ) { -#if defined( WIN32 ) || defined( HAVE_GETADDRINFO ) struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)res->ai_addr; b_multicast = IN6_IS_ADDR_MULTICAST( &v6->sin6_addr ); -#endif } - +#endif + vlc_freeaddrinfo( res ); return b_multicast; } @@ -519,7 +282,7 @@ static inline int net_GetSockAddress( int fd, char *address, int *port ) struct sockaddr_storage addr; socklen_t addrlen = sizeof( addr ); - return getpeername( fd, (struct sockaddr *)&addr, &addrlen ) + return getsockname( fd, (struct sockaddr *)&addr, &addrlen ) || vlc_getnameinfo( (struct sockaddr *)&addr, addrlen, address, NI_MAXNUMERICHOST, port, NI_NUMERICHOST ) ? VLC_EGENERIC : 0; @@ -536,4 +299,8 @@ static inline int net_GetPeerAddress( int fd, char *address, int *port ) ? VLC_EGENERIC : 0; } +# ifdef __cplusplus +} +# endif + #endif