"the multicast packets sent by the stream output (0 = use operating "\
"system built-in default).")
-#define MIFACE_TEXT N_("IPv6 multicast output interface")
+#define MIFACE_TEXT N_("Multicast output interface")
#define MIFACE_LONGTEXT N_( \
- "Default IPv6 multicast interface. This overrides the routing table.")
+ "Default multicast interface. This overrides the routing table.")
#define MIFACE_ADDR_TEXT N_("IPv4 multicast output interface address")
#define MIFACE_ADDR_LONGTEXT N_( \
"IPv4 adress for the default multicast interface. This overrides " \
"the routing table.")
+#define DSCP_TEXT N_("DiffServ Code Point")
+#define DSCP_LONGTEXT N_("Differentiated Services Code Point " \
+ "for outgoing UDP streams (or IPv4 Type Of Service, " \
+ "or IPv6 Traffic Class). This is used for network Quality of Service.")
+
#define INPUT_PROGRAM_TEXT N_("Program")
#define INPUT_PROGRAM_LONGTEXT N_( \
"Choose the program to select by giving its Service ID. " \
add_integer( "ttl", 0, NULL, TTL_TEXT, TTL_LONGTEXT, VLC_TRUE );
add_string( "miface", NULL, NULL, MIFACE_TEXT, MIFACE_LONGTEXT, VLC_TRUE );
add_string( "miface-addr", NULL, NULL, MIFACE_ADDR_TEXT, MIFACE_ADDR_LONGTEXT, VLC_TRUE );
+ add_integer( "dscp", 0, NULL, DSCP_TEXT, DSCP_LONGTEXT, VLC_TRUE );
set_subcategory( SUBCAT_SOUT_PACKETIZER );
add_module( "packetizer","packetizer", NULL, NULL,
}
-static int net_SetMcastIface( vlc_object_t *p_this,
- int fd, int family, const char *str )
+static int net_SetMcastOutIface (int fd, int family, int scope)
{
- switch( family )
+ switch (family)
{
-#ifndef SYS_BEOS
+#ifdef IPV6_MULTICAST_IF
+ case AF_INET6:
+ return setsockopt (fd, SOL_IPV6, IPV6_MULTICAST_IF,
+ &scope, sizeof (scope));
+#endif
+
+#ifdef __linux__
case AF_INET:
{
- struct in_addr addr;
-
- if( inet_pton( AF_INET, str, &addr) <= 0 )
- {
- msg_Err( p_this, "Invalid multicast interface %s", str );
- return VLC_EGENERIC;
- }
+ struct ip_mreqn req = { .imr_ifindex = scope };
- if( setsockopt( fd, SOL_IP, IP_MULTICAST_IF, &addr,
- sizeof( addr ) ) < 0 )
- {
- msg_Err( p_this, "Cannot use %s as multicast interface: %s",
- str, strerror(errno) );
- return VLC_EGENERIC;
- }
- break;
+ return setsockopt (fd, SOL_IP, IP_MULTICAST_IF, &req,
+ sizeof (req));
}
-#endif /* SYS_BEOS */
+#endif
+ }
-#ifdef IPV6_MULTICAST_IF
- case AF_INET6:
+ errno = EAFNOSUPPORT;
+ return -1;
+}
+
+
+static inline int net_SetMcastOutIPv4 (int fd, struct in_addr ipv4)
+{
+#ifdef IP_MULTICAST_IF
+ return setsockopt( fd, SOL_IP, IP_MULTICAST_IF, &ipv4, sizeof (ipv4));
+#else
+ errno = EAFNOSUPPORT;
+ return -1;
+#endif
+}
+
+
+static int net_SetMcastOut (vlc_object_t *p_this, int fd, int family,
+ const char *iface, const char *addr)
+{
+ if (iface != NULL)
+ {
+ int scope = if_nametoindex (iface);
+ if (scope == 0)
{
- int scope = if_nametoindex( str );
+ msg_Err (p_this, "%s: invalid interface for multicast", iface);
+ return -1;
+ }
- if( scope == 0 )
- {
- msg_Err( p_this, "Invalid multicast interface %s", str );
- return VLC_EGENERIC;
- }
+ if (net_SetMcastOutIface (fd, family, scope) == 0)
+ return 0;
- if( setsockopt( fd, SOL_IPV6, IPV6_MULTICAST_IF,
- &scope, sizeof( scope ) ) < 0 )
+ msg_Err (p_this, "%s: %s", iface, net_strerror (net_errno));
+ }
+
+ if (addr != NULL)
+ {
+ if (family == AF_INET)
+ {
+ struct in_addr ipv4;
+ if (inet_pton (AF_INET, addr, &ipv4) <= 0)
{
- msg_Err( p_this, "Cannot use %s as multicast interface: %s",
- str, strerror( errno ) );
- return VLC_EGENERIC;
+ msg_Err (p_this, "%s: invalid IPv4 address for multicast",
+ addr);
+ return -1;
}
- break;
- }
-#endif
- default:
- msg_Warn( p_this, "%s", strerror( EAFNOSUPPORT ) );
- return VLC_EGENERIC;
+ if (net_SetMcastOutIPv4 (fd, ipv4) == 0)
+ return 0;
+
+ msg_Err (p_this, "%s: %s", addr, net_strerror (net_errno));
+ }
}
- return VLC_SUCCESS;
+ return -1;
}
for( ptr = res; ptr != NULL; ptr = ptr->ai_next )
{
- int fd;
- char *psz_mif;
-
- fd = net_Socket( p_this, ptr->ai_family, ptr->ai_socktype,
- ptr->ai_protocol );
- if( fd == -1 )
+ char *str;
+ int fd = net_Socket (p_this, ptr->ai_family, ptr->ai_socktype,
+ ptr->ai_protocol);
+ if (fd == -1)
continue;
+
#if !defined( SYS_BEOS )
- else
- {
- int i_val;
-
- /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s)
- * to avoid packet loss caused by scheduling problems */
- i_val = 0x80000;
- setsockopt( fd, SOL_SOCKET, SO_RCVBUF, (void *)&i_val,
- sizeof( i_val ) );
- i_val = 0x80000;
- setsockopt( fd, SOL_SOCKET, SO_SNDBUF, (void *)&i_val,
- sizeof( i_val ) );
-
- /* Allow broadcast sending */
- i_val = 1;
- setsockopt( fd, SOL_SOCKET, SO_BROADCAST, (void*)&i_val,
- sizeof( i_val ) );
- }
+ /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s)
+ * to avoid packet loss caused by scheduling problems */
+ setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &(int){ 0x80000 }, sizeof (int));
+ setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &(int){ 0x80000 }, sizeof (int));
+
+ /* Allow broadcast sending */
+ setsockopt (fd, SOL_SOCKET, SO_BROADCAST, &(int){ 1 }, sizeof (int));
#endif
if( i_hlim > 0 )
net_SetMcastHopLimit( p_this, fd, ptr->ai_family, i_hlim );
- psz_mif = config_GetPsz( p_this, (ptr->ai_family != AF_INET)
- ? "miface" : "miface-addr" );
- if( psz_mif != NULL )
+
+ str = var_CreateGetString (p_this, "miface");
+ if (str != NULL)
+ {
+ net_SetMcastOut (p_this, fd, ptr->ai_family, str, NULL);
+ free (str);
+ }
+
+ str = var_CreateGetString (p_this, "miface-addr");
+ if (str != NULL)
{
- net_SetMcastIface( p_this, fd, ptr->ai_family, psz_mif );
- free( psz_mif );
+ net_SetMcastOut (p_this, fd, ptr->ai_family, NULL, str);
+ free (str);
}
+ net_SetDSCP (fd, var_CreateGetInteger (p_this, "dscp"));
+
if( connect( fd, ptr->ai_addr, ptr->ai_addrlen ) == 0 )
{
/* success */