Description
Specification
PK needs to use QUIC system for bidirectional hole punching.
QUICClient
The QUICClient starts a "dialing" phase when it is being created and awaiting the establishedP
.
This results in it sending the Initial
frame with an initial delay of 1, and doubling between.
This will repeat until the config.maxIdleTimeout
is exhausted, which defaults to 5 seconds.
Each time it sends the initial frame, this is stuffed into a UDP packet which is sent to the server.
From this point of view, it is pretty much already doing a "hole punching".
The delay is currently not configurable, and currently I believe there's a bug in the QUICConnection.send
that results in a delay pattern of 1, 2, 0, 4, 0, 8, 0...
. I believe that even though we don't have more frames to be sent, there's a repeat of sending the UDP packet. This should be fixed.
This will occur until a connection is established or that the QUICConnection
times out. If it times out, the QUICClient
async creation should fail.
Once a connection is established there should be a keep alive mechanism to ensure that the NAT mappings are maintained.
QUICServer
The QUICServer on the other hand cannot just try to start a connection to the client side.
Instead we need to expose the ability to just send UDP packets to the client side. Right now the QUICServer.socket
is a protected property... and in PK usage, the socket is likely to be created separately and shared between the client and server in the same peer.
But I think it would be ideal to expose the socket somehow... like being able to access QUICServer.socket
.
So one can do server.socket.send()
.
This is actually an application concern, but we just want to support the interface to make this possible.
Tests should test that it's possible to craft random packets and send it via server.socket.send()
.
Random packets may be preferred over simply empty packets as we suspect that empty packets might be thrown away by routers.
Doing this will then result in the reverse hole punch, that will enable the QUIC client to connect.
Now when these packets are received by the client side, these packets are neither associated to an existing connection, nor can they initiate a new connection, so these packets will simply be thrown away. Tests should prove that this is the case.
At the same time once the connection is setup, there should be a keep alive component added to #6.
Additional context
- Create QUIC library that can be exposed to JS and uses the Node
dgram
module #1 (comment) - demonstrates the delay pattern with wireshark screenshot
Tasks
-
Fix the weird delay pattern during the "dialing" phase ofNot a bug, seems to be intentional onQUICClient
quiche
's part. Integrate the keep alive component Keepalive component after QUIC connection is established #6 when a connection is live. The interval should only be created after the connection is already established, not before it is established.Change to be made as part of Keepalive component after QUIC connection is established #6- Add in the ability for the server to do a reverse dial proceedure.