Skip to content

Commit 6a3ddd7

Browse files
committed
Implement sock_addr_local syscall
I also slightly changed the interface - since we already have a `__wasi_addr_t` structure which is an union, there's no need for passing length around - the address buffer will always have the right length (i.e. max of all address families).
1 parent 08fd714 commit 6a3ddd7

File tree

11 files changed

+195
-40
lines changed

11 files changed

+195
-40
lines changed

core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ sendmsg(int sockfd, const struct msghdr *msg, int flags);
114114

115115
int
116116
socket(int domain, int type, int protocol);
117+
118+
int
119+
getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
117120
#endif
118121

119122
/**
@@ -141,16 +144,15 @@ __wasi_sock_accept(__wasi_fd_t fd, __wasi_fd_t *fd_new)
141144
* either IP4 or IP6.
142145
*/
143146
int32_t
144-
__imported_wasi_snapshot_preview1_sock_addr_local(int32_t arg0, int32_t arg1,
145-
int32_t arg2)
147+
__imported_wasi_snapshot_preview1_sock_addr_local(int32_t arg0, int32_t arg1)
146148
__attribute__((__import_module__("wasi_snapshot_preview1"),
147149
__import_name__("sock_addr_local")));
148150

149151
static inline __wasi_errno_t
150-
__wasi_sock_addr_local(__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len)
152+
__wasi_sock_addr_local(__wasi_fd_t fd, __wasi_addr_t *addr)
151153
{
152154
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_addr_local(
153-
(int32_t)fd, (int32_t)buf, (int32_t)buf_len);
155+
(int32_t)fd, (int32_t)addr);
154156
}
155157

