@@ -378,7 +378,7 @@ int8_t _z_open_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoin
378
378
}
379
379
380
380
int8_t _z_listen_udp_multicast (_z_sys_net_socket_t * sock , const _z_sys_net_endpoint_t rep , uint32_t tout ,
381
- const char * iface ) {
381
+ const char * iface , const char * join ) {
382
382
int8_t ret = _Z_RES_OK ;
383
383
384
384
struct sockaddr * lsockaddr = NULL ;
@@ -393,32 +393,35 @@ int8_t _z_listen_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpo
393
393
ret = _Z_ERR_GENERIC ;
394
394
}
395
395
396
- int optflag = 1 ;
397
- if ((ret == _Z_RES_OK ) &&
398
- (setsockopt (sock -> _fd , SOL_SOCKET , SO_REUSEADDR , (char * )& optflag , sizeof (optflag )) < 0 )) {
396
+ int value = true;
397
+ if ((ret == _Z_RES_OK ) && (setsockopt (sock -> _fd , SOL_SOCKET , SO_REUSEADDR , & value , sizeof (value )) < 0 )) {
399
398
ret = _Z_ERR_GENERIC ;
400
399
}
401
-
402
- #if defined(ZENOH_MACOS ) || defined(ZENOH_BSD )
403
- if ((ret == _Z_RES_OK ) && (bind (sock -> _fd , rep ._iptcp -> ai_addr , rep ._iptcp -> ai_addrlen ) < 0 )) {
400
+ if ((ret == _Z_RES_OK ) && (setsockopt (sock -> _fd , SOL_SOCKET , SO_REUSEPORT , & value , sizeof (value )) < 0 )) {
404
401
ret = _Z_ERR_GENERIC ;
405
402
}
406
- #elif defined( ZENOH_LINUX )
403
+
407
404
if (rep ._iptcp -> ai_family == AF_INET ) {
408
- struct sockaddr_in address = {AF_INET , ((struct sockaddr_in * )rep ._iptcp -> ai_addr )-> sin_port , {0 }, {0 }};
409
- if ((ret == _Z_RES_OK ) && (bind (sock -> _fd , (struct sockaddr * )& address , sizeof address ) < 0 )) {
405
+ struct sockaddr_in address ;
406
+ (void )memset (& address , 0 , sizeof (address ));
407
+ address .sin_family = rep ._iptcp -> ai_family ;
408
+ address .sin_port = ((struct sockaddr_in * )rep ._iptcp -> ai_addr )-> sin_port ;
409
+ inet_pton (address .sin_family , "0.0.0.0" , & address .sin_addr );
410
+ if ((ret == _Z_RES_OK ) && (bind (sock -> _fd , (struct sockaddr * )& address , sizeof (address )) < 0 )) {
410
411
ret = _Z_ERR_GENERIC ;
411
412
}
412
413
} else if (rep ._iptcp -> ai_family == AF_INET6 ) {
413
- struct sockaddr_in6 address = {
414
- AF_INET6 , ((struct sockaddr_in6 * )rep ._iptcp -> ai_addr )-> sin6_port , 0 , {{{0 }}}, 0 };
415
- if ((ret == _Z_RES_OK ) && (bind (sock -> _fd , (struct sockaddr * )& address , sizeof address ) < 0 )) {
414
+ struct sockaddr_in6 address ;
415
+ (void )memset (& address , 0 , sizeof (address ));
416
+ address .sin6_family = rep ._iptcp -> ai_family ;
417
+ address .sin6_port = ((struct sockaddr_in6 * )rep ._iptcp -> ai_addr )-> sin6_port ;
418
+ inet_pton (address .sin6_family , "::" , & address .sin6_addr );
419
+ if ((ret == _Z_RES_OK ) && (bind (sock -> _fd , (struct sockaddr * )& address , sizeof (address )) < 0 )) {
416
420
ret = _Z_ERR_GENERIC ;
417
421
}
418
422
} else {
419
423
ret = _Z_ERR_GENERIC ;
420
424
}
421
- #endif
422
425
423
426
// Join the multicast group
424
427
if (rep ._iptcp -> ai_family == AF_INET ) {
@@ -443,6 +446,32 @@ int8_t _z_listen_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpo
443
446
} else {
444
447
ret = _Z_ERR_GENERIC ;
445
448
}
449
+ // Join any additional multicast group
450
+ if (join != NULL ) {
451
+ char * joins = _z_str_clone (join );
452
+ for (char * ip = strsep (& joins , "|" ); ip != NULL ; ip = strsep (& joins , "|" )) {
453
+ if (rep ._iptcp -> ai_family == AF_INET ) {
454
+ struct ip_mreq mreq ;
455
+ (void )memset (& mreq , 0 , sizeof (mreq ));
456
+ inet_pton (rep ._iptcp -> ai_family , ip , & mreq .imr_multiaddr );
457
+ mreq .imr_interface .s_addr = ((struct sockaddr_in * )lsockaddr )-> sin_addr .s_addr ;
458
+ if ((ret == _Z_RES_OK ) &&
459
+ (setsockopt (sock -> _fd , IPPROTO_IP , IP_ADD_MEMBERSHIP , & mreq , sizeof (mreq )) < 0 )) {
460
+ ret = _Z_ERR_GENERIC ;
461
+ }
462
+ } else if (rep ._iptcp -> ai_family == AF_INET6 ) {
463
+ struct ipv6_mreq mreq ;
464
+ (void )memset (& mreq , 0 , sizeof (mreq ));
465
+ inet_pton (rep ._iptcp -> ai_family , ip , & mreq .ipv6mr_multiaddr );
466
+ mreq .ipv6mr_interface = if_nametoindex (iface );
467
+ if ((ret == _Z_RES_OK ) &&
468
+ (setsockopt (sock -> _fd , IPPROTO_IPV6 , IPV6_JOIN_GROUP , & mreq , sizeof (mreq )) < 0 )) {
469
+ ret = _Z_ERR_GENERIC ;
470
+ }
471
+ }
472
+ }
473
+ z_free (joins );
474
+ }
446
475
447
476
if (ret != _Z_RES_OK ) {
448
477
close (sock -> _fd );
0 commit comments