-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Refactor how we handle UDP #6204
Comments
So you're saying the "fake" UDP connections I had originally implemented in mitmproxy_wireguard are coming back? 😉 |
The suggested approach makes a lot of sense to me, especially if the Python-side sees it as a connection and Rust does all the mapping from (local-endpoint,remote-endpoint) => connection. There is only one caveat where things might get trickier this way down the line, namely if we ever want to support full QUIC roaming. [As food for though, maybe - in the long run - it would make sense to do the same for TCP as well, i.e. being protocol-agnostic in Python (cleaning out some OS-dependent code) and support pluggable Rust endpoints. So future |
Yes, you get your "told you so" card. 😄 Do we still have that code lying around somewhere by chance?
Yes. That's a special case we can handle within the QUIC layer I believe.
I think this is not a completely bad idea... although the asyncio TCP story is not too bad from our end. Let's do UDP first and see how that goes! Thank you two for the quick feedback. 🍰 d587353 is hopefully good enough for a first HTTP/3 release, but I'll give this a spin afterwards. :) |
I'm not even sure if this used to work the way you'd want it to work now, but here's the original issue / PR: If this would work the way you want it to, we might be able to re-purpose parts of the code here. |
Awesome, thanks! I'll take a closer look when working on this. 😃 🍰 |
I've made considerable progress on this over at mitmproxy/mitmproxy_rs#127. WireGuard, Windows Redirector, and plain UDP servers all work. I still need to fix macOS local redirect mode and then rip out all the old cruft. :) |
And done! Fake UDP connections are back. 😄 I'll look over things tomorrow again with a fresh mind, but testing has been super successful so far. UDP clients and servers are now implemented entirely in Rust (which is much more sane than DatagramTransport). WireGuard and local redirect mode are ported as well. 🙌 |
Our current UDP implementation roughly looks as follows:
This has two major problems:
Now, how to fix it? I have long thought that a packet-based
handle_udp_datagram(data, address)
API is the right abstraction for UDP (in contrast tohandle_tcp_connection
, which is called once for an entire connection, this is called for each packet). But seeing how Apple's Network Extension API abstractions work – handleNewFlow and handleNewUDPFlow –, I think we should evaluate a similar approach as well. More concretely, in a first step, we could add acreate_udp_server(host, port, handle_udp_flow)
method over in Rust, which takes care of grouping packets by 4-tuple and calling handle_udp_flow with one DatagramTransport object per flow. If this works, we can reuse our flow grouping logic for the transparent modes as well. Over in Python land, UDP flows would then basically be handled the same way as TCP connections (right now we do a similar type of grouping in Python).TL;DR: More Rust to work around asyncio limitations, and also improve our existing UDP Rust story on the way?
(cc @meitinger @decathorpe)
Footnotes
We can obviously do
.get_extra_info("sockname")
, but that does not help for sockets binding to::
or0.0.0.0
. ↩The text was updated successfully, but these errors were encountered: