mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-06-18 07:05:06 +03:00
Merge branch 'develop' into master
This commit is contained in:
commit
91c82c83c0
15 changed files with 247 additions and 94 deletions
|
@ -26,7 +26,7 @@ some of the below:
|
||||||
- Linux
|
- Linux
|
||||||
- `.deb` and `.rpm` packages are built by CI for Debian and Red Hat-based
|
- `.deb` and `.rpm` packages are built by CI for Debian and Red Hat-based
|
||||||
distributions
|
distributions
|
||||||
- Void and Arch packages also available within their respective repositories
|
- Arch, Nix, Void packages also available within their respective repositories
|
||||||
- macOS
|
- macOS
|
||||||
- `.pkg` packages are built by CI
|
- `.pkg` packages are built by CI
|
||||||
- Ubiquiti EdgeOS
|
- Ubiquiti EdgeOS
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -7,11 +7,12 @@ require (
|
||||||
github.com/cheggaaa/pb/v3 v3.0.4
|
github.com/cheggaaa/pb/v3 v3.0.4
|
||||||
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8
|
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8
|
||||||
github.com/hashicorp/go-syslog v1.0.0
|
github.com/hashicorp/go-syslog v1.0.0
|
||||||
github.com/hjson/hjson-go v3.0.1-0.20190209023717-9147687966d9+incompatible
|
github.com/hjson/hjson-go v3.0.2-0.20200316202735-d5d0e8b0617d+incompatible
|
||||||
github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0
|
github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0
|
||||||
github.com/mitchellh/mapstructure v1.1.2
|
github.com/mitchellh/mapstructure v1.1.2
|
||||||
github.com/vishvananda/netlink v1.0.0
|
github.com/vishvananda/netlink v1.0.0
|
||||||
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f // indirect
|
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f // indirect
|
||||||
|
github.com/yggdrasil-network/yggdrasil-extras v0.0.0-20200525205615-6c8a4a2e8855 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
|
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
|
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
|
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -10,8 +10,8 @@ github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8 h1:WD8iJ37bRNwvETMfVTu
|
||||||
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8/go.mod h1:gq31gQ8wEHkR+WekdWsqDuf8pXTUZA9BnnzTuPz1Y9U=
|
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8/go.mod h1:gq31gQ8wEHkR+WekdWsqDuf8pXTUZA9BnnzTuPz1Y9U=
|
||||||
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
|
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
|
||||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||||
github.com/hjson/hjson-go v3.0.1-0.20190209023717-9147687966d9+incompatible h1:bLQ2Ve+eW65id3b8xEMQiAwJT4qGZeywAEMLvXjznvw=
|
github.com/hjson/hjson-go v3.0.2-0.20200316202735-d5d0e8b0617d+incompatible h1:v6BPcb9q9U6JDVsuizxBr/piVB/2Y1Q5GWoBybvZVWI=
|
||||||
github.com/hjson/hjson-go v3.0.1-0.20190209023717-9147687966d9+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio=
|
github.com/hjson/hjson-go v3.0.2-0.20200316202735-d5d0e8b0617d+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio=
|
||||||
github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0 h1:YnZmFjg0Nvk8851WTVWlqMC1ecJH07Ctz+Ezxx4u54g=
|
github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0 h1:YnZmFjg0Nvk8851WTVWlqMC1ecJH07Ctz+Ezxx4u54g=
|
||||||
github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0/go.mod h1:rUi0/YffDo1oXBOGn1KRq7Fr07LX48XEBecQnmwjsAo=
|
github.com/kardianos/minwinsvc v0.0.0-20151122163309-cad6b2b879b0/go.mod h1:rUi0/YffDo1oXBOGn1KRq7Fr07LX48XEBecQnmwjsAo=
|
||||||
github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1 h1:/QwQcwWVOQXcoNuV9tHx30gQ3q7jCE/rKcGjwzsa5tg=
|
github.com/lxn/walk v0.0.0-20191128110447-55ccb3a9f5c1 h1:/QwQcwWVOQXcoNuV9tHx30gQ3q7jCE/rKcGjwzsa5tg=
|
||||||
|
@ -31,6 +31,8 @@ github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCO
|
||||||
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
|
||||||
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I=
|
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I=
|
||||||
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||||
|
github.com/yggdrasil-network/yggdrasil-extras v0.0.0-20200525205615-6c8a4a2e8855 h1:xLQihK8bAKOEDii/Z39dHTgSJzetm2TQ1YKRPRX87R4=
|
||||||
|
github.com/yggdrasil-network/yggdrasil-extras v0.0.0-20200525205615-6c8a4a2e8855/go.mod h1:xQdsh08Io6nV4WRnOVTe6gI8/2iTvfLDQ0CYa5aMt+I=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
|
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
|
||||||
|
|
|
@ -188,17 +188,44 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
|
||||||
},
|
},
|
||||||
}, errors.New("Failed to add peer")
|
}, errors.New("Failed to add peer")
|
||||||
})
|
})
|
||||||
a.AddHandler("removePeer", []string{"port"}, func(in Info) (Info, error) {
|
a.AddHandler("disconnectPeer", []string{"port"}, func(in Info) (Info, error) {
|
||||||
port, err := strconv.ParseInt(fmt.Sprint(in["port"]), 10, 64)
|
port, err := strconv.ParseInt(fmt.Sprint(in["port"]), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Info{}, err
|
return Info{}, err
|
||||||
}
|
}
|
||||||
if a.core.DisconnectPeer(uint64(port)) == nil {
|
if a.core.DisconnectPeer(uint64(port)) == nil {
|
||||||
return Info{
|
return Info{
|
||||||
"removed": []string{
|
"disconnected": []string{
|
||||||
fmt.Sprint(port),
|
fmt.Sprint(port),
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
|
} else {
|
||||||
|
return Info{
|
||||||
|
"not_disconnected": []string{
|
||||||
|
fmt.Sprint(port),
|
||||||
|
},
|
||||||
|
}, errors.New("Failed to disconnect peer")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
a.AddHandler("removePeer", []string{"uri", "[interface]"}, func(in Info) (Info, error) {
|
||||||
|
// Set sane defaults
|
||||||
|
intf := ""
|
||||||
|
// Has interface been specified?
|
||||||
|
if itf, ok := in["interface"]; ok {
|
||||||
|
intf = itf.(string)
|
||||||
|
}
|
||||||
|
if a.core.RemovePeer(in["uri"].(string), intf) == nil {
|
||||||
|
return Info{
|
||||||
|
"removed": []string{
|
||||||
|
in["uri"].(string),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
return Info{
|
||||||
|
"not_removed": []string{
|
||||||
|
in["uri"].(string),
|
||||||
|
},
|
||||||
|
}, errors.New("Failed to remove peer")
|
||||||
}
|
}
|
||||||
return Info{
|
return Info{
|
||||||
"not_removed": []string{
|
"not_removed": []string{
|
||||||
|
|
|
@ -10,7 +10,7 @@ func GetDefaults() platformDefaultParameters {
|
||||||
DefaultAdminListen: "unix:///var/run/yggdrasil.sock",
|
DefaultAdminListen: "unix:///var/run/yggdrasil.sock",
|
||||||
|
|
||||||
// Configuration (used for yggdrasilctl)
|
// Configuration (used for yggdrasilctl)
|
||||||
DefaultConfigFile: "/etc/yggdrasil.conf",
|
DefaultConfigFile: "/usr/local/etc/yggdrasil.conf",
|
||||||
|
|
||||||
// Multicast interfaces
|
// Multicast interfaces
|
||||||
DefaultMulticastInterfaces: []string{
|
DefaultMulticastInterfaces: []string{
|
||||||
|
|
|
@ -21,16 +21,20 @@ import (
|
||||||
// automatically.
|
// automatically.
|
||||||
type Multicast struct {
|
type Multicast struct {
|
||||||
phony.Inbox
|
phony.Inbox
|
||||||
core *yggdrasil.Core
|
core *yggdrasil.Core
|
||||||
config *config.NodeState
|
config *config.NodeState
|
||||||
log *log.Logger
|
log *log.Logger
|
||||||
sock *ipv6.PacketConn
|
sock *ipv6.PacketConn
|
||||||
groupAddr string
|
groupAddr string
|
||||||
listeners map[string]*listenerInfo
|
listeners map[string]*listenerInfo
|
||||||
listenPort uint16
|
listenPort uint16
|
||||||
isOpen bool
|
isOpen bool
|
||||||
announcer *time.Timer
|
_interfaces map[string]interfaceInfo
|
||||||
platformhandler *time.Timer
|
}
|
||||||
|
|
||||||
|
type interfaceInfo struct {
|
||||||
|
iface net.Interface
|
||||||
|
addrs []net.Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
type listenerInfo struct {
|
type listenerInfo struct {
|
||||||
|
@ -45,6 +49,7 @@ func (m *Multicast) Init(core *yggdrasil.Core, state *config.NodeState, log *log
|
||||||
m.config = state
|
m.config = state
|
||||||
m.log = log
|
m.log = log
|
||||||
m.listeners = make(map[string]*listenerInfo)
|
m.listeners = make(map[string]*listenerInfo)
|
||||||
|
m._interfaces = make(map[string]interfaceInfo)
|
||||||
current := m.config.GetCurrent()
|
current := m.config.GetCurrent()
|
||||||
m.listenPort = current.LinkLocalTCPPort
|
m.listenPort = current.LinkLocalTCPPort
|
||||||
m.groupAddr = "[ff02::114]:9001"
|
m.groupAddr = "[ff02::114]:9001"
|
||||||
|
@ -90,8 +95,8 @@ func (m *Multicast) _start() error {
|
||||||
|
|
||||||
m.isOpen = true
|
m.isOpen = true
|
||||||
go m.listen()
|
go m.listen()
|
||||||
m.Act(m, m.multicastStarted)
|
m.Act(nil, m._multicastStarted)
|
||||||
m.Act(m, m.announce)
|
m.Act(nil, m._announce)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -118,12 +123,6 @@ func (m *Multicast) Stop() error {
|
||||||
func (m *Multicast) _stop() error {
|
func (m *Multicast) _stop() error {
|
||||||
m.log.Infoln("Stopping multicast module")
|
m.log.Infoln("Stopping multicast module")
|
||||||
m.isOpen = false
|
m.isOpen = false
|
||||||
if m.announcer != nil {
|
|
||||||
m.announcer.Stop()
|
|
||||||
}
|
|
||||||
if m.platformhandler != nil {
|
|
||||||
m.platformhandler.Stop()
|
|
||||||
}
|
|
||||||
if m.sock != nil {
|
if m.sock != nil {
|
||||||
m.sock.Close()
|
m.sock.Close()
|
||||||
}
|
}
|
||||||
|
@ -134,7 +133,7 @@ func (m *Multicast) _stop() error {
|
||||||
// and then signals the various module goroutines to reconfigure themselves if
|
// and then signals the various module goroutines to reconfigure themselves if
|
||||||
// needed.
|
// needed.
|
||||||
func (m *Multicast) UpdateConfig(config *config.NodeConfig) {
|
func (m *Multicast) UpdateConfig(config *config.NodeConfig) {
|
||||||
m.Act(m, func() { m._updateConfig(config) })
|
m.Act(nil, func() { m._updateConfig(config) })
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Multicast) _updateConfig(config *config.NodeConfig) {
|
func (m *Multicast) _updateConfig(config *config.NodeConfig) {
|
||||||
|
@ -156,10 +155,35 @@ func (m *Multicast) _updateConfig(config *config.NodeConfig) {
|
||||||
m.log.Debugln("Reloaded multicast configuration successfully")
|
m.log.Debugln("Reloaded multicast configuration successfully")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInterfaces returns the currently known/enabled multicast interfaces. It is
|
func (m *Multicast) _updateInterfaces() {
|
||||||
// expected that UpdateInterfaces has been called at least once before calling
|
interfaces := make(map[string]interfaceInfo)
|
||||||
// this method.
|
intfs := m.getAllowedInterfaces()
|
||||||
|
for _, intf := range intfs {
|
||||||
|
addrs, err := intf.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
m.log.Warnf("Failed up get addresses for interface %s: %s", intf.Name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
interfaces[intf.Name] = interfaceInfo{
|
||||||
|
iface: intf,
|
||||||
|
addrs: addrs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m._interfaces = interfaces
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Multicast) Interfaces() map[string]net.Interface {
|
func (m *Multicast) Interfaces() map[string]net.Interface {
|
||||||
|
interfaces := make(map[string]net.Interface)
|
||||||
|
phony.Block(m, func() {
|
||||||
|
for _, info := range m._interfaces {
|
||||||
|
interfaces[info.iface.Name] = info.iface
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return interfaces
|
||||||
|
}
|
||||||
|
|
||||||
|
// getAllowedInterfaces returns the currently known/enabled multicast interfaces.
|
||||||
|
func (m *Multicast) getAllowedInterfaces() map[string]net.Interface {
|
||||||
interfaces := make(map[string]net.Interface)
|
interfaces := make(map[string]net.Interface)
|
||||||
// Get interface expressions from config
|
// Get interface expressions from config
|
||||||
current := m.config.GetCurrent()
|
current := m.config.GetCurrent()
|
||||||
|
@ -198,7 +222,11 @@ func (m *Multicast) Interfaces() map[string]net.Interface {
|
||||||
return interfaces
|
return interfaces
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Multicast) announce() {
|
func (m *Multicast) _announce() {
|
||||||
|
if !m.isOpen {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m._updateInterfaces()
|
||||||
groupAddr, err := net.ResolveUDPAddr("udp6", m.groupAddr)
|
groupAddr, err := net.ResolveUDPAddr("udp6", m.groupAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -207,7 +235,6 @@ func (m *Multicast) announce() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
interfaces := m.Interfaces()
|
|
||||||
// There might be interfaces that we configured listeners for but are no
|
// There might be interfaces that we configured listeners for but are no
|
||||||
// longer up - if that's the case then we should stop the listeners
|
// longer up - if that's the case then we should stop the listeners
|
||||||
for name, info := range m.listeners {
|
for name, info := range m.listeners {
|
||||||
|
@ -219,7 +246,7 @@ func (m *Multicast) announce() {
|
||||||
}
|
}
|
||||||
// If the interface is no longer visible on the system then stop the
|
// If the interface is no longer visible on the system then stop the
|
||||||
// listener, as another one will be started further down
|
// listener, as another one will be started further down
|
||||||
if _, ok := interfaces[name]; !ok {
|
if _, ok := m._interfaces[name]; !ok {
|
||||||
stop()
|
stop()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -232,17 +259,13 @@ func (m *Multicast) announce() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Find the interface that matches the listener
|
// Find the interface that matches the listener
|
||||||
if intf, err := net.InterfaceByName(name); err == nil {
|
if info, ok := m._interfaces[name]; ok {
|
||||||
if addrs, err := intf.Addrs(); err == nil {
|
for _, addr := range info.addrs {
|
||||||
// Loop through the addresses attached to that listener and see if any
|
if ip, _, err := net.ParseCIDR(addr.String()); err == nil {
|
||||||
// of them match the current address of the listener
|
// Does the interface address match our listener address?
|
||||||
for _, addr := range addrs {
|
if ip.Equal(listenaddr.IP) {
|
||||||
if ip, _, err := net.ParseCIDR(addr.String()); err == nil {
|
found = true
|
||||||
// Does the interface address match our listener address?
|
break
|
||||||
if ip.Equal(listenaddr.IP) {
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,13 +279,9 @@ func (m *Multicast) announce() {
|
||||||
}
|
}
|
||||||
// Now that we have a list of valid interfaces from the operating system,
|
// Now that we have a list of valid interfaces from the operating system,
|
||||||
// we can start checking if we can send multicasts on them
|
// we can start checking if we can send multicasts on them
|
||||||
for _, iface := range interfaces {
|
for _, info := range m._interfaces {
|
||||||
// Find interface addresses
|
iface := info.iface
|
||||||
addrs, err := iface.Addrs()
|
for _, addr := range info.addrs {
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
for _, addr := range addrs {
|
|
||||||
addrIP, _, _ := net.ParseCIDR(addr.String())
|
addrIP, _, _ := net.ParseCIDR(addr.String())
|
||||||
// Ignore IPv4 addresses
|
// Ignore IPv4 addresses
|
||||||
if addrIP.To4() != nil {
|
if addrIP.To4() != nil {
|
||||||
|
@ -312,8 +331,8 @@ func (m *Multicast) announce() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.announcer = time.AfterFunc(time.Second, func() {
|
time.AfterFunc(time.Second, func() {
|
||||||
m.Act(m, m.announce)
|
m.Act(nil, m._announce)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +370,11 @@ func (m *Multicast) listen() {
|
||||||
if addr.IP.String() != from.IP.String() {
|
if addr.IP.String() != from.IP.String() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := m.Interfaces()[from.Zone]; ok {
|
var interfaces map[string]interfaceInfo
|
||||||
|
phony.Block(m, func() {
|
||||||
|
interfaces = m._interfaces
|
||||||
|
})
|
||||||
|
if _, ok := interfaces[from.Zone]; ok {
|
||||||
addr.Zone = ""
|
addr.Zone = ""
|
||||||
if err := m.core.CallPeer("tcp://"+addr.String(), from.Zone); err != nil {
|
if err := m.core.CallPeer("tcp://"+addr.String(), from.Zone); err != nil {
|
||||||
m.log.Debugln("Call from multicast failed:", err)
|
m.log.Debugln("Call from multicast failed:", err)
|
||||||
|
|
|
@ -31,16 +31,19 @@ import (
|
||||||
|
|
||||||
var awdlGoroutineStarted bool
|
var awdlGoroutineStarted bool
|
||||||
|
|
||||||
func (m *Multicast) multicastStarted() {
|
func (m *Multicast) _multicastStarted() {
|
||||||
|
if !m.isOpen {
|
||||||
|
return
|
||||||
|
}
|
||||||
C.StopAWDLBrowsing()
|
C.StopAWDLBrowsing()
|
||||||
for intf := range m.Interfaces() {
|
for intf := range m._interfaces {
|
||||||
if intf == "awdl0" {
|
if intf == "awdl0" {
|
||||||
C.StartAWDLBrowsing()
|
C.StartAWDLBrowsing()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.platformhandler = time.AfterFunc(time.Minute, func() {
|
time.AfterFunc(time.Minute, func() {
|
||||||
m.Act(m, m.multicastStarted)
|
m.Act(nil, m._multicastStarted)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ package multicast
|
||||||
|
|
||||||
import "syscall"
|
import "syscall"
|
||||||
|
|
||||||
func (m *Multicast) multicastStarted() {
|
func (m *Multicast) _multicastStarted() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ package multicast
|
||||||
import "syscall"
|
import "syscall"
|
||||||
import "golang.org/x/sys/unix"
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
func (m *Multicast) multicastStarted() {
|
func (m *Multicast) _multicastStarted() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ package multicast
|
||||||
import "syscall"
|
import "syscall"
|
||||||
import "golang.org/x/sys/windows"
|
import "golang.org/x/sys/windows"
|
||||||
|
|
||||||
func (m *Multicast) multicastStarted() {
|
func (m *Multicast) _multicastStarted() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -468,12 +468,31 @@ func (c *Core) AddPeer(addr string, sintf string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemovePeer is not implemented yet.
|
|
||||||
func (c *Core) RemovePeer(addr string, sintf string) error {
|
func (c *Core) RemovePeer(addr string, sintf string) error {
|
||||||
// TODO: Implement a reverse of AddPeer, where we look up the port number
|
if sintf == "" {
|
||||||
// based on the addr and sintf, disconnect it and then remove it from the
|
for i, peer := range c.config.Current.Peers {
|
||||||
// peers list so we don't reconnect to it later
|
if peer == addr {
|
||||||
return errors.New("not implemented")
|
c.config.Current.Peers = append(c.config.Current.Peers[:i], c.config.Current.Peers[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if _, ok := c.config.Current.InterfacePeers[sintf]; ok {
|
||||||
|
for i, peer := range c.config.Current.InterfacePeers[sintf] {
|
||||||
|
if peer == addr {
|
||||||
|
c.config.Current.InterfacePeers[sintf] = append(c.config.Current.InterfacePeers[sintf][:i], c.config.Current.InterfacePeers[sintf][i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ports := c.peers.ports.Load().(map[switchPort]*peer)
|
||||||
|
for p, peer := range ports {
|
||||||
|
if addr == peer.intf.name {
|
||||||
|
c.peers.removePeer(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallPeer calls a peer once. This should be specified in the peer URI format,
|
// CallPeer calls a peer once. This should be specified in the peer URI format,
|
||||||
|
|
|
@ -145,7 +145,8 @@ func (c *Conn) search() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in session keep-alive traffic
|
// Used in session keep-alive traffic
|
||||||
func (c *Conn) doSearch() {
|
func (c *Conn) _doSearch() {
|
||||||
|
s := fmt.Sprintf("conn=%p", c)
|
||||||
routerWork := func() {
|
routerWork := func() {
|
||||||
// Check to see if there is a search already matching the destination
|
// Check to see if there is a search already matching the destination
|
||||||
sinfo, isIn := c.core.router.searches.searches[*c.nodeID]
|
sinfo, isIn := c.core.router.searches.searches[*c.nodeID]
|
||||||
|
@ -153,7 +154,7 @@ func (c *Conn) doSearch() {
|
||||||
// Nothing was found, so create a new search
|
// Nothing was found, so create a new search
|
||||||
searchCompleted := func(sinfo *sessionInfo, e error) {}
|
searchCompleted := func(sinfo *sessionInfo, e error) {}
|
||||||
sinfo = c.core.router.searches.newIterSearch(c.nodeID, c.nodeMask, searchCompleted)
|
sinfo = c.core.router.searches.newIterSearch(c.nodeID, c.nodeMask, searchCompleted)
|
||||||
c.core.log.Debugf("%s DHT search started: %p", c.String(), sinfo)
|
c.core.log.Debugf("%s DHT search started: %p", s, sinfo)
|
||||||
// Start the search
|
// Start the search
|
||||||
sinfo.startSearch()
|
sinfo.startSearch()
|
||||||
}
|
}
|
||||||
|
@ -267,7 +268,7 @@ func (c *Conn) _write(msg FlowKeyMessage) error {
|
||||||
case time.Since(c.session.time) > 6*time.Second:
|
case time.Since(c.session.time) > 6*time.Second:
|
||||||
if c.session.time.Before(c.session.pingTime) && time.Since(c.session.pingTime) > 6*time.Second {
|
if c.session.time.Before(c.session.pingTime) && time.Since(c.session.pingTime) > 6*time.Second {
|
||||||
// TODO double check that the above condition is correct
|
// TODO double check that the above condition is correct
|
||||||
c.doSearch()
|
c._doSearch()
|
||||||
} else {
|
} else {
|
||||||
c.session.ping(c.session) // TODO send from self if this becomes an actor
|
c.session.ping(c.session) // TODO send from self if this becomes an actor
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,7 +260,9 @@ func (t *dht) handleRes(res *dhtRes) {
|
||||||
key: res.Key,
|
key: res.Key,
|
||||||
coords: res.Coords,
|
coords: res.Coords,
|
||||||
}
|
}
|
||||||
t.insert(&rinfo)
|
if t.isImportant(&rinfo) {
|
||||||
|
t.insert(&rinfo)
|
||||||
|
}
|
||||||
for _, info := range res.Infos {
|
for _, info := range res.Infos {
|
||||||
if *info.getNodeID() == t.nodeID {
|
if *info.getNodeID() == t.nodeID {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
|
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/util"
|
"github.com/yggdrasil-network/yggdrasil-go/src/util"
|
||||||
|
"golang.org/x/net/proxy"
|
||||||
|
|
||||||
"github.com/Arceliar/phony"
|
"github.com/Arceliar/phony"
|
||||||
)
|
)
|
||||||
|
@ -50,6 +51,7 @@ type linkInterface struct {
|
||||||
name string
|
name string
|
||||||
link *link
|
link *link
|
||||||
peer *peer
|
peer *peer
|
||||||
|
options linkOptions
|
||||||
msgIO linkInterfaceMsgIO
|
msgIO linkInterfaceMsgIO
|
||||||
info linkInfo
|
info linkInfo
|
||||||
incoming bool
|
incoming bool
|
||||||
|
@ -67,6 +69,11 @@ type linkInterface struct {
|
||||||
unstalled bool // False if an idle notification to the switch hasn't been sent because we stalled (or are first starting up)
|
unstalled bool // False if an idle notification to the switch hasn't been sent because we stalled (or are first starting up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type linkOptions struct {
|
||||||
|
pinnedCurve25519Keys map[crypto.BoxPubKey]struct{}
|
||||||
|
pinnedEd25519Keys map[crypto.SigPubKey]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
func (l *link) init(c *Core) error {
|
func (l *link) init(c *Core) error {
|
||||||
l.core = c
|
l.core = c
|
||||||
l.mutex.Lock()
|
l.mutex.Lock()
|
||||||
|
@ -92,13 +99,41 @@ func (l *link) call(uri string, sintf string) error {
|
||||||
return fmt.Errorf("peer %s is not correctly formatted (%s)", uri, err)
|
return fmt.Errorf("peer %s is not correctly formatted (%s)", uri, err)
|
||||||
}
|
}
|
||||||
pathtokens := strings.Split(strings.Trim(u.Path, "/"), "/")
|
pathtokens := strings.Split(strings.Trim(u.Path, "/"), "/")
|
||||||
|
tcpOpts := tcpOptions{}
|
||||||
|
if pubkeys, ok := u.Query()["curve25519"]; ok && len(pubkeys) > 0 {
|
||||||
|
tcpOpts.pinnedCurve25519Keys = make(map[crypto.BoxPubKey]struct{})
|
||||||
|
for _, pubkey := range pubkeys {
|
||||||
|
if boxPub, err := hex.DecodeString(pubkey); err == nil {
|
||||||
|
var boxPubKey crypto.BoxPubKey
|
||||||
|
copy(boxPubKey[:], boxPub)
|
||||||
|
tcpOpts.pinnedCurve25519Keys[boxPubKey] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pubkeys, ok := u.Query()["ed25519"]; ok && len(pubkeys) > 0 {
|
||||||
|
tcpOpts.pinnedEd25519Keys = make(map[crypto.SigPubKey]struct{})
|
||||||
|
for _, pubkey := range pubkeys {
|
||||||
|
if sigPub, err := hex.DecodeString(pubkey); err == nil {
|
||||||
|
var sigPubKey crypto.SigPubKey
|
||||||
|
copy(sigPubKey[:], sigPub)
|
||||||
|
tcpOpts.pinnedEd25519Keys[sigPubKey] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "tcp":
|
case "tcp":
|
||||||
l.tcp.call(u.Host, nil, sintf, nil)
|
l.tcp.call(u.Host, tcpOpts, sintf)
|
||||||
case "socks":
|
case "socks":
|
||||||
l.tcp.call(pathtokens[0], u.Host, sintf, nil)
|
tcpOpts.socksProxyAddr = u.Host
|
||||||
|
if u.User != nil {
|
||||||
|
tcpOpts.socksProxyAuth = &proxy.Auth{}
|
||||||
|
tcpOpts.socksProxyAuth.User = u.User.Username()
|
||||||
|
tcpOpts.socksProxyAuth.Password, _ = u.User.Password()
|
||||||
|
}
|
||||||
|
l.tcp.call(pathtokens[0], tcpOpts, sintf)
|
||||||
case "tls":
|
case "tls":
|
||||||
l.tcp.call(u.Host, nil, sintf, l.tcp.tls.forDialer)
|
tcpOpts.upgrade = l.tcp.tls.forDialer
|
||||||
|
l.tcp.call(u.Host, tcpOpts, sintf)
|
||||||
default:
|
default:
|
||||||
return errors.New("unknown call scheme: " + u.Scheme)
|
return errors.New("unknown call scheme: " + u.Scheme)
|
||||||
}
|
}
|
||||||
|
@ -122,12 +157,13 @@ func (l *link) listen(uri string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *link) create(msgIO linkInterfaceMsgIO, name, linkType, local, remote string, incoming, force bool) (*linkInterface, error) {
|
func (l *link) create(msgIO linkInterfaceMsgIO, name, linkType, local, remote string, incoming, force bool, options linkOptions) (*linkInterface, error) {
|
||||||
// Technically anything unique would work for names, but let's pick something human readable, just for debugging
|
// Technically anything unique would work for names, but let's pick something human readable, just for debugging
|
||||||
intf := linkInterface{
|
intf := linkInterface{
|
||||||
name: name,
|
name: name,
|
||||||
link: l,
|
link: l,
|
||||||
msgIO: msgIO,
|
options: options,
|
||||||
|
msgIO: msgIO,
|
||||||
info: linkInfo{
|
info: linkInfo{
|
||||||
linkType: linkType,
|
linkType: linkType,
|
||||||
local: local,
|
local: local,
|
||||||
|
@ -181,6 +217,20 @@ func (intf *linkInterface) handler() error {
|
||||||
intf.link.core.log.Errorln("Failed to connect to node: " + intf.name + " version: " + fmt.Sprintf("%d.%d", meta.ver, meta.minorVer))
|
intf.link.core.log.Errorln("Failed to connect to node: " + intf.name + " version: " + fmt.Sprintf("%d.%d", meta.ver, meta.minorVer))
|
||||||
return errors.New("failed to connect: wrong version")
|
return errors.New("failed to connect: wrong version")
|
||||||
}
|
}
|
||||||
|
// Check if the remote side matches the keys we expected. This is a bit of a weak
|
||||||
|
// check - in future versions we really should check a signature or something like that.
|
||||||
|
if pinned := intf.options.pinnedCurve25519Keys; pinned != nil {
|
||||||
|
if _, allowed := pinned[meta.box]; !allowed {
|
||||||
|
intf.link.core.log.Errorf("Failed to connect to node: %q sent curve25519 key that does not match pinned keys", intf.name)
|
||||||
|
return fmt.Errorf("failed to connect: host sent curve25519 key that does not match pinned keys")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pinned := intf.options.pinnedEd25519Keys; pinned != nil {
|
||||||
|
if _, allowed := pinned[meta.sig]; !allowed {
|
||||||
|
intf.link.core.log.Errorf("Failed to connect to node: %q sent ed25519 key that does not match pinned keys", intf.name)
|
||||||
|
return fmt.Errorf("failed to connect: host sent ed25519 key that does not match pinned keys")
|
||||||
|
}
|
||||||
|
}
|
||||||
// Check if we're authorized to connect to this key / IP
|
// Check if we're authorized to connect to this key / IP
|
||||||
if intf.incoming && !intf.force && !intf.link.core.peers.isAllowedEncryptionPublicKey(&meta.box) {
|
if intf.incoming && !intf.force && !intf.link.core.peers.isAllowedEncryptionPublicKey(&meta.box) {
|
||||||
intf.link.core.log.Warnf("%s connection from %s forbidden: AllowedEncryptionPublicKeys does not contain key %s",
|
intf.link.core.log.Warnf("%s connection from %s forbidden: AllowedEncryptionPublicKeys does not contain key %s",
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
|
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
|
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/util"
|
"github.com/yggdrasil-network/yggdrasil-go/src/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,6 +58,14 @@ type TcpUpgrade struct {
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type tcpOptions struct {
|
||||||
|
linkOptions
|
||||||
|
upgrade *TcpUpgrade
|
||||||
|
socksProxyAddr string
|
||||||
|
socksProxyAuth *proxy.Auth
|
||||||
|
socksPeerAddr string
|
||||||
|
}
|
||||||
|
|
||||||
func (l *TcpListener) Stop() {
|
func (l *TcpListener) Stop() {
|
||||||
defer func() { recover() }()
|
defer func() { recover() }()
|
||||||
close(l.stop)
|
close(l.stop)
|
||||||
|
@ -220,7 +229,10 @@ func (t *tcp) listener(l *TcpListener, listenaddr string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.waitgroup.Add(1)
|
t.waitgroup.Add(1)
|
||||||
go t.handler(sock, true, nil, l.upgrade)
|
options := tcpOptions{
|
||||||
|
upgrade: l.upgrade,
|
||||||
|
}
|
||||||
|
go t.handler(sock, true, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,12 +250,12 @@ func (t *tcp) startCalling(saddr string) bool {
|
||||||
// If the dial is successful, it launches the handler.
|
// If the dial is successful, it launches the handler.
|
||||||
// When finished, it removes the outgoing call, so reconnection attempts can be made later.
|
// When finished, it removes the outgoing call, so reconnection attempts can be made later.
|
||||||
// This all happens in a separate goroutine that it spawns.
|
// This all happens in a separate goroutine that it spawns.
|
||||||
func (t *tcp) call(saddr string, options interface{}, sintf string, upgrade *TcpUpgrade) {
|
func (t *tcp) call(saddr string, options tcpOptions, sintf string) {
|
||||||
go func() {
|
go func() {
|
||||||
callname := saddr
|
callname := saddr
|
||||||
callproto := "TCP"
|
callproto := "TCP"
|
||||||
if upgrade != nil {
|
if options.upgrade != nil {
|
||||||
callproto = strings.ToUpper(upgrade.name)
|
callproto = strings.ToUpper(options.upgrade.name)
|
||||||
}
|
}
|
||||||
if sintf != "" {
|
if sintf != "" {
|
||||||
callname = fmt.Sprintf("%s/%s/%s", callproto, saddr, sintf)
|
callname = fmt.Sprintf("%s/%s/%s", callproto, saddr, sintf)
|
||||||
|
@ -262,17 +274,16 @@ func (t *tcp) call(saddr string, options interface{}, sintf string, upgrade *Tcp
|
||||||
}()
|
}()
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
var err error
|
var err error
|
||||||
socksaddr, issocks := options.(string)
|
if options.socksProxyAddr != "" {
|
||||||
if issocks {
|
|
||||||
if sintf != "" {
|
if sintf != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dialerdst, er := net.ResolveTCPAddr("tcp", socksaddr)
|
dialerdst, er := net.ResolveTCPAddr("tcp", options.socksProxyAddr)
|
||||||
if er != nil {
|
if er != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var dialer proxy.Dialer
|
var dialer proxy.Dialer
|
||||||
dialer, err = proxy.SOCKS5("tcp", dialerdst.String(), nil, proxy.Direct)
|
dialer, err = proxy.SOCKS5("tcp", dialerdst.String(), options.socksProxyAuth, proxy.Direct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -281,7 +292,8 @@ func (t *tcp) call(saddr string, options interface{}, sintf string, upgrade *Tcp
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.waitgroup.Add(1)
|
t.waitgroup.Add(1)
|
||||||
t.handler(conn, false, saddr, nil)
|
options.socksPeerAddr = conn.RemoteAddr().String()
|
||||||
|
t.handler(conn, false, options)
|
||||||
} else {
|
} else {
|
||||||
dst, err := net.ResolveTCPAddr("tcp", saddr)
|
dst, err := net.ResolveTCPAddr("tcp", saddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -347,19 +359,19 @@ func (t *tcp) call(saddr string, options interface{}, sintf string, upgrade *Tcp
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.waitgroup.Add(1)
|
t.waitgroup.Add(1)
|
||||||
t.handler(conn, false, nil, upgrade)
|
t.handler(conn, false, options)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tcp) handler(sock net.Conn, incoming bool, options interface{}, upgrade *TcpUpgrade) {
|
func (t *tcp) handler(sock net.Conn, incoming bool, options tcpOptions) {
|
||||||
defer t.waitgroup.Done() // Happens after sock.close
|
defer t.waitgroup.Done() // Happens after sock.close
|
||||||
defer sock.Close()
|
defer sock.Close()
|
||||||
t.setExtraOptions(sock)
|
t.setExtraOptions(sock)
|
||||||
var upgraded bool
|
var upgraded bool
|
||||||
if upgrade != nil {
|
if options.upgrade != nil {
|
||||||
var err error
|
var err error
|
||||||
if sock, err = upgrade.upgrade(sock); err != nil {
|
if sock, err = options.upgrade.upgrade(sock); err != nil {
|
||||||
t.link.core.log.Errorln("TCP handler upgrade failed:", err)
|
t.link.core.log.Errorln("TCP handler upgrade failed:", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -368,14 +380,14 @@ func (t *tcp) handler(sock net.Conn, incoming bool, options interface{}, upgrade
|
||||||
stream := stream{}
|
stream := stream{}
|
||||||
stream.init(sock)
|
stream.init(sock)
|
||||||
var name, proto, local, remote string
|
var name, proto, local, remote string
|
||||||
if socksaddr, issocks := options.(string); issocks {
|
if options.socksProxyAddr != "" {
|
||||||
name = "socks://" + sock.RemoteAddr().String() + "/" + socksaddr
|
name = "socks://" + sock.RemoteAddr().String() + "/" + options.socksPeerAddr
|
||||||
proto = "socks"
|
proto = "socks"
|
||||||
local, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
local, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
||||||
remote, _, _ = net.SplitHostPort(socksaddr)
|
remote, _, _ = net.SplitHostPort(options.socksPeerAddr)
|
||||||
} else {
|
} else {
|
||||||
if upgraded {
|
if upgraded {
|
||||||
proto = upgrade.name
|
proto = options.upgrade.name
|
||||||
name = proto + "://" + sock.RemoteAddr().String()
|
name = proto + "://" + sock.RemoteAddr().String()
|
||||||
} else {
|
} else {
|
||||||
proto = "tcp"
|
proto = "tcp"
|
||||||
|
@ -384,8 +396,21 @@ func (t *tcp) handler(sock net.Conn, incoming bool, options interface{}, upgrade
|
||||||
local, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
local, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
||||||
remote, _, _ = net.SplitHostPort(sock.RemoteAddr().String())
|
remote, _, _ = net.SplitHostPort(sock.RemoteAddr().String())
|
||||||
}
|
}
|
||||||
|
localIP := net.ParseIP(local)
|
||||||
|
if localIP = localIP.To16(); localIP != nil {
|
||||||
|
var laddr address.Address
|
||||||
|
var lsubnet address.Subnet
|
||||||
|
copy(laddr[:], localIP)
|
||||||
|
copy(lsubnet[:], localIP)
|
||||||
|
if laddr.IsValid() || lsubnet.IsValid() {
|
||||||
|
// The local address is with the network address/prefix range
|
||||||
|
// This would route ygg over ygg, which we don't want
|
||||||
|
t.link.core.log.Debugln("Dropping ygg-tunneled connection", local, remote)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
force := net.ParseIP(strings.Split(remote, "%")[0]).IsLinkLocalUnicast()
|
force := net.ParseIP(strings.Split(remote, "%")[0]).IsLinkLocalUnicast()
|
||||||
link, err := t.link.core.link.create(&stream, name, proto, local, remote, incoming, force)
|
link, err := t.link.core.link.create(&stream, name, proto, local, remote, incoming, force, options.linkOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.link.core.log.Println(err)
|
t.link.core.log.Println(err)
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue