Skip to content
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

Add QUIC (or HTTP/3) support #94

Open
bizzbyster opened this issue Feb 9, 2022 · 26 comments
Open

Add QUIC (or HTTP/3) support #94

bizzbyster opened this issue Feb 9, 2022 · 26 comments
Assignees
Labels
enhancement New feature or request

Comments

@bizzbyster
Copy link

QUIC looks very much like regular web traffic so will remain hard to detect and/or block. Also, QUIC between VpnHoodClient and VpnHoodServer will provide a performance benefit (multiplexing, no head-of-line-blocking, etc.) if you terminate TCP connections locally at client-side proxy. Lastly, as I'm sure you are aware, Microsoft recently released a .NET version of QUIC: https://github.com/microsoft/msquic/. Is this something you would consider adding to your roadmap?

@bobvhood
Copy link
Collaborator

bobvhood commented Feb 9, 2022

We use ordinary .NET TcpClient and TSL handshake to establish the connection between client and server, so if TcpClient uses that protocol, the VpnHood connections use that protocol too. Since it is a very new protocol, I reckon many (old) firewalls already drop or block those connections, so it would be better to configure the TcpClient not to use that protocol until we can see it everywhere.

@bizzbyster
Copy link
Author

UDP-based HTTP/3 (used to be called QUIC) is used for Google, Facebook and Snapchat and in general its adoption is happening very fast. Its true that HTTP/3 falls back to HTTP/2 (which is TCP-based) when UDP is blocked and VpnHood could work the same way. It is in HttpClient and gRpc in .NET 6 but in experimental form. See https://devblogs.microsoft.com/dotnet/http-3-support-in-dotnet-6/. But maybe this is a feature that could be added in the future -- maybe after it has matured in .NET 7. Thanks!

@trudyhood
Copy link
Collaborator

trudyhood commented Feb 10, 2022

Nice proposal. I hope to merge it into VpnHood sooner. If that works as expected, maybe a single UdpChannel will be adequate. However, HTTP/3 uses UDP, making blocking VPNs more difficult for those who want to support HTTP/3. At the moment, some firewalls with deep packet inspection don't let much data transfer via UDP.

It gives me an Idea! At the moment, VpnHood uses a random port for UdpChannel. Perhaps we need to test UDP on port 443 and see how it works in restricted countries. They may treat it as HTTP/3 :) @bobvhood
Check #69

@bizzbyster
Copy link
Author

@trudyhood @bobvhood any way I can directly message you? My email is bizzbyster@gmail.com.

@bobvhood
Copy link
Collaborator

bobvhood commented May 5, 2022

I am wondering why not discuss it in public. Anyway you can contact me
You can contact me bob at vpnhood.com

@trudyhood
Copy link
Collaborator

Hi Everyone. Let's recap this issue. I think at one moment; I got crazy. What on earth are we going to do with HTTP 2 or 3? VpnHood has no sense about HTTP; we are SOCKS and UDP proxy!
@bizzbyster would you elaborate more about your idea? VpnhHood already supports HTTP3 if an app is trying to use it. We are working on the network transport layer, while HTTP protocols are about the network Application Layer.

@nibanks
Copy link

nibanks commented May 7, 2022

If you're interested in using MsQuic for QUIC, let me know. I think it'd be really cool to collaborate.

@bizzbyster
Copy link
Author

Hi Nick, definitely. I'd be happy to try to decompose the work and take some parts. Or, what did you have in mind? Feel free to email me to discuss.

@nibanks
Copy link

nibanks commented May 7, 2022

I can't sign up to do any real work. I can review code, answer questions, and help with design. My team owns many of the networking protocols (IP, UDP, TCP, QUIC, etc.) on Windows, so we've got some experience in the area. 😁 We have a Discord (link on our readme) if you'd like to discuss more!

@bizzbyster
Copy link
Author

Great to have you as a resource -- I will follow up on Discord as questions arise. Thanks @nibanks !

@bizzbyster
Copy link
Author

I'd like to summarize the discussion I had with @nibanks on the MsQuic discord here as it is relevant to this feature:

  1. If the QUIC session is established at startup, then a QUIC stream can be created to send the payload data for each redirected local TCP connection. And the payload data can be sent immediately upon the stream create call -- no need to wait for the QUIC server to acknowledge the new stream. This is important for apps like web browsing that open a lot of TCP connections.
  2. Those QUIC streams will not suffer from head-of-line blocking so that if one QUIC packet is dropped which contains only data associated with stream A and another behind it is not dropped and it contains data associated with stream B then the stream B data will not be blocked waiting for a retransmit.
  3. While MsQuic does not support the default CCA implementations on Linux that are friendly to high latency access networks like BBR or Hybla, there is active working going on to implement BBR for MsQuic here: Implement BBR congestion control algorithm microsoft/msquic#2071. This is useful if someone wants to use VpnHood across a high latency satellite network like my customers do.

@trudyhood
Copy link
Collaborator

Dear @bizzbyster

Here is a VPN using the QUICK protocol
image

Here is using ordinary UDP
image

Why do you think the first one would optimize any TCP stream! The APP has already established an HTTP stream via TCP, and it is too late to optimize it. To optimize it, you need to decode and encode the HTTP again. IF you encapuslate TCP stream via QUIC or UDP, all TCP overhead should still be passed through that connection. You can't increase your network speed or make it more reliable by encapsulating a TCP packet as a payload. The QUIC protocol should be established at first place by the app to gain its advantages.

