-
Notifications
You must be signed in to change notification settings - Fork 1.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
Infer public webtransport addrs from quic-v1 addrs. #2251
Changes from all commits
3c87ab8
408671e
f751417
d4ce178
5d1a979
fd3ed65
f640d2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -769,6 +769,7 @@ func (h *BasicHost) Addrs() []ma.Multiaddr { | |
type transportForListeninger interface { | ||
TransportForListening(a ma.Multiaddr) transport.Transport | ||
} | ||
|
||
type addCertHasher interface { | ||
AddCertHashes(m ma.Multiaddr) ma.Multiaddr | ||
} | ||
|
@@ -1005,8 +1006,83 @@ func (h *BasicHost) AllAddrs() []ma.Multiaddr { | |
} | ||
finalAddrs = append(finalAddrs, observedAddrs...) | ||
} | ||
finalAddrs = dedupAddrs(finalAddrs) | ||
finalAddrs = inferWebtransportAddrsFromQuic(finalAddrs) | ||
|
||
return finalAddrs | ||
} | ||
|
||
var wtComponent = ma.StringCast("/webtransport") | ||
|
||
// inferWebtransportAddrsFromQuic infers more webtransport addresses from QUIC addresses. | ||
// This is useful when we discover our public QUIC address, but haven't discovered our public WebTransport addrs. | ||
// If we see that we are listening on the same port for QUIC and WebTransport, | ||
// we can be pretty sure that the WebTransport addr will be reachable if the | ||
// QUIC one is. | ||
// We assume the input is deduped. | ||
func inferWebtransportAddrsFromQuic(in []ma.Multiaddr) []ma.Multiaddr { | ||
// We need to check if we are listening on the same ip+port for QUIC and WebTransport. | ||
// If not, there's nothing to do since we can't infer anything. | ||
|
||
// Count the number of QUIC addrs, this will let us allocate just once at the beginning. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if the plan to reduce allocs actually works out, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it? I thought it just pointed to slices? |
||
quicAddrCount := 0 | ||
for _, addr := range in { | ||
if _, lastComponent := ma.SplitLast(addr); lastComponent.Protocol().Code == ma.P_QUIC_V1 { | ||
quicAddrCount++ | ||
} | ||
} | ||
quicOrWebtransportAddrs := make(map[string]struct{}, quicAddrCount) | ||
webtransportAddrs := make(map[string]struct{}, quicAddrCount) | ||
foundSameListeningAddr := false | ||
for _, addr := range in { | ||
isWebtransport, numCertHashes := libp2pwebtransport.IsWebtransportMultiaddr(addr) | ||
if isWebtransport { | ||
for i := 0; i < numCertHashes; i++ { | ||
// Remove certhashes | ||
addr, _ = ma.SplitLast(addr) | ||
} | ||
webtransportAddrs[addr.String()] = struct{}{} | ||
// Remove webtransport component, now it's a multiaddr that ends in /quic-v1 | ||
addr, _ = ma.SplitLast(addr) | ||
} | ||
|
||
if _, lastComponent := ma.SplitLast(addr); lastComponent.Protocol().Code == ma.P_QUIC_V1 { | ||
addrStr := addr.String() | ||
if _, ok := quicOrWebtransportAddrs[addrStr]; ok { | ||
marten-seemann marked this conversation as resolved.
Show resolved
Hide resolved
|
||
foundSameListeningAddr = true | ||
} else { | ||
quicOrWebtransportAddrs[addrStr] = struct{}{} | ||
} | ||
} | ||
} | ||
|
||
if !foundSameListeningAddr { | ||
return in | ||
} | ||
|
||
if len(webtransportAddrs) == 0 { | ||
// No webtransport addresses, we aren't listening on any webtransport | ||
// address, so we shouldn't add any. | ||
return in | ||
} | ||
|
||
out := make([]ma.Multiaddr, 0, len(in)+(quicAddrCount-len(webtransportAddrs))) | ||
for _, addr := range in { | ||
// Add all the original addresses | ||
out = append(out, addr) | ||
marten-seemann marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if _, lastComponent := ma.SplitLast(addr); lastComponent.Protocol().Code == ma.P_QUIC_V1 { | ||
// Convert quic to webtransport | ||
addr = addr.Encapsulate(wtComponent) | ||
if _, ok := webtransportAddrs[addr.String()]; ok { | ||
// We already have this address | ||
continue | ||
} | ||
// Add the new inferred address | ||
out = append(out, addr) | ||
} | ||
} | ||
|
||
return dedupAddrs(finalAddrs) | ||
return out | ||
} | ||
|
||
// SetAutoNat sets the autonat service for the host. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great explanation, I wish every function we have was that well documented!