#50 Multicast socket binds to

Library (32)

Hello everyone,

Using ccRTP to receive DVB data I have come across the following bug:
When opening a RTPSession on a multicast address, the underlying socket binds to address and issues a correct IGMP request.
IMHO this is an incorrect behaviour as the app receives any traffic sent to the same port even though it is sent to different addresses.
I have seen that this behaviour was introduced due to ccRTP not correctly sending out IGMP joins
(please see the following post: http://osdir.com/ml/gnu.ccrtp.devel/2003-07/msg00000.html\).
This "fix" has introduced this bug.

When binding to the multicast address, in my case (Ubuntu 8.10) the IGMP Joins are not sent out correctly, because commoncpp uses imr_ifindex instead of imr_interface.s_addr=INADDR_ANY for the IP_ADD_MEMBERSHIP call. (see commoncpp2-1.7.0/src/socket.cpp lines 1544-1574 - lines 1544-1559 are executed).
Recompiling the library with the __GNU__ flag for example, makes it work just fine.
I guess the various flags in line 1544 are for portability and I'm wondering why for a regular GNU/Linux system like Ubuntu 8.10 this is not the default behaviour - I hope that someone who knows this better can shed some light on it.

Once this issue is resolved, libccRTP can bind the socket to the correct multicast address and everything works just fine.

I attach the patch for ccrtp-1.7.0/src/ccrtp/rtp.h


  • Stefan Wehner

    Stefan Wehner - 2009-01-20

    Patch for ccrtp-1.7.0/src/ccrtp/rtp.h

  • Comment has been marked as spam. 

    You can see all pending comments posted by this user  here

    Anonymous - 2011-04-06

    Hi, some day ago I felt in the same problem and I fix it in this way.
    Assuming that for multicast reception we need:
    - a bind between the multicast group (using its address), its port and the interface to receive it
    - a join to the multicast address to enable the multicast traffic
    I've done these step:

    instantiate my rtp session giving the int representation of my NIC ip

    RTPSession(aMcastAddr, aPort, 0, 0, MembershipBookkeeping::defaultMembersHashSize, defaultApplication(), int(inet_addr([the ip of my nic]))),

    then the rtp.h is modified in this way:
    #if defined(__GNU__) && defined(IP_ADD_MEMBERSHIP_IF_ADDR)
    dso = new RTPDataChannel(InetHostAddress(ia.getAddress()),dataBasePort);
    cso = new RTCPChannel(InetHostAddress(ia.getAddress()),controlBasePort);
    dso = new RTPDataChannel(InetHostAddress(""),dataBasePort);
    cso = new RTCPChannel(InetHostAddress(""),controlBasePort);

    finally I've changed the file socket.cpp from the commonc++ library in this way:

    Socket::Error UDPSocket::join(const IPV4Multicast &ia,int InterfaceIndex)
    #if defined(WIN32) && defined(IP_ADD_MEMBERSHIP)
    #elif defined(IP_ADD_MEMBERSHIP) && defined(SIOCGIFINDEX) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) && !defined(_OSF_SOURCE) && !defined(__hpux) && !defined(__GNU__)
    #elif defined(IP_ADD_MEMBERSHIP_IF_ADDR) && defined(__GNU__)
    // No by index, use interface address
    struct ip_mreq group;
    struct sockaddr_in myaddr;
    socklen_t len = sizeof(myaddr);

    return error(errMulticastDisabled);
    getsockname(so, (struct sockaddr *)&myaddr, &len);
    memset(&group, sizeof(group), 0);
    group.imr_multiaddr.s_addr = ia.getAddress().s_addr;
    group.imr_interface.s_addr = InterfaceIndex; // the param is the interface address in byte reprepresentation, not the interface index!
    setsockopt(so, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group));
    return errSuccess;

    #elif defined(IP_ADD_MEMBERSHIP)

  • David Sugar

    David Sugar - 2012-11-18

    I have decided to keep this open for further review...

  • David Sugar

    David Sugar - 2012-11-18
    • milestone: --> Common_Libraries

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks