Skip to content

Commit fec1bcf

Browse files
committed
Added setsockopt & getsockopt wrappers
1 parent 2f1420a commit fec1bcf

File tree

4 files changed

+128
-23
lines changed

4 files changed

+128
-23
lines changed

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ typedef struct __wasi_addr_info_hints_t {
9494
* <sys/types.h>
9595
*/
9696

97+
#define SO_RCVTIMEO 20
98+
#define SO_SNDTIMEO 21
99+
97100
int
98101
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
99102

@@ -120,6 +123,14 @@ getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
120123

121124
int
122125
getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
126+
127+
int
128+
getsockopt(int sockfd, int level, int optname, void *__restrict optval,
129+
socklen_t *__restrict optlen);
130+
131+
int
132+
setsockopt(int sockfd, int level, int optname, const void *optval,
133+
socklen_t optlen);
123134
#endif
124135

125136
/**
@@ -461,16 +472,16 @@ __wasi_sock_get_recv_timeout(__wasi_fd_t fd, uint64_t *timeout_us)
461472

462473
int32_t
463474
__imported_wasi_snapshot_preview1_sock_set_recv_timeout(int32_t arg0,
464-
int32_t arg1)
475+
int64_t arg1)
465476
__attribute__((__import_module__("wasi_snapshot_preview1"),
466477
__import_name__("sock_set_recv_timeout")));
467478

468479
static inline __wasi_errno_t
469-
__wasi_sock_set_recv_timeout(__wasi_fd_t fd, uint64_t *timeout_us)
480+
__wasi_sock_set_recv_timeout(__wasi_fd_t fd, uint64_t timeout_us)
470481
{
471482
return (__wasi_errno_t)
472483
__imported_wasi_snapshot_preview1_sock_set_recv_timeout(
473-
(int32_t)fd, (int32_t)timeout_us);
484+
(int32_t)fd, (int64_t)timeout_us);
474485
}
475486

476487
int32_t
@@ -489,16 +500,16 @@ __wasi_sock_get_send_timeout(__wasi_fd_t fd, uint64_t *timeout_us)
489500

490501
int32_t
491502
__imported_wasi_snapshot_preview1_sock_set_send_timeout(int32_t arg0,
492-
int32_t arg1)
503+
int64_t arg1)
493504
__attribute__((__import_module__("wasi_snapshot_preview1"),
494505
__import_name__("sock_set_send_timeout")));
495506

496507
static inline __wasi_errno_t
497-
__wasi_sock_set_send_timeout(__wasi_fd_t fd, uint64_t *timeout_us)
508+
__wasi_sock_set_send_timeout(__wasi_fd_t fd, uint64_t timeout_us)
498509
{
499510
return (__wasi_errno_t)
500511
__imported_wasi_snapshot_preview1_sock_set_send_timeout(
501-
(int32_t)fd, (int32_t)timeout_us);
512+
(int32_t)fd, (int64_t)timeout_us);
502513
}
503514

504515
/**

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

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,3 +282,80 @@ getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
282282

283283
return __WASI_ERRNO_SUCCESS;
284284
}
285+
286+
struct timeval
287+
time_us_to_timeval(uint64_t time_us)
288+
{
289+
struct timeval tv;
290+
tv.tv_sec = time_us / 1000000UL;
291+
tv.tv_usec = time_us % 1000000UL;
292+
return tv;
293+
}
294+
295+
uint64_t
296+
timeval_to_time_us(struct timeval tv)
297+
{
298+
return (tv.tv_sec * 1000000UL) + tv.tv_usec;
299+
}
300+
301+
int
302+
getsockopt(int sockfd, int level, int optname, void *__restrict optval,
303+
socklen_t *__restrict optlen)
304+
{
305+
__wasi_errno_t error;
306+
uint64_t timeout_us;
307+
308+
switch (level) {
309+
case SOL_SOCKET:
310+
switch (optname) {
311+
case SO_RCVTIMEO:
312+
assert(*optlen == sizeof(struct timeval));
313+
error = __wasi_sock_get_recv_timeout(sockfd, &timeout_us);
314+
HANDLE_ERROR(error);
315+
*(struct timeval *)optval = time_us_to_timeval(timeout_us);
316+
return error;
317+
break;
318+
case SO_SNDTIMEO:
319+
assert(*optlen == sizeof(struct timeval));
320+
error = __wasi_sock_get_send_timeout(sockfd, &timeout_us);
321+
HANDLE_ERROR(error);
322+
*(struct timeval *)optval = time_us_to_timeval(timeout_us);
323+
return error;
324+
break;
325+
}
326+
break;
327+
}
328+
329+
HANDLE_ERROR(__WASI_ERRNO_NOTSUP);
330+
}
331+
332+
int
333+
setsockopt(int sockfd, int level, int optname, const void *optval,
334+
socklen_t optlen)
335+
{
336+
__wasi_errno_t error;
337+
uint64_t timeout_us;
338+
339+
switch (level) {
340+
case SOL_SOCKET:
341+
switch (optname) {
342+
case SO_RCVTIMEO:
343+
assert(optlen == sizeof(struct timeval));
344+
timeout_us = timeval_to_time_us(*(struct timeval *)optval);
345+
error = __wasi_sock_set_recv_timeout(sockfd, timeout_us);
346+
HANDLE_ERROR(error);
347+
return error;
348+
break;
349+
case SO_SNDTIMEO:
350+
assert(optlen == sizeof(struct timeval));
351+
timeout_us = timeval_to_time_us(*(struct timeval *)optval);
352+
error = __wasi_sock_set_send_timeout(sockfd, timeout_us);
353+
HANDLE_ERROR(error);
354+
return error;
355+
break;
356+
}
357+
break;
358+
}
359+
360+
HANDLE_ERROR(__WASI_ERRNO_NOTSUP);
361+
}

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,9 @@ wasi_sock_get_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
11241124
if (!wasi_ctx)
11251125
return __WASI_EACCES;
11261126

1127+
if (!validate_native_addr(timeout_us, sizeof(uint64_t)))
1128+
return __WASI_EINVAL;
1129+
11271130
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
11281131

11291132
return wasmtime_ssp_sock_get_recv_timeout(curfds, fd, timeout_us);
@@ -1159,6 +1162,9 @@ wasi_sock_get_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
11591162
if (!wasi_ctx)
11601163
return __WASI_EACCES;
11611164

1165+
if (!validate_native_addr(timeout_us, sizeof(uint64_t)))
1166+
return __WASI_EINVAL;
1167+
11621168
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
11631169

11641170
return wasmtime_ssp_sock_get_send_timeout(curfds, fd, timeout_us);
@@ -1205,7 +1211,7 @@ wasi_sock_set_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
12051211

12061212
static wasi_errno_t
12071213
wasi_sock_set_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
1208-
uint64_t *timeout_us)
1214+
uint64_t timeout_us)
12091215
{
12101216
wasm_module_inst_t module_inst = get_module_inst(exec_env);
12111217
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@@ -1216,7 +1222,7 @@ wasi_sock_set_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
12161222

12171223
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
12181224

1219-
return wasmtime_ssp_sock_set_recv_timeout(curfds, fd, *timeout_us);
1225+
return wasmtime_ssp_sock_set_recv_timeout(curfds, fd, timeout_us);
12201226
}
12211227

12221228
static wasi_errno_t
@@ -1240,7 +1246,7 @@ wasi_sock_set_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
12401246

12411247
static wasi_errno_t
12421248
wasi_sock_set_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
1243-
uint64_t *timeout_us)
1249+
uint64_t timeout_us)
12441250
{
12451251
wasm_module_inst_t module_inst = get_module_inst(exec_env);
12461252
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@@ -1251,7 +1257,7 @@ wasi_sock_set_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
12511257

12521258
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
12531259

1254-
return wasmtime_ssp_sock_set_send_timeout(curfds, fd, *timeout_us);
1260+
return wasmtime_ssp_sock_set_send_timeout(curfds, fd, timeout_us);
12551261
}
12561262

12571263
static wasi_errno_t
@@ -1488,11 +1494,11 @@ static NativeSymbol native_symbols_libc_wasi[] = {
14881494
REG_NATIVE_FUNC(sock_recv, "(i*ii**)i"),
14891495
REG_NATIVE_FUNC(sock_send, "(i*ii*)i"),
14901496
REG_NATIVE_FUNC(sock_set_recv_buf_size, "(ii)i"),
1491-
REG_NATIVE_FUNC(sock_set_recv_timeout, "(i*)i"),
1497+
REG_NATIVE_FUNC(sock_set_recv_timeout, "(iI)i"),
14921498
REG_NATIVE_FUNC(sock_set_reuse_addr, "(ii)i"),
14931499
REG_NATIVE_FUNC(sock_set_reuse_port, "(ii)i"),
14941500
REG_NATIVE_FUNC(sock_set_send_buf_size, "(ii)i"),
1495-
REG_NATIVE_FUNC(sock_set_send_timeout, "(i*)i"),
1501+
REG_NATIVE_FUNC(sock_set_send_timeout, "(iI)i"),
14961502
REG_NATIVE_FUNC(sock_shutdown, "(ii)i"),
14971503
REG_NATIVE_FUNC(sched_yield, "()i"),
14981504
};

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

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,19 @@
1515
return EXIT_FAILURE; \
1616
}
1717

18+
struct timeval
19+
to_timeval(time_t tv_sec, suseconds_t tv_usec)
20+
{
21+
struct timeval tv = { tv_sec, tv_usec };
22+
return tv;
23+
}
24+
1825
int
1926
main(int argc, char *argv[])
2027
{
2128
int socket_fd = 0;
29+
struct timeval tv;
30+
socklen_t tv_len = sizeof(tv);
2231

2332
printf("[Client] Create socket\n");
2433
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
@@ -27,18 +36,20 @@ main(int argc, char *argv[])
2736
return EXIT_FAILURE;
2837
}
2938

30-
// TODO: Replace this with posix sockopts when available
31-
#ifdef __wasi__
32-
uint64_t timeout_us = 5000;
33-
__wasi_sock_set_recv_timeout(socket_fd, &timeout_us);
34-
__wasi_sock_get_recv_timeout(socket_fd, &timeout_us);
35-
OPTION_ASSERT(timeout_us, 5000, "recv_timeout");
39+
tv = to_timeval(123, 1000);
40+
setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
41+
tv = to_timeval(0, 0);
42+
getsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &tv_len);
43+
OPTION_ASSERT(tv.tv_sec, 123, "SO_RCVTIMEO tv_sec");
44+
OPTION_ASSERT(tv.tv_usec, 1000, "SO_RCVTIMEO tv_usec");
45+
46+
tv = to_timeval(456, 2000);
47+
setsockopt(socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
48+
tv = to_timeval(0, 0);
49+
getsockopt(socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &tv_len);
50+
OPTION_ASSERT(tv.tv_sec, 456, "SO_SNDTIMEO tv_sec");
51+
OPTION_ASSERT(tv.tv_usec, 2000, "SO_SNDTIMEO tv_usec");
3652

37-
timeout_us = 10000;
38-
__wasi_sock_set_send_timeout(socket_fd, &timeout_us);
39-
__wasi_sock_get_send_timeout(socket_fd, &timeout_us);
40-
OPTION_ASSERT(timeout_us, 10000, "send_timeout");
41-
#endif
4253
printf("[Client] Close socket\n");
4354
close(socket_fd);
4455
return EXIT_SUCCESS;

0 commit comments

Comments
 (0)