*
* 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.
*****************************************************************************/
/*****************************************************************************
#include <vlc/sout.h>
#include "network.h"
-#if defined( WIN32 ) || defined( UNDER_CE )
-# if defined(UNDER_CE) && defined(sockaddr_storage)
-# undef sockaddr_storage
-# endif
-# include <winsock2.h>
-# include <ws2tcpip.h>
-#else
-# include <netdb.h>
-#endif
#include "charset.h"
/* SAP is always on that port */
{
char *psz_address;
char psz_machine[NI_MAXNUMERICHOST];
- int i_port;
int i_rfd; /* Read socket */
int i_wfd; /* Write socket */
static int announce_SAPAnnounceDel( sap_handler_t *p_sap,
session_descriptor_t *p_session );
-static char *convert_to_utf8( struct sap_handler_t *p_this, char *psz_local );
#define FREE( p ) if( p ) { free( p ); (p) = NULL; }
sap_handler_t *announce_SAPHandlerCreate( announce_handler_t *p_announce )
{
sap_handler_t *p_sap;
- char *psz_charset;
p_sap = vlc_object_create( p_announce, sizeof( sap_handler_t ) );
vlc_mutex_init( p_sap, &p_sap->object_lock );
- vlc_current_charset( &psz_charset );
- p_sap->iconvHandle = vlc_iconv_open( "UTF-8", psz_charset );
- free( psz_charset );
- if( p_sap->iconvHandle == (vlc_iconv_t)(-1) )
- msg_Warn( p_sap, "Unable to do requested conversion" );
-
p_sap->pf_add = announce_SAPAnnounceAdd;
p_sap->pf_del = announce_SAPAnnounceDel;
if( vlc_thread_create( p_sap, "sap handler", RunThread,
VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) )
{
- msg_Dbg( p_announce, "Unable to spawn SAP handler thread");
+ msg_Dbg( p_announce, "unable to spawn SAP handler thread");
free( p_sap );
return NULL;
};
FREE( p_address );
}
- if( p_sap->iconvHandle != (vlc_iconv_t)(-1) )
- vlc_iconv_close( p_sap->iconvHandle );
-
/* Free the structure */
vlc_object_destroy( p_sap );
}
if( p_session->psz_uri == NULL )
{
vlc_mutex_unlock( &p_sap->object_lock );
- msg_Err( p_sap, "*FIXME* Unexpected NULL URI for SAP announce" );
+ msg_Err( p_sap, "*FIXME* unexpected NULL URI for SAP announce" );
msg_Err( p_sap, "This should not happen. VLC needs fixing." );
return VLC_EGENERIC;
}
vlc_mutex_unlock( &p_sap->object_lock );
vlc_freeaddrinfo( res );
msg_Err( p_sap, "Unsupported address family of size %d > %u",
- res->ai_addrlen, sizeof( addr ) );
+ res->ai_addrlen, (unsigned) sizeof( addr ) );
return VLC_EGENERIC;
}
switch( addr.ss_family )
{
-#if defined (HAVE_GETADDRINFO) || defined (WIN32)
+#if defined (HAVE_INET_PTON) || defined (WIN32)
case AF_INET6:
{
/* See RFC3513 for list of valid IPv6 scopes */
if ((ipv4 & 0xfffc0000) == 0xefc00000)
ipv4 = 0xefc3ffff;
else
+ if ((ipv4 & 0xff000000) == 0xef000000)
+ ipv4 = 0;
+ else
/* other addresses => 224.2.127.254 */
ipv4 = 0xe0027ffe;
+
+ if( ipv4 == 0 )
+ {
+ msg_Err( p_sap, "Out-of-scope multicast address "
+ "not supported by SAP: %s", p_session->psz_uri );
+ vlc_mutex_unlock( &p_sap->object_lock );
+ vlc_freeaddrinfo( res );
+ return VLC_EGENERIC;
+ }
+
+ ((struct sockaddr_in *)&addr)->sin_addr.s_addr = htonl( ipv4 );
break;
}
-
+
default:
vlc_mutex_unlock( &p_sap->object_lock );
vlc_freeaddrinfo( res );
return VLC_ENOMEM;
}
p_address->psz_address = strdup( psz_addr );
- p_address->i_port = 9875;
- p_address->i_wfd = net_OpenUDP( p_sap, "", 0, psz_addr,
- p_address->i_port );
+ p_address->i_wfd = net_ConnectUDP( p_sap, psz_addr, SAP_PORT, 255 );
if( p_address->i_wfd != -1 )
{
char *ptr;
net_StopRecv( p_address->i_wfd );
- net_GetSockAddress( p_sap, p_address->i_wfd,
- p_address->psz_machine, NULL );
+ net_GetSockAddress( p_address->i_wfd, p_address->psz_machine,
+ NULL );
/* removes scope if present */
ptr = strchr( p_address->psz_machine, '%' );
if( p_sap->b_control == VLC_TRUE )
{
- p_address->i_rfd = net_OpenUDP( p_sap, psz_addr,
- p_address->i_port, "", 0 );
+ p_address->i_rfd = net_OpenUDP( p_sap, psz_addr, SAP_PORT, "", 0 );
if( p_address->i_rfd != -1 )
net_StopSend( p_address->i_rfd );
p_address->i_buff = 0;
psz_head[2] = (i_hash & 0xFF00) >> 8; /* Msg id hash */
psz_head[3] = (i_hash & 0xFF); /* Msg id hash 2 */
- inet_pton( b_ipv6 ? AF_INET6 : AF_INET, /* can't fail */
- p_sap_session->p_address->psz_machine, psz_head + 4 );
+#if defined (HAVE_INET_PTON) || defined (WIN32)
+ if( b_ipv6 )
+ {
+ inet_pton( AF_INET6, /* can't fail */
+ p_sap_session->p_address->psz_machine,
+ psz_head + 4 );
+ }
+ else
+#endif
+ {
+ inet_pton( AF_INET, /* can't fail */
+ p_sap_session->p_address->psz_machine,
+ psz_head + 4 );
+ }
memcpy( psz_head + (b_ipv6 ? 20 : 8), "application/sdp", 15 );
p_sap->i_sessions,
p_sap->i_sessions,
p_sap_session );
- msg_Dbg( p_sap,"Addresses: %i Sessions: %i",
+ msg_Dbg( p_sap,"%i addresses, %i sessions",
p_sap->i_addresses,p_sap->i_sessions);
/* Remember the SAP session for later deletion */
* TODO: - address refcount
- send a SAP deletion packet */
- msg_Dbg( p_sap,"%i announces remaining", p_sap->i_sessions );
+ msg_Dbg( p_sap,"%i announcements remaining", p_sap->i_sessions );
vlc_mutex_unlock( &p_sap->object_lock );
if( p_session->i_next < mdate() )
{
#ifdef EXTRA_DEBUG
- msg_Dbg( p_sap, "Sending announce");
+ msg_Dbg( p_sap, "sending announce");
#endif
i_ret = net_Write( p_sap, p_session->p_address->i_wfd, NULL,
p_session->psz_data,
if( i_ret != (int)p_session->i_length )
{
msg_Warn( p_sap, "SAP send failed on address %s (%i %i)",
- p_session->p_address->psz_address,
- i_ret, p_session->i_length );
+ p_session->p_address->psz_address,
+ i_ret, p_session->i_length );
}
p_session->i_last = p_session->i_next;
p_session->i_next = p_session->i_last
*psz_sdp;
char ipv;
- psz_group = convert_to_utf8( p_sap, p_session->psz_group );
- psz_name = convert_to_utf8( p_sap, p_session->psz_name );
- if( psz_name == NULL )
- {
- FREE( psz_group );
- return NULL;
- }
+ psz_group = p_session->psz_group;
+ psz_name = p_session->psz_name;
/* FIXME: really check that psz_uri is a real IP address
* FIXME: make a common function to obtain a canonical IP address */
"s=%s\r\n"
"t=0 0\r\n"
"c=IN IP%c %s/%d\r\n"
- "m=video %d udp %d\r\n"
+ "m=video %d %s %d\r\n"
"a=tool:"PACKAGE_STRING"\r\n"
- "a=type:broadcast\r\n",
+ "a=type:broadcast\r\n"
+ "%s%s%s",
i_sdp_id, i_sdp_version,
ipv, p_addr->psz_machine,
- psz_name, ipv,
- psz_uri, p_session->i_ttl,
- p_session->i_port, p_session->i_payload ) == -1 )
- {
- free( psz_name );
- FREE( psz_group );
+ psz_name, ipv, psz_uri,
+ /* FIXME: 1 is IPv4 default TTL, not that of IPv6 */
+ p_session->i_ttl ?: (config_GetInt( p_sap, "ttl" ) ?: 1),
+ p_session->i_port,
+ p_session->b_rtp ? "RTP/AVP" : "udp",
+ p_session->i_payload,
+ psz_group ? "a=x-plgroup:" : "",
+ psz_group ? psz_group : "", psz_group ? "\r\n" : "" ) == -1 )
return NULL;
- }
-
- free( psz_name );
-
- if( psz_group )
- {
- /* FIXME: this is illegal use of sprintf */
- sprintf( psz_sdp, "%sa=x-plgroup:%s\r\n", psz_sdp, psz_group );
- free( psz_group );
- }
msg_Dbg( p_sap, "Generated SDP (%i bytes):\n%s", strlen(psz_sdp),
psz_sdp );
p_address->i_interval = MAX_INTERVAL;
}
#ifdef EXTRA_DEBUG
- msg_Dbg( p_sap,"%s:%i : Rate=%i, Interval = %i s",
- p_address->psz_address,p_address->i_port,
- i_rate,
- p_address->i_interval );
+ msg_Dbg( p_sap,"%s:%i: rate=%i, interval = %i s",
+ p_address->psz_address,SAP_PORT, i_rate, p_address->i_interval );
#endif
p_address->b_ready = VLC_TRUE;
return VLC_SUCCESS;
}
-
-
-static char *convert_to_utf8( struct sap_handler_t *p_this, char *psz_local )
-{
- char *psz_unicode, *psz_in, *psz_out;
- size_t ret, i_in, i_out;
-
- if( psz_local == NULL )
- return NULL;
- if ( p_this->iconvHandle == (vlc_iconv_t)(-1) )
- return strdup( psz_local );
-
- psz_in = psz_local;
- i_in = strlen( psz_local );
-
- i_out = 6 * i_in;
- psz_unicode = malloc( i_out + 1 );
- if( psz_unicode == NULL )
- return strdup( psz_local );
- psz_out = psz_unicode;
-
- ret = vlc_iconv( p_this->iconvHandle,
- &psz_in, &i_in, &psz_out, &i_out);
- if( ret == (size_t)(-1) || i_in )
- {
- msg_Warn( p_this, "Failed to convert \"%s\" to UTF-8", psz_local );
- return strdup( psz_local );
- }
- *psz_out = '\0';
- return psz_unicode;
-}