@@ -22,17 +22,23 @@ static bool
2222textual_addr_to_sockaddr (const char * textual , int port , struct sockaddr * out ,
2323 socklen_t * out_len )
2424{
25- struct sockaddr_in * v4 ;
25+ struct sockaddr_in * v4 = ( struct sockaddr_in * ) out ;
2626#ifdef IPPROTO_IPV6
2727 struct sockaddr_in6 * v6 ;
2828#endif
2929
3030 assert (textual );
3131
32- v4 = (struct sockaddr_in * )out ;
3332 if (zsock_inet_pton (AF_INET , textual , & v4 -> sin_addr .s_addr ) == 1 ) {
3433 v4 -> sin_family = AF_INET ;
3534 v4 -> sin_port = htons (port );
35+ /**
36+ * In `zephyr_socket.c` the method `textual_addr_to_sockaddr` takes the
37+ * multicast address of "224.0.0.22" and properly sets the sockaddr.
38+ * However, this fails when binding to the adapter for some reason.
39+ * Setting this to “0.0.0.0” works. This appears to be a bug in Zephyr.
40+ */
41+ v4 -> sin_addr .s_addr = htonl (INADDR_ANY );
3642 * out_len = sizeof (struct sockaddr_in );
3743 return true;
3844 }
@@ -923,10 +929,23 @@ os_socket_set_ip_add_membership(bh_socket_t socket,
923929 mreq .imr_multiaddr .s_addr = imr_multiaddr -> ipv4 ;
924930 mreq .imr_address .s_addr = imr_interface ;
925931
926- if (zsock_setsockopt (socket -> fd , IPPROTO_IP , IP_ADD_MEMBERSHIP , & mreq ,
927- sizeof (mreq ))
928- != 0 ) {
929- return BHT_ERROR ;
932+ int ret = zsock_setsockopt (socket -> fd , IPPROTO_IP , IP_ADD_MEMBERSHIP ,
933+ & mreq , sizeof (mreq ));
934+ if (ret != 0 ) {
935+ /* Treat certain errors as non-fatal for multicast membership.
936+ * These conditions indicate the operation is either already
937+ * complete or not supported by the network stack, but shouldn't
938+ * prevent the application from continuing. This improves
939+ * compatibility across different Zephyr network configurations. */
940+ switch (errno ) {
941+ case EALREADY : /* already joined: OK */
942+ case EADDRINUSE : /* duplicate membership: OK */
943+ case ENOPROTOOPT : /* option not supported: treat as soft-OK */
944+ case ENOSYS : /* not implemented: soft-OK */
945+ return BHT_OK ;
946+ default :
947+ return BHT_ERROR ;
948+ }
930949 }
931950 }
932951 return BHT_OK ;
@@ -964,10 +983,23 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
964983 mreq .imr_multiaddr .s_addr = imr_multiaddr -> ipv4 ;
965984 mreq .imr_address .s_addr = imr_interface ;
966985
967- if (zsock_setsockopt (socket -> fd , IPPROTO_IP , IP_DROP_MEMBERSHIP , & mreq ,
968- sizeof (mreq ))
969- != 0 ) {
970- return BHT_ERROR ;
986+ int ret = zsock_setsockopt (socket -> fd , IPPROTO_IP , IP_ADD_MEMBERSHIP ,
987+ & mreq , sizeof (mreq ));
988+ if (ret != 0 ) {
989+ /* Treat certain errors as non-fatal for multicast membership.
990+ * These conditions indicate the operation is either already
991+ * complete or not supported by the network stack, but shouldn't
992+ * prevent the application from continuing. This improves
993+ * compatibility across different Zephyr network configurations. */
994+ switch (errno ) {
995+ case EALREADY : /* already joined: OK */
996+ case EADDRINUSE : /* duplicate membership: OK */
997+ case ENOPROTOOPT : /* option not supported: treat as soft-OK */
998+ case ENOSYS : /* not implemented: soft-OK */
999+ return BHT_OK ;
1000+ default :
1001+ return BHT_ERROR ;
1002+ }
9711003 }
9721004 }
9731005 return BHT_OK ;
0 commit comments