p2p/protocol/id: break on version mismatch.

TODOs:
- need to consolidate all the versioning stuff into one package
- need to do the version check as a handshake, before further
  communication happens. we used to do this.
This commit is contained in:
Juan Batiz-Benet 2015-02-02 20:35:30 -08:00
parent 8b419c5de4
commit 884699e1e7
2 changed files with 43 additions and 15 deletions

View File

@ -1,7 +1,7 @@
package identify
import (
"fmt"
"strings"
"sync"
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
@ -24,16 +24,9 @@ var log = eventlog.Logger("net/identify")
const ID protocol.ID = "/ipfs/identify"
// IpfsVersion holds the current protocol version for a client running this code
var IpfsVersion *semver.Version
var ClientVersion = "go-ipfs/" + config.CurrentVersionNumber
func init() {
var err error
IpfsVersion, err = semver.NewVersion("0.0.1")
if err != nil {
panic(fmt.Errorf("invalid protocol version: %v", err))
}
}
// TODO(jbenet): fix the versioning mess.
const IpfsVersion = "ipfs/0.1.0"
const ClientVersion = "go-ipfs/" + config.CurrentVersionNumber
// IDService is a structure that implements ProtocolIdentify.
// It is a trivial service that gives the other peer some
@ -158,9 +151,10 @@ func (ids *IDService) populateMessage(mes *pb.Identify, c inet.Conn) {
log.Debugf("%s sent listen addrs to %s: %s", c.LocalPeer(), c.RemotePeer(), laddrs)
// set protocol versions
s := IpfsVersion.String()
mes.ProtocolVersion = &s
mes.AgentVersion = &ClientVersion
pv := IpfsVersion
av := ClientVersion
mes.ProtocolVersion = &pv
mes.AgentVersion = &av
}
func (ids *IDService) consumeMessage(mes *pb.Identify, c inet.Conn) {
@ -192,6 +186,15 @@ func (ids *IDService) consumeMessage(mes *pb.Identify, c inet.Conn) {
// get protocol versions
pv := mes.GetProtocolVersion()
av := mes.GetAgentVersion()
// version check. if we shouldn't talk, bail.
// TODO: at this point, we've already exchanged information.
// move this into a first handshake before the connection can open streams.
if !protocolVersionsAreCompatible(pv, IpfsVersion) {
c.Close()
return
}
ids.Host.Peerstore().Put(p, "ProtocolVersion", pv)
ids.Host.Peerstore().Put(p, "AgentVersion", av)
}
@ -257,6 +260,31 @@ func addrInAddrs(a ma.Multiaddr, as []ma.Multiaddr) bool {
return false
}
// protocolVersionsAreCompatible checks that the two implementations
// can talk to each other. It will use semver, but for now while
// we're in tight development, we will return false for minor version
// changes too.
func protocolVersionsAreCompatible(v1, v2 string) bool {
if strings.HasPrefix(v1, "ipfs/") {
v1 = v1[5:]
}
if strings.HasPrefix(v2, "ipfs/") {
v2 = v2[5:]
}
v1s, err := semver.NewVersion(v1)
if err != nil {
return false
}
v2s, err := semver.NewVersion(v2)
if err != nil {
return false
}
return v1s.Major == v2s.Major && v1s.Minor == v2s.Minor
}
// netNotifiee defines methods to be used with the IpfsDHT
type netNotifiee IDService

View File

@ -79,7 +79,7 @@ func testHasProtocolVersions(t *testing.T, h host.Host, p peer.ID) {
t.Error("no protocol version")
return
}
if v.(string) != identify.IpfsVersion.String() {
if v.(string) != identify.IpfsVersion {
t.Error("protocol mismatch", err)
}
v, err = h.Peerstore().Get(p, "AgentVersion")