Enhance sock_addr_local syscall (#1320)

Slightly change the __wasi_sock_addr_local interface - since we already have
a `__wasi_addr_t` structure which is an union, there's no need for passing the
length around - the address buffer will always have the right length (i.e. max
of all address families).
This commit is contained in:
Marcin Kolny
2022-08-01 09:15:33 +02:00
committed by GitHub
parent 08fd714551
commit 3e77b053c3
11 changed files with 195 additions and 40 deletions

View File

@ -114,6 +114,9 @@ sendmsg(int sockfd, const struct msghdr *msg, int flags);
int
socket(int domain, int type, int protocol);
int
getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
#endif
/**
@ -141,16 +144,15 @@ __wasi_sock_accept(__wasi_fd_t fd, __wasi_fd_t *fd_new)
* either IP4 or IP6.
*/
int32_t
__imported_wasi_snapshot_preview1_sock_addr_local(int32_t arg0, int32_t arg1,
int32_t arg2)
__imported_wasi_snapshot_preview1_sock_addr_local(int32_t arg0, int32_t arg1)
__attribute__((__import_module__("wasi_snapshot_preview1"),
__import_name__("sock_addr_local")));
static inline __wasi_errno_t
__wasi_sock_addr_local(__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len)
__wasi_sock_addr_local(__wasi_fd_t fd, __wasi_addr_t *addr)
{
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_addr_local(
(int32_t)fd, (int32_t)buf, (int32_t)buf_len);
(int32_t)fd, (int32_t)addr);
}
/**

View File

@ -54,6 +54,38 @@ sockaddr_to_wasi_addr(const struct sockaddr *sock_addr, socklen_t addrlen,
return ret;
}
static __wasi_errno_t
wasi_addr_to_sockaddr(const __wasi_addr_t *wasi_addr,
struct sockaddr *sock_addr, socklen_t *addrlen)
{
switch (wasi_addr->kind) {
case IPv4:
{
struct sockaddr_in sock_addr_in = { 0 };
uint32_t s_addr;
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 = htonl(s_addr);
sock_addr_in.sin_port = htons(wasi_addr->addr.ip4.port);
memcpy(sock_addr, &sock_addr_in, sizeof(sock_addr_in));
*addrlen = sizeof(sock_addr_in);
break;
}
case IPv6:
// TODO: IPV6
return __WASI_ERRNO_AFNOSUPPORT;
default:
return __WASI_ERRNO_AFNOSUPPORT;
}
return __WASI_ERRNO_SUCCESS;
}
static __wasi_errno_t
sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen)
{
@ -67,30 +99,7 @@ sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen)
return error;
}
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 = htonl(s_addr);
sock_addr_in.sin_port = htons(wasi_addr.addr.ip4.port);
memcpy(sock_addr, &sock_addr_in, sizeof(sock_addr_in));
*addrlen = sizeof(sock_addr_in);
}
else if (IPv6 == wasi_addr.kind) {
// TODO: IPV6
return __WASI_ERRNO_AFNOSUPPORT;
}
else {
return __WASI_ERRNO_AFNOSUPPORT;
}
return __WASI_ERRNO_SUCCESS;
return wasi_addr_to_sockaddr(&wasi_addr, sock_addr, addrlen);
}
int
@ -260,3 +269,18 @@ socket(int domain, int type, int protocol)
return sockfd;
}
int
getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
__wasi_addr_t wasi_addr = { 0 };
__wasi_errno_t error;
error = __wasi_sock_addr_local(sockfd, &wasi_addr);
HANDLE_ERROR(error)
error = wasi_addr_to_sockaddr(&wasi_addr, addr, addrlen);
HANDLE_ERROR(error)
return __WASI_ERRNO_SUCCESS;
}