Skip to content

Commit

Permalink
udp multicast can now join multiple groups
Browse files Browse the repository at this point in the history
  • Loading branch information
p-avital committed Sep 20, 2023
1 parent ab578c2 commit 97f3b17
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 7 deletions.
9 changes: 7 additions & 2 deletions include/zenoh-pico/link/config/udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,25 @@

#if Z_LINK_UDP_UNICAST == 1 || Z_LINK_UDP_MULTICAST == 1

#define UDP_CONFIG_ARGC 2
#define UDP_CONFIG_ARGC 3

#define UDP_CONFIG_IFACE_KEY 0x01
#define UDP_CONFIG_IFACE_STR "iface"

#define UDP_CONFIG_TOUT_KEY 0x02
#define UDP_CONFIG_TOUT_STR "tout"

#define UDP_CONFIG_JOIN_KEY 0x03
#define UDP_CONFIG_JOIN_STR "join"

#define UDP_CONFIG_MAPPING_BUILD \
_z_str_intmapping_t args[UDP_CONFIG_ARGC]; \
args[0]._key = UDP_CONFIG_IFACE_KEY; \
args[0]._str = UDP_CONFIG_IFACE_STR; \
args[1]._key = UDP_CONFIG_TOUT_KEY; \
args[1]._str = UDP_CONFIG_TOUT_STR;
args[1]._str = UDP_CONFIG_TOUT_STR; \
args[2]._key = UDP_CONFIG_JOIN_KEY; \
args[2]._str = UDP_CONFIG_JOIN_STR;

size_t _z_udp_config_strlen(const _z_str_intmap_t *s);

Expand Down
2 changes: 1 addition & 1 deletion include/zenoh-pico/system/link/udp.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ size_t _z_send_udp_unicast(const _z_sys_net_socket_t sock, const uint8_t *ptr, s
int8_t _z_open_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t rep, _z_sys_net_endpoint_t *lep,
uint32_t tout, const char *iface);
int8_t _z_listen_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t rep, uint32_t tout,
const char *iface);
const char *iface, const char *join);
void _z_close_udp_multicast(_z_sys_net_socket_t *sockrecv, _z_sys_net_socket_t *socksend,
const _z_sys_net_endpoint_t rep);
size_t _z_read_exact_udp_multicast(const _z_sys_net_socket_t sock, uint8_t *ptr, size_t len,
Expand Down
1 change: 0 additions & 1 deletion src/link/config/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ char *_z_udp_config_to_str(const _z_str_intmap_t *s) {

int8_t _z_udp_config_from_strn(_z_str_intmap_t *strint, const char *s, size_t n) {
UDP_CONFIG_MAPPING_BUILD

return _z_str_intmap_from_strn(strint, s, UDP_CONFIG_ARGC, args, n);
}

Expand Down
4 changes: 3 additions & 1 deletion src/link/multicast/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ int8_t _z_f_link_listen_udp_multicast(_z_link_t *self) {
int8_t ret = _Z_RES_OK;

const char *iface = _z_str_intmap_get(&self->_endpoint._config, UDP_CONFIG_IFACE_KEY);
ret = _z_listen_udp_multicast(&self->_socket._udp._sock, self->_socket._udp._rep, Z_CONFIG_SOCKET_TIMEOUT, iface);
const char *join = _z_str_intmap_get(&self->_endpoint._config, UDP_CONFIG_JOIN_KEY);
ret = _z_listen_udp_multicast(&self->_socket._udp._sock, self->_socket._udp._rep, Z_CONFIG_SOCKET_TIMEOUT, iface,
join);
ret |= _z_open_udp_multicast(&self->_socket._udp._msock, self->_socket._udp._rep, &self->_socket._udp._lep,
Z_CONFIG_SOCKET_TIMEOUT, iface);

Expand Down
38 changes: 37 additions & 1 deletion src/system/unix/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ int8_t _z_open_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoin
}

int8_t _z_listen_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoint_t rep, uint32_t tout,
const char *iface) {
const char *iface, const char *join) {
int8_t ret = _Z_RES_OK;

struct sockaddr *lsockaddr = NULL;
Expand Down Expand Up @@ -443,6 +443,42 @@ int8_t _z_listen_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpo
} else {
ret = _Z_ERR_GENERIC;
}
if (join != NULL) {
char *joins = _z_str_clone(join);
struct addrinfo hints = {0};
hints.ai_family = PF_UNSPEC; // Allow IPv4 or IPv6
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
for (char *j = strsep(&joins, "|"); j != NULL; j = strsep(&joins, ";")) {
struct addrinfo *addr = NULL;
char *ip = strsep(&j, ":");
if (getaddrinfo(ip, j, &hints, &addr) < 0) {
ret = _Z_ERR_GENERIC;
}
if (addr->ai_family == AF_INET) {
struct ip_mreq mreq;
(void)memset(&mreq, 0, sizeof(mreq));
mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr->ai_addr)->sin_addr.s_addr;
mreq.imr_interface.s_addr = ((struct sockaddr_in *)lsockaddr)->sin_addr.s_addr;
if ((ret == _Z_RES_OK) &&
(setsockopt(sock->_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)) {
ret = _Z_ERR_GENERIC;
}
} else if (addr->ai_family == AF_INET6) {
struct ipv6_mreq mreq;
(void)memset(&mreq, 0, sizeof(mreq));
(void)memcpy(&mreq.ipv6mr_multiaddr, &((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr,
sizeof(struct in6_addr));
mreq.ipv6mr_interface = if_nametoindex(iface);
if ((ret == _Z_RES_OK) &&
(setsockopt(sock->_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) < 0)) {
ret = _Z_ERR_GENERIC;
}
}
freeaddrinfo(addr);
}
z_free(joins);
}

if (ret != _Z_RES_OK) {
close(sock->_fd);
Expand Down
2 changes: 1 addition & 1 deletion zenohpico.pc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ prefix=/usr/local
Name: zenohpico
Description:
URL:
Version: 0.10.20230915dev
Version: 0.10.20230920dev
Cflags: -I${prefix}/
Libs: -L${prefix}/ -lzenohpico

0 comments on commit 97f3b17

Please sign in to comment.