-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merge bind and listen? #29
Comments
Yeah, I was about to suggest something similar in response to #28. Preferably, our interface would be:
and drop the separate I guess the question then becomes: how much are we willing to stray from POSIX/BSD compatibility? This will probably work fine for the majority of cases. However, Aside: Regardless of this specific issue, I doubt the rust standard library is going to cut it anyway, as it doesn't provide any async methods nor access to IPV6_V6ONLY, SO_KEEPALIVE, IPV6_UNICAST_HOPS, SO_RCVBUF, SO_SNDBUF. socket2 looks promising. |
A major consideration here is whether other major host APIs do something similar. I looked around a little and found that while Rust's standard library merges listen into bind, Java merges listen into accept, while Python, C#, Ruby, libuv all appear to follow POSIX in keeping bind, listen, and accept separate. Consequently, I now think we should keep bind, listen, and accept separate, as wasi-sockets already does. |
Oh, interesting, thanks for finding that! That is worth thinking about then. I don't think we necessarily need to make a change right now, but is is worth thinking about. |
I'll reopen this as a reminder for myself to re-evaluate this in the future. |
Another consideration when merging bind and listen at the WASI layer is: how to handle the It seems that you'd have to give up on either: being able to specify the backlog size, or: being able to call Edit: because not every platform supports changing the backlog size after the initial listen call. |
Maybe we can solve this entirely in libc. Suppose wasi-sockets provides only:
Then, by default, libc's For the edge case where a client want to make the connection from a specific local address, we can invent a libc pseudo code: fn bind(sock, local_addr) {
if (sock.SO_DEFER_BIND) {
sock.local_addr = local_addr;
} else {
wasi_sockets::tcp::listen(sock, local_addr);
}
}
fn getsockname(sock) {
if (sock.SO_DEFER_BIND) {
sock.local_addr;
} else {
wasi_sockets::tcp::local_address(sock);
}
}
fn listen(sock, backlog) {
wasi_sockets::tcp::set_backlog_size(sock, backlog);
if (sock.SO_DEFER_BIND) {
wasi_sockets::tcp::listen(sock, local_addr);
} else {
// Do nothing
}
}
fn connect(sock, remote_addr) {
wasi_sockets::tcp::connect(sock, remote_addr, sock.local_addr);
} The downside is that existing client software may need to be modified to target WASI. I think this is justified, because:
@sunfishcode What do you think? |
This change sounds risky to me, as it changes the externally-visible behavior. The change for client code making connections with custom local addresses is also concerning. Both of those are relatively obscure, but I think overall, wasi-sockets should err on the side of preserving fundamental POSIX semantics. |
I know this has been iterated on in other contexts, but
Implementing wasi-sockets on top of the Rust standard library, I have to bridge the gap that Rust's
bind
function doessocket
,bind
, andlisten
all in one step. I have it implemented with a little state machine that collects up the socket and bind info and does everything at the point of the listen. But this does mean that if users pass port 0 tobind
and then dogetsockname
afterwards to find out what port it picked, I can't implement it because I haven't actually created a socket at that point.The answer might be that the Rust standard library is too high-level here and I need to use lower-level APIs, and I can do that. But I suspect Rust is not the only language that does something like this. If so, it's worth considering merging these calls.
The text was updated successfully, but these errors were encountered: