From a28dca0fab1a3ba3055a22e1e256f487fe72fa16 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 19 Oct 2022 18:13:39 +0100 Subject: [PATCH] Allow setting link priorities --- cmd/yggdrasilctl/main.go | 3 ++- go.mod | 2 ++ go.sum | 15 +++------------ src/admin/getpeers.go | 5 +++++ src/core/api.go | 18 ++++++++++-------- src/core/link.go | 19 ++++++++++++++----- 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 324550bd..b1af85ca 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -174,10 +174,11 @@ func run() int { if err := json.Unmarshal(recv.Response, &resp); err != nil { panic(err) } - table.SetHeader([]string{"Port", "Public Key", "IP Address", "Uptime", "RX", "TX", "URI"}) + table.SetHeader([]string{"Port", "Priority", "Public Key", "IP Address", "Uptime", "RX", "TX", "URI"}) for _, peer := range resp.Peers { table.Append([]string{ fmt.Sprintf("%d", peer.Port), + fmt.Sprintf("%d", peer.Priority), peer.PublicKey, peer.IPAddress, (time.Duration(peer.Uptime) * time.Second).String(), diff --git a/go.mod b/go.mod index 4e73edea..1c32f9d5 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/yggdrasil-network/yggdrasil-go go 1.17 +replace github.com/Arceliar/ironwood => github.com/neilalexander/ironwood v0.0.0-20221019170140-a75def48d9f8 + require ( github.com/Arceliar/ironwood v0.0.0-20220924160422-ed4b6d4750b6 github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979 diff --git a/go.sum b/go.sum index 9e0b7458..0c3b71b7 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/Arceliar/ironwood v0.0.0-20220924160422-ed4b6d4750b6 h1:iwL6nm2ibyuHXYimRNtFof7RJfe8JB+6CPDskV7K7gA= -github.com/Arceliar/ironwood v0.0.0-20220924160422-ed4b6d4750b6/go.mod h1:RP72rucOFm5udrnEzTmIWLRVGQiV/fSUAQXJ0RST/nk= github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979 h1:WndgpSW13S32VLQ3ugUxx2EnnWmgba1kCqPkd4Gk1yQ= github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979/go.mod h1:6Lkn+/zJilRMsKmbmG1RPoamiArC6HS73xbwRyp3UyI= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -17,8 +15,6 @@ github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwM github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hjson/hjson-go v3.1.0+incompatible h1:DY/9yE8ey8Zv22bY+mHV1uk2yRy0h8tKhZ77hEdi0Aw= github.com/hjson/hjson-go v3.1.0+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio= -github.com/kardianos/minwinsvc v1.0.0 h1:+JfAi8IBJna0jY2dJGZqi7o15z13JelFIklJCAENALA= -github.com/kardianos/minwinsvc v1.0.0/go.mod h1:Bgd0oc+D0Qo3bBytmNtyRKVlp85dAloLKhfxanPFFRc= github.com/kardianos/minwinsvc v1.0.2 h1:JmZKFJQrmTGa/WiW+vkJXKmfzdjabuEW4Tirj5lLdR0= github.com/kardianos/minwinsvc v1.0.2/go.mod h1:LUZNYhNmxujx2tR7FbdxqYJ9XDDoCd3MQcl1o//FWl4= github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= @@ -34,6 +30,8 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4 github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/neilalexander/ironwood v0.0.0-20221019170140-a75def48d9f8 h1:9pepuH9xVhSPfAOHKVaZOr9S78fX5NwYznB7gNeJgq4= +github.com/neilalexander/ironwood v0.0.0-20221019170140-a75def48d9f8/go.mod h1:RP72rucOFm5udrnEzTmIWLRVGQiV/fSUAQXJ0RST/nk= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -50,7 +48,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20221012134737-56aed061732a h1:NmSIgad6KjE6VvHciPZuNRTKxGhlPfD6OA87W/PLkqg= golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -58,8 +55,6 @@ golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9t golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105 h1:3vUV5x5+3LfQbgk7paCM6INOaJG9xXQbn79xoNkwfIk= -golang.org/x/mobile v0.0.0-20220722155234-aaac322e2105/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ= golang.org/x/mobile v0.0.0-20221012134814-c746ac228303 h1:K4fp1rDuJBz0FCPAWzIJwnzwNEM7S6yobdZzMrZ/Zws= golang.org/x/mobile v0.0.0-20221012134814-c746ac228303/go.mod h1:M32cGdzp91A8Ex9qQtyZinr19EYxzkFqDjW2oyHzTDQ= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= @@ -73,7 +68,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210927181540-4e4d966f7476/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211011170408-caeb26a5c8c0/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= @@ -87,7 +82,6 @@ golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -97,9 +91,7 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 h1:OK7RB6t2WQX54srQQYSXMW8dF5C6/8+oA/s5QBmmto4= golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -109,7 +101,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b h1:NXqSWXSRUSCaFuvitrWtU169I3876zRTalMRbfd6LL0= golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= diff --git a/src/admin/getpeers.go b/src/admin/getpeers.go index 61d0937f..c1c9a6f9 100644 --- a/src/admin/getpeers.go +++ b/src/admin/getpeers.go @@ -19,6 +19,7 @@ type PeerEntry struct { IPAddress string `json:"address"` PublicKey string `json:"key"` Port uint64 `json:"port"` + Priority uint8 `json:"priority"` Coords []uint64 `json:"coords"` Remote string `json:"remote"` RXBytes DataUnit `json:"bytes_recvd"` @@ -35,6 +36,7 @@ func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersRespons IPAddress: net.IP(addr[:]).String(), PublicKey: hex.EncodeToString(p.Key), Port: p.Port, + Priority: p.Priority, Coords: p.Coords, Remote: p.Remote, RXBytes: DataUnit(p.RXBytes), @@ -43,6 +45,9 @@ func (a *AdminSocket) getPeersHandler(req *GetPeersRequest, res *GetPeersRespons }) } sort.Slice(res.Peers, func(i, j int) bool { + if res.Peers[i].Port == res.Peers[j].Port { + return res.Peers[i].Priority < res.Peers[j].Priority + } return res.Peers[i].Port < res.Peers[j].Port }) return nil diff --git a/src/core/api.go b/src/core/api.go index 0fa6dd33..a812e95b 100644 --- a/src/core/api.go +++ b/src/core/api.go @@ -20,14 +20,15 @@ type SelfInfo struct { } type PeerInfo struct { - Key ed25519.PublicKey - Root ed25519.PublicKey - Coords []uint64 - Port uint64 - Remote string - RXBytes uint64 - TXBytes uint64 - Uptime time.Duration + Key ed25519.PublicKey + Root ed25519.PublicKey + Coords []uint64 + Port uint64 + Priority uint8 + Remote string + RXBytes uint64 + TXBytes uint64 + Uptime time.Duration } type DHTEntryInfo struct { @@ -72,6 +73,7 @@ func (c *Core) GetPeers() []PeerInfo { info.Root = p.Root info.Coords = p.Coords info.Port = p.Port + info.Priority = p.Priority info.Remote = p.Conn.RemoteAddr().String() if name := names[p.Conn]; name != "" { info.Remote = name diff --git a/src/core/link.go b/src/core/link.go index b4515276..5759bdd2 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -8,6 +8,7 @@ import ( "io" "net" "net/url" + "strconv" "strings" "sync/atomic" "time" @@ -45,6 +46,7 @@ type link struct { type linkOptions struct { pinnedEd25519Keys map[keyArray]struct{} + priority uint8 } type Listener struct { @@ -120,17 +122,24 @@ func (l *links) call(u *url.URL, sintf string) (linkInfo, error) { copy(sigPubKey[:], sigPub) options.pinnedEd25519Keys[sigPubKey] = struct{}{} } + if p := u.Query().Get("priority"); p != "" { + pi, err := strconv.ParseUint(p, 10, 8) + if err != nil { + return info, fmt.Errorf("priority invalid: %w", err) + } + options.priority = uint8(pi) + } switch info.linkType { case "tcp": go func() { - if err := l.tcp.dial(u, options, sintf); err != nil { + if err := l.tcp.dial(u, options, sintf); err != nil && err != io.EOF { l.core.log.Warnf("Failed to dial TCP %s: %s\n", u.Host, err) } }() case "socks": go func() { - if err := l.socks.dial(u, options); err != nil { + if err := l.socks.dial(u, options); err != nil && err != io.EOF { l.core.log.Warnf("Failed to dial SOCKS %s: %s\n", u.Host, err) } }() @@ -154,14 +163,14 @@ func (l *links) call(u *url.URL, sintf string) (linkInfo, error) { } } go func() { - if err := l.tls.dial(u, options, sintf, tlsSNI); err != nil { + if err := l.tls.dial(u, options, sintf, tlsSNI); err != nil && err != io.EOF { l.core.log.Warnf("Failed to dial TLS %s: %s\n", u.Host, err) } }() case "unix": go func() { - if err := l.unix.dial(u, options, sintf); err != nil { + if err := l.unix.dial(u, options, sintf); err != nil && err != io.EOF { l.core.log.Warnf("Failed to dial UNIX %s: %s\n", u.Host, err) } }() @@ -303,7 +312,7 @@ func (intf *link) handler() error { strings.ToUpper(intf.info.linkType), remoteStr, localStr) // TODO don't report an error if it's just a 'use of closed network connection' - if err = intf.links.core.HandleConn(meta.key, intf.conn); err != nil && err != io.EOF { + if err = intf.links.core.HandleConn(meta.key, intf.conn, intf.options.priority); err != nil && err != io.EOF { intf.links.core.log.Infof("Disconnected %s: %s, source %s; error: %s", strings.ToUpper(intf.info.linkType), remoteStr, localStr, err) } else {