Hello,

I have an improvement to IpcGetOperation in wireguard-go.

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.

The output from git format-patch is attached. The patch is also available at https://cgit.m7n.se/pub/wireguard-go/commit/?id=027bf58651f1a7b2be1bedfde187e5277a13f48e

/Mikael
>From 027bf58651f1a7b2be1bedfde187e5277a13f48e Mon Sep 17 00:00:00 2001
From: Mikael Magnusson <mi...@users.sourceforge.net>
Date: Sun, 22 Sep 2019 23:13:30 +0200
Subject: [PATCH] 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 <mi...@users.sourceforge.net>
---
 device/uapi.go | 41 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

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()
 
-- 
2.17.1

_______________________________________________
WireGuard mailing list
WireGuard@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/wireguard

Reply via email to