However, the only advantage is that many Firewalls drop UDP packets at all; they may try to detect QUIC protocol and stop dropping the connection to keep the net working. As UDP is a connectionless protocol, we may establish a fake HTTP3 connection to cheat the firewalls, then start to send and receive our encrypted UDP packets. It would be far faster than using QUIC and doesn't have the QUIC overhead too.

@trudyhood
Copy link
Collaborator

Dear @bizzbyster

I think I have understood what are you talking about. You are talking about VpnHood TCP redirect mode. I can implement it easily as far as there is an easy-to-use HttpClient & HttpListener on .NET so we can easily add and implement a TcpProxyChannel over HTTP3

@bobvhood
Copy link
Collaborator

@trudyhood we just need a compatible NET QUIC Server/Client on NET.

@bizzbyster
Copy link
Author

Hi @trudyhood sorry for my slow response. Yes Tcp redirect mode -- but you can't typically do anything to the traffic at the Http layer because it will be encrypted. Essentially you will break one TCP session into two with Quic with a satellite optimized Congestion Control (CCA) in the middle. Hope that makes sense. I can send a better diagram if not.

@nibanks
Copy link

nibanks commented May 10, 2022

I believe QUIC can benefit a VPN solution regardless of if you use it to proxy IP packets or simply redirect TCP payload. bizzbyster already outlined many of the benefits for the redirect mode, but @trudyhood, QUIC can provide a number of benefits you don't get from plain UDP as well:

  • PMTUD to discover the optimal MTU of the current path
  • Client migration to (1) survive NAT rebindings that are common with UDP and (2) allow/support a client to change between interfaces dynamically.
    • Eventually, true multi-path will be supported so that you can use interfaces/IPs in parallel
  • Secured handshakes and encrypted payload

and the list goes on.

You can obviously build all of this yourself on top of UDP (that's what QUIC is), but it take a lot of time and effort to get it right. If you used MsQuic, you'd be leveraging a QUIC implementation that has a whole team dedicated (and has been for the last 4 years) solely to making the most performance QUIC networking solution available. Let me know if you have any other questions.

@0xRustlang
Copy link

Dear @bizzbyster

Here is a VPN using the QUICK protocol image

Here is using ordinary UDP image

Why do you think the first one would optimize any TCP stream! The APP has already established an HTTP stream via TCP, and it is too late to optimize it. To optimize it, you need to decode and encode the HTTP again. IF you encapuslate TCP stream via QUIC or UDP, all TCP overhead should still be passed through that connection. You can't increase your network speed or make it more reliable by encapsulating a TCP packet as a payload. The QUIC protocol should be established at first place by the app to gain its advantages.

However, the only advantage is that many Firewalls drop UDP packets at all; they may try to detect QUIC protocol and stop dropping the connection to keep the net working. As UDP is a connectionless protocol, we may establish a fake HTTP3 connection to cheat the firewalls, then start to send and receive our encrypted UDP packets. It would be far faster than using QUIC and doesn't have the QUIC overhead too.

In some restricted regions, quick is and can get Whitelisted by the censorship systems to just work for those websites that are on high usage and drop all others.

For ex. Hysteria protocol (that is based on QUIC) currently doesn't work in Iran.

@bizzbyster
Copy link
Author

You might also be interested in this project: https://github.com/Project-Faster/qpep.

@trudyhood trudyhood removed the help wanted Extra attention is needed label Apr 22, 2023
@trudyhood
Copy link
Collaborator

Hi Everyone, We have decided to implement QUIC on VpnHood, but it looks like there is no .NET library to support it on Linux and Xamarin. Am I right?

@nibanks
Copy link

nibanks commented Apr 22, 2023

Are you asking if .NET supports QUIC or if there is a QUIC library built entirely in .NET (not native code)? MsQuic is supported by .NET cross platform, but it is still native code.

@trudyhood
Copy link
Collaborator

@nibanks Thank you for the information. I am wondering how I can use it on Xamarin (Android) and Linux using .NET?
System.Net.Quic.QuicListener.IsSupported returns false on linux (WSL2) and the library does not exist on Xamarin at all. Is there any temporary workaround?

@nibanks
Copy link

nibanks commented Apr 22, 2023

You can call into MsQuic directly and it works. We made a sample cross platform speed test app to try it out a while back. I had it installed on my Android phone for a while. The app code was all C#.

@trudyhood
Copy link
Collaborator

I need more help to start. I looked at https://github.com/microsoft/msquic/ and couldn't find any C# sample. I need to know how to add it to the VpnHood Xamarin project and use it. I would be grateful if you let me know where I can find a working Android sample in C# using MsQuic.

@nibanks
Copy link

nibanks commented Apr 22, 2023

We have a Discord server you can ask for help on. On Monday I can try to find our old code for the app for you.

@trudyhood
Copy link
Collaborator

We have a Discord server you can ask for help on. On Monday I can try to find our old code for the app for you.

Thank you, I found this thread, and it looked like one of the contributors said it is not ready for Xamarin or at least required a bunch of work low-level code required to deal with
microsoft/msquic#2329

@nibanks
Copy link

nibanks commented Apr 22, 2023

That thread is pretty old. Both .NET proper and MsQuic's .NET interop layer have progressed since then. A number of different groups use them now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants