Commit f5357ec1 authored by Derk-Jan Hartman's avatar Derk-Jan Hartman

* Added net_AddressIsMulticast that takes a string and returns true if the...

* Added net_AddressIsMulticast that takes a string and returns true if the string seems to describe a valid IPv4 or IPv6 address.
* Changed all the SDP generators to only add /ttl to the c= line if the address is multicast.
parent d20e734b
......@@ -31,9 +31,13 @@
#elif defined( WIN32 )
# include <winsock2.h>
# include <ws2tcpip.h>
#elif HAVE_SYS_SOCKET_H
#else
# include <netdb.h>
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#endif
/*****************************************************************************
* network_socket_t: structure passed to a network plug-in to define the
......@@ -456,4 +460,57 @@ VLC_EXPORT( int, vlc_getnameinfo, ( const struct sockaddr *, int, char *, int, i
VLC_EXPORT( int, vlc_getaddrinfo, ( vlc_object_t *, const char *, int, const struct addrinfo *, struct addrinfo ** ) );
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.
* FIXME: Only the first returned address is checked. This might be problematic.
*****************************************************************************/
static inline vlc_bool_t net_AddressIsMulticast( vlc_object_t *p_object, char *psz_addr )
{
struct addrinfo hints, *res;
vlc_bool_t b_multicast = VLC_FALSE;
int i;
if( psz_addr == NULL )
{
msg_Err( p_object, "*FIXME* Unexpected NULL URI for net_AddressIsMulticast" );
msg_Err( p_object, "This should not happen. VLC needs fixing." );
return VLC_FALSE;
}
memset( &hints, 0, sizeof( hints ) );
hints.ai_socktype = SOCK_DGRAM; /* UDP */
hints.ai_flags = AI_NUMERICHOST;
i = vlc_getaddrinfo( p_object, psz_addr, 0,
&hints, &res );
/*if( i == 0 )
i = vlc_getnameinfo( res->ai_addr, res->ai_addrlen, psz_buf,
sizeof( psz_buf ), NULL, NI_NUMERICHOST );*/
if( i )
{
msg_Err( p_object, "Invalid node for net_AddressIsMulticast: %s : %s",
psz_addr, vlc_gai_strerror( i ) );
return b_multicast;
}
if( res->ai_family == AF_INET )
{
#if !defined( SYS_BEOS )
struct sockaddr_in *v4 = (struct sockaddr_in *) res->ai_addr;
b_multicast = ( ntohl( v4->sin_addr.s_addr ) > 0xe1000000 && ntohl( v4->sin_addr.s_addr ) <= 0xEFFFFFFF );
#endif
}
else if( res->ai_family == AF_INET6 )
{
#if defined( WIN32 ) || defined( HAVE_IF_NAMETOINDEX )
struct sockaddr_in6 *v6 = (struct sockaddr_in6 *) res->ai_addr;
b_multicast = IN6_IS_ADDR_MULTICAST( &v6->sin6_addr);
#endif
}
vlc_freeaddrinfo( res );
return b_multicast;
}
#endif
......@@ -1016,8 +1016,17 @@ static char *SDPGenerate( vod_media_t *p_media, char *psz_destination )
p += sprintf( p, "t=0 0\r\n" ); /* FIXME */
p += sprintf( p, "a=tool:"PACKAGE_STRING"\r\n" );
p += sprintf( p, "c=IN IP4 %s/%d\r\n", psz_destination ?
psz_destination : "0.0.0.0", p_media->i_ttl );
p += sprintf( p, "c=IN IP4 %s", psz_destination ? psz_destination : "0.0.0.0" );
if( net_AddressIsMulticast( p_media, psz_destination ? psz_destination : "0.0.0.0" ) )
{
/* Add the ttl if it is a multicast address */
p += sprintf( p, "/%d\r\n", p_media->i_ttl );
}
else
{
p += sprintf( p, "\r\n" );
}
if( p_media->i_length > 0 )
p += sprintf( p, "a=range:npt=0-%.3f\r\n",
......
......@@ -264,8 +264,6 @@ struct demux_sys_t
#endif
static void FreeSDP( sdp_t *p_sdp );
/* Detect multicast addresses */
static vlc_bool_t ismult( char * );
#define FREE( p ) \
if( p ) { free( p ); (p) = NULL; }
......@@ -1036,7 +1034,7 @@ static int ParseConnection( vlc_object_t *p_obj, sdp_t *p_sdp )
i_port = 1234;
}
if( ismult( psz_uri ) )
if( net_AddressIsMulticast( p_obj, psz_uri ) )
{
asprintf( &p_sdp->psz_uri, "%s://@%s:%i", psz_proto, psz_uri, i_port );
}
......@@ -1299,32 +1297,6 @@ static char *convert_from_utf8( struct services_discovery_t *p_sd,
return psz_local;
}
/***********************************************************************
* ismult: returns true if we have a multicast address
***********************************************************************/
static vlc_bool_t ismult( char *psz_uri )
{
char *psz_end;
int i_value;
/* IPv6 */
if( psz_uri[0] == '[')
{
if( strncasecmp( &psz_uri[1], "FF0" , 3) ||
( !isalnum( psz_uri[1]) && strncasecmp( &psz_uri[2], "FF0" , 3) ) )
return( VLC_TRUE );
else
return( VLC_FALSE );
}
i_value = strtol( psz_uri, &psz_end, 0 );
if( *psz_end != '.' ) { return( VLC_FALSE ); }
return ( ( i_value < 224 ) || ( i_value >= 240 ) ) ? VLC_FALSE : VLC_TRUE;
}
static int InitSocket( services_discovery_t *p_sd, char *psz_address,
int i_port )
{
......
......@@ -392,6 +392,7 @@ static int Open( vlc_object_t *p_this )
char *psz_rtpmap;
char access[100];
char psz_ttl[100];
char url[p_sys->psz_destination ? strlen( p_sys->psz_destination ) + 1 + 12+1 : 14];
/* Check muxer type */
......@@ -465,7 +466,6 @@ static int Open( vlc_object_t *p_this )
o= don't use the localhost address. use fully qualified domain name or IP4 address
p= international phone number (pass via vars?)
c= IP6 support
c= /ttl should only be added in case of multicast
a= recvonly (missing)
a= type:broadcast (missing)
a= charset: (normally charset should be UTF-8, this can be used to override s= and i=)
......@@ -477,6 +477,16 @@ static int Open( vlc_object_t *p_this )
10 + strlen( p_sys->psz_session_email ) + 10 + strlen( p_sys->psz_destination ) +
10 + 10 + strlen( PACKAGE_STRING ) +
20 + 10 + 20 + 10 + strlen( psz_rtpmap ) );
if( net_AddressIsMulticast( (vlc_object_t *)p_stream, p_sys->psz_destination ) )
{
sprintf( psz_ttl, "/%d", p_sys->i_ttl );
}
else
{
psz_ttl[0] = '\0';
}
sprintf( p_sys->psz_sdp,
"v=0\r\n"
"o=- "I64Fd" %d IN IP4 127.0.0.1\r\n"
......@@ -486,7 +496,7 @@ static int Open( vlc_object_t *p_this )
"e=%s\r\n"
"t=0 0\r\n" /* permanent stream */ /* when scheduled from vlm, we should set this info correctly */
"a=tool:"PACKAGE_STRING"\r\n"
"c=IN IP4 %s/%d\r\n"
"c=IN IP4 %s%s\r\n"
"m=video %d RTP/AVP %d\r\n"
"a=rtpmap:%d %s\r\n",
p_sys->i_sdp_id, p_sys->i_sdp_version,
......@@ -494,7 +504,7 @@ static int Open( vlc_object_t *p_this )
p_sys->psz_session_description,
p_sys->psz_session_url,
p_sys->psz_session_email,
p_sys->psz_destination, p_sys->i_ttl,
p_sys->psz_destination, psz_ttl,
p_sys->i_port, p_sys->i_payload_type,
p_sys->i_payload_type, psz_rtpmap );
fprintf( stderr, "sdp=%s", p_sys->psz_sdp );
......@@ -695,7 +705,6 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url )
o= don't use the localhost address. use fully qualified domain name or IP4 address
p= international phone number (pass via vars?)
c= IP6 support
c= /ttl should only be added in case of multicast
a= recvonly (missing)
a= type:broadcast (missing)
a= charset: (normally charset should be UTF-8, this can be used to override s= and i=)
......@@ -753,8 +762,17 @@ static char *SDPGenerate( sout_stream_t *p_stream, char *psz_destination, vlc_bo
p += sprintf( p, "t=0 0\r\n" ); /* permanent stream */ /* when scheduled from vlm, we should set this info correctly */
p += sprintf( p, "a=tool:"PACKAGE_STRING"\r\n" );
p += sprintf( p, "c=IN IP4 %s/%d\r\n", psz_destination ? psz_destination : "0.0.0.0",
p_sys->i_ttl );
p += sprintf( p, "c=IN IP4 %s", psz_destination ? psz_destination : "0.0.0.0" );
if( net_AddressIsMulticast( (vlc_object_t *)p_stream, psz_destination ? psz_destination : "0.0.0.0" ) )
{
/* Add the ttl if it is a multicast address */
p += sprintf( p, "/%d\r\n", p_sys->i_ttl );
}
else
{
p += sprintf( p, "\r\n" );
}
for( i = 0; i < p_sys->i_es; i++ )
{
......
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