Commit e34b5beb authored by Clément Stenac's avatar Clément Stenac

Patch by Rémi Denis-Courmont to include TCP listening sockets in the abstraction layer

parent ae605781
...@@ -46,6 +46,7 @@ struct network_socket_t ...@@ -46,6 +46,7 @@ struct network_socket_t
/* Socket types */ /* Socket types */
#define NETWORK_UDP 1 #define NETWORK_UDP 1
#define NETWORK_TCP 2 #define NETWORK_TCP 2
#define NETWORK_TCP_PASSIVE 3
typedef struct typedef struct
...@@ -165,6 +166,9 @@ static inline void vlc_UrlClean( vlc_url_t *url ) ...@@ -165,6 +166,9 @@ static inline void vlc_UrlClean( vlc_url_t *url )
#define net_OpenTCP(a, b, c) __net_OpenTCP(VLC_OBJECT(a), b, c) #define net_OpenTCP(a, b, c) __net_OpenTCP(VLC_OBJECT(a), b, c)
VLC_EXPORT( int, __net_OpenTCP, ( vlc_object_t *p_this, char *psz_host, int i_port ) ); VLC_EXPORT( int, __net_OpenTCP, ( vlc_object_t *p_this, 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 *p_this, char *psz_localaddr, int i_port ) );
#define net_OpenUDP(a, b, c, d, e ) __net_OpenUDP(VLC_OBJECT(a), b, c, d, e) #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, char *psz_bind, int i_bind, char *psz_server, int i_server ) ); VLC_EXPORT( int, __net_OpenUDP, ( vlc_object_t *p_this, char *psz_bind, int i_bind, char *psz_server, int i_server ) );
......
...@@ -49,17 +49,8 @@ ...@@ -49,17 +49,8 @@
# include <winsock.h> # include <winsock.h>
#elif defined( WIN32 ) #elif defined( WIN32 )
# include <winsock2.h> # include <winsock2.h>
# include <ws2tcpip.h>
# ifndef IN_MULTICAST
# define IN_MULTICAST(a) IN_CLASSD(a)
# endif
#else #else
# include <netdb.h> /* hostent ... */
# include <sys/socket.h> # include <sys/socket.h>
# include <netinet/in.h>
# ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h> /* inet_ntoa(), inet_aton() */
# endif
#endif #endif
#include "network.h" #include "network.h"
...@@ -72,8 +63,6 @@ ...@@ -72,8 +63,6 @@
#define SOCKET_CLOSE(a) close(a) #define SOCKET_CLOSE(a) close(a)
#endif #endif
#define LISTEN_BACKLOG 100
#define READ_MODE_PWD 1 #define READ_MODE_PWD 1
#define READ_MODE_CMD 2 #define READ_MODE_CMD 2
#define WRITE_MODE_PWD 3 // when we write the word "Password:" #define WRITE_MODE_PWD 3 // when we write the word "Password:"
...@@ -127,7 +116,6 @@ typedef struct ...@@ -127,7 +116,6 @@ typedef struct
static char* MessageToString( vlm_message_t* , int ); static char* MessageToString( vlm_message_t* , int );
static void Write_message( telnet_client_t * , vlm_message_t* , char * , int ); static void Write_message( telnet_client_t * , vlm_message_t* , char * , int );
static int SocketListen( intf_thread_t * , int );
struct intf_sys_t struct intf_sys_t
{ {
...@@ -159,7 +147,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -159,7 +147,7 @@ static int Open( vlc_object_t *p_this )
p_intf->pf_run = Run; p_intf->pf_run = Run;
p_intf->p_sys = malloc( sizeof( intf_sys_t ) ); p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
if( ( p_intf->p_sys->fd = SocketListen( p_intf , i_telnetport ) ) < 0 ) if( ( p_intf->p_sys->fd = net_ListenTCP( p_intf , "", i_telnetport ) ) < 0 )
{ {
msg_Err( p_intf, "cannot listen for telnet" ); msg_Err( p_intf, "cannot listen for telnet" );
free( p_intf->p_sys ); free( p_intf->p_sys );
...@@ -207,7 +195,6 @@ static void Run( intf_thread_t *p_intf ) ...@@ -207,7 +195,6 @@ static void Run( intf_thread_t *p_intf )
{ {
intf_sys_t *p_sys = p_intf->p_sys; intf_sys_t *p_sys = p_intf->p_sys;
struct timeval timeout; struct timeval timeout;
int i_sock_size = sizeof( struct sockaddr_in );
char *s_password; char *s_password;
s_password = config_GetPsz( p_intf, "telnet-password" ); s_password = config_GetPsz( p_intf, "telnet-password" );
...@@ -218,13 +205,12 @@ static void Run( intf_thread_t *p_intf ) ...@@ -218,13 +205,12 @@ static void Run( intf_thread_t *p_intf )
fd_set fds_write; fd_set fds_write;
int i_handle_max = 0; int i_handle_max = 0;
int i_ret; int i_ret;
struct sockaddr_in sock2;
int i_len; int i_len;
int fd; int fd;
int i; int i;
/* if a new client wants to communicate */ /* if a new client wants to communicate */
fd = accept( p_sys->fd, (struct sockaddr *)&sock2, &i_sock_size ); fd = accept( p_sys->fd, NULL, NULL );
if( fd > 0 ) if( fd > 0 )
{ {
telnet_client_t *cl; telnet_client_t *cl;
...@@ -440,81 +426,6 @@ static void Write_message( telnet_client_t * client, vlm_message_t * message, ch ...@@ -440,81 +426,6 @@ static void Write_message( telnet_client_t * client, vlm_message_t * message, ch
free( psz_message ); free( psz_message );
} }
/* Does what we want except select and accept */
static int SocketListen( intf_thread_t *p_intf , int i_port )
{
struct sockaddr_in sock;
int fd;
int i_opt;
int i_flags;
/* open socket */
fd = socket( AF_INET, SOCK_STREAM, 0 );
if( fd < 0 )
{
msg_Err( p_intf, "cannot open socket" );
goto socket_failed;
}
/* reuse socket */
i_opt = 1;
if( setsockopt( fd, SOL_SOCKET, SO_REUSEADDR,
(void *) &i_opt, sizeof( i_opt ) ) < 0 )
{
msg_Warn( p_intf, "cannot configure socket (SO_REUSEADDR)" );
}
/* fill p_socket structure */
memset( &sock, 0, sizeof( struct sockaddr_in ) );
sock.sin_family = AF_INET; /* family */
sock.sin_port = htons( (uint16_t)i_port );
sock.sin_addr.s_addr = INADDR_ANY;
/* bind it */
if( bind( fd, (struct sockaddr *)&sock, sizeof( struct sockaddr_in ) ) < 0 )
{
msg_Err( p_intf, "cannot bind socket" );
goto socket_failed;
}
/* set to non-blocking */
#if defined( WIN32 ) || defined( UNDER_CE )
{
unsigned long i_dummy = 1;
if( ioctlsocket( fd, FIONBIO, &i_dummy ) != 0 )
{
msg_Err( p_intf, "cannot set socket to non-blocking mode" );
goto socket_failed;
}
}
#else
if( ( i_flags = fcntl( fd, F_GETFL, 0 ) ) < 0 )
{
msg_Err( p_intf, "cannot F_GETFL socket" );
goto socket_failed;
}
if( fcntl( fd, F_SETFL, i_flags | O_NONBLOCK ) < 0 )
{
msg_Err( p_intf, "cannot F_SETFL O_NONBLOCK" );
goto socket_failed;
}
#endif
/* listen */
if( listen( fd, LISTEN_BACKLOG ) < 0 )
{
msg_Err( p_intf, "cannot listen socket" );
goto socket_failed;
}
return fd;
socket_failed:
if( fd >= 0 )
{
SOCKET_CLOSE( fd );
}
return -1;
}
/* we need the level of the message to put a beautiful indentation. /* we need the level of the message to put a beautiful indentation.
first level is 0 */ first level is 0 */
static char* MessageToString( vlm_message_t* message , int i_level ) static char* MessageToString( vlm_message_t* message , int i_level )
......
...@@ -437,43 +437,24 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -437,43 +437,24 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
} }
/***************************************************************************** /*****************************************************************************
* OpenTCP: open a TCP socket * SocketTCP: create a TCP socket
***************************************************************************** *****************************************************************************
* psz_server_addr, i_server_port : address and port used for the connect()
* system call. If i_server_port == 0, 80 is used.
* Other parameters are ignored.
* This function returns -1 in case of error. * This function returns -1 in case of error.
*****************************************************************************/ *****************************************************************************/
static int OpenTCP( vlc_object_t * p_this, network_socket_t * p_socket ) static int SocketTCP( vlc_object_t * p_this )
{ {
char * psz_server_addr = p_socket->psz_server_addr;
int i_server_port = p_socket->i_server_port;
int i_handle; int i_handle;
struct sockaddr_in sock;
/* Open a SOCK_STREAM (TCP) socket, in the PF_INET domain, automatic (0)
if( i_server_port == 0 )
{
i_server_port = 80;
}
/* Open a SOCK_STREAM (TCP) socket, in the AF_INET domain, automatic (0)
* protocol */ * protocol */
if( (i_handle = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) if( (i_handle = socket( PF_INET, SOCK_STREAM, 0 )) == -1 )
{ {
#ifdef HAVE_ERRNO_H #ifdef HAVE_ERRNO_H
msg_Warn( p_this, "cannot create socket (%s)", strerror(errno) ); msg_Warn( p_this, "cannot create socket (%s)", strerror(errno) );
#else #else
msg_Warn( p_this, "cannot create socket" ); msg_Warn( p_this, "cannot create socket" );
#endif #endif
goto error; return -1;
}
/* Build remote address */
if ( BuildAddr( &sock, psz_server_addr, i_server_port ) == -1 )
{
msg_Dbg( p_this, "could not build local address" );
goto error;
} }
/* Set to non-blocking */ /* Set to non-blocking */
...@@ -496,6 +477,40 @@ static int OpenTCP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -496,6 +477,40 @@ static int OpenTCP( vlc_object_t * p_this, network_socket_t * p_socket )
} }
#endif #endif
return i_handle;
}
/*****************************************************************************
* OpenTCP: open a TCP socket
*****************************************************************************
* psz_server_addr, i_server_port : address and port used for the connect()
* system call. If i_server_port == 0, 80 is used.
* Other parameters are ignored.
* This function returns -1 in case of error.
*****************************************************************************/
static int OpenTCP( vlc_object_t * p_this, network_socket_t * p_socket )
{
char * psz_server_addr = p_socket->psz_server_addr;
int i_server_port = p_socket->i_server_port;
int i_handle;
struct sockaddr_in sock;
if( i_server_port == 0 )
{
i_server_port = 80;
}
if( (i_handle = SocketTCP( p_this )) == -1 )
return VLC_EGENERIC;
/* Build remote address */
if ( BuildAddr( &sock, psz_server_addr, i_server_port ) == -1 )
{
msg_Dbg( p_this, "could not build local address" );
goto error;
}
/* Connect the socket */ /* Connect the socket */
if( connect( i_handle, (struct sockaddr *) &sock, sizeof( sock ) ) == -1 ) if( connect( i_handle, (struct sockaddr *) &sock, sizeof( sock ) ) == -1 )
{ {
...@@ -580,15 +595,76 @@ static int OpenTCP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -580,15 +595,76 @@ static int OpenTCP( vlc_object_t * p_this, network_socket_t * p_socket )
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
if( i_handle > 0 ) close( i_handle );
return VLC_EGENERIC;
}
/*****************************************************************************
* ListenTCP: open a TCP passive socket (server-side)
*****************************************************************************
* psz_server_addr, i_server_port : address and port used for the bind()
* system call. If i_server_port == 0, 80 is used.
* Other parameters are ignored.
* This function returns -1 in case of error.
*****************************************************************************/
static int ListenTCP( vlc_object_t * p_this, network_socket_t * p_socket )
{
char * psz_server_addr = p_socket->psz_server_addr;
int i_server_port = p_socket->i_server_port;
int i_handle, i_dummy = 1;
struct sockaddr_in sock;
if( (i_handle = SocketTCP( p_this )) == -1 )
return VLC_EGENERIC;
if ( setsockopt( i_handle, SOL_SOCKET, SO_REUSEADDR,
(void *)&i_dummy, sizeof( i_dummy ) ) == -1 )
{ {
close( i_handle ); msg_Warn( p_this, "cannot configure socket (SO_REUSEADDR)" );
}
/* Build remote address */
if ( BuildAddr( &sock, psz_server_addr, i_server_port ) == -1 )
{
msg_Dbg( p_this, "could not build local address" );
return VLC_EGENERIC;
}
/* Bind the socket */
if( bind( i_handle, (struct sockaddr *) &sock, sizeof( sock )) == -1 )
{
#ifdef HAVE_ERRNO_H
msg_Err( p_this, "cannot bind socket (%s)", strerror(errno) );
#else
msg_Err( p_this, "cannot bind socket" );
#endif
goto error;
}
/* Listen */
if( listen( i_handle, 100 ) == -1 )
{
#ifdef HAVE_ERRNO_H
msg_Err( p_this, "cannot bring the socket in listening mode (%s)",
strerror(errno) );
#else
msg_Err( p_this, "cannot bring the socket in listening mode" );
#endif
goto error;
} }
p_socket->i_handle = i_handle;
p_socket->i_mtu = 0; /* There is no MTU notion in TCP */
return VLC_SUCCESS;
error:
close( i_handle );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/***************************************************************************** /*****************************************************************************
* NetOpen: wrapper around OpenUDP and OpenTCP * NetOpen: wrapper around OpenUDP, ListenTCP and OpenTCP
*****************************************************************************/ *****************************************************************************/
static int NetOpen( vlc_object_t * p_this ) static int NetOpen( vlc_object_t * p_this )
{ {
...@@ -598,6 +674,10 @@ static int NetOpen( vlc_object_t * p_this ) ...@@ -598,6 +674,10 @@ static int NetOpen( vlc_object_t * p_this )
{ {
return OpenUDP( p_this, p_socket ); return OpenUDP( p_this, p_socket );
} }
else if( p_socket->i_type == NETWORK_TCP_PASSIVE )
{
return ListenTCP( p_this, p_socket );
}
else else
{ {
return OpenTCP( p_this, p_socket ); return OpenTCP( p_this, p_socket );
......
...@@ -77,7 +77,7 @@ static const struct in6_addr in6addr_any = {{IN6ADDR_ANY_INIT}}; ...@@ -77,7 +77,7 @@ static const struct in6_addr in6addr_any = {{IN6ADDR_ANY_INIT}};
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t * ); static int NetOpen( vlc_object_t * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
...@@ -85,7 +85,7 @@ static int Open( vlc_object_t * ); ...@@ -85,7 +85,7 @@ static int Open( vlc_object_t * );
vlc_module_begin(); vlc_module_begin();
set_description( _("IPv6 network abstraction layer") ); set_description( _("IPv6 network abstraction layer") );
set_capability( "network", 40 ); set_capability( "network", 40 );
set_callbacks( Open, NULL ); set_callbacks( NetOpen, NULL );
vlc_module_end(); vlc_module_end();
/***************************************************************************** /*****************************************************************************
...@@ -437,6 +437,50 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -437,6 +437,50 @@ static int OpenUDP( vlc_object_t * p_this, network_socket_t * p_socket )
return( 0 ); return( 0 );
} }
/*****************************************************************************
* SocketTCP: create a TCP socket
*****************************************************************************
* This function returns -1 in case of error.
*****************************************************************************/
static int SocketTCP( vlc_object_t * p_this )
{
int i_handle;
/* Open a SOCK_STREAM (TCP) socket, in the PF_INET6 domain, automatic (0)
* protocol */
if( (i_handle = socket( PF_INET6, SOCK_STREAM, 0 )) == -1 )
{
#ifdef HAVE_ERRNO_H
msg_Warn( p_this, "cannot create socket (%s)", strerror(errno) );
#else
msg_Warn( p_this, "cannot create socket" );
#endif
return -1;
}
/* Set to non-blocking */
#if defined( WIN32 ) || defined( UNDER_CE )
{
unsigned long i_dummy = 1;
if( ioctlsocket( i_handle, FIONBIO, &i_dummy ) != 0 )
{
msg_Err( p_this, "cannot set socket to non-blocking mode" );
}
}
#elif defined( HAVE_ERRNO_H )
{
int i_flags;
if( ( i_flags = fcntl( i_handle, F_GETFL, 0 ) ) < 0 ||
fcntl( i_handle, F_SETFL, i_flags | O_NONBLOCK ) < 0 )
{
msg_Err( p_this, "cannot set socket to non-blocking mode" );
}
}
#endif
return i_handle;
}
/***************************************************************************** /*****************************************************************************
* OpenTCP: open a TCP socket * OpenTCP: open a TCP socket
***************************************************************************** *****************************************************************************
...@@ -458,40 +502,171 @@ static int OpenTCP( vlc_object_t * p_this, network_socket_t * p_socket ) ...@@ -458,40 +502,171 @@ static int OpenTCP( vlc_object_t * p_this, network_socket_t * p_socket )
i_server_port = 80; i_server_port = 80;
} }
/* Open a SOCK_STREAM (TCP) socket, in the AF_INET6 domain, automatic (0) if( (i_handle = SocketTCP( p_this )) == -1 )
* protocol */ return VLC_EGENERIC;
if( (i_handle = socket( AF_INET6, SOCK_STREAM, 0 )) == -1 )
/* Build remote address */
if ( BuildAddr( p_this, &sock, psz_server_addr, i_server_port ) == -1 )
goto error;
/* Connect the socket */
if( connect( i_handle, (struct sockaddr *) &sock, sizeof( sock ) ) == -1 )
{ {
msg_Warn( p_this, "cannot create socket (%s)", strerror(errno) ); #if defined( WIN32 ) || defined( UNDER_CE )
return( -1 ); if( WSAGetLastError() == WSAEWOULDBLOCK )
#elif defined( HAVE_ERRNO_H )
if( errno == EINPROGRESS )
#else
if( 0 )
#endif
{
int i_ret, i_opt, i_opt_size = sizeof( i_opt ), i_max_count;
struct timeval timeout;
vlc_value_t val;
fd_set fds;
/* FIXME: There is no ipv6-timeout option, so we use ipv4-timeout
* instead */
if( !var_Type( p_this, "ipv4-timeout" ) )
{
var_Create( p_this, "ipv4-timeout",
VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
}
var_Get( p_this, "ipv4-timeout", &val );
i_max_count = val.i_int * 1000 / 100000 /* timeout.tv_usec */;
msg_Dbg( p_this, "connection in progress" );
do
{
if( p_this->b_die || i_max_count <= 0 )
{
msg_Dbg( p_this, "connection aborted" );
goto error;
}
i_max_count--;
/* Initialize file descriptor set */
FD_ZERO( &fds );
FD_SET( i_handle, &fds );
/* We'll wait 0.1 second if nothing happens */
timeout.tv_sec = 0;
timeout.tv_usec = 100000;
} while( ( i_ret = select( i_handle + 1, NULL, &fds, NULL,
&timeout ) ) == 0 ||
#if defined( WIN32 ) || defined( UNDER_CE )
( i_ret < 0 && WSAGetLastError() == WSAEWOULDBLOCK ) );
#elif defined( HAVE_ERRNO_H )
( i_ret < 0 && errno == EINTR ) );
#else
( i_ret < 0 ) );
#endif
if( i_ret < 0 )
{
msg_Warn( p_this, "cannot connect socket (select failed)" );
goto error;
}
#if !defined( SYS_BEOS )
if( getsockopt( i_handle, SOL_SOCKET, SO_ERROR, (void*)&i_opt,
&i_opt_size ) == -1 || i_opt != 0 )
{
msg_Warn( p_this, "cannot connect socket (SO_ERROR)" );
goto error;
}
#endif
}
else
{
#if defined( HAVE_ERRNO_H )
msg_Warn( p_this, "cannot connect socket (%s)", strerror(errno) );
#else
msg_Warn( p_this, "cannot connect socket" );
#endif
goto error;
}
}
p_socket->i_handle = i_handle;
p_socket->i_mtu = 0; /* There is no MTU notion in TCP */
return VLC_SUCCESS;
error:
close( i_handle );
return VLC_EGENERIC;
}
/*****************************************************************************
* ListenTCP: open a TCP passive socket (server-side)
*****************************************************************************
* psz_server_addr, i_server_port : address and port used for the bind()
* system call. If i_server_port == 0, 80 is used.
* Other parameters are ignored.
* This function returns -1 in case of error.
*****************************************************************************/
static int ListenTCP( vlc_object_t * p_this, network_socket_t * p_socket )
{
char * psz_server_addr = p_socket->psz_server_addr;
int i_server_port = p_socket->i_server_port;
int i_handle, i_dummy = 1;
struct sockaddr_in6 sock;
if( (i_handle = SocketTCP( p_this )) == -1 )
return VLC_EGENERIC;
if ( setsockopt( i_handle, SOL_SOCKET, SO_REUSEADDR,
(void *)&i_dummy, sizeof( i_dummy ) ) == -1 )
{
msg_Warn( p_this, "cannot configure socket (SO_REUSEADDR)" );
} }
/* Build remote address */ /* Build remote address */
if ( BuildAddr( p_this, &sock, psz_server_addr, i_server_port ) == -1 ) if ( BuildAddr( p_this, &sock, psz_server_addr, i_server_port ) == -1 )
{ {
close( i_handle ); msg_Dbg( p_this, "could not build local address" );
return( -1 ); return VLC_EGENERIC;
} }
/* Connect the socket */ /* Bind the socket */
if( connect( i_handle, (struct sockaddr *) &sock, if( bind( i_handle, (struct sockaddr *) &sock, sizeof( sock )) == -1 )
sizeof( sock ) ) == (-1) )
{ {
msg_Warn( p_this, "cannot connect socket (%s)", strerror(errno) ); #ifdef HAVE_ERRNO_H
close( i_handle ); msg_Err( p_this, "cannot bind socket (%s)", strerror(errno) );
return( -1 ); #else
msg_Err( p_this, "cannot bind socket" );
#endif
goto error;
}
/* Listen */
if( listen( i_handle, 100 ) == -1 )
{
#ifdef HAVE_ERRNO_H
msg_Err( p_this, "cannot bring the socket in listening mode (%s)",
strerror(errno) );
#else
msg_Err( p_this, "cannot bring the socket in listening mode" );
#endif
goto error;
} }
p_socket->i_handle = i_handle; p_socket->i_handle = i_handle;
p_socket->i_mtu = 0; /* There is no MTU notion in TCP */ p_socket->i_mtu = 0; /* There is no MTU notion in TCP */
return VLC_SUCCESS;
return( 0 ); error:
close( i_handle );
return VLC_EGENERIC;
} }
/***************************************************************************** /*****************************************************************************
* Open: wrapper around OpenUDP and OpenTCP * NetOpen: wrapper around OpenUDP, ListenTCP and OpenTCP
*****************************************************************************/ *****************************************************************************/
static int Open( vlc_object_t * p_this ) static int NetOpen( vlc_object_t * p_this )
{ {
network_socket_t * p_socket = p_this->p_private; network_socket_t * p_socket = p_this->p_private;
...@@ -499,6 +674,10 @@ static int Open( vlc_object_t * p_this ) ...@@ -499,6 +674,10 @@ static int Open( vlc_object_t * p_this )
{ {
return OpenUDP( p_this, p_socket ); return OpenUDP( p_this, p_socket );
} }
else if( p_socket->i_type == NETWORK_TCP_PASSIVE )
{
return ListenTCP( p_this, p_socket );
}
else else
{ {
return OpenTCP( p_this, p_socket ); return OpenTCP( p_this, p_socket );
......
...@@ -110,6 +110,58 @@ int __net_OpenTCP( vlc_object_t *p_this, char *psz_host, int i_port ) ...@@ -110,6 +110,58 @@ int __net_OpenTCP( vlc_object_t *p_this, char *psz_host, int i_port )
return sock.i_handle; return sock.i_handle;
} }
/*****************************************************************************
* __net_ListenTCP:
*****************************************************************************
* Open a TCP listening socket and return it
*****************************************************************************/
int __net_ListenTCP( vlc_object_t *p_this, char *psz_host, int i_port )
{
vlc_value_t val;
void *private;
char *psz_network = "";
network_socket_t sock;
module_t *p_network;
/* Check if we have force ipv4 or ipv6 */
var_Create( p_this, "ipv4", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Get( p_this, "ipv4", &val );
if( val.b_bool )
{
psz_network = "ipv4";
}
var_Create( p_this, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Get( p_this, "ipv6", &val );
if( val.b_bool )
{
psz_network = "ipv6";
}
/* Prepare the network_socket_t structure */
sock.i_type = NETWORK_TCP_PASSIVE;
sock.psz_bind_addr = "";
sock.i_bind_port = 0;
sock.psz_server_addr = psz_host;
sock.i_server_port = i_port;
sock.i_ttl = 0;
msg_Dbg( p_this, "net: listening to '%s:%d'", psz_host, i_port );
private = p_this->p_private;
p_this->p_private = (void*)&sock;
if( !( p_network = module_Need( p_this, "network", psz_network, 0 ) ) )
{
msg_Dbg( p_this, "net: listening to '%s:%d' failed",
psz_host, i_port );
return -1;
}
module_Unneed( p_this, p_network );
p_this->p_private = private;
return sock.i_handle;
}
/***************************************************************************** /*****************************************************************************
* __net_OpenUDP: * __net_OpenUDP:
***************************************************************************** *****************************************************************************
......
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