feat: Add QUIC Address Discovery to iroh #3049
Open
+335
−117
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
There were two main things to "solve" on the iroh side:
The first was accomplished by figuring out how to make
MagicSock::spawn
be the location that builds thequinn::Endpoint
. This is what was changed:AsyncUdpSocket
onMagicSock
itself, rather thanmagicsock::Handle
magicsock::Handle
now contains thequinn::Endpoint
server_config
as aMagicSock::Option
MagicSock::spawn
:MagicSock
we now build thequinn::Endpoint
usingArc<MagicSock>
as theAsyncUdpSocket
quinn::Endpoint
and passed it to themagicsock::Actor
(which is independent ofMagicSock
)quinn::Endpoint
to themagicsock::Handle
, which is the actual struct that we use to interact with the magicsocketiroh::Endpoint
now interacts with thequinn::Endpoint
usingmsock.endpoint()
in all placesThe second was accomplished by keeping a list of special "QAD addresses" on the
NodeMap
(NodeMap::qad_addrs
), and using specific methods toadd_qad_addrs
,get_qad_addrs_for_send
andget_qad_addrs_for_recv
to deal with the fickle way that thequinn::Endpoint
expects SocketAddrs to behave when it dials and when it receives packets:RelayUrl
s in theRelayMap
to get theSocketAddr
s that we expect we will dial when we do a QAD probeNodeMap
AsyncUdpSocket
, after we do our normal checks for QuicMappedAddrs, we then check to see if the QuicMappedAddr is actually just a normal socket addr that we expect to use for QAD. If so, we just send the packets using theget_qad_addr_for_send
addressAsyncUdpSocket
, after we check to see if the recv'd address can be mapped to a QuicMappedAddr & therefore can be received using our normal process, we then check to see if the address is one that we expect for QAD. If so, we make sure to associate the packet with theget_qad_addr_for_recv
address and pass it alongThe most "unreliable" bits of this are due to dns. Before running a net report, we now have to do dns discovery for all the RelayUrls. I've capped this at 300 ms but it means that until we cache the dns responses then we have this delay before starting net-report. I've also done a bit of a cheat: when we initially start the
magicsock::Actor
, I've added a call toresolve_qad_addrs
that has a timeout of 10 ms, just to send out the dns packets and hopefully get a jump on caching the responses.Most interesting bit
So...rather than limiting this to QAD, we could actually generalize it (
bypass_addrs
(bikeshed) rather thanqad_addrs
) & allow folks to use the Endpoint as a sort of normal quinn::Endpoint, bypassing our special iroh holepunching sauce. You just have to have to add theSocketAddr
to the node_map before callingconnect
so that we know to let packets for that particular address through.Just a thought, if we ever want to allow that.
conclusion
I don't know if we actually want to do this, but it works!
Test it by editing the
listen
&connect
examples to useRelayMap::Staging
& limit net-report to use only QAD probes by replacing line 2450 in magicsock fromto
And you should see both public and private IP addresses in the "listening addresses" list
depends on #3032
Change checklist