mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-04-28 14:15:06 +03:00
Priority support (#964)
* Allow setting link priorities * Fix a bug * Allow setting priority on listeners and multicast interfaces * Update `yggdrasilctl` * Update to Arceliar/ironwood#5
This commit is contained in:
parent
9a9452dcc8
commit
f08dec822a
14 changed files with 79 additions and 56 deletions
|
@ -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
|
||||
|
|
|
@ -40,10 +40,11 @@ type NodeConfig struct {
|
|||
}
|
||||
|
||||
type MulticastInterfaceConfig struct {
|
||||
Regex string
|
||||
Beacon bool
|
||||
Listen bool
|
||||
Port uint16
|
||||
Regex string
|
||||
Beacon bool
|
||||
Listen bool
|
||||
Port uint16
|
||||
Priority uint8
|
||||
}
|
||||
|
||||
// NewSigningKeys replaces the signing keypair in the NodeConfig with a new
|
||||
|
|
|
@ -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 {
|
||||
|
@ -75,6 +76,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
|
||||
|
|
|
@ -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 {
|
|||
intf.links.core.log.Infof("Connected %s %s: %s, source %s",
|
||||
dir, strings.ToUpper(intf.info.linkType), remoteStr, localStr)
|
||||
|
||||
err = intf.links.core.HandleConn(meta.key, intf.conn)
|
||||
err = intf.links.core.HandleConn(meta.key, intf.conn, intf.options.priority)
|
||||
switch err {
|
||||
case io.EOF, net.ErrClosed, nil:
|
||||
intf.links.core.log.Infof("Disconnected %s %s: %s, source %s",
|
||||
|
@ -347,3 +356,12 @@ func (c *linkConn) Write(p []byte) (n int, err error) {
|
|||
atomic.AddUint64(&c.tx, uint64(n))
|
||||
return
|
||||
}
|
||||
|
||||
func linkOptionsForListener(u *url.URL) (l linkOptions) {
|
||||
if p := u.Query().Get("priority"); p != "" {
|
||||
if pi, err := strconv.ParseUint(p, 10, 8); err == nil {
|
||||
l.priority = uint8(pi)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ func (l *linkTCP) listen(url *url.URL, sintf string) (*Listener, error) {
|
|||
raddr := conn.RemoteAddr().(*net.TCPAddr)
|
||||
name := fmt.Sprintf("tcp://%s", raddr)
|
||||
info := linkInfoFor("tcp", sintf, tcpIDFor(laddr, raddr))
|
||||
if err = l.handler(name, info, conn, linkOptions{}, true, raddr.IP.IsLinkLocalUnicast()); err != nil {
|
||||
if err = l.handler(name, info, conn, linkOptionsForListener(url), true, raddr.IP.IsLinkLocalUnicast()); err != nil {
|
||||
l.core.log.Errorln("Failed to create inbound link:", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ func (l *linkTLS) listen(url *url.URL, sintf string) (*Listener, error) {
|
|||
raddr := conn.RemoteAddr().(*net.TCPAddr)
|
||||
name := fmt.Sprintf("tls://%s", raddr)
|
||||
info := linkInfoFor("tls", sintf, tcpIDFor(laddr, raddr))
|
||||
if err = l.handler(name, info, conn, linkOptions{}, true, raddr.IP.IsLinkLocalUnicast()); err != nil {
|
||||
if err = l.handler(name, info, conn, linkOptionsForListener(url), true, raddr.IP.IsLinkLocalUnicast()); err != nil {
|
||||
l.core.log.Errorln("Failed to create inbound link:", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ func (l *linkUNIX) listen(url *url.URL, _ string) (*Listener, error) {
|
|||
break
|
||||
}
|
||||
info := linkInfoFor("unix", "", url.String())
|
||||
if err = l.handler(url.String(), info, conn, linkOptions{}, true); err != nil {
|
||||
if err = l.handler(url.String(), info, conn, linkOptionsForListener(url), true); err != nil {
|
||||
l.core.log.Errorln("Failed to create inbound link:", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,11 +37,12 @@ type Multicast struct {
|
|||
}
|
||||
|
||||
type interfaceInfo struct {
|
||||
iface net.Interface
|
||||
addrs []net.Addr
|
||||
beacon bool
|
||||
listen bool
|
||||
port uint16
|
||||
iface net.Interface
|
||||
addrs []net.Addr
|
||||
beacon bool
|
||||
listen bool
|
||||
port uint16
|
||||
priority uint8
|
||||
}
|
||||
|
||||
type listenerInfo struct {
|
||||
|
@ -194,10 +195,11 @@ func (m *Multicast) _getAllowedInterfaces() map[string]*interfaceInfo {
|
|||
continue
|
||||
}
|
||||
interfaces[iface.Name] = &interfaceInfo{
|
||||
iface: iface,
|
||||
beacon: ifcfg.Beacon,
|
||||
listen: ifcfg.Listen,
|
||||
port: ifcfg.Port,
|
||||
iface: iface,
|
||||
beacon: ifcfg.Beacon,
|
||||
listen: ifcfg.Listen,
|
||||
port: ifcfg.Port,
|
||||
priority: ifcfg.Priority,
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -387,7 +389,7 @@ func (m *Multicast) listen() {
|
|||
})
|
||||
if info, ok := interfaces[from.Zone]; ok && info.listen {
|
||||
addr.Zone = ""
|
||||
pin := fmt.Sprintf("/?key=%s", hex.EncodeToString(key))
|
||||
pin := fmt.Sprintf("/?key=%s&priority=%d", hex.EncodeToString(key), info.priority)
|
||||
u, err := url.Parse("tls://" + addr.String() + pin)
|
||||
if err != nil {
|
||||
m.log.Debugln("Call from multicast failed, parse error:", addr.String(), err)
|
||||
|
|
|
@ -16,10 +16,11 @@ type SetupOption interface {
|
|||
}
|
||||
|
||||
type MulticastInterface struct {
|
||||
Regex *regexp.Regexp
|
||||
Beacon bool
|
||||
Listen bool
|
||||
Port uint16
|
||||
Regex *regexp.Regexp
|
||||
Beacon bool
|
||||
Listen bool
|
||||
Port uint16
|
||||
Priority uint8
|
||||
}
|
||||
|
||||
type GroupAddress string
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue