@cryptotaxi247 / kubo / commits / 690619145

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.

Juan Batiz-Benet committed Feb 2, 2015 at 20:35 UTC 690619145a08408a50ae7a850ec0e97ec003fb0d
2 files changed +43 -15
p2p/protocol/identify/id.go
+42 -14
@@ -1,7 +1,7 @@
1 package identify
2
3 import (
4 - "fmt"
4 + "strings"
5 "sync"
6
7 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")
24 const ID protocol.ID = "/ipfs/identify"
25
26 // IpfsVersion holds the current protocol version for a client running this code
27 -var IpfsVersion *semver.Version
28 -var ClientVersion = "go-ipfs/" + config.CurrentVersionNumber
29 -
30 -func init() {
31 - var err error
32 - IpfsVersion, err = semver.NewVersion("0.0.1")
33 - if err != nil {
34 - panic(fmt.Errorf("invalid protocol version: %v", err))
35 - }
36 -}
27 +// TODO(jbenet): fix the versioning mess.
28 +const IpfsVersion = "ipfs/0.1.0"
29 +const ClientVersion = "go-ipfs/" + config.CurrentVersionNumber
30
31 // IDService is a structure that implements ProtocolIdentify.
32 // 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) {
151 log.Debugf("%s sent listen addrs to %s: %s", c.LocalPeer(), c.RemotePeer(), laddrs)
152
153 // set protocol versions
161 - s := IpfsVersion.String()
162 - mes.ProtocolVersion = &s
163 - mes.AgentVersion = &ClientVersion
154 + pv := IpfsVersion
155 + av := ClientVersion
156 + mes.ProtocolVersion = &pv
157 + mes.AgentVersion = &av
158 }
159
160 func (ids *IDService) consumeMessage(mes *pb.Identify, c inet.Conn) {
@@ -192,6 +186,15 @@ func (ids *IDService) consumeMessage(mes *pb.Identify, c inet.Conn) {
186 // get protocol versions
187 pv := mes.GetProtocolVersion()
188 av := mes.GetAgentVersion()
189 +
190 + // version check. if we shouldn't talk, bail.
191 + // TODO: at this point, we've already exchanged information.
192 + // move this into a first handshake before the connection can open streams.
193 + if !protocolVersionsAreCompatible(pv, IpfsVersion) {
194 + c.Close()
195 + return
196 + }
197 +
198 ids.Host.Peerstore().Put(p, "ProtocolVersion", pv)
199 ids.Host.Peerstore().Put(p, "AgentVersion", av)
200 }
@@ -257,6 +260,31 @@ func addrInAddrs(a ma.Multiaddr, as []ma.Multiaddr) bool {
260 return false
261 }
262
263 +// protocolVersionsAreCompatible checks that the two implementations
264 +// can talk to each other. It will use semver, but for now while
265 +// we're in tight development, we will return false for minor version
266 +// changes too.
267 +func protocolVersionsAreCompatible(v1, v2 string) bool {
268 + if strings.HasPrefix(v1, "ipfs/") {
269 + v1 = v1[5:]
270 + }
271 + if strings.HasPrefix(v2, "ipfs/") {
272 + v2 = v2[5:]
273 + }
274 +
275 + v1s, err := semver.NewVersion(v1)
276 + if err != nil {
277 + return false
278 + }
279 +
280 + v2s, err := semver.NewVersion(v2)
281 + if err != nil {
282 + return false
283 + }
284 +
285 + return v1s.Major == v2s.Major && v1s.Minor == v2s.Minor
286 +}
287 +
288 // netNotifiee defines methods to be used with the IpfsDHT
289 type netNotifiee IDService
290
p2p/protocol/identify/id_test.go
+1 -1
@@ -79,7 +79,7 @@ func testHasProtocolVersions(t *testing.T, h host.Host, p peer.ID) {
79 t.Error("no protocol version")
80 return
81 }
82 - if v.(string) != identify.IpfsVersion.String() {
82 + if v.(string) != identify.IpfsVersion {
83 t.Error("protocol mismatch", err)
84 }
85 v, err = h.Peerstore().Get(p, "AgentVersion")