diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 3d5eab97..8185dee0 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -335,10 +335,11 @@ func run(args yggArgs, ctx context.Context) { options := []multicast.SetupOption{} for _, intf := range cfg.MulticastInterfaces { options = append(options, multicast.MulticastInterface{ - Regex: regexp.MustCompile(intf.Regex), - Beacon: intf.Beacon, - Listen: intf.Listen, - Port: intf.Port, + Regex: regexp.MustCompile(intf.Regex), + Beacon: intf.Beacon, + Listen: intf.Listen, + Port: intf.Port, + Priority: intf.Priority, }) } if n.multicast, err = multicast.New(n.core, logger, options...); err != nil { diff --git a/contrib/mobile/mobile.go b/contrib/mobile/mobile.go index 0cf87180..78a3f506 100644 --- a/contrib/mobile/mobile.go +++ b/contrib/mobile/mobile.go @@ -83,10 +83,11 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error { options := []multicast.SetupOption{} for _, intf := range m.config.MulticastInterfaces { options = append(options, multicast.MulticastInterface{ - Regex: regexp.MustCompile(intf.Regex), - Beacon: intf.Beacon, - Listen: intf.Listen, - Port: intf.Port, + Regex: regexp.MustCompile(intf.Regex), + Beacon: intf.Beacon, + Listen: intf.Listen, + Port: intf.Port, + Priority: intf.Priority, }) } m.multicast, err = multicast.New(m.core, logger, options...) diff --git a/src/config/config.go b/src/config/config.go index 5bdeec4b..3fc9c4ed 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -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 diff --git a/src/core/link.go b/src/core/link.go index 5759bdd2..90f8755c 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -362,3 +362,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 +} diff --git a/src/core/link_tcp.go b/src/core/link_tcp.go index c5a73c9e..421c51d3 100644 --- a/src/core/link_tcp.go +++ b/src/core/link_tcp.go @@ -85,7 +85,7 @@ func (l *linkTCP) listen(url *url.URL, sintf string) (*Listener, error) { addr := conn.RemoteAddr().(*net.TCPAddr) name := fmt.Sprintf("tls://%s", addr) info := linkInfoFor("tcp", sintf, strings.SplitN(addr.IP.String(), "%", 2)[0]) - if err = l.handler(name, info, conn, linkOptions{}, true); err != nil { + if err = l.handler(name, info, conn, linkOptionsForListener(url), true); err != nil { l.core.log.Errorln("Failed to create inbound link:", err) } } diff --git a/src/core/link_tls.go b/src/core/link_tls.go index 1e932b66..fe23aaae 100644 --- a/src/core/link_tls.go +++ b/src/core/link_tls.go @@ -108,7 +108,7 @@ func (l *linkTLS) listen(url *url.URL, sintf string) (*Listener, error) { addr := conn.RemoteAddr().(*net.TCPAddr) name := fmt.Sprintf("tls://%s", addr) info := linkInfoFor("tls", sintf, strings.SplitN(addr.IP.String(), "%", 2)[0]) - if err = l.handler(name, info, conn, linkOptions{}, true); err != nil { + if err = l.handler(name, info, conn, linkOptionsForListener(url), true); err != nil { l.core.log.Errorln("Failed to create inbound link:", err) } } diff --git a/src/core/link_unix.go b/src/core/link_unix.go index e71f9362..e3dbf6e3 100644 --- a/src/core/link_unix.go +++ b/src/core/link_unix.go @@ -75,7 +75,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) } } diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index d40bcfc0..81e575f1 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -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 { @@ -190,10 +191,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 } @@ -383,7 +385,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) diff --git a/src/multicast/options.go b/src/multicast/options.go index a03b0677..f36284ed 100644 --- a/src/multicast/options.go +++ b/src/multicast/options.go @@ -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