diff --git a/dial_test.go b/dial_test.go index 5fe4bdc2..1e66c290 100644 --- a/dial_test.go +++ b/dial_test.go @@ -7,6 +7,11 @@ import ( "testing" "time" + "github.com/libp2p/go-tcp-transport" + + "github.com/libp2p/go-libp2p-peerstore/pstoremem" + tnet "github.com/libp2p/go-libp2p-testing/net" + . "github.com/libp2p/go-libp2p-swarm" addrutil "github.com/libp2p/go-addr-util" @@ -28,17 +33,10 @@ func init() { transport.DialTimeout = time.Second } -func closeSwarms(swarms []*Swarm) { - for _, s := range swarms { - s.Close() - } -} - func TestBasicDialPeer(t *testing.T) { t.Parallel() swarms := makeSwarms(t, 2) - defer closeSwarms(swarms) s1 := swarms[0] s2 := swarms[1] @@ -52,12 +50,37 @@ func TestBasicDialPeer(t *testing.T) { s.Close() } +func TestDialBoth(t *testing.T) { + p := tnet.RandPeerNetParamsOrFatal(t) + ps := pstoremem.NewPeerstore() + ps.AddPubKey(p.ID, p.PubKey) + ps.AddPrivKey(p.ID, p.PrivKey) + + swarm, err := NewSwarm(p.ID, ps) + require.NoError(t, err) + negotiatingUpgrader := swarmt.GenUpgrader(swarm, swarmt.UseHandshakeNegotiation()) + swarm.AddTransport(tcp.NewTCPTransport(negotiatingUpgrader)) + secureUpgrader := swarmt.GenUpgrader(swarm) + swarm.AddTransport(tcp.NewTCPTransport(secureUpgrader)) + require.NoError(t, swarm.Listen(ma.StringCast("/ip4/127.0.0.1/tcp/0"))) + require.NoError(t, swarm.Listen(ma.StringCast("/ip4/127.0.0.1/tcp/0/plaintextv2"))) + + negotiatingSwarm := swarmt.GenSwarm(t, swarmt.OptUseHandshakeNegotiation()) + negotiatingSwarm.Peerstore().AddAddrs(p.ID, swarm.ListenAddresses(), peerstore.PermanentAddrTTL) + _, err = negotiatingSwarm.DialPeer(context.Background(), p.ID) + require.NoError(t, err) + + secureSwarm := swarmt.GenSwarm(t) + secureSwarm.Peerstore().AddAddrs(p.ID, swarm.ListenAddresses(), peerstore.PermanentAddrTTL) + _, err = negotiatingSwarm.DialPeer(context.Background(), p.ID) + require.NoError(t, err) +} + func TestDialWithNoListeners(t *testing.T) { t.Parallel() s1 := makeDialOnlySwarm(t) swarms := makeSwarms(t, 1) - defer closeSwarms(swarms) s2 := swarms[0] s1.Peerstore().AddAddrs(s2.LocalPeer(), s2.ListenAddresses(), peerstore.PermanentAddrTTL) @@ -162,7 +185,7 @@ func TestDialWait(t *testing.T) { t.Parallel() ctx := context.Background() - swarms := makeSwarms(t, 1) + swarms := makeSwarms(t, 1, swarmt.OptUseHandshakeNegotiation()) s1 := swarms[0] defer s1.Close() @@ -202,7 +225,7 @@ func TestDialBackoff(t *testing.T) { t.Parallel() ctx := context.Background() - swarms := makeSwarms(t, 2) + swarms := makeSwarms(t, 2, swarmt.OptUseHandshakeNegotiation()) s1 := swarms[0] s2 := swarms[1] defer s1.Close() @@ -409,7 +432,7 @@ func TestDialBackoffClears(t *testing.T) { t.Parallel() ctx := context.Background() - swarms := makeSwarms(t, 2) + swarms := makeSwarms(t, 2, swarmt.OptUseHandshakeNegotiation()) s1 := swarms[0] s2 := swarms[1] defer s1.Close() @@ -478,8 +501,7 @@ func TestDialPeerFailed(t *testing.T) { t.Parallel() ctx := context.Background() - swarms := makeSwarms(t, 2) - defer closeSwarms(swarms) + swarms := makeSwarms(t, 2, swarmt.OptUseHandshakeNegotiation()) testedSwarm, targetSwarm := swarms[0], swarms[1] expectedErrorsCount := 5 @@ -518,7 +540,6 @@ func TestDialExistingConnection(t *testing.T) { ctx := context.Background() swarms := makeSwarms(t, 2) - defer closeSwarms(swarms) s1 := swarms[0] s2 := swarms[1] @@ -561,7 +582,7 @@ func TestDialSimultaneousJoin(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - swarms := makeSwarms(t, 2) + swarms := makeSwarms(t, 2, swarmt.OptUseHandshakeNegotiation()) s1 := swarms[0] s2 := swarms[1] defer s1.Close() diff --git a/go.mod b/go.mod index f7593131..18b6c3c2 100644 --- a/go.mod +++ b/go.mod @@ -6,16 +6,16 @@ require ( github.com/ipfs/go-log v1.0.5 github.com/libp2p/go-addr-util v0.1.0 github.com/libp2p/go-conn-security-multistream v0.3.0 - github.com/libp2p/go-libp2p-core v0.10.0 + github.com/libp2p/go-libp2p-core v0.10.1-0.20210921170543-f829c09c1ca0 github.com/libp2p/go-libp2p-peerstore v0.2.8 - github.com/libp2p/go-libp2p-quic-transport v0.13.0 - github.com/libp2p/go-libp2p-testing v0.5.0 - github.com/libp2p/go-libp2p-transport-upgrader v0.5.0 + github.com/libp2p/go-libp2p-quic-transport v0.13.1-0.20210921102157-e51edf9828e5 + github.com/libp2p/go-libp2p-testing v0.5.1-0.20210921173022-d2d7433a5068 + github.com/libp2p/go-libp2p-transport-upgrader v0.5.1-0.20210922105033-ad6ad0abd9c8 github.com/libp2p/go-libp2p-yamux v0.5.0 github.com/libp2p/go-maddr-filter v0.1.0 github.com/libp2p/go-stream-muxer-multistream v0.3.0 - github.com/libp2p/go-tcp-transport v0.2.7 - github.com/multiformats/go-multiaddr v0.3.3 + github.com/libp2p/go-tcp-transport v0.2.9-0.20210922105139-fe3437611b28 + github.com/multiformats/go-multiaddr v0.4.1 github.com/multiformats/go-multiaddr-fmt v0.1.0 github.com/stretchr/testify v1.7.0 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 diff --git a/go.sum b/go.sum index 9f2eff36..dab9e549 100644 --- a/go.sum +++ b/go.sum @@ -271,7 +271,6 @@ github.com/libp2p/go-addr-util v0.1.0/go.mod h1:6I3ZYuFr2O/9D+SoyM0zEw0EF3YkldtT github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2 h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= -github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= github.com/libp2p/go-conn-security-multistream v0.3.0 h1:9UCIKlBL1hC9u7nkMXpD1nkc/T53PKMAn3/k9ivBAVc= github.com/libp2p/go-conn-security-multistream v0.3.0/go.mod h1:EEP47t4fw/bTelVmEzIDqSe69hO/ip52xBEhZMLWAHM= github.com/libp2p/go-flow-metrics v0.0.3 h1:8tAs/hSdNvUiLgtlSy3mxwxWP4I9y/jlkPFT7epKdeM= @@ -279,31 +278,29 @@ github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= -github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= -github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= -github.com/libp2p/go-libp2p-core v0.10.0 h1:jFy7v5Muq58GTeYkPhGzIH8Qq4BFfziqc0ixPd/pP9k= github.com/libp2p/go-libp2p-core v0.10.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.10.1-0.20210920171028-61a54c107072/go.mod h1:Ac52V2PMajsRlNG09aZWUpzDiY356vVuSVPOQ2H2VpQ= +github.com/libp2p/go-libp2p-core v0.10.1-0.20210921170543-f829c09c1ca0 h1:W1EqIm0+QVnfQ2SV138//D9NyAhseDxqLMoWvvhYsQQ= +github.com/libp2p/go-libp2p-core v0.10.1-0.20210921170543-f829c09c1ca0/go.mod h1:KlkHsZ0nKerWsXLZJm3LfFQwusI5k3iN4BgtYTE4IYE= github.com/libp2p/go-libp2p-mplex v0.4.1 h1:/pyhkP1nLwjG3OM+VuaNJkQT/Pqq73WzB3aDN3Fx1sc= github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= github.com/libp2p/go-libp2p-peerstore v0.2.8 h1:nJghUlUkFVvyk7ccsM67oFA6kqUkwyCM1G4WPVMCWYA= github.com/libp2p/go-libp2p-peerstore v0.2.8/go.mod h1:gGiPlXdz7mIHd2vfAsHzBNAMqSDkt2UBFwgcITgw1lA= github.com/libp2p/go-libp2p-pnet v0.2.0 h1:J6htxttBipJujEjz1y0a5+eYoiPcFHhSYHH6na5f0/k= github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= -github.com/libp2p/go-libp2p-quic-transport v0.13.0 h1:MTVojS4AnGD/rng6rF/HXEqwMHL27rHUEf3DaqSdnUw= -github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= +github.com/libp2p/go-libp2p-quic-transport v0.13.1-0.20210921102157-e51edf9828e5 h1:52ZgWg6ICxN/s27j8xNZkhCsdkcOYZJoP4kxnYf1HHY= +github.com/libp2p/go-libp2p-quic-transport v0.13.1-0.20210921102157-e51edf9828e5/go.mod h1:N65xvhWSylZzC+fmeptSff67wIWXDiAxAWrDqv75d1k= github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= -github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= -github.com/libp2p/go-libp2p-testing v0.4.2/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= -github.com/libp2p/go-libp2p-testing v0.5.0 h1:bTjC29TTQ/ODq0ld3+0KLq3irdA5cAH3OMbRi0/QsvE= github.com/libp2p/go-libp2p-testing v0.5.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= -github.com/libp2p/go-libp2p-tls v0.3.0 h1:8BgvUJiOTcj0Gp6XvEicF0rL5aUtRg/UzEdeZDmDlC8= -github.com/libp2p/go-libp2p-tls v0.3.0/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= -github.com/libp2p/go-libp2p-transport-upgrader v0.4.6/go.mod h1:JE0WQuQdy+uLZ5zOaI3Nw9dWGYJIA7mywEtP2lMvnyk= -github.com/libp2p/go-libp2p-transport-upgrader v0.5.0 h1:7SDl3O2+AYOgfE40Mis83ClpfGNkNA6m4FwhbOHs+iI= -github.com/libp2p/go-libp2p-transport-upgrader v0.5.0/go.mod h1:Rc+XODlB3yce7dvFV4q/RmyJGsFcCZRkeZMu/Zdg0mo= +github.com/libp2p/go-libp2p-testing v0.5.1-0.20210921173022-d2d7433a5068 h1:Uhzao0ft5xsws67/qzZNlK1kvQKMwuDj/jr0RHfpU98= +github.com/libp2p/go-libp2p-testing v0.5.1-0.20210921173022-d2d7433a5068/go.mod h1:zcQ6B90GUqkXx0xdQ0EyBH8XUvlP36pxEdpUFtPtWNk= +github.com/libp2p/go-libp2p-tls v0.3.1-0.20210920171426-0d6a7ee62c41 h1:l0bnSfSXf74zjr3/Q7CjHMMEf2mOL3/6IfmxspFdXTo= +github.com/libp2p/go-libp2p-tls v0.3.1-0.20210920171426-0d6a7ee62c41/go.mod h1:osgsIirN9OU6Rjv88xT8us7gCUcuqgYJ94T4LXLZu3s= +github.com/libp2p/go-libp2p-transport-upgrader v0.5.1-0.20210922105033-ad6ad0abd9c8 h1:3I7js9jPQUmOx9Kyt4tRpp6Dt2tYasbWEkLsoiTOkQg= +github.com/libp2p/go-libp2p-transport-upgrader v0.5.1-0.20210922105033-ad6ad0abd9c8/go.mod h1:4T3Km0CC97JF4T4KH6BjSScdZLvGk/W0WKAm7MAlwYI= github.com/libp2p/go-libp2p-yamux v0.5.0 h1:ZzmUhbQE+X7NuYUT2naxN31JyebZfRmpZVhKtRP13ys= github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE= @@ -328,8 +325,8 @@ github.com/libp2p/go-sockaddr v0.1.0 h1:Y4s3/jNoryVRKEBrkJ576F17CPOaMIzUeCsg7dlT github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-stream-muxer-multistream v0.3.0 h1:TqnSHPJEIqDEO7h1wZZ0p3DXdvDSiLHQidKKUGZtiOY= github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= -github.com/libp2p/go-tcp-transport v0.2.7 h1:Z8Kc/Kb8tD84WiaH55xAlaEnkqzrp88jSEySCKV4+gg= -github.com/libp2p/go-tcp-transport v0.2.7/go.mod h1:lue9p1b3VmZj1MhhEGB/etmvF/nBQ0X9CW2DutBT3MM= +github.com/libp2p/go-tcp-transport v0.2.9-0.20210922105139-fe3437611b28 h1:BraIDc9Q2XH826pZ9qG8KQRcixMVCdVsdF+MyAvVkCE= +github.com/libp2p/go-tcp-transport v0.2.9-0.20210922105139-fe3437611b28/go.mod h1:E2JmEWwhdFGOTL/3ZOjrIb8Nk53fMpyWEm1hvtMmWtg= github.com/libp2p/go-yamux v1.4.1 h1:P1Fe9vF4th5JOxxgQvfbOHkrGqIZniTLf+ddhZp8YTI= github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -400,8 +397,10 @@ github.com/multiformats/go-multiaddr v0.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= -github.com/multiformats/go-multiaddr v0.3.3 h1:vo2OTSAqnENB2rLk79pLtr+uhj+VAzSe3uef5q0lRSs= github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= +github.com/multiformats/go-multiaddr v0.4.1-0.20210920085215-fc723035a20c/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= +github.com/multiformats/go-multiaddr v0.4.1 h1:Pq37uLx3hsyNlTDir7FZyU8+cFCTqd5y1KiM2IzOutI= +github.com/multiformats/go-multiaddr v0.4.1/go.mod h1:3afI9HfVW8csiF8UZqtpYRiDyew8pRX7qLIGHu9FLuM= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= diff --git a/swarm.go b/swarm.go index 73edeb8b..64c44879 100644 --- a/swarm.go +++ b/swarm.go @@ -95,7 +95,7 @@ type Swarm struct { transports struct { sync.RWMutex - m map[int]transport.Transport + m map[string]transport.Transport } // new connection and stream handlers @@ -127,7 +127,7 @@ func NewSwarm(local peer.ID, peers peerstore.Peerstore, opts ...Option) (*Swarm, s.conns.m = make(map[peer.ID][]*Conn) s.listeners.m = make(map[transport.Listener]struct{}) - s.transports.m = make(map[int]transport.Transport) + s.transports.m = make(map[string]transport.Transport) s.notifs.m = make(map[network.Notifiee]struct{}) for _, opt := range opts { diff --git a/swarm_test.go b/swarm_test.go index 07551fd0..82fd9ae8 100644 --- a/swarm_test.go +++ b/swarm_test.go @@ -70,6 +70,7 @@ func makeSwarms(t *testing.T, num int, opts ...Option) []*swarm.Swarm { swarm := GenSwarm(t, opts...) swarm.SetStreamHandler(EchoStreamHandler) swarms = append(swarms, swarm) + t.Cleanup(func() { swarm.Close() }) } return swarms } diff --git a/swarm_transport.go b/swarm_transport.go index 21728ac3..ebd5c133 100644 --- a/swarm_transport.go +++ b/swarm_transport.go @@ -2,7 +2,6 @@ package swarm import ( "fmt" - "strings" "github.com/libp2p/go-libp2p-core/transport" @@ -28,7 +27,7 @@ func (s *Swarm) TransportForDialing(a ma.Multiaddr) transport.Transport { } for _, p := range protocols { - transport, ok := s.transports.m[p.Code] + transport, ok := s.transports.m[transportsToMapKey([]ma.Protocol{p})] if !ok { continue } @@ -37,7 +36,10 @@ func (s *Swarm) TransportForDialing(a ma.Multiaddr) transport.Transport { } } - return s.transports.m[protocols[len(protocols)-1].Code] + if addrContainsSecurityProtocol(a) { + return s.transports.m[transportsToMapKey(protocols[len(protocols)-2:])] + } + return s.transports.m[transportsToMapKey(protocols[len(protocols)-1:])] } // TransportForListening retrieves the appropriate transport for listening on @@ -58,54 +60,65 @@ func (s *Swarm) TransportForListening(a ma.Multiaddr) transport.Transport { return nil } - selected := s.transports.m[protocols[len(protocols)-1].Code] for _, p := range protocols { - transport, ok := s.transports.m[p.Code] + transport, ok := s.transports.m[transportsToMapKey([]ma.Protocol{p})] if !ok { continue } if transport.Proxy() { - selected = transport + return transport } } - return selected + + if addrContainsSecurityProtocol(a) { + return s.transports.m[transportsToMapKey(protocols[len(protocols)-2:])] + } + return s.transports.m[transportsToMapKey(protocols[len(protocols)-1:])] } -// AddTransport adds a transport to this swarm. -// -// Satisfies the Network interface from go-libp2p-transport. +// AddTransport adds a Transport to this swarm. func (s *Swarm) AddTransport(t transport.Transport) error { protocols := t.Protocols() - if len(protocols) == 0 { return fmt.Errorf("useless transport handles no protocols: %T", t) } + // Examples: + // * for TCP (doing handshake protocol negotiation): tcp + // * for TCP / TLS (handling multiaddrs containing tls): tcp/tls + transportKey := transportsToMapKey(protocols) s.transports.Lock() defer s.transports.Unlock() if s.transports.m == nil { return ErrSwarmClosed } - var registered []string - for _, p := range protocols { - if _, ok := s.transports.m[p]; ok { - proto := ma.ProtocolWithCode(p) - name := proto.Name - if name == "" { - name = fmt.Sprintf("unknown (%d)", p) - } - registered = append(registered, name) - } - } - if len(registered) > 0 { - return fmt.Errorf( - "transports already registered for protocol(s): %s", - strings.Join(registered, ", "), - ) + if _, ok := s.transports.m[transportKey]; ok { + // TODO: improve error message + return fmt.Errorf("transport already registered for protocol: %s", transportKey) } - for _, p := range protocols { - s.transports.m[p] = t - } + s.transports.m[transportKey] = t return nil } + +func transportsToMapKey(protocols []ma.Protocol) string { + var key string + for i, p := range protocols { + if i > 0 { + key += "/" + } + key += p.Name + } + return key +} + +func addrContainsSecurityProtocol(addr ma.Multiaddr) bool { + var contains bool + ma.ForEach(addr, func(c ma.Component) bool { + if code := c.Protocol().Code; code == ma.P_TLS || code == ma.P_NOISE || code == ma.P_PLAINTEXTV2 { + contains = true + } + return true + }) + return contains +} diff --git a/testing/testing.go b/testing/testing.go index 0e4974f4..3fa81f54 100644 --- a/testing/testing.go +++ b/testing/testing.go @@ -14,6 +14,7 @@ import ( "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" "github.com/libp2p/go-libp2p-core/sec/insecure" + "github.com/libp2p/go-libp2p-peerstore/pstoremem" quic "github.com/libp2p/go-libp2p-quic-transport" swarm "github.com/libp2p/go-libp2p-swarm" @@ -27,12 +28,13 @@ import ( ) type config struct { - disableReuseport bool - dialOnly bool - disableTCP bool - disableQUIC bool - connectionGater connmgr.ConnectionGater - sk crypto.PrivKey + disableReuseport bool + dialOnly bool + disableTCP bool + disableQUIC bool + useHandshakeNegotiation bool + connectionGater connmgr.ConnectionGater + sk crypto.PrivKey } // Option is an option that can be passed when constructing a test swarm. @@ -72,20 +74,45 @@ func OptPeerPrivateKey(sk crypto.PrivKey) Option { } } +func OptUseHandshakeNegotiation() Option { + return func(_ *testing.T, c *config) { + c.useHandshakeNegotiation = true + } +} + +type upgraderConf struct { + useHandshakeNegotiation bool +} + +type UpgraderOption func(*upgraderConf) + +func UseHandshakeNegotiation() UpgraderOption { + return func(conf *upgraderConf) { + conf.useHandshakeNegotiation = true + } +} + // GenUpgrader creates a new connection upgrader for use with this swarm. -func GenUpgrader(n *swarm.Swarm) *tptu.Upgrader { +func GenUpgrader(n *swarm.Swarm, opts ...UpgraderOption) *tptu.Upgrader { + var conf upgraderConf + for _, o := range opts { + o(&conf) + } id := n.LocalPeer() pk := n.Peerstore().PrivKey(id) - secMuxer := new(csms.SSMuxer) - secMuxer.AddTransport(insecure.ID, insecure.NewWithIdentity(id, pk)) stMuxer := msmux.NewBlankTransport() stMuxer.AddTransport("/yamux/1.0.0", yamux.DefaultTransport) + upgrader := &tptu.Upgrader{Muxer: stMuxer} - return &tptu.Upgrader{ - Secure: secMuxer, - Muxer: stMuxer, + if conf.useHandshakeNegotiation { + secMuxer := new(csms.SSMuxer) + secMuxer.AddTransport(insecure.ID, insecure.NewWithIdentity(id, pk)) + upgrader.SecureMuxer = secMuxer + } else { + upgrader.SecureTransport = insecure.NewWithIdentity(id, pk) } + return upgrader } // GenSwarm generates a new test swarm. @@ -101,9 +128,7 @@ func GenSwarm(t *testing.T, opts ...Option) *swarm.Swarm { } else { pk := cfg.sk.GetPublic() id, err := peer.IDFromPublicKey(pk) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) p.PrivKey = cfg.sk p.PubKey = pk p.ID = id @@ -122,33 +147,30 @@ func GenSwarm(t *testing.T, opts ...Option) *swarm.Swarm { s, err := swarm.NewSwarm(p.ID, ps, swarmOpts...) require.NoError(t, err) - upgrader := GenUpgrader(s) + var upgraderOpts []UpgraderOption + if cfg.useHandshakeNegotiation { + upgraderOpts = append(upgraderOpts, UseHandshakeNegotiation()) + } + upgrader := GenUpgrader(s, upgraderOpts...) upgrader.ConnGater = cfg.connectionGater + if upgrader.SecureTransport != nil { + p.Addr = p.Addr.Encapsulate(ma.StringCast("/" + upgrader.SecureTransport.Protocol().Name)) + } if !cfg.disableTCP { tcpTransport := tcp.NewTCPTransport(upgrader) tcpTransport.DisableReuseport = cfg.disableReuseport - if err := s.AddTransport(tcpTransport); err != nil { - t.Fatal(err) - } + require.NoError(t, s.AddTransport(tcpTransport)) if !cfg.dialOnly { - if err := s.Listen(p.Addr); err != nil { - t.Fatal(err) - } + require.NoError(t, s.Listen(p.Addr)) } } if !cfg.disableQUIC { quicTransport, err := quic.NewTransport(p.PrivKey, nil, cfg.connectionGater) - if err != nil { - t.Fatal(err) - } - if err := s.AddTransport(quicTransport); err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.NoError(t, s.AddTransport(quicTransport)) if !cfg.dialOnly { - if err := s.Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic")); err != nil { - t.Fatal(err) - } + require.NoError(t, s.Listen(ma.StringCast("/ip4/127.0.0.1/udp/0/quic"))) } } if !cfg.dialOnly { diff --git a/transport_test.go b/transport_test.go index 6d5913cf..ccc92e5a 100644 --- a/transport_test.go +++ b/transport_test.go @@ -16,7 +16,7 @@ import ( ) type dummyTransport struct { - protocols []int + protocols []ma.Protocol proxy bool closed bool } @@ -37,7 +37,7 @@ func (dt *dummyTransport) Proxy() bool { return dt.proxy } -func (dt *dummyTransport) Protocols() []int { +func (dt *dummyTransport) Protocols() []ma.Protocol { return dt.protocols } func (dt *dummyTransport) Close() error { @@ -52,7 +52,7 @@ func TestUselessTransport(t *testing.T) { func TestTransportClose(t *testing.T) { s := swarmt.GenSwarm(t) - tpt := &dummyTransport{protocols: []int{1}} + tpt := &dummyTransport{protocols: []ma.Protocol{ma.ProtocolWithCode(ma.P_TCP)}} require.NoError(t, s.AddTransport(tpt)) _ = s.Close() if !tpt.closed { @@ -64,7 +64,7 @@ func TestTransportAfterClose(t *testing.T) { s := swarmt.GenSwarm(t) s.Close() - tpt := &dummyTransport{protocols: []int{1}} + tpt := &dummyTransport{protocols: []ma.Protocol{ma.ProtocolWithCode(ma.P_TCP)}} if err := s.AddTransport(tpt); err != swarm.ErrSwarmClosed { t.Fatal("expected swarm closed error, got: ", err) }