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

@ -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;
}