Commit 3fd2bd46 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

- Kludge to be able to use strerror() with Winsock

  (should fix IPv6 error reporting on Win32)
- Some cleanup
parent a066d5a9
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Mathias Kretschmer <mathias@research.att.com> * Mathias Kretschmer <mathias@research.att.com>
* Alexis de Lattre <alexis@via.ecp.fr> * Alexis de Lattre <alexis@via.ecp.fr>
* Rémi Denis-Courmont <rem # videolan.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -84,7 +85,7 @@ ...@@ -84,7 +85,7 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int NetOpen( vlc_object_t * ); static int OpenUDP( vlc_object_t * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -96,11 +97,11 @@ static int NetOpen( vlc_object_t * ); ...@@ -96,11 +97,11 @@ static int NetOpen( vlc_object_t * );
vlc_module_begin(); vlc_module_begin();
set_shortname( "IPv4" ); set_shortname( "IPv4" );
set_description( _("IPv4 network abstraction layer") ); set_description( _("UDP/IPv4 network abstraction layer") );
set_capability( "network", 50 ); set_capability( "network", 50 );
set_category( CAT_INPUT ); set_category( CAT_INPUT );
set_subcategory( SUBCAT_INPUT_ADVANCED ); set_subcategory( SUBCAT_INPUT_ADVANCED );
set_callbacks( NetOpen, NULL ); set_callbacks( OpenUDP, NULL );
add_string( "miface-addr", NULL, NULL, MIFACE_TEXT, MIFACE_LONGTEXT, VLC_TRUE ); add_string( "miface-addr", NULL, NULL, MIFACE_TEXT, MIFACE_LONGTEXT, VLC_TRUE );
vlc_module_end(); vlc_module_end();
...@@ -145,21 +146,33 @@ static int BuildAddr( struct sockaddr_in * p_socket, ...@@ -145,21 +146,33 @@ static int BuildAddr( struct sockaddr_in * p_socket,
return( 0 ); return( 0 );
} }
#if defined(WIN32) || defined(UNDER_CE)
# define WINSOCK_STRERROR_SIZE 20
static const char *winsock_strerror( char *buf )
{
snprintf( buf, WINSOCK_STRERROR_SIZE, "Winsock error %d",
WSAGetLastError( ) );
buf[WINSOCK_STRERROR_SIZE - 1] = '\0';
return buf;
}
#endif
/***************************************************************************** /*****************************************************************************
* OpenUDP: open a UDP socket * OpenUDP: open a UDP socket
***************************************************************************** *****************************************************************************
* psz_bind_addr, i_bind_port : address and port used for the bind() * psz_bind_addr, i_bind_port : address and port used for the bind()
* system call. If psz_bind_addr == "", the socket is bound to * system call. If psz_bind_addr == "", the socket is bound to
* INADDR_ANY and broadcast reception is enabled. If i_bind_port == 0, * INADDR_ANY and broadcast reception is enabled. If psz_bind_addr is a
* 1234 is used. If psz_bind_addr is a multicast (class D) address, * multicast (class D) address, join the multicast group.
* join the multicast group.
* psz_server_addr, i_server_port : address and port used for the connect() * psz_server_addr, i_server_port : address and port used for the connect()
* system call. It can avoid receiving packets from unauthorized IPs. * system call. It can avoid receiving packets from unauthorized IPs.
* Its use leads to great confusion and is currently discouraged. * Its use leads to great confusion and is currently discouraged.
* This function returns -1 in case of error. * This function returns -1 in case of error.
*****************************************************************************/ *****************************************************************************/
static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) static int OpenUDP( vlc_object_t * p_this )
{ {
network_socket_t * p_socket = p_this->p_private;
const char * psz_bind_addr = p_socket->psz_bind_addr; const char * psz_bind_addr = p_socket->psz_bind_addr;
int i_bind_port = p_socket->i_bind_port; int i_bind_port = p_socket->i_bind_port;
const char * psz_server_addr = p_socket->psz_server_addr; const char * psz_server_addr = p_socket->psz_server_addr;
...@@ -168,6 +181,10 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -168,6 +181,10 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
int i_handle, i_opt; int i_handle, i_opt;
struct sockaddr_in sock; struct sockaddr_in sock;
vlc_value_t val; vlc_value_t val;
#if defined(WIN32) || defined(UNDER_CE)
char strerror_buf[WINSOCK_STRERROR_SIZE];
# define strerror( x ) winsock_strerror( strerror_buf )
#endif
/* If IP_ADD_SOURCE_MEMBERSHIP is not defined in the headers /* If IP_ADD_SOURCE_MEMBERSHIP is not defined in the headers
(because it's not in glibc for example), we have to define the (because it's not in glibc for example), we have to define the
...@@ -185,11 +202,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -185,11 +202,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
* protocol */ * protocol */
if( (i_handle = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 ) if( (i_handle = socket( AF_INET, SOCK_DGRAM, 0 )) == -1 )
{ {
#if defined(WIN32) || defined(UNDER_CE)
msg_Warn( p_this, "cannot create socket (%i)", WSAGetLastError() );
#else
msg_Warn( p_this, "cannot create socket (%s)", strerror(errno) ); msg_Warn( p_this, "cannot create socket (%s)", strerror(errno) );
#endif
return( -1 ); return( -1 );
} }
...@@ -198,13 +211,8 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -198,13 +211,8 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
if( setsockopt( i_handle, SOL_SOCKET, SO_REUSEADDR, if( setsockopt( i_handle, SOL_SOCKET, SO_REUSEADDR,
(void *) &i_opt, sizeof( i_opt ) ) == -1 ) (void *) &i_opt, sizeof( i_opt ) ) == -1 )
{ {
#if defined(WIN32) || defined(UNDER_CE)
msg_Warn( p_this, "cannot configure socket (SO_REUSEADDR: %i)",
WSAGetLastError() );
#else
msg_Warn( p_this, "cannot configure socket (SO_REUSEADDR: %s)", msg_Warn( p_this, "cannot configure socket (SO_REUSEADDR: %s)",
strerror(errno)); strerror(errno));
#endif
close( i_handle ); close( i_handle );
return( -1 ); return( -1 );
} }
...@@ -222,17 +230,11 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -222,17 +230,11 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
* packet loss caused by scheduling problems */ * packet loss caused by scheduling problems */
i_opt = 0x80000; i_opt = 0x80000;
#if !defined( SYS_BEOS ) #if !defined( SYS_BEOS )
if( setsockopt( i_handle, SOL_SOCKET, SO_RCVBUF, (void *) &i_opt, sizeof( i_opt ) ) == -1 ) if( setsockopt( i_handle, SOL_SOCKET, SO_RCVBUF, (void *) &i_opt,
{ sizeof( i_opt ) ) == -1 )
#if defined(WIN32) || defined(UNDER_CE)
msg_Dbg( p_this, "cannot configure socket (SO_RCVBUF: %i)",
WSAGetLastError() );
#else
msg_Dbg( p_this, "cannot configure socket (SO_RCVBUF: %s)", msg_Dbg( p_this, "cannot configure socket (SO_RCVBUF: %s)",
strerror(errno)); strerror(errno));
#endif #endif
}
#endif
/* Build the local socket */ /* Build the local socket */
...@@ -253,11 +255,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -253,11 +255,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
/* Bind it */ /* Bind it */
if( bind( i_handle, (struct sockaddr *)&sock, sizeof( sock ) ) < 0 ) if( bind( i_handle, (struct sockaddr *)&sock, sizeof( sock ) ) < 0 )
{ {
#if defined(WIN32) || defined(UNDER_CE)
msg_Warn( p_this, "cannot bind socket (%i)", WSAGetLastError() );
#else
msg_Warn( p_this, "cannot bind socket (%s)", strerror(errno) ); msg_Warn( p_this, "cannot bind socket (%s)", strerror(errno) );
#endif
close( i_handle ); close( i_handle );
return( -1 ); return( -1 );
} }
...@@ -280,16 +278,10 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -280,16 +278,10 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
if( !*psz_bind_addr ) if( !*psz_bind_addr )
{ {
i_opt = 1; i_opt = 1;
if( setsockopt( i_handle, SOL_SOCKET, SO_BROADCAST, (void*) &i_opt, sizeof( i_opt ) ) == -1 ) if( setsockopt( i_handle, SOL_SOCKET, SO_BROADCAST, (void*) &i_opt,
{ sizeof( i_opt ) ) == -1 )
#if defined(WIN32) || defined(UNDER_CE)
msg_Warn( p_this, "cannot configure socket (SO_BROADCAST: %i)",
WSAGetLastError() );
#else
msg_Warn( p_this, "cannot configure socket (SO_BROADCAST: %s)", msg_Warn( p_this, "cannot configure socket (SO_BROADCAST: %s)",
strerror(errno) ); strerror(errno) );
#endif
}
} }
#endif #endif
...@@ -327,13 +319,8 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -327,13 +319,8 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
(char*)&imr, (char*)&imr,
sizeof(struct ip_mreq_source) ) == -1 ) sizeof(struct ip_mreq_source) ) == -1 )
{ {
#if defined(WIN32) || defined(UNDER_CE)
msg_Err( p_this, "failed to join IP multicast group (%i)",
WSAGetLastError() );
#else
msg_Err( p_this, "failed to join IP multicast group (%s)", msg_Err( p_this, "failed to join IP multicast group (%s)",
strerror(errno) ); strerror(errno) );
#endif
msg_Err( p_this, "are you sure your OS supports IGMPv3?" ); msg_Err( p_this, "are you sure your OS supports IGMPv3?" );
close( i_handle ); close( i_handle );
return( -1 ); return( -1 );
...@@ -361,13 +348,8 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -361,13 +348,8 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_MEMBERSHIP, if( setsockopt( i_handle, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char*)&imr, sizeof(struct ip_mreq) ) == -1 ) (char*)&imr, sizeof(struct ip_mreq) ) == -1 )
{ {
#if defined(WIN32) || defined(UNDER_CE)
msg_Err( p_this, "failed to join IP multicast group (%i)",
WSAGetLastError() );
#else
msg_Err( p_this, "failed to join IP multicast group (%s)", msg_Err( p_this, "failed to join IP multicast group (%s)",
strerror(errno) ); strerror(errno) );
#endif
close( i_handle ); close( i_handle );
return( -1 ); return( -1 );
} }
...@@ -389,11 +371,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -389,11 +371,7 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
if( connect( i_handle, (struct sockaddr *) &sock, if( connect( i_handle, (struct sockaddr *) &sock,
sizeof( sock ) ) == (-1) ) sizeof( sock ) ) == (-1) )
{ {
#if defined(WIN32) || defined(UNDER_CE)
msg_Warn( p_this, "cannot connect socket (%i)", WSAGetLastError());
#else
msg_Warn( p_this, "cannot connect socket (%s)", strerror(errno) ); msg_Warn( p_this, "cannot connect socket (%s)", strerror(errno) );
#endif
close( i_handle ); close( i_handle );
return( -1 ); return( -1 );
} }
...@@ -465,15 +443,6 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -465,15 +443,6 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
var_Get( p_this, "mtu", &val ); var_Get( p_this, "mtu", &val );
} }
p_socket->i_mtu = val.i_int; p_socket->i_mtu = val.i_int;
return( 0 );
}
/*****************************************************************************
* NetOpen: wrapper around OpenUDP, ListenTCP and OpenTCP
*****************************************************************************/
static int NetOpen( vlc_object_t * p_this )
{
network_socket_t * p_socket = p_this->p_private;
return OpenUDP( p_this, p_socket ); return 0;
} }
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Authors: Alexis Guillard <alexis.guillard@bt.com> * Authors: Alexis Guillard <alexis.guillard@bt.com>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
* Remco Poortinga <poortinga@telin.nl> * Remco Poortinga <poortinga@telin.nl>
* Rémi Denis-Courmont <rem # videolan.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -89,7 +90,7 @@ static int OpenUDP( vlc_object_t * ); ...@@ -89,7 +90,7 @@ static int OpenUDP( vlc_object_t * );
* Module descriptor * Module descriptor
*****************************************************************************/ *****************************************************************************/
vlc_module_begin(); vlc_module_begin();
set_description( _("IPv6 network abstraction layer") ); set_description( _("UDP/IPv6 network abstraction layer") );
set_capability( "network", 40 ); set_capability( "network", 40 );
set_callbacks( OpenUDP, NULL ); set_callbacks( OpenUDP, NULL );
vlc_module_end(); vlc_module_end();
...@@ -127,14 +128,25 @@ static int BuildAddr( vlc_object_t *p_this, struct sockaddr_in6 *p_socket, ...@@ -127,14 +128,25 @@ static int BuildAddr( vlc_object_t *p_this, struct sockaddr_in6 *p_socket,
return 0; return 0;
} }
#if defined(WIN32) || defined(UNDER_CE)
# define WINSOCK_STRERROR_SIZE 20
static const char *winsock_strerror( char *buf )
{
snprintf( buf, WINSOCK_STRERROR_SIZE, "Winsock error %d",
WSAGetLastError( ) );
buf[WINSOCK_STRERROR_SIZE - 1] = '\0';
return buf;
}
#endif
/***************************************************************************** /*****************************************************************************
* OpenUDP: open a UDP socket * OpenUDP: open a UDP socket
***************************************************************************** *****************************************************************************
* psz_bind_addr, i_bind_port : address and port used for the bind() * psz_bind_addr, i_bind_port : address and port used for the bind()
* system call. If psz_bind_addr == NULL, the socket is bound to * system call. If psz_bind_addr == NULL, the socket is bound to
* in6addr_any and broadcast reception is enabled. If i_bind_port == 0, * in6addr_any and broadcast reception is enabled. If psz_bind_addr is a
* 1234 is used. If psz_bind_addr is a multicast (class D) address, * multicast (FF00::/8) address, join the multicast group.
* join the multicast group.
* psz_server_addr, i_server_port : address and port used for the connect() * psz_server_addr, i_server_port : address and port used for the connect()
* system call. It can avoid receiving packets from unauthorized IPs. * system call. It can avoid receiving packets from unauthorized IPs.
* Its use leads to great confusion and is currently discouraged. * Its use leads to great confusion and is currently discouraged.
...@@ -150,6 +162,10 @@ static int OpenUDP( vlc_object_t * p_this ) ...@@ -150,6 +162,10 @@ static int OpenUDP( vlc_object_t * p_this )
int i_handle, i_opt; int i_handle, i_opt;
struct sockaddr_in6 sock; struct sockaddr_in6 sock;
vlc_value_t val; vlc_value_t val;
#if defined(WIN32) || defined(UNDER_CE)
char strerror_buf[WINSOCK_STRERROR_SIZE];
# define strerror( x ) winsock_strerror( strerror_buf )
#endif
/* Open a SOCK_DGRAM (UDP) socket, in the AF_INET6 domain, automatic (0) /* Open a SOCK_DGRAM (UDP) socket, in the AF_INET6 domain, automatic (0)
* protocol */ * protocol */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment