mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-11-22 22:20:27 +00:00
Fix merge conflict from develop
This commit is contained in:
commit
d37133e311
@ -5,7 +5,7 @@ version: 2.1
|
|||||||
jobs:
|
jobs:
|
||||||
build-linux:
|
build-linux:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.12.7
|
- image: circleci/golang:1.13.3
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
@ -48,6 +48,7 @@ jobs:
|
|||||||
PKGARCH=mipsel sh contrib/deb/generate.sh && mv yggdrasil /tmp/upload/$CINAME-$CIVERSION-linux-mipsel && mv yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-linux-mipsel;
|
PKGARCH=mipsel sh contrib/deb/generate.sh && mv yggdrasil /tmp/upload/$CINAME-$CIVERSION-linux-mipsel && mv yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-linux-mipsel;
|
||||||
PKGARCH=mips sh contrib/deb/generate.sh && mv yggdrasil /tmp/upload/$CINAME-$CIVERSION-linux-mips && mv yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-linux-mips;
|
PKGARCH=mips sh contrib/deb/generate.sh && mv yggdrasil /tmp/upload/$CINAME-$CIVERSION-linux-mips && mv yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-linux-mips;
|
||||||
PKGARCH=armhf sh contrib/deb/generate.sh && mv yggdrasil /tmp/upload/$CINAME-$CIVERSION-linux-armhf && mv yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-linux-armhf;
|
PKGARCH=armhf sh contrib/deb/generate.sh && mv yggdrasil /tmp/upload/$CINAME-$CIVERSION-linux-armhf && mv yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-linux-armhf;
|
||||||
|
PKGARCH=armel sh contrib/deb/generate.sh && mv yggdrasil /tmp/upload/$CINAME-$CIVERSION-linux-armel && mv yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-linux-armel;
|
||||||
PKGARCH=arm64 sh contrib/deb/generate.sh && mv yggdrasil /tmp/upload/$CINAME-$CIVERSION-linux-arm64 && mv yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-linux-arm64;
|
PKGARCH=arm64 sh contrib/deb/generate.sh && mv yggdrasil /tmp/upload/$CINAME-$CIVERSION-linux-arm64 && mv yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-linux-arm64;
|
||||||
mv *.deb /tmp/upload/
|
mv *.deb /tmp/upload/
|
||||||
|
|
||||||
@ -105,11 +106,11 @@ jobs:
|
|||||||
echo -e "Host *\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
echo -e "Host *\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Install Go 1.12.7
|
name: Install Go 1.13.3
|
||||||
command: |
|
command: |
|
||||||
cd /tmp
|
cd /tmp
|
||||||
curl -LO https://dl.google.com/go/go1.12.7.darwin-amd64.pkg
|
curl -LO https://dl.google.com/go/go1.13.3.darwin-amd64.pkg
|
||||||
sudo installer -pkg /tmp/go1.12.7.darwin-amd64.pkg -target /
|
sudo installer -pkg /tmp/go1.13.3.darwin-amd64.pkg -target /
|
||||||
|
|
||||||
#- run:
|
#- run:
|
||||||
# name: Install Gomobile
|
# name: Install Gomobile
|
||||||
@ -145,7 +146,7 @@ jobs:
|
|||||||
|
|
||||||
build-other:
|
build-other:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.12.7
|
- image: circleci/golang:1.13.3
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
|
@ -49,7 +49,7 @@ You may also find other platform-specific wrappers, scripts or tools in the
|
|||||||
If you want to build from source, as opposed to installing one of the pre-built
|
If you want to build from source, as opposed to installing one of the pre-built
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
1. Install [Go](https://golang.org) (requires Go 1.12 or later)
|
1. Install [Go](https://golang.org) (requires Go 1.13 or later)
|
||||||
2. Clone this repository
|
2. Clone this repository
|
||||||
2. Run `./build`
|
2. Run `./build`
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ ProtectHome=true
|
|||||||
ProtectSystem=true
|
ProtectSystem=true
|
||||||
SyslogIdentifier=yggdrasil
|
SyslogIdentifier=yggdrasil
|
||||||
CapabilityBoundSet=CAP_NET_ADMIN
|
CapabilityBoundSet=CAP_NET_ADMIN
|
||||||
ExecStartPre=+/sbin/modprobe tun
|
ExecStartPre=+-/sbin/modprobe tun
|
||||||
ExecStartPre=/bin/sh -ec "if ! test -s /etc/yggdrasil.conf; \
|
ExecStartPre=/bin/sh -ec "if ! test -s /etc/yggdrasil.conf; \
|
||||||
then umask 077; \
|
then umask 077; \
|
||||||
yggdrasil -genconf > /etc/yggdrasil.conf; \
|
yggdrasil -genconf > /etc/yggdrasil.conf; \
|
||||||
|
15
go.mod
15
go.mod
@ -1,19 +1,18 @@
|
|||||||
module github.com/yggdrasil-network/yggdrasil-go
|
module github.com/yggdrasil-network/yggdrasil-go
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Arceliar/phony v0.0.0-20191005181740-21679e75e3f0
|
github.com/Arceliar/phony v0.0.0-20191006174943-d0c68492aca0
|
||||||
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.0+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/songgao/packets v0.0.0-20160404182456-549a10cd4091
|
github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091
|
||||||
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b // indirect
|
|
||||||
github.com/vishvananda/netlink v1.0.0
|
|
||||||
github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f // indirect
|
|
||||||
github.com/yggdrasil-network/water v0.0.0-20190812103929-c83fe40250f8
|
github.com/yggdrasil-network/water v0.0.0-20190812103929-c83fe40250f8
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7
|
golang.org/x/net v0.0.0-20191021144547-ec77196f6094
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a
|
golang.org/x/sys v0.0.0-20191024073052-e66fe6eb8e0c
|
||||||
golang.org/x/text v0.3.2
|
golang.org/x/text v0.3.2
|
||||||
)
|
)
|
||||||
|
29
go.sum
29
go.sum
@ -1,35 +1,30 @@
|
|||||||
github.com/Arceliar/phony v0.0.0-20191005181740-21679e75e3f0 h1:IOFsvAMFkgnKfSQHxXTeqb1+ODFeR5px1HCHU86KF30=
|
github.com/Arceliar/phony v0.0.0-20191006174943-d0c68492aca0 h1:p3puK8Sl2xK+2FnnIvY/C0N1aqJo2kbEsdAzU+Tnv48=
|
||||||
github.com/Arceliar/phony v0.0.0-20191005181740-21679e75e3f0/go.mod h1:6Lkn+/zJilRMsKmbmG1RPoamiArC6HS73xbwRyp3UyI=
|
github.com/Arceliar/phony v0.0.0-20191006174943-d0c68492aca0/go.mod h1:6Lkn+/zJilRMsKmbmG1RPoamiArC6HS73xbwRyp3UyI=
|
||||||
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8 h1:WD8iJ37bRNwvETMfVTusVSAi0WdXTpfNVGY2aHycNKY=
|
github.com/gologme/log v0.0.0-20181207131047-4e5d8ccb38e8 h1:WD8iJ37bRNwvETMfVTusVSAi0WdXTpfNVGY2aHycNKY=
|
||||||
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.0+incompatible h1:mc8olpIxqF8mrEx6ePJOD6wCCOkX7+JcrKgINcJES10=
|
||||||
github.com/hjson/hjson-go v3.0.1-0.20190209023717-9147687966d9+incompatible/go.mod h1:qsetwF8NlsTsOTwZTApNlTCerV+b2GjYRRcIk4JMFio=
|
github.com/hjson/hjson-go v3.0.0+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/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091 h1:1zN6ImoqhSJhN8hGXFaJlSC8msLmIbX8bFqOfWLKw0w=
|
github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091 h1:1zN6ImoqhSJhN8hGXFaJlSC8msLmIbX8bFqOfWLKw0w=
|
||||||
github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091/go.mod h1:N20Z5Y8oye9a7HmytmZ+tr8Q2vlP0tAHP13kTHzwvQY=
|
github.com/songgao/packets v0.0.0-20160404182456-549a10cd4091/go.mod h1:N20Z5Y8oye9a7HmytmZ+tr8Q2vlP0tAHP13kTHzwvQY=
|
||||||
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b h1:+y4hCMc/WKsDbAPsOQZgBSaSZ26uh2afyaWeVg/3s/c=
|
|
||||||
github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
|
|
||||||
github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=
|
|
||||||
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/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
|
||||||
github.com/yggdrasil-network/water v0.0.0-20190812103929-c83fe40250f8 h1:YY9Pg2BEp0jeUVU60svTOaDr+fs1ySC9RbdC1Qc6wOw=
|
github.com/yggdrasil-network/water v0.0.0-20190812103929-c83fe40250f8 h1:YY9Pg2BEp0jeUVU60svTOaDr+fs1ySC9RbdC1Qc6wOw=
|
||||||
github.com/yggdrasil-network/water v0.0.0-20190812103929-c83fe40250f8/go.mod h1:R0SBCsugm+Sf1katgTb2t7GXMm+nRIv43tM4VDZbaOs=
|
github.com/yggdrasil-network/water v0.0.0-20190812103929-c83fe40250f8/go.mod h1:R0SBCsugm+Sf1katgTb2t7GXMm+nRIv43tM4VDZbaOs=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
|
||||||
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/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20191021144547-ec77196f6094 h1:5O4U9trLjNpuhpynaDsqwCk+Tw6seqJz1EbqbnzHrc8=
|
||||||
|
golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191024073052-e66fe6eb8e0c h1:usSYQsGq37L8RjJc5eznJ/AbwBxn3QFFEVkWNPAejLs=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/sys v0.0.0-20191024073052-e66fe6eb8e0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Arceliar/phony"
|
"github.com/Arceliar/phony"
|
||||||
@ -28,7 +29,7 @@ type Multicast struct {
|
|||||||
groupAddr string
|
groupAddr string
|
||||||
listeners map[string]*listenerInfo
|
listeners map[string]*listenerInfo
|
||||||
listenPort uint16
|
listenPort uint16
|
||||||
isOpen bool
|
isOpen atomic.Value // bool
|
||||||
announcer *time.Timer
|
announcer *time.Timer
|
||||||
platformhandler *time.Timer
|
platformhandler *time.Timer
|
||||||
}
|
}
|
||||||
@ -48,6 +49,7 @@ func (m *Multicast) Init(core *yggdrasil.Core, state *config.NodeState, log *log
|
|||||||
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"
|
||||||
|
m.isOpen.Store(false)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,12 +57,22 @@ func (m *Multicast) Init(core *yggdrasil.Core, state *config.NodeState, log *log
|
|||||||
// listen for multicast beacons from other hosts and will advertise multicast
|
// listen for multicast beacons from other hosts and will advertise multicast
|
||||||
// beacons out to the network.
|
// beacons out to the network.
|
||||||
func (m *Multicast) Start() error {
|
func (m *Multicast) Start() error {
|
||||||
if len(m.config.GetCurrent().MulticastInterfaces) == 0 {
|
var err error
|
||||||
return fmt.Errorf("no MulticastInterfaces configured")
|
phony.Block(m, func() {
|
||||||
|
err = m._start()
|
||||||
|
})
|
||||||
|
m.log.Debugln("Started multicast module")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Multicast) _start() error {
|
||||||
|
if m.IsStarted() {
|
||||||
|
return fmt.Errorf("multicast module is already started")
|
||||||
|
}
|
||||||
|
if len(m.config.GetCurrent().MulticastInterfaces) == 0 {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
m.log.Infoln("Starting multicast module")
|
m.log.Infoln("Starting multicast module")
|
||||||
|
|
||||||
addr, err := net.ResolveUDPAddr("udp", m.groupAddr)
|
addr, err := net.ResolveUDPAddr("udp", m.groupAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -78,7 +90,7 @@ func (m *Multicast) Start() error {
|
|||||||
// Windows can't set this flag, so we need to handle it in other ways
|
// Windows can't set this flag, so we need to handle it in other ways
|
||||||
}
|
}
|
||||||
|
|
||||||
m.isOpen = true
|
m.isOpen.Store(true)
|
||||||
go m.listen()
|
go m.listen()
|
||||||
m.Act(m, m.multicastStarted)
|
m.Act(m, m.multicastStarted)
|
||||||
m.Act(m, m.announce)
|
m.Act(m, m.announce)
|
||||||
@ -88,13 +100,25 @@ func (m *Multicast) Start() error {
|
|||||||
|
|
||||||
// IsStarted returns true if the module has been started.
|
// IsStarted returns true if the module has been started.
|
||||||
func (m *Multicast) IsStarted() bool {
|
func (m *Multicast) IsStarted() bool {
|
||||||
return m.isOpen
|
if m.isOpen.Load() == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return m.isOpen.Load().(bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop is not implemented for multicast yet.
|
// Stop stops the multicast module.
|
||||||
func (m *Multicast) Stop() error {
|
func (m *Multicast) Stop() error {
|
||||||
|
var err error
|
||||||
|
phony.Block(m, func() {
|
||||||
|
err = m._stop()
|
||||||
|
})
|
||||||
|
m.log.Debugln("Stopped multicast module")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Multicast) _stop() error {
|
||||||
m.log.Infoln("Stopping multicast module")
|
m.log.Infoln("Stopping multicast module")
|
||||||
m.isOpen = false
|
m.isOpen.Store(false)
|
||||||
if m.announcer != nil {
|
if m.announcer != nil {
|
||||||
m.announcer.Stop()
|
m.announcer.Stop()
|
||||||
}
|
}
|
||||||
@ -113,17 +137,22 @@ func (m *Multicast) UpdateConfig(config *config.NodeConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Multicast) _updateConfig(config *config.NodeConfig) {
|
func (m *Multicast) _updateConfig(config *config.NodeConfig) {
|
||||||
m.log.Debugln("Reloading multicast configuration...")
|
m.log.Infoln("Reloading multicast configuration...")
|
||||||
if m.IsStarted() {
|
if m.IsStarted() {
|
||||||
if len(config.MulticastInterfaces) == 0 || config.LinkLocalTCPPort != m.listenPort {
|
if len(config.MulticastInterfaces) == 0 || config.LinkLocalTCPPort != m.listenPort {
|
||||||
m.Stop()
|
if err := m._stop(); err != nil {
|
||||||
|
m.log.Errorln("Error stopping multicast module:", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.config.Replace(*config)
|
m.config.Replace(*config)
|
||||||
m.listenPort = config.LinkLocalTCPPort
|
m.listenPort = config.LinkLocalTCPPort
|
||||||
if !m.IsStarted() && len(config.MulticastInterfaces) > 0 {
|
if !m.IsStarted() && len(config.MulticastInterfaces) > 0 {
|
||||||
m.Start()
|
if err := m._start(); err != nil {
|
||||||
|
m.log.Errorln("Error starting multicast module:", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
m.log.Debugln("Reloaded multicast configuration successfully")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInterfaces returns the currently known/enabled multicast interfaces. It is
|
// GetInterfaces returns the currently known/enabled multicast interfaces. It is
|
||||||
@ -296,7 +325,7 @@ func (m *Multicast) listen() {
|
|||||||
for {
|
for {
|
||||||
nBytes, rcm, fromAddr, err := m.sock.ReadFrom(bs)
|
nBytes, rcm, fromAddr, err := m.sock.ReadFrom(bs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !m.isOpen {
|
if !m.IsStarted() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -280,7 +280,14 @@ func (c *Core) ConnDialer() (*Dialer, error) {
|
|||||||
// "Listen" configuration item, e.g.
|
// "Listen" configuration item, e.g.
|
||||||
// tcp://a.b.c.d:e
|
// tcp://a.b.c.d:e
|
||||||
func (c *Core) ListenTCP(uri string) (*TcpListener, error) {
|
func (c *Core) ListenTCP(uri string) (*TcpListener, error) {
|
||||||
return c.link.tcp.listen(uri)
|
return c.link.tcp.listen(uri, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListenTLS starts a new TLS listener. The input URI should match that of the
|
||||||
|
// "Listen" configuration item, e.g.
|
||||||
|
// tls://a.b.c.d:e
|
||||||
|
func (c *Core) ListenTLS(uri string) (*TcpListener, error) {
|
||||||
|
return c.link.tcp.listen(uri, c.link.tcp.tls.forListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeID gets the node ID. This is derived from your router encryption keys.
|
// NodeID gets the node ID. This is derived from your router encryption keys.
|
||||||
|
@ -93,9 +93,11 @@ func (l *link) call(uri string, sintf string) error {
|
|||||||
pathtokens := strings.Split(strings.Trim(u.Path, "/"), "/")
|
pathtokens := strings.Split(strings.Trim(u.Path, "/"), "/")
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "tcp":
|
case "tcp":
|
||||||
l.tcp.call(u.Host, nil, sintf)
|
l.tcp.call(u.Host, nil, sintf, nil)
|
||||||
case "socks":
|
case "socks":
|
||||||
l.tcp.call(pathtokens[0], u.Host, sintf)
|
l.tcp.call(pathtokens[0], u.Host, sintf, nil)
|
||||||
|
case "tls":
|
||||||
|
l.tcp.call(u.Host, nil, sintf, l.tcp.tls.forDialer)
|
||||||
default:
|
default:
|
||||||
return errors.New("unknown call scheme: " + u.Scheme)
|
return errors.New("unknown call scheme: " + u.Scheme)
|
||||||
}
|
}
|
||||||
@ -109,7 +111,10 @@ func (l *link) listen(uri string) error {
|
|||||||
}
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "tcp":
|
case "tcp":
|
||||||
_, err := l.tcp.listen(u.Host)
|
_, err := l.tcp.listen(u.Host, nil)
|
||||||
|
return err
|
||||||
|
case "tls":
|
||||||
|
_, err := l.tcp.listen(u.Host, l.tcp.tls.forListener)
|
||||||
return err
|
return err
|
||||||
default:
|
default:
|
||||||
return errors.New("unknown listen scheme: " + u.Scheme)
|
return errors.New("unknown listen scheme: " + u.Scheme)
|
||||||
|
@ -39,6 +39,7 @@ type tcp struct {
|
|||||||
listeners map[string]*TcpListener
|
listeners map[string]*TcpListener
|
||||||
calls map[string]struct{}
|
calls map[string]struct{}
|
||||||
conns map[linkInfo](chan struct{})
|
conns map[linkInfo](chan struct{})
|
||||||
|
tls tcptls
|
||||||
}
|
}
|
||||||
|
|
||||||
// TcpListener is a stoppable TCP listener interface. These are typically
|
// TcpListener is a stoppable TCP listener interface. These are typically
|
||||||
@ -47,9 +48,15 @@ type tcp struct {
|
|||||||
// multicast interfaces.
|
// multicast interfaces.
|
||||||
type TcpListener struct {
|
type TcpListener struct {
|
||||||
Listener net.Listener
|
Listener net.Listener
|
||||||
|
upgrade *TcpUpgrade
|
||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TcpUpgrade struct {
|
||||||
|
upgrade func(c net.Conn) (net.Conn, error)
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
func (l *TcpListener) Stop() {
|
func (l *TcpListener) Stop() {
|
||||||
defer func() { recover() }()
|
defer func() { recover() }()
|
||||||
close(l.stop)
|
close(l.stop)
|
||||||
@ -81,6 +88,7 @@ func (t *tcp) getAddr() *net.TCPAddr {
|
|||||||
// Initializes the struct.
|
// Initializes the struct.
|
||||||
func (t *tcp) init(l *link) error {
|
func (t *tcp) init(l *link) error {
|
||||||
t.link = l
|
t.link = l
|
||||||
|
t.tls.init(t)
|
||||||
t.mutex.Lock()
|
t.mutex.Lock()
|
||||||
t.calls = make(map[string]struct{})
|
t.calls = make(map[string]struct{})
|
||||||
t.conns = make(map[linkInfo](chan struct{}))
|
t.conns = make(map[linkInfo](chan struct{}))
|
||||||
@ -90,13 +98,18 @@ func (t *tcp) init(l *link) error {
|
|||||||
t.link.core.config.Mutex.RLock()
|
t.link.core.config.Mutex.RLock()
|
||||||
defer t.link.core.config.Mutex.RUnlock()
|
defer t.link.core.config.Mutex.RUnlock()
|
||||||
for _, listenaddr := range t.link.core.config.Current.Listen {
|
for _, listenaddr := range t.link.core.config.Current.Listen {
|
||||||
if listenaddr[:6] != "tcp://" {
|
switch listenaddr[:6] {
|
||||||
t.link.core.log.Errorln("Failed to add listener: listener", listenaddr, "is not correctly formatted, ignoring")
|
case "tcp://":
|
||||||
continue
|
if _, err := t.listen(listenaddr[6:], nil); err != nil {
|
||||||
}
|
|
||||||
if _, err := t.listen(listenaddr[6:]); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case "tls://":
|
||||||
|
if _, err := t.listen(listenaddr[6:], t.tls.forListener); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.link.core.log.Errorln("Failed to add listener: listener", listenaddr, "is not correctly formatted, ignoring")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -119,18 +132,21 @@ func (t *tcp) reconfigure() {
|
|||||||
t.link.core.config.Mutex.RUnlock()
|
t.link.core.config.Mutex.RUnlock()
|
||||||
if len(added) > 0 || len(deleted) > 0 {
|
if len(added) > 0 || len(deleted) > 0 {
|
||||||
for _, a := range added {
|
for _, a := range added {
|
||||||
if a[:6] != "tcp://" {
|
switch a[:6] {
|
||||||
t.link.core.log.Errorln("Failed to add listener: listener", a, "is not correctly formatted, ignoring")
|
case "tcp://":
|
||||||
continue
|
if _, err := t.listen(a[6:], nil); err != nil {
|
||||||
}
|
|
||||||
if _, err := t.listen(a[6:]); err != nil {
|
|
||||||
t.link.core.log.Errorln("Error adding TCP", a[6:], "listener:", err)
|
t.link.core.log.Errorln("Error adding TCP", a[6:], "listener:", err)
|
||||||
} else {
|
}
|
||||||
t.link.core.log.Infoln("Started TCP listener:", a[6:])
|
case "tls://":
|
||||||
|
if _, err := t.listen(a[6:], t.tls.forListener); err != nil {
|
||||||
|
t.link.core.log.Errorln("Error adding TLS", a[6:], "listener:", err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.link.core.log.Errorln("Failed to add listener: listener", a, "is not correctly formatted, ignoring")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, d := range deleted {
|
for _, d := range deleted {
|
||||||
if d[:6] != "tcp://" {
|
if d[:6] != "tcp://" && d[:6] != "tls://" {
|
||||||
t.link.core.log.Errorln("Failed to delete listener: listener", d, "is not correctly formatted, ignoring")
|
t.link.core.log.Errorln("Failed to delete listener: listener", d, "is not correctly formatted, ignoring")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -146,7 +162,7 @@ func (t *tcp) reconfigure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tcp) listen(listenaddr string) (*TcpListener, error) {
|
func (t *tcp) listen(listenaddr string, upgrade *TcpUpgrade) (*TcpListener, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@ -157,6 +173,7 @@ func (t *tcp) listen(listenaddr string) (*TcpListener, error) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
l := TcpListener{
|
l := TcpListener{
|
||||||
Listener: listener,
|
Listener: listener,
|
||||||
|
upgrade: upgrade,
|
||||||
stop: make(chan struct{}),
|
stop: make(chan struct{}),
|
||||||
}
|
}
|
||||||
t.waitgroup.Add(1)
|
t.waitgroup.Add(1)
|
||||||
@ -204,7 +221,7 @@ func (t *tcp) listener(l *TcpListener, listenaddr string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.waitgroup.Add(1)
|
t.waitgroup.Add(1)
|
||||||
go t.handler(sock, true, nil)
|
go t.handler(sock, true, nil, l.upgrade)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,11 +239,15 @@ 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) {
|
func (t *tcp) call(saddr string, options interface{}, sintf string, upgrade *TcpUpgrade) {
|
||||||
go func() {
|
go func() {
|
||||||
callname := saddr
|
callname := saddr
|
||||||
|
callproto := "TCP"
|
||||||
|
if upgrade != nil {
|
||||||
|
callproto = strings.ToUpper(upgrade.name)
|
||||||
|
}
|
||||||
if sintf != "" {
|
if sintf != "" {
|
||||||
callname = fmt.Sprintf("%s/%s", saddr, sintf)
|
callname = fmt.Sprintf("%s/%s/%s", callproto, saddr, sintf)
|
||||||
}
|
}
|
||||||
if !t.startCalling(callname) {
|
if !t.startCalling(callname) {
|
||||||
return
|
return
|
||||||
@ -261,7 +282,7 @@ func (t *tcp) call(saddr string, options interface{}, sintf string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.waitgroup.Add(1)
|
t.waitgroup.Add(1)
|
||||||
t.handler(conn, false, saddr)
|
t.handler(conn, false, saddr, nil)
|
||||||
} else {
|
} else {
|
||||||
dst, err := net.ResolveTCPAddr("tcp", saddr)
|
dst, err := net.ResolveTCPAddr("tcp", saddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -322,19 +343,29 @@ func (t *tcp) call(saddr string, options interface{}, sintf string) {
|
|||||||
}
|
}
|
||||||
conn, err = dialer.Dial("tcp", dst.String())
|
conn, err = dialer.Dial("tcp", dst.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.link.core.log.Debugln("Failed to dial TCP:", err)
|
t.link.core.log.Debugf("Failed to dial %s: %s", callproto, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t.waitgroup.Add(1)
|
t.waitgroup.Add(1)
|
||||||
t.handler(conn, false, nil)
|
t.handler(conn, false, nil, upgrade)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tcp) handler(sock net.Conn, incoming bool, options interface{}) {
|
func (t *tcp) handler(sock net.Conn, incoming bool, options interface{}, upgrade *TcpUpgrade) {
|
||||||
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
|
||||||
|
if upgrade != nil {
|
||||||
|
var err error
|
||||||
|
if sock, err = upgrade.upgrade(sock); err != nil {
|
||||||
|
t.link.core.log.Errorln("TCP handler upgrade failed:", err)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
upgraded = true
|
||||||
|
}
|
||||||
|
}
|
||||||
stream := stream{}
|
stream := stream{}
|
||||||
stream.init(sock)
|
stream.init(sock)
|
||||||
var name, proto, local, remote string
|
var name, proto, local, remote string
|
||||||
@ -344,8 +375,13 @@ func (t *tcp) handler(sock net.Conn, incoming bool, options interface{}) {
|
|||||||
local, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
local, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
||||||
remote, _, _ = net.SplitHostPort(socksaddr)
|
remote, _, _ = net.SplitHostPort(socksaddr)
|
||||||
} else {
|
} else {
|
||||||
name = "tcp://" + sock.RemoteAddr().String()
|
if upgraded {
|
||||||
|
proto = upgrade.name
|
||||||
|
name = proto + "://" + sock.RemoteAddr().String()
|
||||||
|
} else {
|
||||||
proto = "tcp"
|
proto = "tcp"
|
||||||
|
name = proto + "://" + sock.RemoteAddr().String()
|
||||||
|
}
|
||||||
local, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
local, _, _ = net.SplitHostPort(sock.LocalAddr().String())
|
||||||
remote, _, _ = net.SplitHostPort(sock.RemoteAddr().String())
|
remote, _, _ = net.SplitHostPort(sock.RemoteAddr().String())
|
||||||
}
|
}
|
||||||
|
93
src/yggdrasil/tls.go
Normal file
93
src/yggdrasil/tls.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package yggdrasil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/pem"
|
||||||
|
"log"
|
||||||
|
"math/big"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type tcptls struct {
|
||||||
|
tcp *tcp
|
||||||
|
config *tls.Config
|
||||||
|
forDialer *TcpUpgrade
|
||||||
|
forListener *TcpUpgrade
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tcptls) init(tcp *tcp) {
|
||||||
|
t.tcp = tcp
|
||||||
|
t.forDialer = &TcpUpgrade{
|
||||||
|
upgrade: t.upgradeDialer,
|
||||||
|
name: "tls",
|
||||||
|
}
|
||||||
|
t.forListener = &TcpUpgrade{
|
||||||
|
upgrade: t.upgradeListener,
|
||||||
|
name: "tls",
|
||||||
|
}
|
||||||
|
|
||||||
|
edpriv := make(ed25519.PrivateKey, ed25519.PrivateKeySize)
|
||||||
|
copy(edpriv[:], tcp.link.core.sigPriv[:])
|
||||||
|
|
||||||
|
certBuf := &bytes.Buffer{}
|
||||||
|
|
||||||
|
// TODO: because NotAfter is finite, we should add some mechanism to regenerate the certificate and restart the listeners periodically for nodes with very high uptimes. Perhaps regenerate certs and restart listeners every few months or so.
|
||||||
|
pubtemp := x509.Certificate{
|
||||||
|
SerialNumber: big.NewInt(1),
|
||||||
|
Subject: pkix.Name{
|
||||||
|
CommonName: hex.EncodeToString(tcp.link.core.sigPub[:]),
|
||||||
|
},
|
||||||
|
NotBefore: time.Now(),
|
||||||
|
NotAfter: time.Now().Add(time.Hour * 24 * 365),
|
||||||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
derbytes, err := x509.CreateCertificate(rand.Reader, &pubtemp, &pubtemp, edpriv.Public(), edpriv)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to create certificate: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pem.Encode(certBuf, &pem.Block{Type: "CERTIFICATE", Bytes: derbytes}); err != nil {
|
||||||
|
panic("failed to encode certificate into PEM")
|
||||||
|
}
|
||||||
|
|
||||||
|
cpool := x509.NewCertPool()
|
||||||
|
cpool.AppendCertsFromPEM(derbytes)
|
||||||
|
|
||||||
|
t.config = &tls.Config{
|
||||||
|
RootCAs: cpool,
|
||||||
|
Certificates: []tls.Certificate{
|
||||||
|
{
|
||||||
|
Certificate: [][]byte{derbytes},
|
||||||
|
PrivateKey: edpriv,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
MinVersion: tls.VersionTLS13,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tcptls) upgradeListener(c net.Conn) (net.Conn, error) {
|
||||||
|
conn := tls.Server(c, t.config)
|
||||||
|
if err := conn.Handshake(); err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tcptls) upgradeDialer(c net.Conn) (net.Conn, error) {
|
||||||
|
conn := tls.Client(c, t.config)
|
||||||
|
if err := conn.Handshake(); err != nil {
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
return conn, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user