[Pkg-voip-commits] [janus] 179/282: Streaming plugin UDP multicast socket bind option to `SO_REUSEADDR`

Jonas Smedegaard dr at jones.dk
Wed Dec 20 21:53:39 UTC 2017


This is an automated email from the git hooks/post-receive script.

js pushed a commit to annotated tag debian/0.2.6-1
in repository janus.

commit 8a76e3a69d2228ede432a268fa852e08cb4ea145
Author: Bao Nguyen <ngqbao at gmail.com>
Date:   Sat Nov 11 17:36:34 2017 -0800

    Streaming plugin UDP multicast socket bind option to `SO_REUSEADDR`
    
    In multicast, SO_REUSEPORT and SO_REUSEADDR behaviors are identical.
    
    SO_REUSEPORT was added[1] to help unicast behave exactly like what SO_REUSEADDR
    already done for multicast. Using SO_REUSEPORT[2] instead of SO_REUSEADDR on
    multicast can cause incompatability with other software, such as ffmpeg[3]. When
    attempting to receive on the same set of address:port ffmpeg uses SO_REUSEADDR
    instead which cause binding to fail. Even though it's socket option is set with
    SO_REUSEADDR.
    
    ```
    host:~$  netstat -paun | grep 239.2.0.2
    udp        0      0 239.2.0.2:10000         0.0.0.0:*                           17051/janus
    udp        0      0 239.2.0.2:10000         0.0.0.0:*                           4102/janus
    udp        0      0 239.2.0.2:10000         0.0.0.0:*                           28619/janus
    udp        0      0 239.2.0.2:10000         0.0.0.0:*                           14662/janus
    udp        0      0 239.2.0.2:10001         0.0.0.0:*                           17051/janus
    udp        0      0 239.2.0.2:10001         0.0.0.0:*                           4102/janus
    udp        0      0 239.2.0.2:10001         0.0.0.0:*                           28619/janus
    udp        0      0 239.2.0.2:10001         0.0.0.0:*                           14662/janus
    
    setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
    bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("239.2.0.2")}, 16) = -1 EADDRINUSE (Address already in use)
    dup(2)                                  = 4
    fcntl(4, F_GETFL)                       = 0x8402 (flags O_RDWR|O_APPEND|O_LARGEFILE)
    ```
    
    For SO_REUSEPORT, when 2 processes want to share the same address/port part,
    their socket options must be identical during setup before bind()
    (plus the user ID, to prevent listening by another user [1]). Since these two
    sockets options are functionally identical for multicast, their option name is
    not for multicast. Changing `SO_REUSEADDR` for multicast and `SO_REUSEPORT` for
    Unicast fixes this incompatible issue.
    
    This fix is to address the issue pointed out in [4]
    
    ```
    socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
    setsockopt(3, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0
    bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("239.2.0.2")}, 16) = 0
    setsockopt(3, SOL_IP, IP_ADD_MEMBERSHIP, {imr_multiaddr=inet_addr("239.2.0.2"),
    
            int one = 1;
            if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != 0)
            //if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != 0)
            {
                perror("Error setting reuse flag");
                return 2;
            }
    
            // Bind to listening address.
            bind_addr.sin_family = AF_INET;
            bind_addr.sin_port = in->endpoints[i].port;
            if (in->endpoints[i].bind_any)
            {
                bind_addr.sin_addr.s_addr = INADDR_ANY;
            }
            else
            {
                memcpy(&(bind_addr.sin_addr),
                       &(in->endpoints[i].multicast),
                       sizeof(in->endpoints[i].multicast));
            }
            if (bind(s, (const struct sockaddr *)(&bind_addr),
                     sizeof(bind_addr)) != 0)
            {
                perror("Error binding to listening address");
                return 3;
            }
    ```
    
    [1] https://lwn.net/Articles/542629/
    [2] https://github.com/meetecho/janus-gateway/issues/617
    [3] https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/udp.c#L833
    [4] https://github.com/meetecho/janus-gateway/issues/1065
---
 plugins/janus_streaming.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/plugins/janus_streaming.c b/plugins/janus_streaming.c
index 02be58c..a46b240 100644
--- a/plugins/janus_streaming.c
+++ b/plugins/janus_streaming.c
@@ -2950,8 +2950,8 @@ static int janus_streaming_create_fd(int port, in_addr_t mcast, const janus_netw
 	/* If this is multicast, allow a re-use of the same ports (different groups may be used) */
 	if(port > 0 && IN_MULTICAST(ntohl(mcast))) {
 		int reuse = 1;
-		if(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(reuse)) == -1) {
-			JANUS_LOG(LOG_ERR, "[%s] %s listener setsockopt SO_REUSEPORT failed\n", mountpointname, listenername);
+		if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
+			JANUS_LOG(LOG_ERR, "[%s] %s listener setsockopt SO_REUSEADDR failed\n", mountpointname, listenername);
 			close(fd);
 			return -1;
 		}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/janus.git



More information about the Pkg-voip-commits mailing list