Skip to content

Commit d92e4b1

Browse files
committed
Changes to support open62541 client/server
Signed-off-by: Dan Kouba <dan@atym.io>
1 parent 7208703 commit d92e4b1

1 file changed

Lines changed: 104 additions & 66 deletions

File tree

core/shared/platform/zephyr/zephyr_socket.c

Lines changed: 104 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,34 @@ static bool
2222
textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr *out,
2323
socklen_t *out_len)
2424
{
25+
2526
struct sockaddr_in *v4;
2627
#ifdef IPPROTO_IPV6
27-
struct sockaddr_in *v6;
28+
struct sockaddr_in6 *v6;
2829
#endif
2930

3031
assert(textual);
32+
const char *t = textual;
33+
34+
/* Normalize localhost */
35+
if (strcmp(t, "localhost") == 0) {
36+
t = "127.0.0.1"; // Only IPV4 for now
37+
}
3138

3239
v4 = (struct sockaddr_in *)out;
33-
if (zsock_inet_pton(AF_INET, textual, &v4->sin_addr.s_addr) == 1) {
40+
if (zsock_inet_pton(AF_INET, t, &v4->sin_addr.s_addr) == 1) {
3441
v4->sin_family = AF_INET;
3542
v4->sin_port = htons(port);
3643
*out_len = sizeof(struct sockaddr_in);
3744
return true;
3845
}
3946

4047
#ifdef IPPROTO_IPV6
41-
v6 = (struct sockaddr_in *)out;
42-
if (zsock_inet_pton(AF_INET6, textual, &v6->sin6_addr.s6_addr) == 1) {
48+
v6 = (struct sockaddr_in6 *)out;
49+
if (zsock_inet_pton(AF_INET6, t, &v6->sin6_addr) == 1) {
4350
v6->sin6_family = AF_INET6;
4451
v6->sin6_port = htons(port);
45-
*out_len = sizeof(struct sockaddr_in);
52+
*out_len = sizeof(struct sockaddr_in6);
4653
return true;
4754
}
4855
#endif
@@ -67,7 +74,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr,
6774
#ifdef IPPROTO_IPV6
6875
case AF_INET6:
6976
{
70-
struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
77+
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)sockaddr;
7178
size_t i;
7279

7380
bh_sockaddr->port = ntohs(addr->sin6_port);
@@ -173,7 +180,7 @@ os_socket_getbooloption(bh_socket_t socket, int level, int optname,
173180
int optval;
174181
socklen_t optval_size = sizeof(optval);
175182

176-
if (zsock_setsockopt(socket->fd, level, optname, &optval, optval_size)
183+
if (zsock_getsockopt(socket->fd, level, optname, &optval, &optval_size)
177184
!= 0) {
178185
return BHT_ERROR;
179186
}
@@ -190,7 +197,7 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
190197

191198
*(sock) = BH_MALLOC(sizeof(zephyr_handle));
192199

193-
if (!sock) {
200+
if (!*sock) {
194201
return BHT_ERROR;
195202
}
196203

@@ -215,40 +222,55 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
215222
int
216223
os_socket_bind(bh_socket_t socket, const char *host, int *port)
217224
{
218-
struct sockaddr_storage addr = { 0 };
219-
socklen_t socklen;
220-
int ret;
225+
(void)host; /* PoC: ignore host, listen on all interfaces */
221226

222-
assert(host);
227+
assert(socket);
223228
assert(port);
224229

225-
if (!textual_addr_to_sockaddr(host, *port, (struct sockaddr *)&addr,
226-
&socklen)) {
227-
return BHT_ERROR;
230+
int ret;
231+
int fam = AF_INET; /* default to IPv4 */
232+
socklen_t flen = sizeof(fam);
233+
234+
/* Honor the socket's domain if available so IPv6 sockets get :: */
235+
(void)zsock_getsockopt(socket->fd, SOL_SOCKET, SO_DOMAIN, &fam, &flen);
236+
237+
#ifdef CONFIG_NET_IPV6
238+
if (fam == AF_INET6) {
239+
struct sockaddr_in6 sa6;
240+
memset(&sa6, 0, sizeof(sa6));
241+
sa6.sin6_family = AF_INET6;
242+
sa6.sin6_port = htons(*port); /* *port may be 0 */
243+
/* :: (all zeros) means in6addr_any */
244+
ret = zsock_bind(socket->fd, (struct sockaddr *)&sa6, sizeof(sa6));
245+
} else
246+
#endif
247+
{
248+
struct sockaddr_in sa4;
249+
memset(&sa4, 0, sizeof(sa4));
250+
sa4.sin_family = AF_INET;
251+
sa4.sin_port = htons(*port); /* *port may be 0 */
252+
sa4.sin_addr.s_addr = htonl(INADDR_ANY); /* 0.0.0.0 */
253+
ret = zsock_bind(socket->fd, (struct sockaddr *)&sa4, sizeof(sa4));
228254
}
229255

230-
// F_SETF_SETFD and FD_CLOEXEC are not defined in zephyr.
231-
// SO_LINGER: Socket lingers on close (ignored, for compatibility)
232-
233-
ret = zsock_bind(socket->fd, (struct sockaddr *)&addr, socklen);
234256
if (ret < 0) {
235-
return BHT_ERROR;
236-
}
237-
238-
socklen = sizeof(addr);
239-
if (zsock_getsockname(socket->fd, (void *)&addr, &socklen) == -1) {
240-
return BHT_ERROR;
257+
return BHT_ERROR; /* or convert_errno(errno) if your code uses it */
241258
}
242259

243-
if (addr.ss_family == AF_INET) { // addr.sin_family
244-
*port = ntohs(((struct sockaddr_in *)&addr)->sin_port);
245-
}
246-
else {
247-
#ifdef IPPROTO_IPV6
248-
*port = ntohs(((struct sockaddr_in *)&addr)->sin6_port);
249-
#else
250-
return BHT_ERROR;
260+
/* If caller asked for port 0, report the kernel-chosen port back */
261+
if (*port == 0) {
262+
struct sockaddr_storage ss;
263+
socklen_t sl = sizeof(ss);
264+
if (zsock_getsockname(socket->fd, (struct sockaddr *)&ss, &sl) == 0) {
265+
if (ss.ss_family == AF_INET) {
266+
*port = ntohs(((struct sockaddr_in *)&ss)->sin_port);
267+
}
268+
#ifdef CONFIG_NET_IPV6
269+
else if (ss.ss_family == AF_INET6) {
270+
*port = ntohs(((struct sockaddr_in6 *)&ss)->sin6_port);
271+
}
251272
#endif
273+
}
252274
}
253275

254276
return BHT_OK;
@@ -263,7 +285,7 @@ os_socket_settimeout(bh_socket_t socket, uint64 timeout_us)
263285
timeout.tv_usec = timeout_us % 1000000;
264286

265287
return zsock_setsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &timeout,
266-
sizeof(timeout));
288+
sizeof(timeout)) == 0 ? BHT_OK : BHT_ERROR;
267289
}
268290

269291
int
@@ -277,7 +299,7 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
277299
unsigned int *addrlen)
278300
{
279301
*sock = BH_MALLOC(sizeof(zephyr_handle));
280-
if (!sock) {
302+
if (!*sock) {
281303
return BHT_ERROR;
282304
}
283305

@@ -442,18 +464,17 @@ os_socket_addr_resolve(const char *host, const char *service,
442464
}
443465
}
444466

445-
char *_host;
446-
if (!strcmp(host, "localhost")) {
467+
const char *_host = host ? host : NULL;
468+
if (_host && strcmp(_host, "localhost") == 0) {
447469
printk("os_socket_addr_resolve called with host=\"localhost\" - "
448470
"substituting 127.0.0.1\n");
449471
_host = "127.0.0.1";
450-
} else {
451-
_host = (char *)host;
452472
}
453473

454-
ret = zsock_getaddrinfo(_host, strlen(service) == 0 ? NULL : service,
474+
const char *_service = (service && service[0]) ? service : NULL;
475+
ret = zsock_getaddrinfo(_host, _service,
455476
hints_enabled ? &hints : NULL, &result);
456-
if (ret != BHT_OK) {
477+
if (ret != 0) {
457478
errno = getaddrinfo_error_to_errno(ret);
458479
return BHT_ERROR;
459480
}
@@ -498,7 +519,7 @@ os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
498519
ret = zsock_getsockname(socket->fd, (struct sockaddr *)&addr_storage,
499520
&addr_len);
500521

501-
if (ret != BHT_OK) {
522+
if (ret != 0) {
502523
return BHT_ERROR;
503524
}
504525

@@ -515,7 +536,7 @@ os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
515536
ret = zsock_getpeername(socket->fd, (struct sockaddr *)&addr_storage,
516537
&addr_len);
517538

518-
if (ret != BHT_OK) {
539+
if (ret != 0) {
519540
return BHT_ERROR;
520541
}
521542

@@ -557,8 +578,9 @@ os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
557578
int
558579
os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
559580
{
560-
if (zsock_setsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &bufsiz,
561-
sizeof(bufsiz))
581+
int opt = (int)bufsiz;
582+
if (zsock_setsockopt(socket->fd, SOL_SOCKET, SO_RCVBUF, &opt,
583+
sizeof(opt))
562584
!= 0) {
563585
return BHT_ERROR;
564586
}
@@ -618,7 +640,7 @@ os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
618640
struct timeval tv;
619641
socklen_t tv_len = sizeof(tv);
620642

621-
if (zsock_setsockopt(socket->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, tv_len)
643+
if (zsock_getsockopt(socket->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &tv_len)
622644
!= 0) {
623645
return BHT_ERROR;
624646
}
@@ -645,10 +667,10 @@ os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
645667
int
646668
os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
647669
{
648-
struct timeval tv;
670+
struct timeval tv = {0};
649671
socklen_t tv_len = sizeof(tv);
650672

651-
if (zsock_setsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, tv_len)
673+
if (zsock_getsockopt(socket->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &tv_len)
652674
!= 0) {
653675
return BHT_ERROR;
654676
}
@@ -702,21 +724,34 @@ os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
702724
return BHT_ERROR;
703725
}
704726

705-
// TCP_NODELAY Disable TCP buffering (ignored, for compatibility)
706727
int
707728
os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
708729
{
709-
errno = ENOSYS;
710-
711-
return BHT_ERROR;
730+
int on = is_enabled ? 1 : 0;
731+
if (zsock_setsockopt(socket->fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) {
732+
/* Best-effort: ignore lack of support so connections don’t abort */
733+
if (errno == ENOPROTOOPT || errno == ENOSYS) {
734+
return BHT_OK;
735+
}
736+
return BHT_ERROR;
737+
}
738+
return BHT_OK;
712739
}
713740

714741
int
715742
os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
716743
{
717-
errno = ENOSYS;
718-
719-
return BHT_ERROR;
744+
int on = 0;
745+
socklen_t len = sizeof(on);
746+
if (zsock_getsockopt(socket->fd, IPPROTO_TCP, TCP_NODELAY, &on, &len) != 0) {
747+
if (errno == ENOPROTOOPT || errno == ENOSYS) {
748+
*is_enabled = false;
749+
return BHT_OK;
750+
}
751+
return BHT_ERROR;
752+
}
753+
*is_enabled = (on != 0);
754+
return BHT_OK;
720755
}
721756

722757
int
@@ -769,17 +804,17 @@ os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32_t *time_s)
769804
socklen_t time_s_len = sizeof(time_s_int);
770805

771806
#ifdef TCP_KEEPIDLE
772-
if (zsock_setsockopt(socket->fd, IPPROTO_TCP, TCP_KEEPIDLE, &time_s_int,
773-
time_s_len)
807+
if (zsock_getsockopt(socket->fd, IPPROTO_TCP, TCP_KEEPIDLE, &time_s_int,
808+
&time_s_len)
774809
!= 0) {
775810
return BHT_ERROR;
776811
}
777812
*time_s = (uint32)time_s_int;
778813

779814
return BHT_OK;
780815
#elif defined(TCP_KEEPALIVE)
781-
if (zsock_setsockopt(socket->fd, IPPROTO_TCP, TCP_KEEPALIVE, &time_s_int,
782-
time_s_len)
816+
if (zsock_getsockopt(socket->fd, IPPROTO_TCP, TCP_KEEPALIVE, &time_s_int,
817+
&time_s_len)
783818
!= 0) {
784819
return BHT_ERROR;
785820
}
@@ -895,7 +930,7 @@ os_socket_set_ip_add_membership(bh_socket_t socket,
895930
}
896931
mreq.ipv6mr_interface = imr_interface;
897932

898-
if (setsockopt(socket->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq,
933+
if (zsock_setsockopt(socket->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq,
899934
sizeof(mreq))
900935
!= 0) {
901936
return BHT_ERROR;
@@ -974,13 +1009,14 @@ os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
9741009
int
9751010
os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
9761011
{
977-
socklen_t opt_len = sizeof(*ttl_s);
1012+
int opt;
1013+
socklen_t opt_len = sizeof(opt);
9781014

979-
if (zsock_setsockopt(socket->fd, IPPROTO_IP, IP_MULTICAST_TTL, ttl_s,
980-
opt_len)
1015+
if (zsock_getsockopt(socket->fd, IPPROTO_IP, IP_TTL, &opt, &opt_len)
9811016
!= 0) {
9821017
return BHT_ERROR;
9831018
}
1019+
*ttl_s = (uint8_t)opt;
9841020

9851021
return BHT_OK;
9861022
}
@@ -1000,13 +1036,15 @@ os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
10001036
int
10011037
os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
10021038
{
1003-
socklen_t opt_len = sizeof(*ttl_s);
1039+
int opt;
1040+
socklen_t opt_len = sizeof(opt);
10041041

1005-
if (zsock_setsockopt(socket->fd, IPPROTO_IP, IP_MULTICAST_TTL, ttl_s,
1006-
opt_len)
1042+
if (zsock_getsockopt(socket->fd, IPPROTO_IP, IP_MULTICAST_TTL, &opt,
1043+
&opt_len)
10071044
!= 0) {
10081045
return BHT_ERROR;
10091046
}
1047+
*ttl_s = (uint8_t)opt;
10101048

10111049
return BHT_OK;
10121050
}

0 commit comments

Comments
 (0)