Skip to content

Commit 45136bc

Browse files
authored
Implement sock_addr_remote syscall (#1360)
Slightly changed the interface sock_addr_remote - 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 3e77b05 commit 45136bc

File tree

10 files changed

+142
-53
lines changed

10 files changed

+142
-53
lines changed

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ socket(int domain, int type, int protocol);
117117

118118
int
119119
getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
120+
121+
int
122+
getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
120123
#endif
121124

122125
/**
@@ -164,16 +167,15 @@ __wasi_sock_addr_local(__wasi_fd_t fd, __wasi_addr_t *addr)
164167
* either IP4 or IP6.
165168
*/
166169
int32_t
167-
__imported_wasi_snapshot_preview1_sock_addr_remote(int32_t arg0, int32_t arg1,
168-
int32_t arg2)
170+
__imported_wasi_snapshot_preview1_sock_addr_remote(int32_t arg0, int32_t arg1)
169171
__attribute__((__import_module__("wasi_snapshot_preview1"),
170172
__import_name__("sock_addr_remote")));
171173

172174
static inline __wasi_errno_t
173-
__wasi_sock_addr_remote(__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len)
175+
__wasi_sock_addr_remote(__wasi_fd_t fd, __wasi_addr_t *addr)
174176
{
175177
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_addr_remote(
176-
(int32_t)fd, (int32_t)buf, (int32_t)buf_len);
178+
(int32_t)fd, (int32_t)addr);
177179
}
178180

179181
/**
@@ -448,4 +450,4 @@ __wasi_sock_set_send_buf_size(__wasi_fd_t fd)
448450
* since don't want to re-compile the wasi-libc,
449451
* we tend to keep original implentations of recv() and send().
450452
*/
451-
#endif
453+
#endif

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

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ wasi_addr_to_sockaddr(const __wasi_addr_t *wasi_addr,
6464
struct sockaddr_in sock_addr_in = { 0 };
6565
uint32_t s_addr;
6666

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;
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;
7171

7272
sock_addr_in.sin_family = AF_INET;
7373
sock_addr_in.sin_addr.s_addr = htonl(s_addr);
@@ -86,22 +86,6 @@ wasi_addr_to_sockaddr(const __wasi_addr_t *wasi_addr,
8686
return __WASI_ERRNO_SUCCESS;
8787
}
8888

89-
static __wasi_errno_t
90-
sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen)
91-
{
92-
__wasi_addr_t wasi_addr = { 0 };
93-
uint32_t s_addr;
94-
__wasi_errno_t error;
95-
96-
error =
97-
__wasi_sock_addr_remote(fd, (uint8_t *)&wasi_addr, sizeof(wasi_addr));
98-
if (__WASI_ERRNO_SUCCESS != error) {
99-
return error;
100-
}
101-
102-
return wasi_addr_to_sockaddr(&wasi_addr, sock_addr, addrlen);
103-
}
104-
10589
int
10690
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
10791
{
@@ -112,9 +96,8 @@ accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
11296
error = __wasi_sock_accept(sockfd, &new_sockfd);
11397
HANDLE_ERROR(error)
11498

115-
// error = sock_addr_remote(new_sockfd, addr, addrlen);
116-
// HANDLE_ERROR(error)
117-
*addrlen = 0;
99+
error = getpeername(new_sockfd, addr, addrlen);
100+
HANDLE_ERROR(error)
118101

119102
return new_sockfd;
120103
}
@@ -284,3 +267,18 @@ getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
284267

285268
return __WASI_ERRNO_SUCCESS;
286269
}
270+
271+
int
272+
getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
273+
{
274+
__wasi_addr_t wasi_addr = { 0 };
275+
__wasi_errno_t error;
276+
277+
error = __wasi_sock_addr_remote(sockfd, &wasi_addr);
278+
HANDLE_ERROR(error)
279+
280+
error = wasi_addr_to_sockaddr(&wasi_addr, addr, addrlen);
281+
HANDLE_ERROR(error)
282+
283+
return __WASI_ERRNO_SUCCESS;
284+
}

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,8 +1028,8 @@ wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd,
10281028
}
10291029

