* Changed all the SDP generators to only add /ttl to the c= line if the address is multicast.
#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
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
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",
#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; }
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 );
}
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 )
{
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 */
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=)
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"
"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,
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 );
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=)
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++ )
{