From 027bf58651f1a7b2be1bedfde187e5277a13f48e Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 22 Sep 2019 23:13:30 +0200 Subject: uapi: IpcGetOperation: return peers in sorted order 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 --- device/uapi.go | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'device') 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() -- cgit v1.2.3