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")