diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2019-09-22 23:13:30 +0200 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2020-02-15 23:36:40 +0100 |
commit | 027bf58651f1a7b2be1bedfde187e5277a13f48e (patch) | |
tree | 95e92e7bb95c7dd685afb4e5e95b5f7bebbc2069 | |
parent | 9cbcff10dd3e04671d31ab224526f3d22a7ba665 (diff) |
uapi: IpcGetOperation: return peers in sorted orderHEADsorted-peers
Sort peers based on the public key.
The pros of using a sorted peer list is that the order doesn't change in
each ipc operation, or execution of the "wg showconf" command. Which could
be the case previously with an unsorted peer list.
Signed-off-by: Mikael Magnusson <mikma@users.sourceforge.net>
-rw-r--r-- | device/uapi.go | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/device/uapi.go b/device/uapi.go index 72611ab..bd66451 100644 --- a/device/uapi.go +++ b/device/uapi.go @@ -7,9 +7,11 @@ package device import ( "bufio" + "bytes" "fmt" "io" "net" + "sort" "strconv" "strings" "sync/atomic" @@ -30,6 +32,42 @@ func (s IPCError) ErrorCode() int64 { return s.int64 } +type PeerInfo struct { + pubkey NoisePublicKey + pubkeySlice []byte + peer *Peer +} + +type PeerInfoList []PeerInfo + +func (list PeerInfoList) Len() int { + return len(list) +} + +func (list PeerInfoList) Less(i, j int) bool { + k1 := list[i].pubkeySlice + k2 := list[j].pubkeySlice + + return bytes.Compare(k1, k2) == -1; +} + +func (list PeerInfoList) Swap(i, j int) { + list[i], list[j] = list[j], list[i] +} + +func (device *Device) GetSortedPeers() PeerInfoList { + peers := make(PeerInfoList, 0, len(device.peers.keyMap)) + for pubkey, peer := range device.peers.keyMap { + info := PeerInfo{} + info.pubkey = pubkey + info.pubkeySlice = info.pubkey[:] + info.peer = peer + peers = append(peers, info) + } + sort.Sort(peers) + return peers +} + func (device *Device) IpcGetOperation(socket *bufio.Writer) *IPCError { lines := make([]string, 0, 100) send := func(line string) { @@ -65,7 +103,8 @@ func (device *Device) IpcGetOperation(socket *bufio.Writer) *IPCError { // serialize each peer state - for _, peer := range device.peers.keyMap { + for _, peerInfo := range device.GetSortedPeers() { + peer := peerInfo.peer peer.RLock() defer peer.RUnlock() |