From 26dfc420344b971b234ff39398a3c2e6c30a5168 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Wed, 29 Apr 2015 16:39:14 +0100 Subject: [PATCH 1/5] Bump protocol version due to gob restructuring --- router/protocol.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/router/protocol.go b/router/protocol.go index 0fc548c6..d42c5cbd 100644 --- a/router/protocol.go +++ b/router/protocol.go @@ -2,7 +2,7 @@ package router const ( Protocol = "weave" - ProtocolVersion = 15 + ProtocolVersion = 16 ) type ProtocolTag byte From 047614b5406c98298f015c9436fdb578bc9be228 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Wed, 29 Apr 2015 17:09:53 +0100 Subject: [PATCH 2/5] Encode/decode []ConnectionSummary instead of []byte --- router/peers.go | 85 ++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 51 deletions(-) diff --git a/router/peers.go b/router/peers.go index 059e41c3..640479c4 100644 --- a/router/peers.go +++ b/router/peers.go @@ -25,6 +25,13 @@ type NameCollisionError struct { type PeerNameSet map[PeerName]struct{} +type ConnectionSummary struct { + NameByte []byte + RemoteTCPAddr string + Outbound bool + Established bool +} + func NewPeers(ourself *Peer, onGC func(*Peer)) *Peers { return &Peers{ ourself: ourself, @@ -180,17 +187,17 @@ func setFromPeersMap(peers map[PeerName]*Peer) PeerNameSet { return names } -func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, decodedUpdate []*Peer, decodedConns [][]byte, err error) { +func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, decodedUpdate []*Peer, decodedConns [][]ConnectionSummary, err error) { newPeers = make(map[PeerName]*Peer) decodedUpdate = []*Peer{} - decodedConns = [][]byte{} + decodedConns = [][]ConnectionSummary{} updateBuf := new(bytes.Buffer) updateBuf.Write(update) decoder := gob.NewDecoder(updateBuf) for { - nameByte, nickName, uid, version, connsBuf, decErr := decodePeerNoConns(decoder) + nameByte, nickName, uid, version, connSummaries, decErr := decodePeer(decoder) if decErr == io.EOF { break } else if decErr != nil { @@ -200,7 +207,7 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de name := PeerNameFromBin(nameByte) newPeer := NewPeer(name, nickName, uid, version) decodedUpdate = append(decodedUpdate, newPeer) - decodedConns = append(decodedConns, connsBuf) + decodedConns = append(decodedConns, connSummaries) existingPeer, found := peers.table[name] if !found { newPeers[name] = newPeer @@ -210,8 +217,8 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de } } - for _, connsBuf := range decodedConns { - decErr := connsIterator(connsBuf, func(remoteNameByte []byte, _ string, _, _ bool) { + for _, connSummaries := range decodedConns { + connsIterator(connSummaries, func(remoteNameByte []byte, _ string, _, _ bool) { remoteName := PeerNameFromBin(remoteNameByte) if _, found := newPeers[remoteName]; found { return @@ -223,9 +230,6 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de // of. Thus we can't apply the update. Abort. err = UnknownPeerError{remoteName} }) - if decErr != nil && decErr != io.EOF { - err = decErr - } if err != nil { return } @@ -233,10 +237,10 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de return } -func (peers *Peers) applyUpdate(decodedUpdate []*Peer, decodedConns [][]byte) map[PeerName]*Peer { +func (peers *Peers) applyUpdate(decodedUpdate []*Peer, decodedConns [][]ConnectionSummary) map[PeerName]*Peer { newUpdate := make(map[PeerName]*Peer) for idx, newPeer := range decodedUpdate { - connsBuf := decodedConns[idx] + connSummaries := decodedConns[idx] name := newPeer.Name // guaranteed to find peer in the peers.table peer := peers.table[name] @@ -257,7 +261,7 @@ func (peers *Peers) applyUpdate(decodedUpdate []*Peer, decodedConns [][]byte) ma // for an update would be someone else calling // router.Peers.ApplyUpdate. But ApplyUpdate takes the Lock on // the router.Peers, so there can be no race here. - conns := readConnsMap(peer, connsBuf, peers.table) + conns := makeConnsMap(peer, connSummaries, peers.table) peer.SetVersionAndConnections(newPeer.Version(), conns) newUpdate[name] = peer } @@ -273,19 +277,21 @@ func (peer *Peer) encode(enc *gob.Encoder) { checkFatal(enc.Encode(peer.UID)) checkFatal(enc.Encode(peer.version)) - connsBuf := new(bytes.Buffer) - connsEnc := gob.NewEncoder(connsBuf) + connSummaries := []ConnectionSummary{} for _, conn := range peer.connections { - checkFatal(connsEnc.Encode(conn.Remote().NameByte)) - checkFatal(connsEnc.Encode(conn.RemoteTCPAddr())) - checkFatal(connsEnc.Encode(conn.Outbound())) - // DANGER holding rlock on peer, going to take rlock on conn - checkFatal(connsEnc.Encode(conn.Established())) + connSummaries = append(connSummaries, ConnectionSummary{ + conn.Remote().NameByte, + conn.RemoteTCPAddr(), + conn.Outbound(), + // DANGER holding rlock on peer, going to take rlock on conn + conn.Established(), + }) } - checkFatal(enc.Encode(connsBuf.Bytes())) + + checkFatal(enc.Encode(connSummaries)) } -func decodePeerNoConns(dec *gob.Decoder) (nameByte []byte, nickName string, uid uint64, version uint64, conns []byte, err error) { +func decodePeer(dec *gob.Decoder) (nameByte []byte, nickName string, uid uint64, version uint64, connSummaries []ConnectionSummary, err error) { if err = dec.Decode(&nameByte); err != nil { return } @@ -298,48 +304,25 @@ func decodePeerNoConns(dec *gob.Decoder) (nameByte []byte, nickName string, uid if err = dec.Decode(&version); err != nil { return } - if err = dec.Decode(&conns); err != nil { + if err = dec.Decode(&connSummaries); err != nil { return } return } -func connsIterator(input []byte, fun func([]byte, string, bool, bool)) error { - buf := new(bytes.Buffer) - buf.Write(input) - dec := gob.NewDecoder(buf) - for { - var nameByte []byte - if err := dec.Decode(&nameByte); err != nil { - return err - } - var foundAt string - if err := dec.Decode(&foundAt); err != nil { - return err - } - var outbound bool - if err := dec.Decode(&outbound); err != nil { - return err - } - var established bool - if err := dec.Decode(&established); err != nil { - return err - } - fun(nameByte, foundAt, outbound, established) +func connsIterator(connSummaries []ConnectionSummary, fun func([]byte, string, bool, bool)) { + for _, connSummary := range connSummaries { + fun(connSummary.NameByte, connSummary.RemoteTCPAddr, connSummary.Outbound, connSummary.Established) } } -func readConnsMap(peer *Peer, buf []byte, table map[PeerName]*Peer) map[PeerName]Connection { +func makeConnsMap(peer *Peer, connSummaries []ConnectionSummary, table map[PeerName]*Peer) map[PeerName]Connection { conns := make(map[PeerName]Connection) - if err := connsIterator(buf, func(nameByte []byte, remoteTCPAddr string, outbound bool, established bool) { + connsIterator(connSummaries, func(nameByte []byte, remoteTCPAddr string, outbound bool, established bool) { name := PeerNameFromBin(nameByte) remotePeer := table[name] conn := NewRemoteConnection(peer, remotePeer, remoteTCPAddr, outbound, established) conns[name] = conn - }); err != io.EOF { - // this should never happen since we've already successfully - // decoded the same data in decodeUpdate - checkFatal(err) - } + }) return conns } From b48a93c483c8238bbc363a8e2eb2b05dbe74cb87 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Wed, 29 Apr 2015 18:01:51 +0100 Subject: [PATCH 3/5] Remove obsolete connsIterator --- router/peers.go | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/router/peers.go b/router/peers.go index 640479c4..851031dc 100644 --- a/router/peers.go +++ b/router/peers.go @@ -217,20 +217,19 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de } } + for _, connSummaries := range decodedConns { - connsIterator(connSummaries, func(remoteNameByte []byte, _ string, _, _ bool) { - remoteName := PeerNameFromBin(remoteNameByte) + for _, connSummary := range connSummaries { + remoteName := PeerNameFromBin(connSummary.NameByte) if _, found := newPeers[remoteName]; found { - return + continue } if _, found := peers.table[remoteName]; found { - return + continue } // Update refers to a peer which we have no knowledge // of. Thus we can't apply the update. Abort. err = UnknownPeerError{remoteName} - }) - if err != nil { return } } @@ -310,19 +309,13 @@ func decodePeer(dec *gob.Decoder) (nameByte []byte, nickName string, uid uint64, return } -func connsIterator(connSummaries []ConnectionSummary, fun func([]byte, string, bool, bool)) { - for _, connSummary := range connSummaries { - fun(connSummary.NameByte, connSummary.RemoteTCPAddr, connSummary.Outbound, connSummary.Established) - } -} - func makeConnsMap(peer *Peer, connSummaries []ConnectionSummary, table map[PeerName]*Peer) map[PeerName]Connection { conns := make(map[PeerName]Connection) - connsIterator(connSummaries, func(nameByte []byte, remoteTCPAddr string, outbound bool, established bool) { - name := PeerNameFromBin(nameByte) + for _, connSummary := range connSummaries { + name := PeerNameFromBin(connSummary.NameByte) remotePeer := table[name] - conn := NewRemoteConnection(peer, remotePeer, remoteTCPAddr, outbound, established) + conn := NewRemoteConnection(peer, remotePeer, connSummary.RemoteTCPAddr, connSummary.Outbound, connSummary.Established) conns[name] = conn - }) + } return conns } From ab68a1c32502d46493ca204a88cb74ee8e1a37ad Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Thu, 30 Apr 2015 12:16:16 +0100 Subject: [PATCH 4/5] Introduce PeerSummary --- router/peers.go | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/router/peers.go b/router/peers.go index 851031dc..e51b2bc0 100644 --- a/router/peers.go +++ b/router/peers.go @@ -32,6 +32,13 @@ type ConnectionSummary struct { Established bool } +type PeerSummary struct { + NameByte []byte + NickName string + UID uint64 + Version uint64 +} + func NewPeers(ourself *Peer, onGC func(*Peer)) *Peers { return &Peers{ ourself: ourself, @@ -197,15 +204,15 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de decoder := gob.NewDecoder(updateBuf) for { - nameByte, nickName, uid, version, connSummaries, decErr := decodePeer(decoder) + peerSummary, connSummaries, decErr := decodePeer(decoder) if decErr == io.EOF { break } else if decErr != nil { err = decErr return } - name := PeerNameFromBin(nameByte) - newPeer := NewPeer(name, nickName, uid, version) + name := PeerNameFromBin(peerSummary.NameByte) + newPeer := NewPeer(name, peerSummary.NickName, peerSummary.UID, peerSummary.Version) decodedUpdate = append(decodedUpdate, newPeer) decodedConns = append(decodedConns, connSummaries) existingPeer, found := peers.table[name] @@ -217,7 +224,6 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de } } - for _, connSummaries := range decodedConns { for _, connSummary := range connSummaries { remoteName := PeerNameFromBin(connSummary.NameByte) @@ -271,10 +277,11 @@ func (peer *Peer) encode(enc *gob.Encoder) { peer.RLock() defer peer.RUnlock() - checkFatal(enc.Encode(peer.NameByte)) - checkFatal(enc.Encode(peer.NickName)) - checkFatal(enc.Encode(peer.UID)) - checkFatal(enc.Encode(peer.version)) + checkFatal(enc.Encode(PeerSummary{ + peer.NameByte, + peer.NickName, + peer.UID, + peer.version})) connSummaries := []ConnectionSummary{} for _, conn := range peer.connections { @@ -290,17 +297,8 @@ func (peer *Peer) encode(enc *gob.Encoder) { checkFatal(enc.Encode(connSummaries)) } -func decodePeer(dec *gob.Decoder) (nameByte []byte, nickName string, uid uint64, version uint64, connSummaries []ConnectionSummary, err error) { - if err = dec.Decode(&nameByte); err != nil { - return - } - if err = dec.Decode(&nickName); err != nil { - return - } - if err = dec.Decode(&uid); err != nil { - return - } - if err = dec.Decode(&version); err != nil { +func decodePeer(dec *gob.Decoder) (peerSummary PeerSummary, connSummaries []ConnectionSummary, err error) { + if err = dec.Decode(&peerSummary); err != nil { return } if err = dec.Decode(&connSummaries); err != nil { From e656d7463357e7763200916cb1d08f731ee74b0e Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Tue, 5 May 2015 22:08:03 +0100 Subject: [PATCH 5/5] cosmetic --- router/peers.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/router/peers.go b/router/peers.go index e51b2bc0..c2767ed0 100644 --- a/router/peers.go +++ b/router/peers.go @@ -25,13 +25,6 @@ type NameCollisionError struct { type PeerNameSet map[PeerName]struct{} -type ConnectionSummary struct { - NameByte []byte - RemoteTCPAddr string - Outbound bool - Established bool -} - type PeerSummary struct { NameByte []byte NickName string @@ -39,6 +32,13 @@ type PeerSummary struct { Version uint64 } +type ConnectionSummary struct { + NameByte []byte + RemoteTCPAddr string + Outbound bool + Established bool +} + func NewPeers(ourself *Peer, onGC func(*Peer)) *Peers { return &Peers{ ourself: ourself,