Skip to content

Commit

Permalink
Merge pull request #312 from mrdeep1/group_reg
Browse files Browse the repository at this point in the history
Fix mcast registrations when using TCP
  • Loading branch information
obgm authored Apr 12, 2019
2 parents 3bd5f48 + fda991f commit 1d48484
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 132 deletions.
66 changes: 1 addition & 65 deletions examples/coap-rd.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,70 +611,6 @@ get_context(const char *node, const char *port) {
return ctx;
}

static int
join(coap_context_t *ctx, char *group_name) {
struct ipv6_mreq mreq;
struct addrinfo *reslocal = NULL, *resmulti = NULL, hints, *ainfo;
int result = -1;

/* we have to resolve the link-local interface to get the interface id */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;

result = getaddrinfo("::", NULL, &hints, &reslocal);
if ( result != 0 ) {
fprintf( stderr, "join: cannot resolve link-local interface: %s\n", gai_strerror( result ) );
goto finish;
}

/* get the first suitable interface identifier */
for (ainfo = reslocal; ainfo != NULL; ainfo = ainfo->ai_next) {
if ( ainfo->ai_family == AF_INET6 ) {
mreq.ipv6mr_interface =
((struct sockaddr_in6 *)ainfo->ai_addr)->sin6_scope_id;
break;
}
}

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;

/* resolve the multicast group address */
result = getaddrinfo(group_name, NULL, &hints, &resmulti);

if ( result != 0 ) {
fprintf( stderr, "join: cannot resolve multicast address: %s\n", gai_strerror( result ) );
goto finish;
}

for (ainfo = resmulti; ainfo != NULL; ainfo = ainfo->ai_next) {
if ( ainfo->ai_family == AF_INET6 ) {
mreq.ipv6mr_multiaddr =
((struct sockaddr_in6 *)ainfo->ai_addr)->sin6_addr;
break;
}
}

if (ctx->endpoint) {
result = setsockopt(ctx->endpoint->sock.fd,
IPPROTO_IPV6, IPV6_JOIN_GROUP,
(char *)&mreq, sizeof(mreq) );
if ( result == COAP_SOCKET_ERROR ) {
fprintf( stderr, "join: setsockopt: %s\n", coap_socket_strerror() );
}
} else {
result = -1;
}

finish:
freeaddrinfo(resmulti);
freeaddrinfo(reslocal);

return result;
}

