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

SAP can now listen for IPv6 announces

To enable this, start vlc with --sap-ipv6
To disable IPv4 listening, use --no-sap-ipv4

You can also set the scope of the announces (default is 3)
parent 3f737ba4
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* sap.c : SAP interface module * sap.c : SAP interface module
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: sap.c,v 1.13 2003/06/17 16:09:16 gbazin Exp $ * $Id: sap.c,v 1.14 2003/06/18 12:18:51 zorglub Exp $
* *
* Authors: Arnaud Schauly <gitan@via.ecp.fr> * Authors: Arnaud Schauly <gitan@via.ecp.fr>
* *
...@@ -77,6 +77,9 @@ ...@@ -77,6 +77,9 @@
#define HELLO_GROUP "224.2.127.254" #define HELLO_GROUP "224.2.127.254"
#define ADD_SESSION 1 #define ADD_SESSION 1
#define IPV6_ADDR_1 "FF0" /* Scope is inserted between them */
#define IPV6_ADDR_2 "::2:7FFE"
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -88,7 +91,7 @@ static int Activate ( vlc_object_t * ); ...@@ -88,7 +91,7 @@ static int Activate ( vlc_object_t * );
static void Run ( intf_thread_t *p_intf ); static void Run ( intf_thread_t *p_intf );
static int Kill ( intf_thread_t * ); static int Kill ( intf_thread_t * );
static ssize_t NetRead ( intf_thread_t*, int , byte_t *, size_t ); static ssize_t NetRead ( intf_thread_t*, int, int , byte_t *, size_t );
/* playlist related functions */ /* playlist related functions */
static int sess_toitem( intf_thread_t *, sess_descr_t * ); static int sess_toitem( intf_thread_t *, sess_descr_t * );
...@@ -137,6 +140,22 @@ vlc_module_begin(); ...@@ -137,6 +140,22 @@ vlc_module_begin();
add_category_hint( N_("SAP"), NULL, VLC_TRUE ); add_category_hint( N_("SAP"), NULL, VLC_TRUE );
add_string( "sap-addr", NULL, NULL, add_string( "sap-addr", NULL, NULL,
"SAP multicast address", "SAP multicast address", VLC_TRUE ); "SAP multicast address", "SAP multicast address", VLC_TRUE );
add_bool( "no-sap-ipv4", 0 , NULL,
"NO IPv4-SAP listening",
"Set this if you do not want SAP to listen for IPv4 announces",
VLC_TRUE);
add_bool( "sap-ipv6", 0 , NULL,
"IPv6-SAP listening",
"Set this if you want SAP to listen for IPv6 announces",
VLC_TRUE);
add_string( "sap-ipv6-scope", "3" , NULL,
"IPv6-SAP scope",
"Sets the scope for IPv6 announces (default is 3)",
VLC_TRUE);
set_description( _("SAP interface") ); set_description( _("SAP interface") );
set_capability( "interface", 0 ); set_capability( "interface", 0 );
set_callbacks( Activate, NULL); set_callbacks( Activate, NULL);
...@@ -164,14 +183,29 @@ static int Activate( vlc_object_t *p_this ) ...@@ -164,14 +183,29 @@ static int Activate( vlc_object_t *p_this )
static void Run( intf_thread_t *p_intf ) static void Run( intf_thread_t *p_intf )
{ {
char *psz_addr; char *psz_addr;
char *psz_addrv6;
char *psz_network = NULL; char *psz_network = NULL;
int fd; int fd = - 1;
int fdv6 = -1;
int no_sap_ipv4 = config_GetInt( p_intf, "no-sap-ipv4" );
int sap_ipv6 = config_GetInt( p_intf, "sap-ipv6" );
char *sap_ipv6_scope = config_GetPsz( p_intf, "sap-ipv6-scope" );
char buffer[MAX_SAP_BUFFER + 1]; char buffer[MAX_SAP_BUFFER + 1];
module_t *p_network; module_t *p_network;
network_socket_t socket_desc; network_socket_t socket_desc;
if( no_sap_ipv4 == -1 || sap_ipv6 == -1 || sap_ipv6_scope == NULL )
{
msg_Warn( p_intf, "Unable to parse module configuration" );
return;
}
/* Prepare IPv4 Networking */
if ( no_sap_ipv4 == 0)
{
if( !(psz_addr = config_GetPsz( p_intf, "sap-addr" ) ) ) if( !(psz_addr = config_GetPsz( p_intf, "sap-addr" ) ) )
{ {
psz_addr = strdup( HELLO_GROUP ); psz_addr = strdup( HELLO_GROUP );
...@@ -185,7 +219,7 @@ static void Run( intf_thread_t *p_intf ) ...@@ -185,7 +219,7 @@ static void Run( intf_thread_t *p_intf )
socket_desc.i_server_port = 0; socket_desc.i_server_port = 0;
p_intf->p_private = (void*) &socket_desc; p_intf->p_private = (void*) &socket_desc;
psz_network = "ipv4"; // FIXME psz_network = "ipv4";
/* Create, Bind the socket, ... with the appropriate module */ /* Create, Bind the socket, ... with the appropriate module */
...@@ -197,6 +231,39 @@ static void Run( intf_thread_t *p_intf ) ...@@ -197,6 +231,39 @@ static void Run( intf_thread_t *p_intf )
module_Unneed( p_intf, p_network ); module_Unneed( p_intf, p_network );
fd = socket_desc.i_handle; fd = socket_desc.i_handle;
}
/* Prepare IPv6 Networking */
if ( sap_ipv6 > 0)
{
/* Prepare the network_socket_t structure */
psz_addrv6=(char *)malloc(sizeof(char)*38);
/* Max size of an IPv6 address */
sprintf(psz_addrv6,"[%s%c%s]",IPV6_ADDR_1,
sap_ipv6_scope[0],IPV6_ADDR_2);
socket_desc.i_type = NETWORK_UDP;
socket_desc.psz_bind_addr = psz_addrv6;
socket_desc.i_bind_port = HELLO_PORT;
socket_desc.psz_server_addr = "";
socket_desc.i_server_port = 0;
p_intf->p_private = (void*) &socket_desc;
psz_network = "ipv6";
/* Create, Bind the socket, ... with the appropriate module */
if( !( p_network = module_Need( p_intf, "network", psz_network ) ) )
{
msg_Warn( p_intf, "failed to open a connection (udp)" );
return;
}
module_Unneed( p_intf, p_network );
fdv6 = socket_desc.i_handle;
}
/* read SAP packets */ /* read SAP packets */
...@@ -206,7 +273,7 @@ static void Run( intf_thread_t *p_intf ) ...@@ -206,7 +273,7 @@ static void Run( intf_thread_t *p_intf )
//memset( buffer, 0, MAX_SAP_BUFFER + 1); //memset( buffer, 0, MAX_SAP_BUFFER + 1);
i_read = NetRead( p_intf, fd, buffer, MAX_SAP_BUFFER ); i_read = NetRead( p_intf, fd, fdv6, buffer, MAX_SAP_BUFFER );
if( i_read < 0 ) if( i_read < 0 )
{ {
...@@ -676,8 +743,7 @@ static int ismult( char *psz_uri ) ...@@ -676,8 +743,7 @@ static int ismult( char *psz_uri )
i_value = strtol( psz_uri, &psz_end, 0 ); i_value = strtol( psz_uri, &psz_end, 0 );
/* FIXME: This is an ugly way to detect IPv6 and to say that this is /* FIXME: This is an ugly way to detect IPv6 multicast */
multicast */
if( psz_uri[0] == '[') { return( VLC_TRUE ); } if( psz_uri[0] == '[') { return( VLC_TRUE ); }
if( *psz_end != '.' ) { return( VLC_FALSE ); } if( *psz_end != '.' ) { return( VLC_FALSE ); }
...@@ -691,7 +757,8 @@ multicast */ ...@@ -691,7 +757,8 @@ multicast */
* Taken from udp.c * Taken from udp.c
******************************************************************************/ ******************************************************************************/
static ssize_t NetRead( intf_thread_t *p_intf, static ssize_t NetRead( intf_thread_t *p_intf,
int i_handle, byte_t *p_buffer, size_t i_len) int i_handle, int i_handle_v6,
byte_t *p_buffer, size_t i_len)
{ {
#ifdef UNDER_CE #ifdef UNDER_CE
return -1; return -1;
...@@ -700,17 +767,29 @@ static ssize_t NetRead( intf_thread_t *p_intf, ...@@ -700,17 +767,29 @@ static ssize_t NetRead( intf_thread_t *p_intf,
struct timeval timeout; struct timeval timeout;
fd_set fds; fd_set fds;
int i_ret; int i_ret;
int i_max_handle;
ssize_t i_recv=-1;
/* Get the max handle for select */
if( i_handle_v6 > i_handle )
i_max_handle = i_handle_v6;
else
i_max_handle = i_handle;
/* Initialize file descriptor set */ /* Initialize file descriptor set */
FD_ZERO( &fds ); FD_ZERO( &fds );
FD_SET( i_handle, &fds ); if( i_handle > 0 ) FD_SET( i_handle, &fds );
if( i_handle_v6 > 0 ) FD_SET( i_handle_v6, &fds);
/* We'll wait 0.5 second if nothing happens */ /* We'll wait 0.5 second if nothing happens */
timeout.tv_sec = 0; timeout.tv_sec = 0;
timeout.tv_usec = 500000; timeout.tv_usec = 500000;
/* Find if some data is available */ /* Find if some data is available */
i_ret = select( i_handle + 1, &fds, i_ret = select( i_max_handle + 1, &fds,
NULL, NULL, &timeout ); NULL, NULL, &timeout );
if( i_ret == -1 && errno != EINTR ) if( i_ret == -1 && errno != EINTR )
...@@ -719,13 +798,26 @@ static ssize_t NetRead( intf_thread_t *p_intf, ...@@ -719,13 +798,26 @@ static ssize_t NetRead( intf_thread_t *p_intf,
} }
else if( i_ret > 0 ) else if( i_ret > 0 )
{ {
ssize_t i_recv = recv( i_handle, p_buffer, i_len, 0 ); /* Get the data */
if(i_handle >0)
{
if(FD_ISSET( i_handle, &fds ))
{
i_recv = recv( i_handle, p_buffer, i_len, 0 );
}
}
if(i_handle_v6 >0)
{
if(FD_ISSET( i_handle_v6, &fds ))
{
i_recv = recv( i_handle_v6, p_buffer, i_len, 0 );
}
}
if( i_recv < 0 ) if( i_recv < 0 )
{ {
msg_Err( p_intf, "recv failed (%s)", strerror(errno) ); msg_Err( p_intf, "recv failed (%s)", strerror(errno) );
} }
return i_recv; return i_recv;
} }
......
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