diff --git a/p2p/net/conn/dial.go b/p2p/net/conn/dial.go index 12f41688..b2d4908a 100644 --- a/p2p/net/conn/dial.go +++ b/p2p/net/conn/dial.go @@ -10,6 +10,7 @@ import ( addrutil "github.com/ipfs/go-libp2p/p2p/net/swarm/addr" transport "github.com/ipfs/go-libp2p/p2p/net/transport" peer "github.com/ipfs/go-libp2p/p2p/peer" + msmux "gx/ipfs/QmUeEcYJrzAEKdQXjzTxCgNZgc9sRuwharsvzzm5Gd2oGB/go-multistream" manet "gx/ipfs/QmYVqhVfbK4BKvbW88Lhm26b3ud14sTBvcm1H7uWUx1Fkp/go-multiaddr-net" context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" ma "gx/ipfs/QmcobAGsCjYt5DXoq9et9L8yR8er7o7Cu3DTvpaq12jYSz/go-multiaddr" @@ -62,6 +63,17 @@ func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) ( maconn = d.Wrapper(maconn) } + cryptoProtoChoice := SecioTag + if !EncryptConnections { + cryptoProtoChoice = NoEncryptionTag + } + + err = msmux.SelectProtoOrFail(cryptoProtoChoice, maconn) + if err != nil { + errOut = err + return + } + c, err := newSingleConn(ctx, d.LocalPeer, remote, maconn) if err != nil { maconn.Close() diff --git a/p2p/net/conn/dial_test.go b/p2p/net/conn/dial_test.go index 9f4923e2..c91fd5bf 100644 --- a/p2p/net/conn/dial_test.go +++ b/p2p/net/conn/dial_test.go @@ -13,6 +13,7 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" tu "github.com/ipfs/go-libp2p/testutil" + msmux "gx/ipfs/QmUeEcYJrzAEKdQXjzTxCgNZgc9sRuwharsvzzm5Gd2oGB/go-multistream" context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" ma "gx/ipfs/QmcobAGsCjYt5DXoq9et9L8yR8er7o7Cu3DTvpaq12jYSz/go-multiaddr" ) @@ -319,3 +320,32 @@ func TestDialerCloseEarlySecure(t *testing.T) { // t.Skip("Skipping in favor of another test") testDialerCloseEarly(t, true) } + +func TestMultistreamHeader(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + p1 := tu.RandPeerNetParamsOrFatal(t) + + l1, err := Listen(ctx, p1.Addr, p1.ID, p1.PrivKey) + if err != nil { + t.Fatal(err) + } + + p1.Addr = l1.Multiaddr() // Addr has been determined by kernel. + + go func() { + _, _ = l1.Accept() + }() + + con, err := net.Dial("tcp", l1.Addr().String()) + if err != nil { + t.Fatal(err) + } + defer con.Close() + + err = msmux.SelectProtoOrFail(SecioTag, con) + if err != nil { + t.Fatal(err) + } +} diff --git a/p2p/net/conn/listen.go b/p2p/net/conn/listen.go index 84ff12e6..33b09756 100644 --- a/p2p/net/conn/listen.go +++ b/p2p/net/conn/listen.go @@ -11,11 +11,15 @@ import ( peer "github.com/ipfs/go-libp2p/p2p/peer" "gx/ipfs/QmQopLATEYMNg7dVqZRNDfeE2S1yKy8zrRh5xnYiuqeZBn/goprocess" goprocessctx "gx/ipfs/QmQopLATEYMNg7dVqZRNDfeE2S1yKy8zrRh5xnYiuqeZBn/goprocess/context" + msmux "gx/ipfs/QmUeEcYJrzAEKdQXjzTxCgNZgc9sRuwharsvzzm5Gd2oGB/go-multistream" tec "gx/ipfs/QmWHgLqrghM9zw77nF6gdvT9ExQ2RB9pLxkd8sDHZf1rWb/go-temp-err-catcher" context "gx/ipfs/QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt/go-net/context" ma "gx/ipfs/QmcobAGsCjYt5DXoq9et9L8yR8er7o7Cu3DTvpaq12jYSz/go-multiaddr" ) +const SecioTag = "/secio/1.0.0" +const NoEncryptionTag = "/plaintext/1.0.0" + // ConnWrapper is any function that wraps a raw multiaddr connection type ConnWrapper func(transport.Conn) transport.Conn @@ -31,6 +35,8 @@ type listener struct { wrapper ConnWrapper proc goprocess.Process + + mux *msmux.MultistreamMuxer } func (l *listener) teardown() error { @@ -98,6 +104,11 @@ func (l *listener) Accept() (net.Conn, error) { maconn = l.wrapper(maconn) } + _, _, err = l.mux.Negotiate(maconn) + if err != nil { + return nil, err + } + c, err := newSingleConn(ctx, l.local, "", maconn) if err != nil { if catcher.IsTemporary(err) { @@ -150,9 +161,16 @@ func WrapTransportListener(ctx context.Context, ml transport.Listener, local pee Listener: ml, local: local, privk: sk, + mux: msmux.NewMultistreamMuxer(), } l.proc = goprocessctx.WithContextAndTeardown(ctx, l.teardown) + if EncryptConnections { + l.mux.AddHandler(SecioTag, nil) + } else { + l.mux.AddHandler(NoEncryptionTag, nil) + } + log.Debugf("Conn Listener on %s", l.Multiaddr()) log.Event(ctx, "swarmListen", l) return l, nil diff --git a/p2p/net/swarm/swarm.go b/p2p/net/swarm/swarm.go index 543c01c2..b8e041e8 100644 --- a/p2p/net/swarm/swarm.go +++ b/p2p/net/swarm/swarm.go @@ -46,8 +46,8 @@ func init() { LogOutput: ioutil.Discard, } - msstpt.AddTransport("/yamux", ymxtpt) - msstpt.AddTransport("/spdystream", spdy.Transport) + msstpt.AddTransport("/yamux/1.0.0", ymxtpt) + msstpt.AddTransport("/spdy/3.1.0", spdy.Transport) PSTransport = msstpt } diff --git a/p2p/protocol/identify/id.go b/p2p/protocol/identify/id.go index 2f2dbef2..76212e57 100644 --- a/p2p/protocol/identify/id.go +++ b/p2p/protocol/identify/id.go @@ -22,7 +22,7 @@ import ( var log = logging.Logger("net/identify") // ID is the protocol.ID of the Identify Service. -const ID = "/ipfs/identify" +const ID = "/ipfs/id/1.0.0" // LibP2PVersion holds the current protocol version for a client running this code // TODO(jbenet): fix the versioning mess. diff --git a/p2p/protocol/ping/ping.go b/p2p/protocol/ping/ping.go index 4b2200fb..7cb18b0e 100644 --- a/p2p/protocol/ping/ping.go +++ b/p2p/protocol/ping/ping.go @@ -18,7 +18,7 @@ var log = logging.Logger("ping") const PingSize = 32 -const ID = "/ipfs/ping" +const ID = "/ipfs/ping/1.0.0" type PingService struct { Host host.Host diff --git a/p2p/protocol/relay/relay.go b/p2p/protocol/relay/relay.go index 7c2f7c75..f46e4a5d 100644 --- a/p2p/protocol/relay/relay.go +++ b/p2p/protocol/relay/relay.go @@ -17,7 +17,7 @@ import ( var log = logging.Logger("github.com/ipfs/go-libp2p/p2p/protocol/relay") // ID is the protocol.ID of the Relay Service. -const ID protocol.ID = "/ipfs/relay" +const ID protocol.ID = "/ipfs/relay/line/0.1.0" // Relay is a structure that implements ProtocolRelay. // It is a simple relay service which forwards traffic