int
main(int argc, char **argv) {
coap_context_t *ctx;
Expand Down Expand Up @@ -716,7 +652,7 @@ main(int argc, char **argv) {
return -1;

if (group)
join(ctx, group);
coap_join_mcast_group(ctx, group);

init_resources(ctx);

Expand Down
66 changes: 1 addition & 65 deletions examples/coap-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -866,70 +866,6 @@ get_context(const char *node, const char *port) {
return ctx;
}

static int
join(coap_context_t *ctx, char *group_name){
struct ipv6_mreq mreq;
struct addrinfo *reslocal = NULL, *resmulti = NULL, hints, *ainfo;
int result = -1;

/* we have to resolve the link-local interface to get the interface id */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;

result = getaddrinfo("::", NULL, &hints, &reslocal);
if (result != 0) {
fprintf(stderr, "join: cannot resolve link-local interface: %s\n",
gai_strerror(result));
goto finish;
}

/* get the first suitable interface identifier */
for (ainfo = reslocal; ainfo != NULL; ainfo = ainfo->ai_next) {
if (ainfo->ai_family == AF_INET6) {
mreq.ipv6mr_interface =
((struct sockaddr_in6 *)ainfo->ai_addr)->sin6_scope_id;
break;
}
}

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;

/* resolve the multicast group address */
result = getaddrinfo(group_name, NULL, &hints, &resmulti);

if (result != 0) {
fprintf(stderr, "join: cannot resolve multicast address: %s\n",
gai_strerror(result));
goto finish;
}

for (ainfo = resmulti; ainfo != NULL; ainfo = ainfo->ai_next) {
if (ainfo->ai_family == AF_INET6) {
mreq.ipv6mr_multiaddr =
((struct sockaddr_in6 *)ainfo->ai_addr)->sin6_addr;
break;
}
}

if (ctx->endpoint) {
result = setsockopt(ctx->endpoint->sock.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq, sizeof(mreq));
if ( result == COAP_SOCKET_ERROR ) {
fprintf( stderr, "join: setsockopt: %s\n", coap_socket_strerror() );
}
} else {
result = -1;
}

finish:
freeaddrinfo(resmulti);
freeaddrinfo(reslocal);

return result;
}

static ssize_t
cmdline_read_key(char *arg, unsigned char *buf, size_t maxlen) {
size_t len = strnlen(arg, maxlen);
Expand Down Expand Up @@ -1030,7 +966,7 @@ main(int argc, char **argv) {

/* join multicast group if requested at command line */
if (group)
join(ctx, group);
coap_join_mcast_group(ctx, group);

#ifdef _WIN32
signal(SIGINT, handle_sigint);
Expand Down
11 changes: 11 additions & 0 deletions include/coap2/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,4 +739,15 @@ coap_pdu_t *coap_wellknown_response(coap_context_t *context,
*/
unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r);

/**
* Function interface for joining a multicast group for listening
*
* @param ctx The current context
* @param groupname The name of the group that is to be joined for listening
*
* @return 0 on success, -1 on error
*/
int
coap_join_mcast_group(coap_context_t *ctx, const char *groupname);

#endif /* COAP_NET_H_ */
1 change: 1 addition & 0 deletions libcoap-2.map
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ global:
coap_insert_node;
coap_insert_optlist;
coap_is_mcast;
coap_join_mcast_group;
coap_log_impl;
coap_malloc_endpoint;
coap_malloc_type;
Expand Down
1 change: 1 addition & 0 deletions libcoap-2.sym
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ coap_hash_impl
coap_insert_node
coap_insert_optlist
coap_is_mcast
coap_join_mcast_group
coap_log_impl
coap_malloc_endpoint
coap_malloc_type
Expand Down
4 changes: 2 additions & 2 deletions man/coap-rd.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ verbosity level is set to '5'.

* Example
----
coap-rd -A 2001:db8:81a8:0:6ef0:dead:feed:beef -g FF02:FD
coap-rd -A 2001:db8:81a8:0:6ef0:dead:feed:beef -g FF02::FD
----
Set listening address to '2001:db8:81a8:0:6ef0:dead:feed:beef' and join the
All CoAP Nodes multicast group 'FF02:FD'.
All CoAP Nodes multicast group 'FF02::FD'.

FILES
------
Expand Down
89 changes: 89 additions & 0 deletions src/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <ws2tcpip.h>
#endif

#include <netdb.h>

#ifdef WITH_LWIP
#include <lwip/pbuf.h>
#include <lwip/udp.h>
Expand Down Expand Up @@ -2366,6 +2368,93 @@ void coap_cleanup(void) {
#endif
}

#if ! defined WITH_CONTIKI && ! defined WITH_LWIP
int
coap_join_mcast_group(coap_context_t *ctx, const char *group_name) {
struct ipv6_mreq mreq;
struct addrinfo *reslocal = NULL, *resmulti = NULL, hints, *ainfo;
int result = -1;
coap_endpoint_t *endpoint;
int mgroup_setup = 0;

/* we have to resolve the link-local interface to get the interface id */
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;

result = getaddrinfo("::", NULL, &hints, &reslocal);
if (result != 0) {
coap_log(LOG_ERR,
"coap_join_mcast_group: cannot resolve link-local interface: %s\n",
gai_strerror(result));
goto finish;
}

/* get the first suitable interface identifier */
for (ainfo = reslocal; ainfo != NULL; ainfo = ainfo->ai_next) {
if (ainfo->ai_family == AF_INET6) {
mreq.ipv6mr_interface =
((struct sockaddr_in6 *)ainfo->ai_addr)->sin6_scope_id;
break;
}
}

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;

/* resolve the multicast group address */
result = getaddrinfo(group_name, NULL, &hints, &resmulti);

if (result != 0) {
coap_log(LOG_ERR,
"coap_join_mcast_group: cannot resolve multicast address: %s\n",
gai_strerror(result));
goto finish;
}

for (ainfo = resmulti; ainfo != NULL; ainfo = ainfo->ai_next) {
if (ainfo->ai_family == AF_INET6) {
mreq.ipv6mr_multiaddr =
((struct sockaddr_in6 *)ainfo->ai_addr)->sin6_addr;
break;
}
}

LL_FOREACH(ctx->endpoint, endpoint) {
if (endpoint->proto == COAP_PROTO_UDP ||
endpoint->proto == COAP_PROTO_DTLS) {
result = setsockopt(endpoint->sock.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
(char *)&mreq, sizeof(mreq));
if (result == COAP_SOCKET_ERROR) {
coap_log(LOG_ERR,
"coap_join_mcast_group: setsockopt: %s: '%s'\n",
coap_socket_strerror(), group_name);
}
else {
mgroup_setup = 1;
}
}
}
if (!mgroup_setup) {
result = -1;
}

finish:
freeaddrinfo(resmulti);
freeaddrinfo(reslocal);

return result;
}
#else /* defined WITH_CONTIKI || defined WITH_LWIP */
int
coap_join_mcast_group(coap_context_t *ctx, const char *group_name) {
(void)ctx;
(void)group_name;
return -1;
}
#endif /* defined WITH_CONTIKI || defined WITH_LWIP */

#ifdef WITH_CONTIKI

/*---------------------------------------------------------------------------*/
Expand Down

0 comments on commit 1d48484

Please sign in to comment.