bbs icon indicating copy to clipboard operation
bbs copied to clipboard

Is it possibe to do 2 diffrent quic handshakes in a single udp socket?

Open CyrusTheG opened this issue 7 months ago • 10 comments
trafficstars

hello everyone,I was just wondering,is it possible to do 2 diffrent quic handshake(with difrrent sni) in a single udp socket?does it violate rfc or something?if not then a lot of strategies can be used for bypassing quic censorship,idk if this is the right place to ask this but did not know where else to do it lol

CyrusTheG avatar Apr 04 '25 16:04 CyrusTheG

never mind,found my answer

CyrusTheG avatar Apr 04 '25 19:04 CyrusTheG

Wait, this is an interesting question. What answer did you find?

wkrp avatar Apr 04 '25 19:04 wkrp

I could be wrong,but from my undrestanding,quic protocol itself does not care about undrelying udp socket,it recognizes each quic connection with a unique connectionID ,maybe(a BIG maybe) we could do something like this: in a single udp socket client does a quic handshake with sni of whitelisteddomain.com,after that sends another quic client hello with our blocked sni,gfw ussually only checks first few packets in each socket,so this way maybe we could bypass gfw by doing 2 handshakes in a single socket maybe?

CyrusTheG avatar Apr 04 '25 19:04 CyrusTheG

I don't know the answer to your larger question of whether it would actually do something worthwhile, but it is definitely possible to "coalesce" multiple QUIC packets into one UDP datagram. (I'm not sure if you're asking about UDP datagrams or UDP 4-tuple "sockets".)

https://datatracker.ietf.org/doc/html/rfc9000#section-12.2

Using the Length field, a sender can coalesce multiple QUIC packets into one UDP datagram. This can reduce the number of UDP datagrams needed to complete the cryptographic handshake and start sending data. This can also be used to construct Path Maximum Transmission Unit (PMTU) probes; see Section 14.4.1. Receivers MUST be able to process coalesced packets.

Note that there is even a further layer past UDP datagrams and QUIC packets: QUIC frames. It's worth comparing to TLS record fragmentation (#308), where TLS can be fragmented at multiple layers.

wkrp avatar Apr 04 '25 20:04 wkrp

Intuitively it should be possible. Since UDP is stateless, and ports are recycled, a network observer could not reliably differentiate between the two situations:

  1. Client opens one UDP socket, makes a QUIC handshake. Client closes the socket, then opens a new one which happens to have the same source port as the previous socket, and makes a second handshake.
  2. Client opens a single UDP socket and makes two QUIC handshakes (your proposal)

The key question here IMO is how GFW tracks state for QUIC connections. If reusing a source port after a short period of time can skip the new connection filtering then it would be useful.

wallpunch avatar Apr 25 '25 01:04 wallpunch

Yes; this is possible if the connections use non-zero connection IDs. See RFC9000.

larseggert avatar Apr 25 '25 04:04 larseggert

The key question here IMO is how GFW tracks state for QUIC connections. If reusing a source port after a short period of time can skip the new connection filtering then it would be useful.

where i live,as of right now my firewall does not do any real tracking at all,they just inspect first packet in a udp socket,and thats it,right now chrome sends its quic handshake requests in multiple packets for some reason,and is enough to fully bypass their blockage lol i tried to do something like this in golang with quic-go but it did not let me do this and gave me a error one i tried to reuse the socket,i will try some lower level libraries later,cloudflare quiche is probably what i need (~it is a pain to work with~)

CyrusTheG avatar Apr 25 '25 07:04 CyrusTheG

where i live,as of right now my firewall does not do any real tracking at all,they just inspect first packet in a udp socket,and thats it

Even that requires some basic state tracking. How do they determine which is the "first packet"? With TCP it is easy because the initial handshake packets have the SYN flag set. But for UDP you must track some state. At the minimum keep a list of "ip/port tuples that have sent a packet within the last X seconds". If the packet is not in the list, then consider it a "first packet".

What error did you get? If you are reusing the same socket/port immediately you usually have to make a system call to tell the OS. Otherwise recently used ones are temporarily unavailable.

wallpunch avatar Apr 25 '25 08:04 wallpunch

Initial QUIC packets have a unique packet type that identifies them.

larseggert avatar Apr 25 '25 09:04 larseggert

Even that requires some basic state tracking. How do they determine which is the "first packet"? With TCP it is easy because the initial handshake packets have the SYN flag set. But for UDP you must track some state. At the minimum keep a list of "ip/port tuples that have sent a packet within the last X seconds". If the packet is not in the list, then consider it a "first packet".

True,my isp does exactly that,something interesting,another isp that i tested blocked quic entirely for CF ip ranges,,but if i use the same socket and send some junk before quic client hello,then quic handshake can go smoothly,Xray core already has this feature(udp noises)

What error did you get?

it was a quic-go specific error,I do not remember,i will try other libraries soon

CyrusTheG avatar Apr 25 '25 19:04 CyrusTheG