Note that there are some explanatory texts on larger screens.

plurals
  1. POMulticast groups Linux - Joining and Leaving
    primarykey
    data
    text
    <p>I am building a overlay network system to test a protocol (Uni research). I need to join and leave multicast groups in order to receive packets from different sources. </p> <p>I am unsure about the correct setup of the socket so I can close the socket and leave the multicast group and then rejoin the same multicast group later. When I try to join the same multicast group I get "<code>bind error: Address already in use</code>". </p> <pre><code>//for setting up individual groups int setUpForGroup(struct locgro_node* node, const char* port) { char mcastaddr[INET6_ADDRSTRLEN]; struct in6_addr* full_addr_gro = &amp;(node-&gt;group); if( NULL == inet_ntop(AF_INET6, full_addr_gro, mcastaddr, INET6_ADDRSTRLEN)) { printf("error inet_pton, retval: \n"); return -1; } if (buildAdd(mcastaddr, port, AF_INET6, SOCK_DGRAM, &amp;(node-&gt;addr_st)) &lt;0) { fprintf(stderr, "get_addr error:: could not find multicast, address=[%s] port=[%s]\n", mcastaddr, port); return -1; } node-&gt;sockfd = socket(AF_INET6, SOCK_DGRAM, 0); if (bind(node-&gt;sockfd, (struct sockaddr *)&amp;(node-&gt;addr_st), sizeof(node-&gt;addr_st)) &lt; 0) { perror("bind error:: "); close(node-&gt;sockfd); return -1; } if (joinGroup(node-&gt;sockfd, 0 , 8, &amp;(node-&gt;addr_st)) &lt;0) { close(node-&gt;sockfd); return -1; } return 0; } //internal function int joinGroup(int sockfd, int loopBack, int mcastTTL, struct sockaddr_in6 *addr_st) { int r1, r2, r3, retval; retval=-1; struct ipv6_mreq mreq6; memcpy(&amp;mreq6.ipv6mr_multiaddr, &amp;((addr_st)-&gt;sin6_addr), sizeof(struct in6_addr)); mreq6.ipv6mr_interface= 0; // allow any interface //set the loopback case r1 = setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &amp;loopBack, sizeof(loopBack)); if (r1&lt;0) perror("joinGroup:: IPV6_MULTICAST_LOOP:: "); /* setsockopt(sock_fd, IPPROTO_IPV6, SO_REUSEADDR, &amp;mreq6, sizeof(mreq6)); setsockopt(sock_fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &amp;multicast_req, sizeof(multicast_req)); */ //set the time to live for the packets (hops) r2 = setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &amp;mcastTTL, sizeof(mcastTTL)); if (r2&lt;0) perror("joinGroup:: IPV6_MULTICAST_HOPS:: "); //add this address to the group r3 = setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &amp;mreq6, sizeof(mreq6)); if (r3&lt;0) perror("joinGroup:: IPV6_ADD_MEMBERSHIP:: "); if ((r1&gt;=0) &amp;&amp; (r2&gt;=0) &amp;&amp; (r3&gt;=0)) retval=0; return retval; } //internal function int buildAdd(const char *hostname, const char *service, int family, int socktype, struct sockaddr_in6 *addr_st) { struct addrinfo hints, *res, *ressave; int n, sockfd, retval; retval = -1; memset(&amp;hints, 0, sizeof(struct addrinfo)); hints.ai_family = family; hints.ai_socktype = socktype; n = getaddrinfo(hostname, service, &amp;hints, &amp;res); if (n &lt;0) { fprintf(stderr, "getaddrinfo error: [%s]\n", gai_strerror(n)); return retval; } ressave = res; sockfd=-1; while(res) { sockfd = socket(res-&gt;ai_family, res-&gt;ai_socktype, res-&gt;ai_protocol); if (!(sockfd &lt; 0)) { int opval = 1; setsockopt(sockfd, IPPROTO_IPV6, SO_REUSEADDR, &amp;opval, res-&gt;ai_addrlen); if (bind(sockfd, res-&gt;ai_addr, res-&gt;ai_addrlen) == 0) { //to test that the address really is correct close(sockfd); memcpy(addr_st, res-&gt;ai_addr, sizeof(*addr_st)); retval=0; break; } perror("build addr : bind error"); close(sockfd); sockfd=-1; } res=res-&gt;ai_next; } freeaddrinfo(ressave); //free the struct return retval; } </code></pre> <p>This are the functions I used for joining a group. When leaving I simply do: (that happens inside another function)</p> <pre><code> struct ipv6_mreq mreq6; memcpy(&amp;mreq6.ipv6mr_multiaddr, &amp;(temp_lnode-&gt;group), sizeof(struct in6_addr)); mreq6.ipv6mr_interface= 0; // allow any interface setsockopt(temp_lnode-&gt;sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &amp;mreq6, sizeof(mreq6)); close(temp_lnode-&gt;sockfd); //close socket </code></pre> <p>I am getting a "Address already in use" error when I try to bind the address inside the build address function. I tried solving that by setting SO_REUSEADDR but it didn't help, also added the DROP_MEMBERSHIP but bind still fails. </p> <p>Do I need to bind in order to get it to work? What should I call or do to allow for joining and leaving of groups without this issues? I would need to do this during intervals of 30s. </p> <p>Thanks a lot M</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload