Skip to content

Commit b59edc1

Browse files
committed
Implement functions required for pub/sub
Signed-off-by: Dan Kouba <dan@atym.io>
1 parent d92e4b1 commit b59edc1

1 file changed

Lines changed: 98 additions & 50 deletions

File tree

core/shared/platform/zephyr/zephyr_socket.c

Lines changed: 98 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -900,54 +900,100 @@ os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
900900
int
901901
os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
902902
{
903-
errno = ENOSYS;
903+
int opt = is_enabled ? 1 : 0;
904+
int ret;
904905

905-
return BHT_ERROR;
906+
#ifdef IPPROTO_IPV6
907+
if (ipv6) {
908+
ret = zsock_setsockopt(socket->fd, IPPROTO_IPV6,
909+
IPV6_MULTICAST_LOOP, &opt, sizeof(opt));
910+
} else
911+
#endif
912+
{
913+
ret = zsock_setsockopt(socket->fd, IPPROTO_IP,
914+
IP_MULTICAST_LOOP, &opt, sizeof(opt));
915+
}
916+
917+
if (ret != 0) {
918+
/* Best-effort: some stacks don’t support this; don’t hard-fail */
919+
if (errno == ENOPROTOOPT || errno == ENOSYS) {
920+
return BHT_OK;
921+
}
922+
return BHT_ERROR;
923+
}
924+
return BHT_OK;
906925
}
907926

908927
int
909928
os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled)
910929
{
911-
errno = ENOSYS;
930+
int opt = 0;
931+
socklen_t len = sizeof(opt);
932+
int ret;
912933

913-
return BHT_ERROR;
934+
#ifdef IPPROTO_IPV6
935+
if (ipv6) {
936+
ret = zsock_getsockopt(socket->fd, IPPROTO_IPV6,
937+
IPV6_MULTICAST_LOOP, &opt, &len);
938+
} else
939+
#endif
940+
{
941+
ret = zsock_getsockopt(socket->fd, IPPROTO_IP,
942+
IP_MULTICAST_LOOP, &opt, &len);
943+
}
944+
945+
if (ret != 0) {
946+
if (errno == ENOPROTOOPT || errno == ENOSYS) {
947+
/* Report “disabled” if the stack doesn’t expose the knob */
948+
*is_enabled = false;
949+
return BHT_OK;
950+
}
951+
return BHT_ERROR;
952+
}
953+
954+
*is_enabled = (opt != 0);
955+
return BHT_OK;
914956
}
915957

958+
916959
int
917960
os_socket_set_ip_add_membership(bh_socket_t socket,
918961
bh_ip_addr_buffer_t *imr_multiaddr,
919962
uint32_t imr_interface, bool is_ipv6)
920963
{
921964
assert(imr_multiaddr);
922965

923-
if (is_ipv6) {
924-
#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN)
925-
struct ipv6_mreq mreq;
966+
int ret = -1;
926967

927-
for (int i = 0; i < 8; i++) {
928-
((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] =
929-
imr_multiaddr->ipv6[i];
930-
}
931-
mreq.ipv6mr_interface = imr_interface;
968+
#ifdef IPPROTO_IPV6
969+
if (is_ipv6) {
970+
struct ipv6_mreq mreq6 = {0};
971+
memcpy(&mreq6.ipv6mr_multiaddr,
972+
&imr_multiaddr->ipv6[0], sizeof(mreq6.ipv6mr_multiaddr));
973+
mreq6.ipv6mr_interface = imr_interface; /* 0 ⇒ first suitable iface */
932974

933-
if (zsock_setsockopt(socket->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq,
934-
sizeof(mreq))
935-
!= 0) {
936-
return BHT_ERROR;
937-
}
938-
#else
939-
errno = EAFNOSUPPORT;
940-
return BHT_ERROR;
975+
ret = zsock_setsockopt(socket->fd, IPPROTO_IPV6,
976+
IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6));
977+
} else
941978
#endif
942-
}
943-
else {
944-
struct ip_mreqn mreq;
979+
{
980+
struct ip_mreqn mreq = {0};
945981
mreq.imr_multiaddr.s_addr = imr_multiaddr->ipv4;
946-
mreq.imr_address.s_addr = imr_interface;
982+
mreq.imr_address.s_addr = imr_interface; /* 0 ⇒ first suitable iface */
983+
/* mreq.imr_ifindex is optional; leave 0 unless you have an index */
984+
985+
ret = zsock_setsockopt(socket->fd, IPPROTO_IP,
986+
IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
987+
}
947988

948-
if (zsock_setsockopt(socket->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
949-
sizeof(mreq))
950-
!= 0) {
989+
if (ret != 0) {
990+
switch (errno) {
991+
case EALREADY: /* already joined: OK */
992+
case EADDRINUSE: /* duplicate membership: OK */
993+
case ENOPROTOOPT: /* option not supported: treat as soft-OK */
994+
case ENOSYS: /* not implemented: soft-OK */
995+
return BHT_OK;
996+
default:
951997
return BHT_ERROR;
952998
}
953999
}
@@ -961,34 +1007,36 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
9611007
{
9621008
assert(imr_multiaddr);
9631009

964-
if (is_ipv6) {
965-
#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN)
966-
struct ipv6_mreq mreq;
1010+
int ret = -1;
9671011

968-
for (int i = 0; i < 8; i++) {
969-
((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] =
970-
imr_multiaddr->ipv6[i];
971-
}
972-
mreq.ipv6mr_interface = imr_interface;
1012+
#ifdef IPPROTO_IPV6
1013+
if (is_ipv6) {
1014+
struct ipv6_mreq mreq6 = {0};
1015+
memcpy(&mreq6.ipv6mr_multiaddr,
1016+
&imr_multiaddr->ipv6[0], sizeof(mreq6.ipv6mr_multiaddr));
1017+
mreq6.ipv6mr_interface = imr_interface;
9731018

974-
if (zsock_setsockopt(socket->fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP,
975-
&mreq, sizeof(mreq))
976-
!= 0) {
977-
return BHT_ERROR;
978-
}
979-
#else
980-
errno = EAFNOSUPPORT;
981-
return BHT_ERROR;
1019+
ret = zsock_setsockopt(socket->fd, IPPROTO_IPV6,
1020+
IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
1021+
} else
9821022
#endif
983-
}
984-
else {
985-
struct ip_mreqn mreq;
1023+
{
1024+
struct ip_mreqn mreq = {0};
9861025
mreq.imr_multiaddr.s_addr = imr_multiaddr->ipv4;
987-
mreq.imr_address.s_addr = imr_interface;
1026+
mreq.imr_address.s_addr = imr_interface;
9881027

989-
if (zsock_setsockopt(socket->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq,
990-
sizeof(mreq))
991-
!= 0) {
1028+
ret = zsock_setsockopt(socket->fd, IPPROTO_IP,
1029+
IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
1030+
}
1031+
1032+
if (ret != 0) {
1033+
switch (errno) {
1034+
case ENOENT: /* not a member: OK */
1035+
case EINVAL: /* some stacks use this for “not joined” */
1036+
case ENOPROTOOPT:
1037+
case ENOSYS:
1038+
return BHT_OK;
1039+
default:
9921040
return BHT_ERROR;
9931041
}
9941042
}

0 commit comments

Comments
 (0)