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:
Neil Alexander 2022-10-26 09:24:24 +01:00 committed by GitHub
parent 9a9452dcc8
commit f08dec822a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 79 additions and 56 deletions

View file

@ -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

View file

@ -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
}

View file

@ -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)
}
}

View file

@ -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)
}
}

View file

@ -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)
}
}