From 75ed7d52b91d08821a37bac83aca6d05bbabcb16 Mon Sep 17 00:00:00 2001 From: Matthias Radestock Date: Thu, 25 Dec 2014 13:49:58 +0000 Subject: [PATCH] refactor: give Peers knowledge of Ourself.Peer and MacCache so their use (when applying updates and performing gc) is opaque --- router/connection.go | 2 +- router/peer.go | 2 +- router/peers.go | 34 ++++++++++++++++++++-------------- router/router.go | 2 +- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/router/connection.go b/router/connection.go index ac8f2ca9..17c6b0e2 100644 --- a/router/connection.go +++ b/router/connection.go @@ -495,7 +495,7 @@ func (conn *LocalConnection) receiveTCP(decoder *gob.Decoder, usingPassword bool // receiver's version are updated conn.SendTCP(Concat(ProtocolUpdateByte, conn.Router.Peers.EncodeAllPeers())) } else if msg[0] == ProtocolUpdate { - newUpdate, err := conn.Router.Peers.ApplyUpdate(msg[1:], conn.Router.Ourself.Peer, conn.Router.Macs) + newUpdate, err := conn.Router.Peers.ApplyUpdate(msg[1:]) if _, ok := err.(UnknownPeersError); err != nil && ok { // That update contained a peer we didn't know about; // request full update diff --git a/router/peer.go b/router/peer.go index 1552626a..ca993aff 100644 --- a/router/peer.go +++ b/router/peer.go @@ -362,7 +362,7 @@ func (peer *LocalPeer) handleDeleteConnection(conn *LocalConnection) { } // Must do garbage collection first to ensure we don't send out an // update with unreachable peers (can cause looping) - peer.Router.Peers.GarbageCollect(peer.Router.Ourself.Peer, peer.Router.Macs) + peer.Router.Peers.GarbageCollect() if broadcast { peer.broadcastPeerUpdate() } diff --git a/router/peers.go b/router/peers.go index 35296c37..fd5d5782 100644 --- a/router/peers.go +++ b/router/peers.go @@ -10,12 +10,18 @@ import ( type Peers struct { sync.RWMutex - table map[PeerName]*Peer - onGC func(*Peer) + ourself *Peer + macs *MacCache + table map[PeerName]*Peer + onGC func(*Peer) } -func NewPeers(onGC func(*Peer)) *Peers { - return &Peers{table: make(map[PeerName]*Peer), onGC: onGC} +func NewPeers(ourself *Peer, macs *MacCache, onGC func(*Peer)) *Peers { + return &Peers{ + ourself: ourself, + macs: macs, + table: make(map[PeerName]*Peer), + onGC: onGC} } func (peers *Peers) FetchWithDefault(peer *Peer) *Peer { @@ -51,7 +57,7 @@ func (peers *Peers) ForEach(fun func(PeerName, *Peer)) { } } -func (peers *Peers) ApplyUpdate(update []byte, ourself *Peer, macs *MacCache) ([]byte, error) { +func (peers *Peers) ApplyUpdate(update []byte) ([]byte, error) { peers.Lock() newPeers, decodedUpdate, decodedConns, err := peers.decodeUpdate(update) @@ -68,9 +74,9 @@ func (peers *Peers) ApplyUpdate(update []byte, ourself *Peer, macs *MacCache) ([ } // Now apply the updates - newUpdate := peers.applyUpdate(decodedUpdate, decodedConns, ourself) + newUpdate := peers.applyUpdate(decodedUpdate, decodedConns) - for _, peerRemoved := range peers.garbageCollect(ourself, macs) { + for _, peerRemoved := range peers.garbageCollect() { delete(newUpdate, peerRemoved.Name) } @@ -95,10 +101,10 @@ func EncodePeers(peers ...*Peer) []byte { return buf.Bytes() } -func (peers *Peers) GarbageCollect(ourself *Peer, macs *MacCache) []*Peer { +func (peers *Peers) GarbageCollect() []*Peer { peers.Lock() defer peers.Unlock() - return peers.garbageCollect(ourself, macs) + return peers.garbageCollect() } func (peers *Peers) String() string { @@ -124,14 +130,14 @@ func (peers *Peers) fetchAlias(peer *Peer) (*Peer, bool) { return nil, false } -func (peers *Peers) garbageCollect(ourself *Peer, macs *MacCache) []*Peer { +func (peers *Peers) garbageCollect() []*Peer { removed := []*Peer{} for name, peer := range peers.table { - found, _ := ourself.Routes(peer, false) + found, _ := peers.ourself.Routes(peer, false) if !found && !peer.IsLocallyReferenced() { peers.onGC(peer) delete(peers.table, name) - macs.Delete(peer) + peers.macs.Delete(peer) removed = append(removed, peer) } } @@ -199,7 +205,7 @@ func (peers *Peers) decodeUpdate(update []byte) (newPeers map[PeerName]*Peer, de return } -func (peers *Peers) applyUpdate(decodedUpdate []*Peer, decodedConns [][]byte, ourself *Peer) map[PeerName]*Peer { +func (peers *Peers) applyUpdate(decodedUpdate []*Peer, decodedConns [][]byte) map[PeerName]*Peer { newUpdate := make(map[PeerName]*Peer) for idx, newPeer := range decodedUpdate { connsBuf := decodedConns[idx] @@ -216,7 +222,7 @@ func (peers *Peers) applyUpdate(decodedUpdate []*Peer, decodedConns [][]byte, ou // change. newUpdate[name] = peer continue - } else if peer == ourself { + } else if peer == peers.ourself { // nobody but us updates us continue } else if peer.Version() == newPeer.Version() { diff --git a/router/router.go b/router/router.go index 19c395d6..e4bfb348 100644 --- a/router/router.go +++ b/router/router.go @@ -27,7 +27,6 @@ func NewRouter(iface *net.Interface, name PeerName, password []byte, connLimit i router := &Router{ Iface: iface, Macs: NewMacCache(macMaxAge, onMacExpiry), - Peers: NewPeers(onPeerGC), ConnLimit: connLimit, BufSz: bufSz, LogFrame: logFrame} @@ -35,6 +34,7 @@ func NewRouter(iface *net.Interface, name PeerName, password []byte, connLimit i router.Password = &password } router.Ourself = StartLocalPeer(name, router) + router.Peers = NewPeers(router.Ourself.Peer, router.Macs, onPeerGC) router.Peers.FetchWithDefault(router.Ourself.Peer) log.Println("Our name is", router.Ourself.Name)