Stream: wasi

Topic: Fine-grained network policies


view this post on Zulip Ryan Levick (rylev) (Dec 18 2023 at 10:47):

@Badeend I really love how things are coming together in https://github.com/bytecodealliance/wasmtime/issues/7681 and https://github.com/bytecodealliance/wasmtime/issues/7694. How do you want to go about implementing this since the design (at least at a high-level) seems pretty clear? I'm keen on diving into this, but I don't want to step on toes or increase risk of duplicate work.

#7662 is a good first step towards letting users of the wasmtime library customize network behavior. After that change, library users have two options: either use inherit_network which grants acces...
My use case is essentially to allow any socket operation as long as the IP addressed used for that operation was resolved in the last call to wasi:sockets/ip-name-lookup#resolve_addresses. Given th...

view this post on Zulip Dave Bakker (badeend) (Dec 18 2023 at 15:44):

I think the first step will be to introduce all the required extension points. I posted an idea for that in https://github.com/bytecodealliance/wasmtime/issues/7681#issuecomment-1860560055

#7662 is a good first step towards letting users of the wasmtime library customize network behavior. After that change, library users have two options: either use inherit_network which grants acces...

view this post on Zulip Ryan Levick (rylev) (Dec 19 2023 at 11:16):

@Dave Bakker (badeend) your approach laid out here seems reasonable. Would you mind if I started on trying out the implementation?

#7662 is a good first step towards letting users of the wasmtime library customize network behavior. After that change, library users have two options: either use inherit_network which grants acces...

view this post on Zulip Dave Bakker (badeend) (Dec 19 2023 at 11:33):

Yeah, sure. No problem!
Maybe start out with UDP and/or domain name lookup? I already started tinkering with TCP

view this post on Zulip Ryan Levick (rylev) (Dec 19 2023 at 11:38):

Cool. I’ll start with domain names then.

view this post on Zulip Ryan Levick (rylev) (Dec 19 2023 at 15:49):

https://github.com/bytecodealliance/wasmtime/pull/7705

This follows the design outlined in #7681 for IpNameLookup. A new trait IpNameLookup is introduced that factors out the conversion from a String to a list of IP addresses. Another trait, WasiIpName...

view this post on Zulip Dave Bakker (badeend) (Dec 20 2023 at 15:24):

@Ryan Levick (rylev) I've spent a day trying to get wasi-io's InputStream & OutputStream working on top of tokio's AsyncRead & AsyncWrite, but getting that to work would require a lot more work than I'm willing to put in right now. So if you don't mind I'm going to continue on with custom traits:

#[async_trait]
pub trait TcpReader {
    fn try_read(&mut self, size: usize) -> io::Result<Bytes>;
    async fn readable(&mut self);
}

#[async_trait]
pub trait TcpWriter {
    fn try_write(&mut self, bytes: Bytes) -> io::Result<usize>;
    async fn writable(&mut self);
}

view this post on Zulip Ryan Levick (rylev) (Dec 20 2023 at 15:58):

Works for me! Just out of curiosity, do you imagine you would run into the same issues with the futures crate’s AsyncRead and AsyncWrite?

view this post on Zulip Dave Bakker (badeend) (Dec 20 2023 at 16:48):

Yeah, they're the same general design

view this post on Zulip Ryan Levick (rylev) (Jan 03 2024 at 13:57):

@Dave Bakker (badeend) Happy New Year - I wanted to check in with you on this. Are you still hoping to have a PR for TCP support similar to the one I have for IP name lookups? I was thinking about jumping into UDP soon.

view this post on Zulip Dave Bakker (badeend) (Jan 03 2024 at 14:25):

Happy new year to you too. :fireworks: I haven't worked on WASI at all the past week, but expect to continue somewhere this week

view this post on Zulip Dave Bakker (badeend) (Jan 11 2024 at 19:27):

@Ryan Levick (rylev) To keep you up to date on my progress, I've opened a draft PR. To my estimation it is about ~70% done.

Standalone JIT-style runtime for WebAsssembly, using Cranelift - TCP overrides by badeend · Pull Request #2 · rylev/wasmtime

view this post on Zulip Dave Bakker (badeend) (Jan 14 2024 at 21:32):

Alright, I'm done. I've updated the PR. Let me know what you think

view this post on Zulip Ryan Levick (rylev) (Jan 15 2024 at 16:26):

Looks great! I think we should merge this ASAP so that I can get in a PR for UDP.