10301030
static wasi_errno_t
1031-
wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *buf,
1032-
wasi_size_t buf_len)
1031+
wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd,
1032+
__wasi_addr_t *addr)
10331033
{
10341034
wasm_module_inst_t module_inst = get_module_inst(exec_env);
10351035
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@@ -1038,9 +1038,12 @@ wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *buf,
10381038
if (!wasi_ctx)
10391039
return __WASI_EACCES;
10401040

1041+
if (!validate_native_addr(addr, sizeof(__wasi_addr_t)))
1042+
return __WASI_EINVAL;
1043+
10411044
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
10421045

1043-
return wasi_ssp_sock_addr_remote(curfds, fd, buf, buf_len);
1046+
return wasi_ssp_sock_addr_remote(curfds, fd, addr);
10441047
}
10451048

10461049
static wasi_errno_t
@@ -1405,7 +1408,7 @@ static NativeSymbol native_symbols_libc_wasi[] = {
14051408
REG_NATIVE_FUNC(random_get, "(*~)i"),
14061409
REG_NATIVE_FUNC(sock_accept, "(i*)i"),
14071410
REG_NATIVE_FUNC(sock_addr_local, "(i*)i"),
1408-
REG_NATIVE_FUNC(sock_addr_remote, "(i*i)i"),
1411+
REG_NATIVE_FUNC(sock_addr_remote, "(i*)i"),
14091412
REG_NATIVE_FUNC(sock_addr_resolve, "($$**i*)i"),
14101413
REG_NATIVE_FUNC(sock_bind, "(i*)i"),
14111414
REG_NATIVE_FUNC(sock_close, "(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
@@ -1015,7 +1015,7 @@ wasi_ssp_sock_addr_remote(
10151015
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
10161016
struct fd_table *curfds,
10171017
#endif
1018-
__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len
1018+
__wasi_fd_t fd, __wasi_addr_t *addr
10191019
) __attribute__((__warn_unused_result__));
10201020

10211021
__wasi_errno_t

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2918,16 +2918,34 @@ wasi_ssp_sock_addr_remote(
29182918
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
29192919
struct fd_table *curfds,
29202920
#endif
2921-
__wasi_fd_t fd, uint8 *buf, __wasi_size_t buf_len)
2921+
__wasi_fd_t fd, __wasi_addr_t *addr)
29222922
{
29232923
struct fd_object *fo;
2924+
uint8 buf[16];
2925+
__wasi_ip_port_t port;
2926+
uint8 is_ipv4;
2927+
int ret;
2928+
29242929
__wasi_errno_t error =
2925-
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ADDR_REMOTE, 0);
2930+
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ADDR_LOCAL, 0);
29262931
if (error != __WASI_ESUCCESS)
29272932
return error;
29282933

2934+
ret = os_socket_addr_remote(fd_number(fo), buf,
2935+
sizeof(buf) / sizeof(buf[0]), &port, &is_ipv4);
29292936
fd_object_release(fo);
2930-
return __WASI_ENOSYS;
2937+
if (ret != BHT_OK) {
2938+
return convert_errno(errno);
2939+
}
2940+
2941+
if (is_ipv4) {
2942+
ipv4_addr_to_wasi_addr(*(uint32_t *)buf, port, addr);
2943+
}
2944+
else {
2945+
ipv6_addr_to_wasi_addr((uint16 *)buf, port, addr);
2946+
}
2947+
2948+
return __WASI_ESUCCESS;
29312949
}
29322950

29332951
__wasi_errno_t

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

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -273,28 +273,18 @@ os_socket_addr_resolve(const char *host, const char *service,
273273
return BHT_OK;
274274
}
275275

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)
276+
static int
277+
os_socket_convert_sockaddr(struct sockaddr *addr, uint8_t *buf, size_t buflen,
278+
uint16_t *port, uint8_t *is_ipv4)
279279
{
280-
struct sockaddr_storage addr_storage = { 0 };
281-
socklen_t addr_len = sizeof(addr_storage);
282-
int ret;
283-
284280
assert(buf);
285281
assert(is_ipv4);
286282
assert(port);
287283

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) {
284+
switch (addr->sa_family) {
295285
case AF_INET:
296286
{
297-
struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr_storage;
287+
struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
298288

299289
assert(buflen >= sizeof(addr_in->sin_addr));
300290
*port = ntohs(addr_in->sin_port);
@@ -304,7 +294,7 @@ os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
304294
}
305295
case AF_INET6:
306296
{
307-
struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)&addr_storage;
297+
struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)addr;
308298
assert(buflen >= sizeof(addr_in->sin6_addr));
309299
*port = ntohs(addr_in->sin6_port);
310300

@@ -320,4 +310,40 @@ os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
320310
}
321311

