From 08fd71455167820bfc83148fee0b4d2c3053ab4c Mon Sep 17 00:00:00 2001 From: Marcin Kolny Date: Fri, 29 Jul 2022 04:26:06 +0200 Subject: [PATCH] Fix socket-api byte order issue when host/network order are the same (#1327) Fix socket-api byte order issue for systems where host byte order and network byte order are the same: - Document data structures used for storing IP addresses - Fix bug in bind and connect methods by updating code in wasi_socket_ext --- .../lib-socket/inc/wasi_socket_ext.h | 20 ++++++++++++++++--- .../lib-socket/src/wasi/wasi_socket_ext.c | 20 +++++++++++-------- .../platform/common/posix/posix_socket.c | 4 +--- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h b/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h index fd1d0de8..e89837bc 100644 --- a/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h +++ b/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h @@ -20,7 +20,12 @@ typedef uint16_t __wasi_ip_port_t; typedef enum { IPv4 = 0, IPv6 } __wasi_addr_type_t; -/* n0.n1.n2.n3 */ +/* + n0.n1.n2.n3 + Example: + IP Address: 127.0.0.1 + Structure: {n0: 127, n1: 0, n2: 0, n3: 1} +*/ typedef struct __wasi_addr_ip4_t { uint8_t n0; uint8_t n1; @@ -30,9 +35,18 @@ typedef struct __wasi_addr_ip4_t { typedef struct __wasi_addr_ip4_port_t { __wasi_addr_ip4_t addr; - __wasi_ip_port_t port; + __wasi_ip_port_t port; /* host byte order */ } __wasi_addr_ip4_port_t; +/* + n0:n1:n2:n3:h0:h1:h2:h3, each 16bit value uses host byte order + Example (little-endian system) + IP Address fe80::3ba2:893b:4be0:e3dd + Structure: { + n0: 0xfe80, n1:0x0, n2: 0x0, n3: 0x0, + h0: 0x3ba2, h1: 0x893b, h2: 0x4be0, h3: 0xe3dd + } +*/ typedef struct __wasi_addr_ip6_t { uint16_t n0; uint16_t n1; @@ -46,7 +60,7 @@ typedef struct __wasi_addr_ip6_t { typedef struct __wasi_addr_ip6_port_t { __wasi_addr_ip6_t addr; - __wasi_ip_port_t port; + __wasi_ip_port_t port; /* host byte order */ } __wasi_addr_ip6_port_t; typedef struct __wasi_addr_t { diff --git a/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c b/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c index a96156f7..a81ff6ce 100644 --- a/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c +++ b/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c @@ -22,12 +22,13 @@ static void ipv4_addr_to_wasi_addr(uint32_t addr_num, uint16_t port, __wasi_addr_t *out) { + addr_num = ntohl(addr_num); out->kind = IPv4; out->addr.ip4.port = ntohs(port); - out->addr.ip4.addr.n3 = (addr_num & 0xFF000000) >> 24; - out->addr.ip4.addr.n2 = (addr_num & 0x00FF0000) >> 16; - out->addr.ip4.addr.n1 = (addr_num & 0x0000FF00) >> 8; - out->addr.ip4.addr.n0 = (addr_num & 0x000000FF); + out->addr.ip4.addr.n0 = (addr_num & 0xFF000000) >> 24; + out->addr.ip4.addr.n1 = (addr_num & 0x00FF0000) >> 16; + out->addr.ip4.addr.n2 = (addr_num & 0x0000FF00) >> 8; + out->addr.ip4.addr.n3 = (addr_num & 0x000000FF); } static __wasi_errno_t @@ -57,6 +58,7 @@ static __wasi_errno_t sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen) { __wasi_addr_t wasi_addr = { 0 }; + uint32_t s_addr; __wasi_errno_t error; error = @@ -68,11 +70,13 @@ sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen) if (IPv4 == wasi_addr.kind) { struct sockaddr_in sock_addr_in = { 0 }; + s_addr = (wasi_addr.addr.ip4.addr.n0 << 24) + | (wasi_addr.addr.ip4.addr.n1 << 16) + | (wasi_addr.addr.ip4.addr.n2 << 8) + | wasi_addr.addr.ip4.addr.n3; + sock_addr_in.sin_family = AF_INET; - sock_addr_in.sin_addr.s_addr = (wasi_addr.addr.ip4.addr.n3 << 24) - | (wasi_addr.addr.ip4.addr.n2 << 16) - | (wasi_addr.addr.ip4.addr.n1 << 8) - | wasi_addr.addr.ip4.addr.n0; + sock_addr_in.sin_addr.s_addr = htonl(s_addr); sock_addr_in.sin_port = htons(wasi_addr.addr.ip4.port); memcpy(sock_addr, &sock_addr_in, sizeof(sock_addr_in)); diff --git a/core/shared/platform/common/posix/posix_socket.c b/core/shared/platform/common/posix/posix_socket.c index ec425a33..be9ede0a 100644 --- a/core/shared/platform/common/posix/posix_socket.c +++ b/core/shared/platform/common/posix/posix_socket.c @@ -60,9 +60,7 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port) goto fail; } - addr.sin_addr.s_addr = inet_addr(host); - addr.sin_port = htons(*port); - addr.sin_family = AF_INET; + textual_addr_to_sockaddr(host, *port, &addr); ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) {