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
This commit is contained in:
Marcin Kolny 2022-07-29 04:26:06 +02:00 committed by GitHub
parent f6bbeade2a
commit 08fd714551
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 14 deletions

View File

@ -20,7 +20,12 @@ typedef uint16_t __wasi_ip_port_t;
typedef enum { IPv4 = 0, IPv6 } __wasi_addr_type_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 { typedef struct __wasi_addr_ip4_t {
uint8_t n0; uint8_t n0;
uint8_t n1; uint8_t n1;
@ -30,9 +35,18 @@ typedef struct __wasi_addr_ip4_t {
typedef struct __wasi_addr_ip4_port_t { typedef struct __wasi_addr_ip4_port_t {
__wasi_addr_ip4_t addr; __wasi_addr_ip4_t addr;
__wasi_ip_port_t port; __wasi_ip_port_t port; /* host byte order */
} __wasi_addr_ip4_port_t; } __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 { typedef struct __wasi_addr_ip6_t {
uint16_t n0; uint16_t n0;
uint16_t n1; uint16_t n1;
@ -46,7 +60,7 @@ typedef struct __wasi_addr_ip6_t {
typedef struct __wasi_addr_ip6_port_t { typedef struct __wasi_addr_ip6_port_t {
__wasi_addr_ip6_t addr; __wasi_addr_ip6_t addr;
__wasi_ip_port_t port; __wasi_ip_port_t port; /* host byte order */
} __wasi_addr_ip6_port_t; } __wasi_addr_ip6_port_t;
typedef struct __wasi_addr_t { typedef struct __wasi_addr_t {

View File

@ -22,12 +22,13 @@
static void static void
ipv4_addr_to_wasi_addr(uint32_t addr_num, uint16_t port, __wasi_addr_t *out) 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->kind = IPv4;
out->addr.ip4.port = ntohs(port); out->addr.ip4.port = ntohs(port);
out->addr.ip4.addr.n3 = (addr_num & 0xFF000000) >> 24; out->addr.ip4.addr.n0 = (addr_num & 0xFF000000) >> 24;
out->addr.ip4.addr.n2 = (addr_num & 0x00FF0000) >> 16; out->addr.ip4.addr.n1 = (addr_num & 0x00FF0000) >> 16;
out->addr.ip4.addr.n1 = (addr_num & 0x0000FF00) >> 8; out->addr.ip4.addr.n2 = (addr_num & 0x0000FF00) >> 8;
out->addr.ip4.addr.n0 = (addr_num & 0x000000FF); out->addr.ip4.addr.n3 = (addr_num & 0x000000FF);
} }
static __wasi_errno_t 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) sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen)
{ {
__wasi_addr_t wasi_addr = { 0 }; __wasi_addr_t wasi_addr = { 0 };
uint32_t s_addr;
__wasi_errno_t error; __wasi_errno_t error;
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) { if (IPv4 == wasi_addr.kind) {
struct sockaddr_in sock_addr_in = { 0 }; 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_family = AF_INET;
sock_addr_in.sin_addr.s_addr = (wasi_addr.addr.ip4.addr.n3 << 24) sock_addr_in.sin_addr.s_addr = htonl(s_addr);
| (wasi_addr.addr.ip4.addr.n2 << 16)
| (wasi_addr.addr.ip4.addr.n1 << 8)
| wasi_addr.addr.ip4.addr.n0;
sock_addr_in.sin_port = htons(wasi_addr.addr.ip4.port); sock_addr_in.sin_port = htons(wasi_addr.addr.ip4.port);
memcpy(sock_addr, &sock_addr_in, sizeof(sock_addr_in)); memcpy(sock_addr, &sock_addr_in, sizeof(sock_addr_in));

View File

@ -60,9 +60,7 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port)
goto fail; goto fail;
} }
addr.sin_addr.s_addr = inet_addr(host); textual_addr_to_sockaddr(host, *port, &addr);
addr.sin_port = htons(*port);
addr.sin_family = AF_INET;
ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr)); ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) { if (ret < 0) {