Skip to content

Commit

Permalink
Remove port endian swap + make sure aligment of __wasi_addr_port_t is 2
Browse files Browse the repository at this point in the history
  • Loading branch information
Arshia001 committed Sep 13, 2023
1 parent 6a51c50 commit 6b90a28
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 55 deletions.
46 changes: 9 additions & 37 deletions libc-bottom-half/cloudlibc/src/common/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,53 +21,23 @@
#define MIN(a,b) ((a)<(b) ? (a) : (b))
#endif

static inline int is_wasi_port_ok() {
// check if wasi port in sockaddr is not byte swapped already.
// To find out: create a socket, bind to a port, read back and check the port
// in case of error, return 1 as default
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock<0)
return 1;
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = 9000;
if(bind(sock, (struct sockaddr *)&addr, sizeof(addr))<0) {
close(sock);
return 1;
}
// readback the address
__wasi_addr_port_t local_addr;
if(__wasi_sock_addr_local(sock, &local_addr)!=0) {
close(sock);
return 1;
}
close(sock);
return (local_addr.u.inet4.port==10275); //10275 is 9000 with swapped bytes
}

/// Converts a WASI address into a socket address
static inline int wasi_to_sockaddr(const struct __wasi_addr_port_t *restrict peer_addr, struct sockaddr *restrict addr, socklen_t *restrict addrlen) {
static int tested = 0;
static int need_revert = 1;
if(!tested && addr) {
tested = 1;
need_revert = is_wasi_port_ok();
}
if (addr != NULL) {
memset(addr, 0, *addrlen);
if (peer_addr->tag == __WASI_ADDRESS_FAMILY_INET4) {
struct sockaddr_in addr4;
addr4.sin_family = AF_INET;
addr4.sin_port = need_revert?htons(peer_addr->u.inet4.port):peer_addr->u.inet4.port;
addr4.sin_port = peer_addr->u.inet4.port;
addr4.sin_addr.s_addr = *((in_addr_t*)&peer_addr->u.inet4.addr);
memcpy(addr, &addr4, MIN(sizeof(struct sockaddr_in), *addrlen));
*addrlen = sizeof(struct sockaddr_in);
} else if (peer_addr->tag == __WASI_ADDRESS_FAMILY_INET6) {
struct sockaddr_in6 addr6;
addr6.sin6_family = AF_INET6;
addr6.sin6_flowinfo = need_revert?htonl(peer_addr->u.inet6.addr.flow_info):peer_addr->u.inet6.addr.flow_info;
addr6.sin6_scope_id = need_revert?htonl(peer_addr->u.inet6.addr.scope_id):peer_addr->u.inet6.addr.scope_id;;
addr6.sin6_port = need_revert?htons(peer_addr->u.inet6.port):peer_addr->u.inet6.port;
addr6.sin6_flowinfo = peer_addr->u.inet6.addr.flow_info1 << 16 & peer_addr->u.inet6.addr.flow_info0;
addr6.sin6_scope_id = peer_addr->u.inet6.addr.scope_id1 << 16 & peer_addr->u.inet6.addr.scope_id0;;
addr6.sin6_port = peer_addr->u.inet6.port;
memcpy(&addr6.sin6_addr.s6_addr, &peer_addr->u.inet6.addr, sizeof(struct in6_addr));
memcpy(addr, &addr6, MIN(sizeof(struct sockaddr_in6), *addrlen));
*addrlen = sizeof(struct sockaddr_in6);
Expand Down Expand Up @@ -97,9 +67,11 @@ static inline int sockaddr_to_wasi(const struct sockaddr *restrict addr, const s
} else if (addr->sa_family == AF_INET6 && addrlen >= sizeof(struct sockaddr_in6)) {
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
peer_addr->tag = __WASI_ADDRESS_FAMILY_INET6;
peer_addr->u.inet6.port = ntohs(addr6->sin6_port);
peer_addr->u.inet6.addr.flow_info = ntohl(addr6->sin6_flowinfo);
peer_addr->u.inet6.addr.scope_id = ntohl(addr6->sin6_scope_id);
peer_addr->u.inet6.port = addr6->sin6_port;
peer_addr->u.inet6.addr.flow_info1 = addr6->sin6_flowinfo >> 16;
peer_addr->u.inet6.addr.flow_info0 = addr6->sin6_flowinfo & 0xffff;
peer_addr->u.inet6.addr.scope_id1 = addr6->sin6_scope_id >> 16;
peer_addr->u.inet6.addr.scope_id0 = addr6->sin6_scope_id & 0xffff;
memcpy(&peer_addr->u.inet6.addr, &addr6->sin6_addr.s6_addr, sizeof(struct in6_addr));
return 0;
} else if (addr->sa_family == AF_UNIX && addrlen >= offsetof(struct sockaddr_un, sun_path) + 1) {
Expand Down
49 changes: 32 additions & 17 deletions libc-bottom-half/headers/public/wasi/api_wasix.h
Original file line number Diff line number Diff line change
Expand Up @@ -2681,14 +2681,27 @@ typedef struct __wasi_addr_ip6_t {

uint16_t h3;

uint32_t flow_info;
/**
* flow_info1 contains the most significant two bytes, and comes first in keeping with all wasix syscalls being little endian
*/
uint16_t flow_info1;

/**
* flow_info0 contains the least significant two bytes
*/
uint16_t flow_info0;

/**
* Same as flow_info1 and flow_info0
*/
uint16_t scope_id1;

uint32_t scope_id;
uint16_t scope_id0;

} __wasi_addr_ip6_t;

_Static_assert(sizeof(__wasi_addr_ip6_t) == 24, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_ip6_t) == 4, "witx calculated align");
_Static_assert(_Alignof(__wasi_addr_ip6_t) == 2, "witx calculated align");
_Static_assert(offsetof(__wasi_addr_ip6_t, n0) == 0, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, n1) == 2, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, n2) == 4, "witx calculated offset");
Expand All @@ -2697,8 +2710,10 @@ _Static_assert(offsetof(__wasi_addr_ip6_t, h0) == 8, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, h1) == 10, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, h2) == 12, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, h3) == 14, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, flow_info) == 16, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, scope_id) == 20, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, flow_info1) == 16, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, flow_info0) == 18, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, scope_id1) == 20, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_t, scope_id0) == 22, "witx calculated offset");

