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 @@ ...@@ -31,9 +31,13 @@
#elif defined( WIN32 ) #elif defined( WIN32 )
# include <winsock2.h> # include <winsock2.h>
# include <ws2tcpip.h> # include <ws2tcpip.h>
#elif HAVE_SYS_SOCKET_H #else
# include <netdb.h>
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h> # include <sys/socket.h>
#endif #endif
#endif
/***************************************************************************** /*****************************************************************************
* network_socket_t: structure passed to a network plug-in to define the * 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 ...@@ -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( int, vlc_getaddrinfo, ( vlc_object_t *, const char *, int, const struct addrinfo *, struct addrinfo ** ) );
VLC_EXPORT( void, vlc_freeaddrinfo, ( 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 #endif
...@@ -1016,8 +1016,17 @@ static char *SDPGenerate( vod_media_t *p_media, char *psz_destination ) ...@@ -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, "t=0 0\r\n" ); /* FIXME */
p += sprintf( p, "a=tool:"PACKAGE_STRING"\r\n" ); p += sprintf( p, "a=tool:"PACKAGE_STRING"\r\n" );
p += sprintf( p, "c=IN IP4 %s/%d\r\n", psz_destination ? p += sprintf( p, "c=IN IP4 %s", psz_destination ? psz_destination : "0.0.0.0" );
psz_destination : "0.0.0.0", p_media->i_ttl );
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 ) if( p_media->i_length > 0 )
p += sprintf( p, "a=range:npt=0-%.3f\r\n", p += sprintf( p, "a=range:npt=0-%.3f\r\n",
......
...@@ -264,8 +264,6 @@ struct demux_sys_t ...@@ -264,8 +264,6 @@ struct demux_sys_t
#endif #endif
static void FreeSDP( sdp_t *p_sdp ); static void FreeSDP( sdp_t *p_sdp );
/* Detect multicast addresses */
static vlc_bool_t ismult( char * );
#define FREE( p ) \ #define FREE( p ) \
if( p ) { free( p ); (p) = NULL; } if( p ) { free( p ); (p) = NULL; }
...@@ -1036,7 +1034,7 @@ static int ParseConnection( vlc_object_t *p_obj, sdp_t *p_sdp ) ...@@ -1036,7 +1034,7 @@ static int ParseConnection( vlc_object_t *p_obj, sdp_t *p_sdp )
i_port = 1234; 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 ); 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, ...@@ -1299,32 +1297,6 @@ static char *convert_from_utf8( struct services_discovery_t *p_sd,
return psz_local; 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, static int InitSocket( services_discovery_t *p_sd, char *psz_address,
int i_port ) int i_port )
{ {
......
...@@ -392,6 +392,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -392,6 +392,7 @@ static int Open( vlc_object_t *p_this )
char *psz_rtpmap; char *psz_rtpmap;
char access[100]; char access[100];
char psz_ttl[100];
char url[p_sys->psz_destination ? strlen( p_sys->psz_destination ) + 1 + 12+1 : 14]; char url[p_sys->psz_destination ? strlen( p_sys->psz_destination ) + 1 + 12+1 : 14];
/* Check muxer type */ /* Check muxer type */
...@@ -465,7 +466,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -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 o= don't use the localhost address. use fully qualified domain name or IP4 address
p= international phone number (pass via vars?) p= international phone number (pass via vars?)
c= IP6 support c= IP6 support
c= /ttl should only be added in case of multicast
a= recvonly (missing) a= recvonly (missing)
a= type:broadcast (missing) a= type:broadcast (missing)
a= charset: (normally charset should be UTF-8, this can be used to override s= and i=) 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 ) ...@@ -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 + strlen( p_sys->psz_session_email ) + 10 + strlen( p_sys->psz_destination ) +
10 + 10 + strlen( PACKAGE_STRING ) + 10 + 10 + strlen( PACKAGE_STRING ) +
20 + 10 + 20 + 10 + strlen( psz_rtpmap ) ); 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, sprintf( p_sys->psz_sdp,
"v=0\r\n" "v=0\r\n"
"o=- "I64Fd" %d IN IP4 127.0.0.1\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 ) ...@@ -486,7 +496,7 @@ static int Open( vlc_object_t *p_this )
"e=%s\r\n" "e=%s\r\n"
"t=0 0\r\n" /* permanent stream */ /* when scheduled from vlm, we should set this info correctly */ "t=0 0\r\n" /* permanent stream */ /* when scheduled from vlm, we should set this info correctly */
"a=tool:"PACKAGE_STRING"\r\n" "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" "m=video %d RTP/AVP %d\r\n"
"a=rtpmap:%d %s\r\n", "a=rtpmap:%d %s\r\n",
p_sys->i_sdp_id, p_sys->i_sdp_version, p_sys->i_sdp_id, p_sys->i_sdp_version,
...@@ -494,7 +504,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -494,7 +504,7 @@ static int Open( vlc_object_t *p_this )
p_sys->psz_session_description, p_sys->psz_session_description,
p_sys->psz_session_url, p_sys->psz_session_url,
p_sys->psz_session_email, 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_port, p_sys->i_payload_type,
p_sys->i_payload_type, psz_rtpmap ); p_sys->i_payload_type, psz_rtpmap );
fprintf( stderr, "sdp=%s", p_sys->psz_sdp ); fprintf( stderr, "sdp=%s", p_sys->psz_sdp );
...@@ -695,7 +705,6 @@ static void SDPHandleUrl( sout_stream_t *p_stream, char *psz_url ) ...@@ -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 o= don't use the localhost address. use fully qualified domain name or IP4 address
p= international phone number (pass via vars?) p= international phone number (pass via vars?)
c= IP6 support c= IP6 support
c= /ttl should only be added in case of multicast
a= recvonly (missing) a= recvonly (missing)
a= type:broadcast (missing) a= type:broadcast (missing)
a= charset: (normally charset should be UTF-8, this can be used to override s= and i=) 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 ...@@ -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, "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, "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 += sprintf( p, "c=IN IP4 %s", psz_destination ? psz_destination : "0.0.0.0" );
p_sys->i_ttl );
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++ ) 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