156158
/**

core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,38 @@ sockaddr_to_wasi_addr(const struct sockaddr *sock_addr, socklen_t addrlen,
5454
return ret;
5555
}
5656

57+
static __wasi_errno_t
58+
wasi_addr_to_sockaddr(const __wasi_addr_t *wasi_addr,
59+
struct sockaddr *sock_addr, socklen_t *addrlen)
60+
{
61+
switch (wasi_addr->kind) {
62+
case IPv4:
63+
{
64+
struct sockaddr_in sock_addr_in = { 0 };
65+
uint32_t s_addr;
66+
67+
s_addr = (wasi_addr.addr.ip4.addr.n0 << 24)
68+
| (wasi_addr.addr.ip4.addr.n1 << 16)
69+
| (wasi_addr.addr.ip4.addr.n2 << 8)
70+
| wasi_addr.addr.ip4.addr.n3;
71+
72+
sock_addr_in.sin_family = AF_INET;
73+
sock_addr_in.sin_addr.s_addr = htonl(s_addr);
74+
sock_addr_in.sin_port = htons(wasi_addr->addr.ip4.port);
75+
memcpy(sock_addr, &sock_addr_in, sizeof(sock_addr_in));
76+
77+
*addrlen = sizeof(sock_addr_in);
78+
break;
79+
}
80+
case IPv6:
81+
// TODO: IPV6
82+
return __WASI_ERRNO_AFNOSUPPORT;
83+
default:
84+
return __WASI_ERRNO_AFNOSUPPORT;
85+
}
86+
return __WASI_ERRNO_SUCCESS;
87+
}
88+
5789
static __wasi_errno_t
5890
sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen)
5991
{
@@ -67,30 +99,7 @@ sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen)
6799
return error;
68100
}
69101

70-
if (IPv4 == wasi_addr.kind) {
71-
struct sockaddr_in sock_addr_in = { 0 };
72-
73-
s_addr = (wasi_addr.addr.ip4.addr.n0 << 24)
74-
| (wasi_addr.addr.ip4.addr.n1 << 16)
75-
| (wasi_addr.addr.ip4.addr.n2 << 8)
76-
| wasi_addr.addr.ip4.addr.n3;
77-
78-
sock_addr_in.sin_family = AF_INET;
79-
sock_addr_in.sin_addr.s_addr = htonl(s_addr);
80-
sock_addr_in.sin_port = htons(wasi_addr.addr.ip4.port);
81-
memcpy(sock_addr, &sock_addr_in, sizeof(sock_addr_in));
82-
83-
*addrlen = sizeof(sock_addr_in);
84-
}
85-
else if (IPv6 == wasi_addr.kind) {
86-
// TODO: IPV6
87-
return __WASI_ERRNO_AFNOSUPPORT;
88-
}
89-
else {
90-
return __WASI_ERRNO_AFNOSUPPORT;
91-
}
92-
93-
return __WASI_ERRNO_SUCCESS;
102+
return wasi_addr_to_sockaddr(&wasi_addr, sock_addr, addrlen);
94103
}
95104

96105
int
@@ -260,3 +269,18 @@ socket(int domain, int type, int protocol)
260269

261270
return sockfd;
262271
}
272+
273+
int
274+
getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
275+
{
276+
__wasi_addr_t wasi_addr = { 0 };
277+
__wasi_errno_t error;
278+
279+
error = __wasi_sock_addr_local(sockfd, &wasi_addr);
280+
HANDLE_ERROR(error)
281+
282+
error = wasi_addr_to_sockaddr(&wasi_addr, addr, addrlen);
283+
HANDLE_ERROR(error)
284+
285+
return __WASI_ERRNO_SUCCESS;
286+
}

core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,8 +1009,8 @@ wasi_sock_accept(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_fd_t *fd_new)
10091009
}
10101010

10111011
static wasi_errno_t
1012-
wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *buf,
1013-
wasi_size_t buf_len)
1012+
wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd,
1013+
__wasi_addr_t *addr)
10141014
{
10151015
wasm_module_inst_t module_inst = get_module_inst(exec_env);
10161016
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@@ -1019,9 +1019,12 @@ wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *buf,
10191019
if (!wasi_ctx)
10201020
return __WASI_EACCES;
10211021

1022+
if (!validate_native_addr(addr, sizeof(__wasi_addr_t)))
1023+
return __WASI_EINVAL;
1024+
10221025
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
10231026

1024-
return wasi_ssp_sock_addr_local(curfds, fd, buf, buf_len);
1027+
return wasi_ssp_sock_addr_local(curfds, fd, addr);
10251028
}
10261029

10271030
static wasi_errno_t
@@ -1401,7 +1404,7 @@ static NativeSymbol native_symbols_libc_wasi[] = {
14011404
REG_NATIVE_FUNC(proc_raise, "(i)i"),
14021405
REG_NATIVE_FUNC(random_get, "(*~)i"),
14031406
REG_NATIVE_FUNC(sock_accept, "(i*)i"),
1404-
REG_NATIVE_FUNC(sock_addr_local, "(i*i)i"),
1407+
REG_NATIVE_FUNC(sock_addr_local, "(i*)i"),
14051408
REG_NATIVE_FUNC(sock_addr_remote, "(i*i)i"),
14061409
REG_NATIVE_FUNC(sock_addr_resolve, "($$**i*)i"),
14071410
REG_NATIVE_FUNC(sock_bind, "(i*)i"),

core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ wasi_ssp_sock_addr_local(
10071007
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
10081008
struct fd_table *curfds,
10091009
#endif
1010-
__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len
1010+
__wasi_fd_t fd, __wasi_addr_t *addr
10111011
) __attribute__((__warn_unused_result__));
10121012

10131013
__wasi_errno_t

core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,14 @@ convert_clockid(__wasi_clockid_t in, clockid_t *out)
203203
static void
204204
ipv4_addr_to_wasi_addr(uint32_t addr, __wasi_ip_port_t port, __wasi_addr_t *out)
205205
{
206+
addr = ntohl(addr);
207+
206208
out->kind = IPv4;
207209
out->addr.ip4.port = port;
208-
out->addr.ip4.addr.n3 = (addr & 0xFF000000) >> 24;
209-
out->addr.ip4.addr.n2 = (addr & 0x00FF0000) >> 16;
210-
out->addr.ip4.addr.n1 = (addr & 0x0000FF00) >> 8;
211-
out->addr.ip4.addr.n0 = (addr & 0x000000FF);
210+
out->addr.ip4.addr.n0 = (addr & 0xFF000000) >> 24;
211+
out->addr.ip4.addr.n1 = (addr & 0x00FF0000) >> 16;
212+
out->addr.ip4.addr.n2 = (addr & 0x0000FF00) >> 8;
213+
out->addr.ip4.addr.n3 = (addr & 0x000000FF);
212214
}
213215

214216
// Converts an IPv6 binary address object to WASI address object.
@@ -2881,16 +2883,34 @@ wasi_ssp_sock_addr_local(
28812883
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
28822884
struct fd_table *curfds,
28832885
#endif
2884-
__wasi_fd_t fd, uint8 *buf, __wasi_size_t buf_len)
2886+
__wasi_fd_t fd, __wasi_addr_t *addr)
28852887
{
28862888
struct fd_object *fo;
2889+
uint8 buf[16];
2890+
__wasi_ip_port_t port;
2891+
uint8 is_ipv4;
2892+
int ret;
2893+
28872894
__wasi_errno_t error =
28882895
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ADDR_LOCAL, 0);
28892896
if (error != __WASI_ESUCCESS)
28902897
return error;
28912898

2899+
ret = os_socket_addr_local(fd_number(fo), buf, sizeof(buf) / sizeof(buf[0]),
2900+
&port, &is_ipv4);
28922901
fd_object_release(fo);
2893-
return __WASI_ENOSYS;
2902+
if (ret != BHT_OK) {
2903+
return convert_errno(errno);
2904+
}
2905+
2906+
if (is_ipv4) {
2907+
ipv4_addr_to_wasi_addr(*(uint32_t *)buf, port, addr);
2908+
}
2909+
else {
2910+
ipv6_addr_to_wasi_addr((uint16 *)buf, port, addr);
2911+
}
2912+
2913+
return __WASI_ESUCCESS;
28942914
}
28952915

28962916
__wasi_errno_t

core/shared/platform/common/posix/posix_socket.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,5 +270,54 @@ os_socket_addr_resolve(const char *host, const char *service,
270270
*max_info_size = pos;
271271
freeaddrinfo(result);
272272

273+
return BHT_OK;
274+
}
275+
276+
int
277+
os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
278+
uint16_t *port, uint8_t *is_ipv4)
279+
{
280+
struct sockaddr_storage addr_storage = { 0 };
281+
socklen_t addr_len = sizeof(addr_storage);
282+
int ret;
283+
284+
assert(buf);
285+
assert(is_ipv4);
286+
assert(port);
287+
288+
ret = getsockname(socket, (struct sockaddr *)&addr_storage, &addr_len);
289+
290+
if (ret != BHT_OK) {
291+
return BHT_ERROR;
292+
}
293+
294+
switch (addr_storage.ss_family) {
295+
case AF_INET:
296+
{
297+
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr_storage;
298+
299+
assert(buflen >= sizeof(addr_in->sin_addr));
300+
*port = ntohs(addr_in->sin_port);
301+
memcpy(buf, &addr_in->sin_addr, sizeof(addr_in->sin_addr));
302+
*is_ipv4 = true;
303+
break;
304+
}
305+
case AF_INET6:
306+
{
307+
struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)&addr_storage;
308+
assert(buflen >= sizeof(addr_in->sin6_addr));
309+
*port = ntohs(addr_in->sin6_port);
310+
311+
for (int i = 0; i < 8; i++) {
312+
((uint16_t *)buf)[i] =
313+
ntohs(((uint16_t *)&addr_in->sin6_addr)[i]);
314+
}
315+
*is_ipv4 = false;
316+
break;
317+
}
318+
default:
319+
return BHT_ERROR;
320+
}
321+
273322
return BHT_OK;
274323
}

core/shared/platform/include/platform_api_extension.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,25 @@ os_socket_addr_resolve(const char *host, const char *service,
374374
bh_addr_info_t *addr_info, size_t addr_info_size,
375375
size_t *max_info_size);
376376

377+
/**
378+
* Returns an binary address and a port of the local socket
379+
*
380+
* @param socket the local socket
381+
*
382+
* @param buf buffer to store the address
383+
*
384+
* @param buflen length of the buf buffer
385+
*
386+
* @param port a buffer for storing socket's port
387+
*
388+
* @param is_ipv4 a buffer for storing information about the address family
389+
*
390+
* @return On success, returns 0; otherwise, it returns -1.
391+
*/
392+
int
393+
os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
394+
uint16_t *port, uint8_t *is_ipv4);
395+
377396
#ifdef __cplusplus
378397
}
379398
#endif