/**
* Unix socket that is bound to no more than 107 bytes
Expand Down Expand Up @@ -3055,10 +3070,10 @@ typedef struct __wasi_addr_ip6_port_t {

} __wasi_addr_ip6_port_t;

_Static_assert(sizeof(__wasi_addr_ip6_port_t) == 28, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_ip6_port_t) == 4, "witx calculated align");
_Static_assert(sizeof(__wasi_addr_ip6_port_t) == 26, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_ip6_port_t) == 2, "witx calculated align");
_Static_assert(offsetof(__wasi_addr_ip6_port_t, port) == 0, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_port_t, addr) == 4, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_port_t, addr) == 2, "witx calculated offset");

/**
* An IPv6 address CIDR
Expand All @@ -3070,8 +3085,8 @@ typedef struct __wasi_addr_ip6_cidr_t {

} __wasi_addr_ip6_cidr_t;

_Static_assert(sizeof(__wasi_addr_ip6_cidr_t) == 28, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_ip6_cidr_t) == 4, "witx calculated align");
_Static_assert(sizeof(__wasi_addr_ip6_cidr_t) == 26, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_ip6_cidr_t) == 2, "witx calculated align");
_Static_assert(offsetof(__wasi_addr_ip6_cidr_t, addr) == 0, "witx calculated offset");
_Static_assert(offsetof(__wasi_addr_ip6_cidr_t, prefix) == 24, "witx calculated offset");

Expand All @@ -3089,8 +3104,8 @@ typedef struct __wasi_addr_t {
__wasi_addr_u_t u;
} __wasi_addr_t;

_Static_assert(sizeof(__wasi_addr_t) == 112, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_t) == 4, "witx calculated align");
_Static_assert(sizeof(__wasi_addr_t) == 110, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_t) == 2, "witx calculated align");

/**
* Union that makes a generic IP address and port
Expand All @@ -3106,8 +3121,8 @@ typedef struct __wasi_addr_port_t {
__wasi_addr_port_u_t u;
} __wasi_addr_port_t;

_Static_assert(sizeof(__wasi_addr_port_t) == 112, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_port_t) == 4, "witx calculated align");
_Static_assert(sizeof(__wasi_addr_port_t) == 110, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_port_t) == 2, "witx calculated align");

/**
* Union that makes a generic IP address and prefix. a.k.a. CIDR
Expand All @@ -3123,8 +3138,8 @@ typedef struct __wasi_addr_cidr_t {
__wasi_addr_cidr_u_t u;
} __wasi_addr_cidr_t;

_Static_assert(sizeof(__wasi_addr_cidr_t) == 32, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_cidr_t) == 4, "witx calculated align");
_Static_assert(sizeof(__wasi_addr_cidr_t) == 28, "witx calculated size");
_Static_assert(_Alignof(__wasi_addr_cidr_t) == 2, "witx calculated align");

typedef struct __wasi_route_t {
__wasi_addr_cidr_t cidr;
Expand All @@ -3140,7 +3155,7 @@ typedef struct __wasi_route_t {
_Static_assert(sizeof(__wasi_route_t) == 176, "witx calculated size");
_Static_assert(_Alignof(__wasi_route_t) == 8, "witx calculated align");
_Static_assert(offsetof(__wasi_route_t, cidr) == 0, "witx calculated offset");
_Static_assert(offsetof(__wasi_route_t, via_router) == 32, "witx calculated offset");
_Static_assert(offsetof(__wasi_route_t, via_router) == 28, "witx calculated offset");
_Static_assert(offsetof(__wasi_route_t, preferred_until) == 144, "witx calculated offset");
_Static_assert(offsetof(__wasi_route_t, expires_at) == 160, "witx calculated offset");

Expand Down
2 changes: 1 addition & 1 deletion tools/wasix-headers/WASI

0 comments on commit 6b90a28

Please sign in to comment.