diff --git a/router/connection_maker.go b/router/connection_maker.go index 50d65cfb..6a1e7bf2 100644 --- a/router/connection_maker.go +++ b/router/connection_maker.go @@ -116,7 +116,7 @@ func (cm *ConnectionMaker) checkStateAndAttemptConnections() time.Duration { // copy the set of things we are connected to, so we can access them without locking ourConnectedPeers := make(PeerNameSet) ourConnectedTargets := make(map[string]struct{}) - for _, conn := range cm.ourself.Connections() { + for conn := range cm.ourself.Connections() { ourConnectedPeers[conn.Remote().Name] = void ourConnectedTargets[conn.RemoteTCPAddr()] = void } @@ -136,7 +136,7 @@ func (cm *ConnectionMaker) checkStateAndAttemptConnections() time.Duration { // Add targets for peers that someone else is connected to, but we // aren't cm.peers.ForEach(func(peer *Peer) { - for _, conn := range peer.Connections() { + for conn := range peer.Connections() { otherPeer := conn.Remote().Name if otherPeer == cm.ourself.Name { continue diff --git a/router/gossip.go b/router/gossip.go index 6c234116..9f1a30a4 100644 --- a/router/gossip.go +++ b/router/gossip.go @@ -179,7 +179,7 @@ func (c *GossipChannel) Send(data GossipData) { retainedSenders := make(connectionSenders) c.Lock() defer c.Unlock() - for _, conn := range connections { + for conn := range connections { c.sendDown(conn, data) retainedSenders[conn] = c.senders[conn] delete(c.senders, conn) diff --git a/router/json.go b/router/json.go index 07e538e5..2d01e8f6 100644 --- a/router/json.go +++ b/router/json.go @@ -64,13 +64,18 @@ func (routes *Routes) MarshalJSON() ([]byte, error) { } func (peer *Peer) MarshalJSON() ([]byte, error) { + conns := peer.Connections() + connections := make([]Connection, 0, len(conns)) + for conn := range conns { + connections = append(connections, conn) + } return json.Marshal(struct { Name string NickName string UID uint64 Version uint64 Connections []Connection - }{peer.Name.String(), peer.NickName, peer.UID, peer.version, peer.Connections()}) + }{peer.Name.String(), peer.NickName, peer.UID, peer.version, connections}) } func (conn *RemoteConnection) MarshalJSON() ([]byte, error) { diff --git a/router/peer.go b/router/peer.go index bc49acde..1ab58104 100644 --- a/router/peer.go +++ b/router/peer.go @@ -17,6 +17,8 @@ type Peer struct { connections map[PeerName]Connection } +type ConnectionSet map[Connection]struct{} + func NewPeer(name PeerName, nickName string, uid uint64, version uint64) *Peer { if uid == 0 { uid = randUint64() @@ -77,12 +79,12 @@ func (peer *Peer) ConnectionTo(name PeerName) (Connection, bool) { return conn, found // yes, you really can't inline that. FFS. } -func (peer *Peer) Connections() []Connection { +func (peer *Peer) Connections() ConnectionSet { + connections := make(ConnectionSet) peer.RLock() defer peer.RUnlock() - connections := make([]Connection, 0, len(peer.connections)) for _, conn := range peer.connections { - connections = append(connections, conn) + connections[conn] = void } return connections } diff --git a/router/peers.go b/router/peers.go index 31a8cc1f..2ade26bd 100644 --- a/router/peers.go +++ b/router/peers.go @@ -133,7 +133,7 @@ func (peers *Peers) String() string { var buf bytes.Buffer peers.ForEach(func(peer *Peer) { fmt.Fprint(&buf, peer, "\n") - for _, conn := range peer.Connections() { + for conn := range peer.Connections() { established := "" if !conn.Established() { established = " (unestablished)" diff --git a/router/routes.go b/router/routes.go index b7d839db..4745972d 100644 --- a/router/routes.go +++ b/router/routes.go @@ -162,7 +162,7 @@ func (routes *Routes) calculateBroadcast(establishedAndSymmetric bool) map[PeerN // This is rather similar to the inner loop on // peer.Routes(...); the main difference is in the // locking. - for _, conn := range ourself.Connections() { + for conn := range ourself.Connections() { if establishedAndSymmetric && !conn.Established() { continue }