core/shared/platform/linux-sgx/sgx_socket.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ htonl(uint32 value)
105105
return value;
106106
}
107107

108-
static uint32
108+
uint32
109109
ntohl(uint32 value)
110110
{
111111
return htonl(value);
@@ -632,4 +632,13 @@ os_socket_addr_resolve(const char *host, const char *service,
632632
return BHT_ERROR;
633633
}
634634

635+
int
636+
os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
637+
uint16_t *port, uint8_t *is_ipv4)
638+
{
639+
errno = ENOSYS;
640+
641+
return BHT_ERROR;
642+
}
643+
635644
#endif

core/shared/platform/linux-sgx/sgx_socket.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ struct sockaddr {
9595
char sa_data[14]; /* Address data. */
9696
};
9797

98+
uint32_t
99+
ntohl(uint32_t value);
100+
98101
int
99102
socket(int domain, int type, int protocol);
100103

core/shared/platform/windows/win_socket.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,5 +171,14 @@ os_socket_addr_resolve(const char *host, const char *service,
171171
{
172172
errno = ENOSYS;
173173

174+
return BHT_ERROR;
175+
}
176+
177+
int
178+
os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
179+
uint16_t *port, uint8_t *is_ipv4)
180+
{
181+
errno = ENOSYS;
182+
174183
return BHT_ERROR;
175184
}

0 commit comments

Comments
 (0)