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

swarm: return a more meaningful error when dialing QUIC draft-29 #2524

Merged
merged 5 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions p2p/net/swarm/dial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,3 +642,12 @@ func TestDialSelf(t *testing.T) {
_, err := s1.DialPeer(context.Background(), s1.LocalPeer())
require.ErrorIs(t, err, swarm.ErrDialToSelf, "expected error from self dial")
}

func TestDialQUICDraft29(t *testing.T) {
s := makeDialOnlySwarm(t)
id := testutil.RandPeerIDFatal(t)
s.Peerstore().AddAddr(id, ma.StringCast("/ip4/127.0.0.1/udp/1234/quic"), time.Hour)
_, err := s.DialPeer(context.Background(), id)
require.ErrorIs(t, err, swarm.ErrQUICDraft29)
require.ErrorIs(t, err, swarm.ErrNoTransport)
}
marten-seemann marked this conversation as resolved.
Show resolved Hide resolved
25 changes: 24 additions & 1 deletion p2p/net/swarm/swarm_dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import (
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/peerstore"
"github.com/libp2p/go-libp2p/core/transport"

ma "github.com/multiformats/go-multiaddr"
madns "github.com/multiformats/go-multiaddr-dns"
mafmt "github.com/multiformats/go-multiaddr-fmt"
manet "github.com/multiformats/go-multiaddr/net"
)

Expand Down Expand Up @@ -65,6 +67,19 @@ var (
ErrGaterDisallowedConnection = errors.New("gater disallows connection to peer")
)

// ErrQUICDraft29 wraps ErrNoTransport and provide a more meaningful error message
var ErrQUICDraft29 errQUICDraft29

type errQUICDraft29 struct{}

func (errQUICDraft29) Error() string {
return "QUIC draft-29 has been removed, QUIC (RFC 9000) is accessible with /quic-v1"
}

func (errQUICDraft29) Unwrap() error {
return ErrNoTransport
}

// DialAttempts governs how many times a goroutine will try to dial a given peer.
// Note: this is down to one, as we have _too many dials_ atm. To add back in,
// add loop back in Dial(.)
Expand Down Expand Up @@ -407,6 +422,8 @@ func (s *Swarm) nonProxyAddr(addr ma.Multiaddr) bool {
return !t.Proxy()
}

var quicDraft29DialMatcher = mafmt.And(mafmt.IP, mafmt.Base(ma.P_UDP), mafmt.Base(ma.P_QUIC))

// filterKnownUndialables takes a list of multiaddrs, and removes those
// that we definitely don't want to dial: addresses configured to be blocked,
// IPv6 link-local addresses, addresses without a dial-capable transport,
Expand Down Expand Up @@ -435,7 +452,13 @@ func (s *Swarm) filterKnownUndialables(p peer.ID, addrs []ma.Multiaddr) (goodAdd
// filter addresses with no transport
addrs = ma.FilterAddrs(addrs, func(a ma.Multiaddr) bool {
if s.TransportForDialing(a) == nil {
addrErrs = append(addrErrs, TransportError{Address: a, Cause: ErrNoTransport})
e := ErrNoTransport
// We used to support QUIC draft-29 for a long time.
// Provide a more useful error when attempting to dial a QUIC draft-29 address.
if quicDraft29DialMatcher.Matches(a) {
e = ErrQUICDraft29
}
addrErrs = append(addrErrs, TransportError{Address: a, Cause: e})
return false
}
return true
Expand Down