322312
return BHT_OK;
313+
}
314+
315+
int
316+
os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
317+
uint16_t *port, uint8_t *is_ipv4)
318+
{
319+
struct sockaddr_storage addr_storage = { 0 };
320+
socklen_t addr_len = sizeof(addr_storage);
321+
int ret;
322+
323+
ret = getsockname(socket, (struct sockaddr *)&addr_storage, &addr_len);
324+
325+
if (ret != BHT_OK) {
326+
return BHT_ERROR;
327+
}
328+
329+
return os_socket_convert_sockaddr((struct sockaddr *)&addr_storage, buf,
330+
buflen, port, is_ipv4);
331+
}
332+
333+
int
334+
os_socket_addr_remote(bh_socket_t socket, uint8_t *buf, size_t buflen,
335+
uint16_t *port, uint8_t *is_ipv4)
336+
{
337+
struct sockaddr_storage addr_storage = { 0 };
338+
socklen_t addr_len = sizeof(addr_storage);
339+
int ret;
340+
341+
ret = getpeername(socket, (struct sockaddr *)&addr_storage, &addr_len);
342+
343+
if (ret != BHT_OK) {
344+
return BHT_ERROR;
345+
}
346+
347+
return os_socket_convert_sockaddr((struct sockaddr *)&addr_storage, buf,
348+
buflen, port, is_ipv4);
323349
}

core/shared/platform/include/platform_api_extension.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,25 @@ int
393393
os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
394394
uint16_t *port, uint8_t *is_ipv4);
395395

396+
/**
397+
* Returns an binary address and a port of the remote socket
398+
*
399+
* @param socket the remote socket
400+
*
401+
* @param buf buffer to store the address
402+
*
403+
* @param buflen length of the buf buffer
404+
*
405+
* @param port a buffer for storing socket's port
406+
*
407+
* @param is_ipv4 a buffer for storing information about the address family
408+
*
409+
* @return On success, returns 0; otherwise, it returns -1.
410+
*/
411+
int
412+
os_socket_addr_remote(bh_socket_t socket, uint8_t *buf, size_t buflen,
413+
uint16_t *port, uint8_t *is_ipv4);
414+
396415
#ifdef __cplusplus
397416
}
398417
#endif

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,4 +641,13 @@ os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
641641
return BHT_ERROR;
642642
}
643643

644+
int
645+
os_socket_addr_remote(bh_socket_t socket, uint8_t *buf, size_t buflen,
646+
uint16_t *port, uint8_t *is_ipv4)
647+
{
648+
errno = ENOSYS;
649+
650+
return BHT_ERROR;
651+
}
652+
644653
#endif

core/shared/platform/windows/win_socket.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,5 +180,14 @@ os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
180180
{
181181
errno = ENOSYS;
182182

183+
return BHT_ERROR;
184+
}
185+
186+
int
187+
os_socket_addr_remote(bh_socket_t socket, uint8_t *buf, size_t buflen,
188+
uint16_t *port, uint8_t *is_ipv4)
189+
{
190+
errno = ENOSYS;
191+
183192
return BHT_ERROR;
184193
}

samples/socket-api/wasm-src/tcp_server.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ main(int argc, char *argv[])
4949
unsigned connections = 0;
5050
pthread_t workers[WORKER_NUM] = { 0 };
5151
int client_sock_fds[WORKER_NUM] = { 0 };
52+
char ip_string[16];
5253

5354
printf("[Server] Create socket\n");
5455
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
@@ -84,7 +85,11 @@ main(int argc, char *argv[])
8485
break;
8586
}
8687

87-
printf("[Server] Client connected\n");
88+
inet_ntop(AF_INET, &addr.sin_addr, ip_string,
89+
sizeof(ip_string) / sizeof(ip_string[0]));
90+
91+
printf("[Server] Client connected (%s:%d)\n", ip_string,
92+
ntohs(addr.sin_port));
8893
if (pthread_create(&workers[connections], NULL, run,
8994
&client_sock_fds[connections])) {
9095
perror("Create a worker thread failed");

0 commit comments

Comments
 (0)