Skip to content

Commit 6bf31c8

Browse files
authored
Merge branch 'master' into add-ipv6-transport-tests
2 parents d39a124 + b3f1e66 commit 6bf31c8

File tree

12 files changed

+159
-0
lines changed

12 files changed

+159
-0
lines changed

core/network/conn.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,20 @@ type Conn interface {
8787
// IsClosed returns whether a connection is fully closed, so it can
8888
// be garbage collected.
8989
IsClosed() bool
90+
91+
// As finds the first conn in Conn's wrapped types that matches target, and
92+
// if one is found, sets target to that conn value and returns true.
93+
// Otherwise, it returns false. Similar to errors.As.
94+
//
95+
// target must be a pointer to the type you are matching against.
96+
//
97+
// This is an EXPERIMENTAL API. Getting access to the underlying type can
98+
// lead to hard to debug issues. For example, if you mutate connection state
99+
// on the underlying type, hooks that relied on only mutating that state
100+
// from the wrapped connection would never be called.
101+
//
102+
// You very likely do not need to use this method.
103+
As(target any) bool
90104
}
91105

92106
// ConnectionState holds information about the connection.

core/network/mux.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,20 @@ type MuxedConn interface {
137137

138138
// AcceptStream accepts a stream opened by the other side.
139139
AcceptStream() (MuxedStream, error)
140+
141+
// As finds the first conn in MuxedConn's wrapped types that matches target,
142+
// and if one is found, sets target to that conn value and returns true.
143+
// Otherwise, it returns false. Similar to errors.As.
144+
//
145+
// target must be a pointer to the type you are matching against.
146+
//
147+
// This is an EXPERIMENTAL API. Getting access to the underlying type can
148+
// lead to hard to debug issues. For example, if you mutate connection state
149+
// on the underlying type, hooks that relied on only mutating that state
150+
// from the wrapped connection would never be called.
151+
//
152+
// You very likely do not need to use this method.
153+
As(target any) bool
140154
}
141155

142156
// Multiplexer wraps a net.Conn with a stream multiplexing

libp2p_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ import (
4040
libp2pwebrtc "github.com/libp2p/go-libp2p/p2p/transport/webrtc"
4141
"github.com/libp2p/go-libp2p/p2p/transport/websocket"
4242
webtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport"
43+
"github.com/libp2p/go-yamux/v5"
44+
"github.com/pion/webrtc/v4"
45+
quicgo "github.com/quic-go/quic-go"
46+
wtgo "github.com/quic-go/webtransport-go"
4347
"go.uber.org/goleak"
4448

4549
ma "github.com/multiformats/go-multiaddr"
@@ -842,3 +846,76 @@ func BenchmarkAllAddrs(b *testing.B) {
842846
addrsHost.AllAddrs()
843847
}
844848
}
849+
850+
func TestConnAs(t *testing.T) {
851+
type testCase struct {
852+
name string
853+
listenAddr string
854+
testAs func(t *testing.T, c network.Conn)
855+
}
856+
857+
testCases := []testCase{
858+
{
859+
"QUIC",
860+
"/ip4/0.0.0.0/udp/0/quic-v1",
861+
func(t *testing.T, c network.Conn) {
862+
var quicConn *quicgo.Conn
863+
require.True(t, c.As(&quicConn))
864+
},
865+
},
866+
{
867+
"TCP+Yamux",
868+
"/ip4/0.0.0.0/tcp/0",
869+
func(t *testing.T, c network.Conn) {
870+
var yamuxSession *yamux.Session
871+
require.True(t, c.As(&yamuxSession))
872+
},
873+
},
874+
{
875+
"WebRTC",
876+
"/ip4/0.0.0.0/udp/0/webrtc-direct",
877+
func(t *testing.T, c network.Conn) {
878+
var webrtcPC *webrtc.PeerConnection
879+
require.True(t, c.As(&webrtcPC))
880+
},
881+
},
882+
{
883+
"WebTransport Session",
884+
"/ip4/0.0.0.0/udp/0/quic-v1/webtransport",
885+
func(t *testing.T, c network.Conn) {
886+
var s *wtgo.Session
887+
require.True(t, c.As(&s))
888+
},
889+
},
890+
{
891+
"WebTransport QUIC Conn",
892+
"/ip4/0.0.0.0/udp/0/quic-v1/webtransport",
893+
func(t *testing.T, c network.Conn) {
894+
var quicConn *quicgo.Conn
895+
require.True(t, c.As(&quicConn))
896+
},
897+
},
898+
}
899+
900+
for _, tc := range testCases {
901+
t.Run(tc.name, func(t *testing.T) {
902+
h1, err := New(ListenAddrStrings(
903+
tc.listenAddr,
904+
))
905+
require.NoError(t, err)
906+
defer h1.Close()
907+
h2, err := New(ListenAddrStrings(
908+
tc.listenAddr,
909+
))
910+
require.NoError(t, err)
911+
defer h2.Close()
912+
err = h1.Connect(context.Background(), peer.AddrInfo{
913+
ID: h2.ID(),
914+
Addrs: h2.Addrs(),
915+
})
916+
require.NoError(t, err)
917+
c := h1.Network().ConnsToPeer(h2.ID())[0]
918+
tc.testAs(t, c)
919+
})
920+
}
921+
}

