Network: added notion of versions (h1) to h3

This commit is contained in:
Juan Batiz-Benet 2014-12-21 05:25:18 -08:00
parent 8768c1f8e7
commit e6fc31bbc4
6 changed files with 69 additions and 5 deletions

View File

@ -54,6 +54,13 @@ func Handshake1Compatible(handshakeA, handshakeB *pb.Handshake1) error {
// NewHandshake1 creates a new Handshake1 from the two strings
func NewHandshake1(protoVer, agentVer string) *pb.Handshake1 {
if protoVer == "" {
protoVer = IpfsVersion.String()
}
if agentVer == "" {
agentVer = ClientVersion
}
return &pb.Handshake1{
ProtocolVersion: &protoVer,
AgentVersion: &agentVer,

View File

@ -53,6 +53,8 @@ func (m *Handshake1) GetAgentVersion() string {
// Handshake3 is delivered _after_ the secure channel is initialized
type Handshake3 struct {
// can include all the values in handshake1, for protocol version, etc.
H1 *Handshake1 `protobuf:"bytes,5,opt,name=h1" json:"h1,omitempty"`
// publicKey is this node's public key (which also gives its node.ID)
// - may not need to be sent, as secure channel implies it has been sent.
// - then again, if we change / disable secure channel, may still want it.
@ -72,6 +74,13 @@ func (m *Handshake3) Reset() { *m = Handshake3{} }
func (m *Handshake3) String() string { return proto.CompactTextString(m) }
func (*Handshake3) ProtoMessage() {}
func (m *Handshake3) GetH1() *Handshake1 {
if m != nil {
return m.H1
}
return nil
}
func (m *Handshake3) GetPublicKey() []byte {
if m != nil {
return m.PublicKey

View File

@ -17,6 +17,9 @@ message Handshake1 {
// Handshake3 is delivered _after_ the secure channel is initialized
message Handshake3 {
// can include all the values in handshake1, for protocol version, etc.
optional Handshake1 h1 = 5;
// publicKey is this node's public key (which also gives its node.ID)
// - may not need to be sent, as secure channel implies it has been sent.
// - then again, if we change / disable secure channel, may still want it.

View File

@ -1,6 +1,7 @@
package net
import (
handshake "github.com/jbenet/go-ipfs/net/handshake"
pb "github.com/jbenet/go-ipfs/net/handshake/pb"
ggio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/gogoprotobuf/io"
@ -74,9 +75,13 @@ func (ids *IDService) populateMessage(mes *pb.Handshake3, c Conn) {
for i, addr := range laddrs {
mes.ListenAddrs[i] = addr.Bytes()
}
// set protocol versions
mes.H1 = handshake.NewHandshake1("", "")
}
func (ids *IDService) consumeMessage(mes *pb.Handshake3, c Conn) {
p := c.RemotePeer()
// mes.Protocols
// mes.ObservedAddr
@ -87,13 +92,19 @@ func (ids *IDService) consumeMessage(mes *pb.Handshake3, c Conn) {
for _, addr := range laddrs {
maddr, err := ma.NewMultiaddrBytes(addr)
if err != nil {
log.Errorf("%s failed to parse multiaddr from %s %s", ProtocolIdentify,
c.RemotePeer(), c.RemoteMultiaddr())
log.Errorf("%s failed to parse multiaddr from %s %s", ProtocolIdentify, p,
c.RemoteMultiaddr())
continue
}
lmaddrs = append(lmaddrs, maddr)
}
// update our peerstore with the addresses.
ids.Network.Peerstore().AddAddresses(c.RemotePeer(), lmaddrs)
ids.Network.Peerstore().AddAddresses(p, lmaddrs)
// get protocol versions
pv := *mes.H1.ProtocolVersion
av := *mes.H1.AgentVersion
ids.Network.Peerstore().Put(p, "ProtocolVersion", pv)
ids.Network.Peerstore().Put(p, "AgentVersion", av)
}

View File

@ -5,6 +5,7 @@ import (
"time"
inet "github.com/jbenet/go-ipfs/net"
handshake "github.com/jbenet/go-ipfs/net/handshake"
peer "github.com/jbenet/go-ipfs/peer"
testutil "github.com/jbenet/go-ipfs/util/testutil"
@ -57,6 +58,17 @@ func TestIDService(t *testing.T) {
}
}
testHasProtocolVersions := func(n inet.Network, p peer.ID) {
v, err := n.Peerstore().Get(p, "ProtocolVersion")
if v.(string) != handshake.IpfsVersion.String() {
t.Fatal("protocol mismatch", err)
}
v, err = n.Peerstore().Get(p, "AgentVersion")
if v.(string) != handshake.ClientVersion {
t.Fatal("agent version mismatch", err)
}
}
n1p := n1.LocalPeer()
n2p := n2.LocalPeer()
@ -79,4 +91,8 @@ func TestIDService(t *testing.T) {
// what we should see now is that both peers know about each others listen addresses.
testKnowsAddrs(n1, n2p, n2.Peerstore().Addresses(n2p)) // has them
testKnowsAddrs(n2, n1p, n1.Peerstore().Addresses(n1p)) // has them
// and the protocol versions.
testHasProtocolVersions(n1, n2p)
testHasProtocolVersions(n2, n1p)
}

View File

@ -6,6 +6,8 @@ import (
ic "github.com/jbenet/go-ipfs/crypto"
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
dssync "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore/sync"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
)
@ -23,6 +25,12 @@ type Peerstore interface {
// This is a small slice of the information Peerstore has on
// that peer, useful to other services.
PeerInfo(ID) PeerInfo
// Get/Put is a simple registry for other peer-related key/value pairs.
// if we find something we use often, it should become its own set of
// methods. this is a last resort.
Get(id ID, key string) (interface{}, error)
Put(id ID, key string, val interface{}) error
}
// AddressBook tracks the addresses of Peers
@ -177,7 +185,7 @@ type peerstore struct {
metrics
// store other data, like versions
data map[ID]map[string]interface{}
ds ds.ThreadSafeDatastore
}
// NewPeerstore creates a threadsafe collection of peers.
@ -186,10 +194,20 @@ func NewPeerstore() Peerstore {
keybook: *newKeybook(),
addressbook: *newAddressbook(),
metrics: *(NewMetrics()).(*metrics),
data: map[ID]map[string]interface{}{},
ds: dssync.MutexWrap(ds.NewMapDatastore()),
}
}
func (ps *peerstore) Put(p ID, key string, val interface{}) error {
dsk := ds.NewKey(string(p) + "/" + key)
return ps.ds.Put(dsk, val)
}
func (ps *peerstore) Get(p ID, key string) (interface{}, error) {
dsk := ds.NewKey(string(p) + "/" + key)
return ps.ds.Get(dsk)
}
func (ps *peerstore) Peers() []ID {
set := map[ID]struct{}{}
for _, p := range ps.keybook.Peers() {