Skip to content

Conversation

@cimacmillan
Copy link
Contributor

Added socket send and recv timeout options with implementation for posix platform

This is part of a extending support for sockets in WASI. #1336

I've also added a WIP sample that sets and reads back the send and receive timeouts using the native function binding, however I still need to add the posix-like shim.

}

// TODO: Replace this with posix sockopts when available
#ifdef __wasi__
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd like to use the original API and translate them to Wasm. Users should not learn another set of APIs to develop Wasm application

Since timeout is an opt of a socket, SO_SNDTIMEO, using setsockopt(...) and getsockopt(..) is better.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is just an intermediate step and it will be replaced with getsockopt() and secksockopt() once we have it implemented in wasi_socket_ext.c, is that right, @cimacmillan ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my original plan, but I'll raise a revision for it as part of this PR if that's preferred

@wenyongh
Copy link
Contributor

wenyongh commented Sep 1, 2022

@loganek Could you please help review the PR?

}

// TODO: Replace this with posix sockopts when available
#ifdef __wasi__
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could already add #else branch because (get/set)sockopt is available for non-wasi platform.

{
return (__wasi_errno_t)
__imported_wasi_snapshot_preview1_sock_set_recv_timeout(
(int32_t)fd, (int32_t)timeout_us);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason we convert timeout_us to int32_t and not keeping it 64-bit variable? Wasm supports both 32-bit and 64-bit variables. See https://webassembly.github.io/spec/core/syntax/types.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I'm converting the timeout_us pointer to int32_t, rather than passing the value as int64. It's because of this limitation:

export_native_api.md - As function parameters are always passed in 32 bits numbers, you can also use 'i' for the pointer type argument, then you must do all the address conversion and boundary checking in your native function.

Tested that passing ULLONG_MAX (rounded down to nearest 1000) sets and receives properly. There should probably be a specific test case for this though

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't that refer to pointer types? I think it's possible to pass int64, that's why we have I (uppercase i) as a registration parameter. You can also see some examples in wasi libc, e.g. fd_pwrite's offset parameter is of wasi_filesize_t type which is a type alias of uint64_t.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah you're right I can use I, misunderstood this part. Will update

}

// TODO: Replace this with posix sockopts when available
#ifdef __wasi__
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is just an intermediate step and it will be replaced with getsockopt() and secksockopt() once we have it implemented in wasi_socket_ext.c, is that right, @cimacmillan ?


curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);

return wasmtime_ssp_sock_set_recv_timeout(curfds, fd, *timeout_us);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before passing the timeout_us further, we need to check do check the memory using validate_native_addr(). See usage of that macro in this file for examples.

HANDLE_ERROR(error);
*(struct timeval *)optval = time_us_to_timeval(timeout_us);
return error;
break;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no need for break if you already have return one line above that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to remove, thanks for catching


switch (level) {
case SOL_SOCKET:
switch (optname) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switch inside another switch makes the code a bit less readable, consider refactoring the code to avoid deeply nested code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, maybe separate functions depending on the level? What'd you recommend?

Copy link
Collaborator

@loganek loganek Sep 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think splitting it into functions is not a bad idea. Also, I don't think we're going to add support to level different than SOL_SOCKET, so you might consider failing early at the beginning of the function:

if (level != SOL_SOCKET) {
  return -1;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will split because I was planning to include a couple IPPROTO_TCP ones

@wenyongh wenyongh merged commit 72367f4 into bytecodealliance:dev/socket Sep 3, 2022
vickiegpt pushed a commit to vickiegpt/wamr-aot-gc-checkpoint-restore that referenced this pull request May 27, 2024
Added socket send and recv timeout options with implementation for posix platform.

This is part of a extending support for sockets in WASI. bytecodealliance#1336.

Also add sample that sets and reads back the send and receive timeouts using
the native function binding.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants