@@ -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_in * 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 }
@@ -173,7 +179,7 @@ os_socket_getbooloption(bh_socket_t socket, int level, int optname,
173179 int optval ;
174180 socklen_t optval_size = sizeof (optval );
175181
176- if (zsock_setsockopt (socket -> fd , level , optname , & optval , optval_size )
182+ if (zsock_getsockopt (socket -> fd , level , optname , & optval , & optval_size )
177183 != 0 ) {
178184 return BHT_ERROR ;
179185 }
@@ -190,7 +196,7 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
190196
191197 * (sock ) = BH_MALLOC (sizeof (zephyr_handle ));
192198
193- if (!sock ) {
199+ if (!* sock ) {
194200 return BHT_ERROR ;
195201 }
196202
@@ -262,8 +268,13 @@ os_socket_settimeout(bh_socket_t socket, uint64 timeout_us)
262268 timeout .tv_sec = timeout_us / 1000000 ;
263269 timeout .tv_usec = timeout_us % 1000000 ;
264270
265- return zsock_setsockopt (socket -> fd , SOL_SOCKET , SO_RCVTIMEO , & timeout ,
266- sizeof (timeout ));
271+ if (zsock_setsockopt (socket -> fd , SOL_SOCKET , SO_RCVTIMEO , & timeout ,
272+ sizeof (timeout ))
273+ != 0 ) {
274+ return BHT_ERROR ;
275+ }
276+
277+ return BHT_OK ;
267278}
268279
269280int
@@ -277,7 +288,7 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
277288 unsigned int * addrlen )
278289{
279290 * sock = BH_MALLOC (sizeof (zephyr_handle ));
280- if (!sock ) {
291+ if (!* sock ) {
281292 return BHT_ERROR ;
282293 }
283294
@@ -609,7 +620,7 @@ os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
609620 struct timeval tv ;
610621 socklen_t tv_len = sizeof (tv );
611622
612- if (zsock_setsockopt (socket -> fd , SOL_SOCKET , SO_SNDTIMEO , & tv , tv_len )
623+ if (zsock_getsockopt (socket -> fd , SOL_SOCKET , SO_SNDTIMEO , & tv , & tv_len )
613624 != 0 ) {
614625 return BHT_ERROR ;
615626 }
@@ -639,7 +650,7 @@ os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
639650 struct timeval tv ;
640651 socklen_t tv_len = sizeof (tv );
641652
642- if (zsock_setsockopt (socket -> fd , SOL_SOCKET , SO_RCVTIMEO , & tv , tv_len )
653+ if (zsock_getsockopt (socket -> fd , SOL_SOCKET , SO_RCVTIMEO , & tv , & tv_len )
643654 != 0 ) {
644655 return BHT_ERROR ;
645656 }
@@ -693,21 +704,18 @@ os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
693704 return BHT_ERROR ;
694705}
695706
696- // TCP_NODELAY Disable TCP buffering (ignored, for compatibility)
697707int
698708os_socket_set_tcp_no_delay (bh_socket_t socket , bool is_enabled )
699709{
700- errno = ENOSYS ;
701-
702- return BHT_ERROR ;
710+ return os_socket_setbooloption (socket , IPPROTO_TCP , TCP_NODELAY ,
711+ is_enabled );
703712}
704713
705714int
706715os_socket_get_tcp_no_delay (bh_socket_t socket , bool * is_enabled )
707716{
708- errno = ENOSYS ;
709-
710- return BHT_ERROR ;
717+ return os_socket_getbooloption (socket , IPPROTO_TCP , TCP_NODELAY ,
718+ is_enabled );
711719}
712720
713721int
@@ -760,17 +768,17 @@ os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32_t *time_s)
760768 socklen_t time_s_len = sizeof (time_s_int );
761769
762770#ifdef TCP_KEEPIDLE
763- if (zsock_setsockopt (socket -> fd , IPPROTO_TCP , TCP_KEEPIDLE , & time_s_int ,
764- time_s_len )
771+ if (zsock_getsockopt (socket -> fd , IPPROTO_TCP , TCP_KEEPIDLE , & time_s_int ,
772+ & time_s_len )
765773 != 0 ) {
766774 return BHT_ERROR ;
767775 }
768776 * time_s = (uint32 )time_s_int ;
769777
770778 return BHT_OK ;
771779#elif defined(TCP_KEEPALIVE )
772- if (zsock_setsockopt (socket -> fd , IPPROTO_TCP , TCP_KEEPALIVE , & time_s_int ,
773- time_s_len )
780+ if (zsock_getsockopt (socket -> fd , IPPROTO_TCP , TCP_KEEPALIVE , & time_s_int ,
781+ & time_s_len )
774782 != 0 ) {
775783 return BHT_ERROR ;
776784 }
@@ -856,17 +864,37 @@ os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
856864int
857865os_socket_set_ip_multicast_loop (bh_socket_t socket , bool ipv6 , bool is_enabled )
858866{
859- errno = ENOSYS ;
860-
861- return BHT_ERROR ;
867+ if (ipv6 ) {
868+ #ifdef IPPROTO_IPV6
869+ return os_socket_setbooloption (socket , IPPROTO_IPV6 ,
870+ IPV6_MULTICAST_LOOP , is_enabled );
871+ #else
872+ errno = EAFNOSUPPORT ;
873+ return BHT_ERROR ;
874+ #endif
875+ }
876+ else {
877+ return os_socket_setbooloption (socket , IPPROTO_IP , IP_MULTICAST_LOOP ,
878+ is_enabled );
879+ }
862880}
863881
864882int
865883os_socket_get_ip_multicast_loop (bh_socket_t socket , bool ipv6 , bool * is_enabled )
866884{
867- errno = ENOSYS ;
868-
869- return BHT_ERROR ;
885+ if (ipv6 ) {
886+ #ifdef IPPROTO_IPV6
887+ return os_socket_getbooloption (socket , IPPROTO_IPV6 ,
888+ IPV6_MULTICAST_LOOP , is_enabled );
889+ #else
890+ errno = EAFNOSUPPORT ;
891+ return BHT_ERROR ;
892+ #endif
893+ }
894+ else {
895+ return os_socket_getbooloption (socket , IPPROTO_IP , IP_MULTICAST_LOOP ,
896+ is_enabled );
897+ }
870898}
871899
872900int
@@ -901,10 +929,23 @@ os_socket_set_ip_add_membership(bh_socket_t socket,
901929 mreq .imr_multiaddr .s_addr = imr_multiaddr -> ipv4 ;
902930 mreq .imr_address .s_addr = imr_interface ;
903931
904- if (zsock_setsockopt (socket -> fd , IPPROTO_IP , IP_ADD_MEMBERSHIP , & mreq ,
905- sizeof (mreq ))
906- != 0 ) {
907- 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+ }
908949 }
909950 }
910951 return BHT_OK ;
@@ -942,10 +983,23 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
942983 mreq .imr_multiaddr .s_addr = imr_multiaddr -> ipv4 ;
943984 mreq .imr_address .s_addr = imr_interface ;
944985
945- if (zsock_setsockopt (socket -> fd , IPPROTO_IP , IP_DROP_MEMBERSHIP , & mreq ,
946- sizeof (mreq ))
947- != 0 ) {
948- 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+ }
9491003 }
9501004 }
9511005 return BHT_OK ;
@@ -965,13 +1019,13 @@ os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
9651019int
9661020os_socket_get_ip_ttl (bh_socket_t socket , uint8_t * ttl_s )
9671021{
968- socklen_t opt_len = sizeof (* ttl_s );
969-
970- if (zsock_setsockopt (socket -> fd , IPPROTO_IP , IP_MULTICAST_TTL , ttl_s ,
971- opt_len )
972- != 0 ) {
1022+ /* Use proper int for zsock_getsockopt */
1023+ int opt ;
1024+ socklen_t opt_len = sizeof (opt );
1025+ if (zsock_getsockopt (socket -> fd , IPPROTO_IP , IP_TTL , & opt , & opt_len ) != 0 ) {
9731026 return BHT_ERROR ;
9741027 }
1028+ * ttl_s = (uint8_t )opt ;
9751029
9761030 return BHT_OK ;
9771031}
@@ -991,13 +1045,15 @@ os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
9911045int
9921046os_socket_get_ip_multicast_ttl (bh_socket_t socket , uint8_t * ttl_s )
9931047{
994- socklen_t opt_len = sizeof (* ttl_s );
995-
996- if (zsock_setsockopt (socket -> fd , IPPROTO_IP , IP_MULTICAST_TTL , ttl_s ,
997- opt_len )
1048+ /* Use proper int for zsock_getsockopt */
1049+ int opt ;
1050+ socklen_t opt_len = sizeof (opt );
1051+ if (zsock_getsockopt (socket -> fd , IPPROTO_IP , IP_MULTICAST_TTL , & opt ,
1052+ & opt_len )
9981053 != 0 ) {
9991054 return BHT_ERROR ;
10001055 }
1056+ * ttl_s = (uint8_t )opt ;
10011057
10021058 return BHT_OK ;
10031059}
@@ -1059,4 +1115,4 @@ int
10591115os_poll (os_poll_file_handle * fds , os_nfds_t nfs , int timeout )
10601116{
10611117 return zsock_poll (fds , nfs , timeout );
1062- }
1118+ }
0 commit comments