Changeset 495353bb08f93ba5b01caaa1cc7cb71d4a17fda4

Show
Ignore:
Timestamp:
20/10/06 21:16:25 (2 years ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1161371785 +0000
git-parent:

[e4f7eb8e91b05d9e56375119793bef68073b058e]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1161371785 +0000
Message:

- Support for setting DSCP via dscp option
- Support for setting outgoing IPv4 multicast interface

(note that only the Linux kernel can do that)

- Some cleaning/dirtying up

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • src/libvlc.h

    rc4ec9be r495353b  
    438438    "system built-in default).") 
    439439 
    440 #define MIFACE_TEXT N_("IPv6 multicast output interface") 
     440#define MIFACE_TEXT N_("Multicast output interface") 
    441441#define MIFACE_LONGTEXT N_( \ 
    442     "Default IPv6 multicast interface. This overrides the routing table.") 
     442    "Default multicast interface. This overrides the routing table.") 
    443443 
    444444#define MIFACE_ADDR_TEXT N_("IPv4 multicast output interface address") 
     
    446446    "IPv4 adress for the default multicast interface. This overrides " \ 
    447447    "the routing table.") 
     448 
     449#define DSCP_TEXT N_("DiffServ Code Point") 
     450#define DSCP_LONGTEXT N_("Differentiated Services Code Point " \ 
     451    "for outgoing UDP streams (or IPv4 Type Of Service, " \ 
     452    "or IPv6 Traffic Class). This is used for network Quality of Service.") 
    448453 
    449454#define INPUT_PROGRAM_TEXT N_("Program") 
     
    15361541    add_string( "miface", NULL, NULL, MIFACE_TEXT, MIFACE_LONGTEXT, VLC_TRUE ); 
    15371542    add_string( "miface-addr", NULL, NULL, MIFACE_ADDR_TEXT, MIFACE_ADDR_LONGTEXT, VLC_TRUE ); 
     1543    add_integer( "dscp", 0, NULL, DSCP_TEXT, DSCP_LONGTEXT, VLC_TRUE ); 
    15381544 
    15391545    set_subcategory( SUBCAT_SOUT_PACKETIZER ); 
  • src/network/udp.c

    re7ef1d9 r495353b  
    112112 
    113113 
    114 static int net_SetMcastIface( vlc_object_t *p_this, 
    115                               int fd, int family, const char *str ) 
    116 
    117     switch( family ) 
    118     { 
    119 #ifndef SYS_BEOS 
    120         case AF_INET: 
    121         { 
    122             struct in_addr addr; 
    123  
    124             if( inet_pton( AF_INET, str, &addr) <= 0 ) 
    125             { 
    126                 msg_Err( p_this, "Invalid multicast interface %s", str ); 
    127                 return VLC_EGENERIC; 
    128             } 
    129  
    130             if( setsockopt( fd, SOL_IP, IP_MULTICAST_IF, &addr, 
    131                             sizeof( addr ) ) < 0 ) 
    132             { 
    133                 msg_Err( p_this, "Cannot use %s as multicast interface: %s", 
    134                          str, strerror(errno) ); 
    135                 return VLC_EGENERIC; 
    136             } 
    137             break; 
    138         } 
    139 #endif /* SYS_BEOS */ 
    140  
     114static int net_SetMcastOutIface (int fd, int family, int scope) 
     115
     116    switch (family) 
     117    { 
    141118#ifdef IPV6_MULTICAST_IF 
    142119        case AF_INET6: 
    143         { 
    144             int scope = if_nametoindex( str ); 
    145  
    146             if( scope == 0 ) 
     120            return setsockopt (fd, SOL_IPV6, IPV6_MULTICAST_IF, 
     121                               &scope, sizeof (scope)); 
     122#endif 
     123 
     124#ifdef __linux__ 
     125        case AF_INET: 
     126        { 
     127            struct ip_mreqn req = { .imr_ifindex = scope }; 
     128 
     129            return setsockopt (fd, SOL_IP, IP_MULTICAST_IF, &req, 
     130                               sizeof (req)); 
     131        } 
     132#endif 
     133    } 
     134 
     135    errno = EAFNOSUPPORT; 
     136    return -1; 
     137
     138 
     139 
     140static inline int net_SetMcastOutIPv4 (int fd, struct in_addr ipv4) 
     141
     142#ifdef IP_MULTICAST_IF 
     143    return setsockopt( fd, SOL_IP, IP_MULTICAST_IF, &ipv4, sizeof (ipv4)); 
     144#else 
     145    errno = EAFNOSUPPORT; 
     146    return -1; 
     147#endif 
     148
     149 
     150 
     151static int net_SetMcastOut (vlc_object_t *p_this, int fd, int family, 
     152                            const char *iface, const char *addr) 
     153
     154    if (iface != NULL) 
     155    { 
     156        int scope = if_nametoindex (iface); 
     157        if (scope == 0) 
     158        { 
     159            msg_Err (p_this, "%s: invalid interface for multicast", iface); 
     160            return -1; 
     161        } 
     162 
     163        if (net_SetMcastOutIface (fd, family, scope) == 0) 
     164            return 0; 
     165 
     166        msg_Err (p_this, "%s: %s", iface, net_strerror (net_errno)); 
     167    } 
     168 
     169    if (addr != NULL) 
     170    { 
     171        if (family == AF_INET) 
     172        { 
     173            struct in_addr ipv4; 
     174            if (inet_pton (AF_INET, addr, &ipv4) <= 0) 
    147175            { 
    148                 msg_Err( p_this, "Invalid multicast interface %s", str ); 
    149                 return VLC_EGENERIC; 
     176                msg_Err (p_this, "%s: invalid IPv4 address for multicast", 
     177                         addr); 
     178                return -1; 
    150179            } 
    151180 
    152             if( setsockopt( fd, SOL_IPV6, IPV6_MULTICAST_IF, 
    153                             &scope, sizeof( scope ) ) < 0 ) 
    154             { 
    155                 msg_Err( p_this, "Cannot use %s as multicast interface: %s", 
    156                          str, strerror( errno ) ); 
    157                 return VLC_EGENERIC; 
    158             } 
    159             break; 
    160         } 
    161 #endif 
    162  
    163         default: 
    164             msg_Warn( p_this, "%s", strerror( EAFNOSUPPORT ) ); 
    165             return VLC_EGENERIC; 
    166     } 
    167  
    168     return VLC_SUCCESS; 
     181            if (net_SetMcastOutIPv4 (fd, ipv4) == 0) 
     182                return 0; 
     183 
     184            msg_Err (p_this, "%s: %s", addr, net_strerror (net_errno)); 
     185        } 
     186    } 
     187 
     188    return -1; 
    169189} 
    170190 
     
    237257    for( ptr = res; ptr != NULL; ptr = ptr->ai_next ) 
    238258    { 
    239         int fd; 
    240         char *psz_mif; 
    241  
    242         fd = net_Socket( p_this, ptr->ai_family, ptr->ai_socktype, 
    243                          ptr->ai_protocol ); 
    244         if( fd == -1 ) 
     259        char *str; 
     260        int fd = net_Socket (p_this, ptr->ai_family, ptr->ai_socktype, 
     261                             ptr->ai_protocol); 
     262        if (fd == -1) 
    245263            continue; 
     264 
    246265#if !defined( SYS_BEOS ) 
    247         else 
    248         { 
    249             int i_val; 
    250  
    251             /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s) 
    252              * to avoid packet loss caused by scheduling problems */ 
    253             i_val = 0x80000; 
    254             setsockopt( fd, SOL_SOCKET, SO_RCVBUF, (void *)&i_val, 
    255                         sizeof( i_val ) ); 
    256             i_val = 0x80000; 
    257             setsockopt( fd, SOL_SOCKET, SO_SNDBUF, (void *)&i_val, 
    258                         sizeof( i_val ) ); 
    259  
    260             /* Allow broadcast sending */ 
    261             i_val = 1; 
    262             setsockopt( fd, SOL_SOCKET, SO_BROADCAST, (void*)&i_val, 
    263                         sizeof( i_val ) ); 
    264         } 
     266        /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s) 
     267        * to avoid packet loss caused by scheduling problems */ 
     268        setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &(int){ 0x80000 }, sizeof (int)); 
     269        setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &(int){ 0x80000 }, sizeof (int)); 
     270 
     271        /* Allow broadcast sending */ 
     272        setsockopt (fd, SOL_SOCKET, SO_BROADCAST, &(int){ 1 }, sizeof (int)); 
    265273#endif 
    266274 
    267275        if( i_hlim > 0 ) 
    268276            net_SetMcastHopLimit( p_this, fd, ptr->ai_family, i_hlim ); 
    269         psz_mif = config_GetPsz( p_this, (ptr->ai_family != AF_INET) 
    270                                             ? "miface" : "miface-addr" ); 
    271         if( psz_mif != NULL ) 
    272         { 
    273             net_SetMcastIface( p_this, fd, ptr->ai_family, psz_mif ); 
    274             free( psz_mif ); 
    275         } 
     277 
     278        str = var_CreateGetString (p_this, "miface"); 
     279        if (str != NULL) 
     280        { 
     281            net_SetMcastOut (p_this, fd, ptr->ai_family, str, NULL); 
     282            free (str); 
     283        } 
     284 
     285        str = var_CreateGetString (p_this, "miface-addr"); 
     286        if (str != NULL) 
     287        { 
     288            net_SetMcastOut (p_this, fd, ptr->ai_family, NULL, str); 
     289            free (str); 
     290        } 
     291 
     292        net_SetDSCP (fd, var_CreateGetInteger (p_this, "dscp")); 
    276293 
    277294        if( connect( fd, ptr->ai_addr, ptr->ai_addrlen ) == 0 )