view this post on Zulip Ryan Levick (rylev) (Jan 19 2024 at 17:14):

@Dave Bakker (badeend) I finally had time to sit down today and do the UDP work. It's not quite done, and I haven't actually tested it, but if you're curious for a preview, you can find it here: https://github.com/rylev/wasmtime/pull/4. I'll move the PR out of draft state early next week.

Standalone JIT-style runtime for WebAsssembly, using Cranelift - UDP override by rylev · Pull Request #4 · rylev/wasmtime

view this post on Zulip Dave Bakker (badeend) (Jan 19 2024 at 19:15):

Already looking great! :tada: I only skimmed the PR , but I have two thoughts so far:

  1. You've implemented UdpSocketResource::inner as an Arc. This forces implementors to use a Mutex if they want to maintain additional state. Is there any way to get around this?
  2. Perhaps we can merge send_data_to, send_data & await_writable into a single fn poll_send(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<Result<usize>> similar to how tokio does it?

view this post on Zulip Dave Bakker (badeend) (Jan 19 2024 at 19:17):

and the same for receive.
That would be similar to TcpSocket::poll_accept

view this post on Zulip Ryan Levick (rylev) (Jan 22 2024 at 12:35):

You've implemented UdpSocketResource::inner as an Arc. This forces implementors to use a Mutex if they want to maintain additional state. Is there any way to get around this?

Yea, that's not ideal. Unfortunately, at least in the naive implementation I don't know if we can avoid it. The dyn UdpSocket lives both in the SocketResource, the IncomingDatagramStream, and the OutgoingDatagramStream. So in order to support multiple owners we need to use reference counting. We could of course change things to that the two stream types don't own a dyn UdpSocket but rather get some ownership over different handle types.

Perhaps we can merge send_data_to, send_data & await_writable into a single fn poll_send(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<Result<usize>> similar to how tokio does it?

I thought the same about this and only avoided it since it's not quite a simple as the current naive implementation. I'll play around with this and the idea of different handle types discussed above, and we'll see what happens.

view this post on Zulip Ryan Levick (rylev) (Jan 22 2024 at 17:53):

@Dave Bakker (badeend) I unfortunately couldn't come up with a way to both signal readiness and allow for reading and writing data within the same function. Perhaps you have an idea for how to do this elegantly. In any case, it might be best to have you review https://github.com/rylev/wasmtime/pull/4 and if you're generally ok with the direction, we can merge it, and then start doing final tweaks before we get Alex to review the whole thing for merging into Wasmtime main.

This PR moves UDP to a similar architecture to how TCP works after #2. The UdpSocket trait sets out all of the overrideable features for UDP including the ability to generate outgoing and incoming ...

view this post on Zulip Ryan Levick (rylev) (Jan 29 2024 at 16:02):

@Dave Bakker (badeend) I tried to do a rebase against the latest main and it was pretty painful. I'm thinking I might squash all the commits on the branch so that only one commit needs to be rebased. Would you object to this?

view this post on Zulip Dave Bakker (badeend) (Jan 29 2024 at 19:17):

Go ahead

view this post on Zulip Ryan Levick (rylev) (Mar 28 2024 at 08:59):

@Dave Bakker (badeend) I'd like to try to see if we can land all of this work. Unless you object I'll start breaking up https://github.com/bytecodealliance/wasmtime/pull/7705 (like you suggested here)

This follows the design outlined in #7681 for IpNameLookup. A new trait IpNameLookup is introduced that factors out the conversion from a String to a list of IP addresses. Another trait, WasiIpName...
This follows the design outlined in #7681 for IpNameLookup. A new trait IpNameLookup is introduced that factors out the conversion from a String to a list of IP addresses. Another trait, WasiIpName...

view this post on Zulip Dave Bakker (badeend) (Mar 28 2024 at 09:04):

I won't be able to work on WASI for at least a couple of weeks, so go ahead! :smile:

view this post on Zulip Ryan Levick (rylev) (Mar 28 2024 at 09:58):

Absolutely no worries! That's why there's one than one of us :-)

view this post on Zulip Ryan Levick (rylev) (Apr 02 2024 at 13:03):

Started this process with https://github.com/bytecodealliance/wasmtime/pull/8282

Part of #7705 was moving the implementation of TCP (and UDP) out of the host bindings and into their own types. This PR starts this process (only for TCP) by doing a simple lift and shift of the co...

Last updated: Dec 23 2024 at 13:07 UTC