diff --git a/config/config.go b/config/config.go index 4ccbc509f8..90fa9c16cf 100644 --- a/config/config.go +++ b/config/config.go @@ -64,6 +64,11 @@ type Config struct { // Set it via the UserAgent option function. UserAgent string + // ProtocolVersion is the protocol version that identifies the family + // of protocols used by the peer in the Identify protocol. It is set + // using the [ProtocolVersion] option. + ProtocolVersion string + PeerKey crypto.PrivKey Transports []TptC @@ -223,6 +228,7 @@ func (cfg *Config) NewNode() (host.Host, error) { NATManager: cfg.NATManager, EnablePing: !cfg.DisablePing, UserAgent: cfg.UserAgent, + ProtocolVersion: cfg.ProtocolVersion, MultiaddrResolver: cfg.MultiaddrResolver, EnableHolePunching: cfg.EnableHolePunching, HolePunchingOptions: cfg.HolePunchingOptions, diff --git a/options.go b/options.go index 6ed6a94d35..3509c61d4c 100644 --- a/options.go +++ b/options.go @@ -414,6 +414,15 @@ var NoTransports = func(cfg *Config) error { return nil } +// ProtocolVersion sets the protocolVersion string required by the +// libp2p Identify protocol. +func ProtocolVersion(s string) Option { + return func(cfg *Config) error { + cfg.ProtocolVersion = s + return nil + } +} + // UserAgent sets the libp2p user-agent sent along with the identify protocol func UserAgent(userAgent string) Option { return func(cfg *Config) error { diff --git a/p2p/host/basic/basic_host.go b/p2p/host/basic/basic_host.go index d3642bd810..9997876395 100644 --- a/p2p/host/basic/basic_host.go +++ b/p2p/host/basic/basic_host.go @@ -145,6 +145,9 @@ type HostOpts struct { // UserAgent sets the user-agent for the host. UserAgent string + // ProtocolVersion sets the protocol version for the host. + ProtocolVersion string + // DisableSignedPeerRecord disables the generation of Signed Peer Records on this host. DisableSignedPeerRecord bool @@ -226,9 +229,18 @@ func NewHost(n network.Network, opts *HostOpts) (*BasicHost, error) { // we can't set this as a default above because it depends on the *BasicHost. if h.disableSignedPeerRecord { - h.ids, err = identify.NewIDService(h, identify.UserAgent(opts.UserAgent), identify.DisableSignedPeerRecord()) + h.ids, err = identify.NewIDService( + h, + identify.UserAgent(opts.UserAgent), + identify.ProtocolVersion(opts.ProtocolVersion), + identify.DisableSignedPeerRecord(), + ) } else { - h.ids, err = identify.NewIDService(h, identify.UserAgent(opts.UserAgent)) + h.ids, err = identify.NewIDService( + h, + identify.UserAgent(opts.UserAgent), + identify.ProtocolVersion(opts.ProtocolVersion), + ) } if err != nil { return nil, fmt.Errorf("failed to create Identify service: %s", err) diff --git a/p2p/protocol/identify/id.go b/p2p/protocol/identify/id.go index 4794619d9a..b9d95240e3 100644 --- a/p2p/protocol/identify/id.go +++ b/p2p/protocol/identify/id.go @@ -33,11 +33,7 @@ var log = logging.Logger("net/identify") // service. 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. -// XXX: Don't change this till 2020. You'll break all go-ipfs versions prior to -// 0.4.17 which asserted an exact version match. -const LibP2PVersion = "ipfs/0.1.0" +const DefaultProtocolVersion = "ipfs/0.1.0" const ServiceName = "libp2p.identify" @@ -89,8 +85,9 @@ type IDService interface { // - Our IPFS Agent Version // - Our public Listen Addresses type idService struct { - Host host.Host - UserAgent string + Host host.Host + UserAgent string + ProtocolVersion string ctx context.Context ctxCancel context.CancelFunc @@ -135,9 +132,15 @@ func NewIDService(h host.Host, opts ...Option) (*idService, error) { userAgent = cfg.userAgent } + protocolVersion := DefaultProtocolVersion + if cfg.protocolVersion != "" { + protocolVersion = cfg.protocolVersion + } + s := &idService{ - Host: h, - UserAgent: userAgent, + Host: h, + UserAgent: userAgent, + ProtocolVersion: protocolVersion, conns: make(map[network.Conn]chan struct{}), @@ -188,8 +191,10 @@ func (ids *idService) loop() { defer ids.refCount.Done() phs := make(map[peer.ID]*peerHandler) - sub, err := ids.Host.EventBus().Subscribe([]interface{}{&event.EvtLocalProtocolsUpdated{}, - &event.EvtLocalAddressesUpdated{}}, eventbus.BufSize(256)) + sub, err := ids.Host.EventBus().Subscribe([]interface{}{ + &event.EvtLocalProtocolsUpdated{}, + &event.EvtLocalAddressesUpdated{}, + }, eventbus.BufSize(256)) if err != nil { log.Errorf("failed to subscribe to events on the bus, err=%s", err) return @@ -489,7 +494,6 @@ func (ids *idService) writeChunkedIdentifyMsg(c network.Conn, snapshot *identify m := &pb.Identify{SignedPeerRecord: sr} err := writer.WriteMsg(m) return err - } func (ids *idService) createBaseIdentifyResponse( @@ -541,10 +545,8 @@ func (ids *idService) createBaseIdentifyResponse( } // set protocol versions - pv := LibP2PVersion - av := ids.UserAgent - mes.ProtocolVersion = &pv - mes.AgentVersion = &av + mes.ProtocolVersion = &ids.ProtocolVersion + mes.AgentVersion = &ids.UserAgent return mes } diff --git a/p2p/protocol/identify/id_test.go b/p2p/protocol/identify/id_test.go index d86fc915e6..ebdb634961 100644 --- a/p2p/protocol/identify/id_test.go +++ b/p2p/protocol/identify/id_test.go @@ -75,7 +75,7 @@ func testHasProtocolVersions(t *testing.T, h host.Host, p peer.ID) { t.Error("no protocol version") return } - if v.(string) != identify.LibP2PVersion { + if v.(string) != identify.DefaultProtocolVersion { t.Error("protocol mismatch", err) } v, err = h.Peerstore().Get(p, "AgentVersion") diff --git a/p2p/protocol/identify/opts.go b/p2p/protocol/identify/opts.go index 0eb1d96644..38f505b69b 100644 --- a/p2p/protocol/identify/opts.go +++ b/p2p/protocol/identify/opts.go @@ -1,6 +1,7 @@ package identify type config struct { + protocolVersion string userAgent string disableSignedPeerRecord bool } @@ -8,6 +9,14 @@ type config struct { // Option is an option function for identify. type Option func(*config) +// ProtocolVersion sets the protocol version string that will be used to +// identify the family of protocols used by the peer. +func ProtocolVersion(s string) Option { + return func(cfg *config) { + cfg.protocolVersion = s + } +} + // UserAgent sets the user agent this node will identify itself with to peers. func UserAgent(ua string) Option { return func(cfg *config) {