p2p/muxer/yamux/conn.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ type conn yamux.Session
1313

1414
var _ network.MuxedConn = &conn{}
1515

16+
func (c *conn) As(target any) bool {
17+
if t, ok := target.(**yamux.Session); ok {
18+
*t = (*yamux.Session)(c)
19+
return true
20+
}
21+
return false
22+
}
23+
1624
// NewMuxedConn constructs a new MuxedConn from a yamux.Session.
1725
func NewMuxedConn(m *yamux.Session) network.MuxedConn {
1826
return (*conn)(m)

p2p/net/connmgr/connmgr_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ func (m mockConn) NewStream(_ context.Context) (network.Stream, error) { panic("
818818
func (m mockConn) GetStreams() []network.Stream { panic("implement me") }
819819
func (m mockConn) Scope() network.ConnScope { panic("implement me") }
820820
func (m mockConn) ConnState() network.ConnectionState { return network.ConnectionState{} }
821+
func (m mockConn) As(_ any) bool { return false }
821822

822823
func makeSegmentsWithPeerInfos(peerInfos peerInfos) *segments {
823824
var s = func() *segments {

p2p/net/mock/mock_conn.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ func (c *conn) Close() error {
8686
return nil
8787
}
8888

89+
func (c *conn) As(_ any) bool {
90+
return false
91+
}
92+
8993
func (c *conn) teardown() {
9094
for _, s := range c.allStreams() {
9195
s.Reset()

p2p/net/swarm/swarm.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,10 @@ func wrapWithMetrics(capableConn transport.CapableConn, metricsTracer MetricsTra
833833
return c
834834
}
835835

836+
func (c *connWithMetrics) As(target any) bool {
837+
return c.CapableConn.As(target)
838+
}
839+
836840
func (c *connWithMetrics) completedHandshake() {
837841
c.metricsTracer.CompletedHandshake(time.Since(c.opened), c.ConnState(), c.LocalMultiaddr())
838842
}

p2p/net/swarm/swarm_conn.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ type Conn struct {
4242

4343
var _ network.Conn = &Conn{}
4444

45+
func (c *Conn) As(target any) bool {
46+
return c.conn.As(target)
47+
}
48+
4549
func (c *Conn) IsClosed() bool {
4650
return c.conn.IsClosed()
4751
}

p2p/net/upgrader/conn.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ type transportConn struct {
2323

2424
var _ transport.CapableConn = &transportConn{}
2525

26+
func (c *transportConn) As(target any) bool {
27+
return c.MuxedConn.As(target)
28+
}
29+
2630
func (t *transportConn) Transport() transport.Transport {
2731
return t.transport
2832
}

p2p/transport/quic/conn.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ type conn struct {
2525
remoteMultiaddr ma.Multiaddr
2626
}
2727

28+
func (c *conn) As(target any) bool {
29+
if t, ok := target.(**quic.Conn); ok {
30+
*t = c.quicConn
31+
return true
32+
}
33+
34+
return false
35+
}
36+
2837
var _ tpt.CapableConn = &conn{}
2938

3039
// Close closes the connection.

0 commit comments

Comments
 (0)