Merge branch 'future' into neilalexander/mdns

This commit is contained in:
Neil Alexander 2021-05-31 18:36:23 +01:00
commit 2ec3c4a0d5
84 changed files with 2557 additions and 11161 deletions

View file

@ -13,119 +13,66 @@ This only matters if it's high enough to make you the root of the tree.
package main
import (
"crypto/ed25519"
"encoding/hex"
"flag"
"fmt"
"net"
"runtime"
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
)
var doSig = flag.Bool("sig", false, "generate new signing keys instead")
type keySet struct {
priv []byte
pub []byte
id []byte
ip string
priv ed25519.PrivateKey
pub ed25519.PublicKey
}
func main() {
threads := runtime.GOMAXPROCS(0)
var threadChannels []chan []byte
var currentBest []byte
var currentBest ed25519.PublicKey
newKeys := make(chan keySet, threads)
flag.Parse()
for i := 0; i < threads; i++ {
threadChannels = append(threadChannels, make(chan []byte, threads))
switch {
case *doSig:
go doSigKeys(newKeys, threadChannels[i])
default:
go doBoxKeys(newKeys, threadChannels[i])
}
go doKeys(newKeys)
}
for {
newKey := <-newKeys
if isBetter(currentBest[:], newKey.id[:]) || len(currentBest) == 0 {
currentBest = newKey.id
for _, channel := range threadChannels {
select {
case channel <- newKey.id:
}
}
fmt.Println("--------------------------------------------------------------------------------")
switch {
case *doSig:
fmt.Println("sigPriv:", hex.EncodeToString(newKey.priv[:]))
fmt.Println("sigPub:", hex.EncodeToString(newKey.pub[:]))
fmt.Println("TreeID:", hex.EncodeToString(newKey.id[:]))
default:
fmt.Println("boxPriv:", hex.EncodeToString(newKey.priv[:]))
fmt.Println("boxPub:", hex.EncodeToString(newKey.pub[:]))
fmt.Println("NodeID:", hex.EncodeToString(newKey.id[:]))
fmt.Println("IP:", newKey.ip)
}
if isBetter(currentBest, newKey.pub) || len(currentBest) == 0 {
currentBest = newKey.pub
fmt.Println("-----")
fmt.Println("Priv:", hex.EncodeToString(newKey.priv))
fmt.Println("Pub:", hex.EncodeToString(newKey.pub))
addr := address.AddrForKey(newKey.pub)
fmt.Println("IP:", net.IP(addr[:]).String())
}
}
}
func isBetter(oldID, newID []byte) bool {
for idx := range oldID {
if newID[idx] > oldID[idx] {
func isBetter(oldPub, newPub ed25519.PublicKey) bool {
for idx := range oldPub {
if newPub[idx] < oldPub[idx] {
return true
}
if newID[idx] < oldID[idx] {
return false
if newPub[idx] > oldPub[idx] {
break
}
}
return false
}
func doBoxKeys(out chan<- keySet, in <-chan []byte) {
var bestID crypto.NodeID
for {
select {
case newBestID := <-in:
if isBetter(bestID[:], newBestID) {
copy(bestID[:], newBestID)
}
default:
pub, priv := crypto.NewBoxKeys()
id := crypto.GetNodeID(pub)
if !isBetter(bestID[:], id[:]) {
continue
}
bestID = *id
ip := net.IP(address.AddrForNodeID(id)[:]).String()
out <- keySet{priv[:], pub[:], id[:], ip}
}
}
}
func doSigKeys(out chan<- keySet, in <-chan []byte) {
var bestID crypto.TreeID
for idx := range bestID {
bestID[idx] = 0
func doKeys(out chan<- keySet) {
bestKey := make(ed25519.PublicKey, ed25519.PublicKeySize)
for idx := range bestKey {
bestKey[idx] = 0xff
}
for {
select {
case newBestID := <-in:
if isBetter(bestID[:], newBestID) {
copy(bestID[:], newBestID)
}
default:
pub, priv, err := ed25519.GenerateKey(nil)
if err != nil {
panic(err)
}
pub, priv := crypto.NewSigKeys()
id := crypto.GetTreeID(pub)
if !isBetter(bestID[:], id[:]) {
if !isBetter(bestKey, pub) {
continue
}
bestID = *id
out <- keySet{priv[:], pub[:], id[:], ""}
bestKey = pub
out <- keySet{priv, pub}
}
}

View file

@ -2,6 +2,7 @@ package main
import (
"bytes"
"crypto/ed25519"
"encoding/hex"
"encoding/json"
"flag"
@ -24,17 +25,21 @@ import (
"github.com/yggdrasil-network/yggdrasil-go/src/address"
"github.com/yggdrasil-network/yggdrasil-go/src/admin"
"github.com/yggdrasil-network/yggdrasil-go/src/config"
<<<<<<< HEAD
"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
"github.com/yggdrasil-network/yggdrasil-go/src/mdns"
=======
"github.com/yggdrasil-network/yggdrasil-go/src/core"
>>>>>>> future
"github.com/yggdrasil-network/yggdrasil-go/src/module"
"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
"github.com/yggdrasil-network/yggdrasil-go/src/tuntap"
"github.com/yggdrasil-network/yggdrasil-go/src/version"
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
)
type node struct {
core yggdrasil.Core
core core.Core
state *config.NodeState
tuntap module.Module // tuntap.TunAdapter
multicast module.Module // multicast.Multicast
@ -62,8 +67,8 @@ func readConfig(useconf *bool, useconffile *string, normaliseconf *bool) *config
// throwing everywhere when it's converting things into UTF-16 for the hell
// of it - remove it and decode back down into UTF-8. This is necessary
// because hjson doesn't know what to do with UTF-16 and will panic
if bytes.Compare(conf[0:2], []byte{0xFF, 0xFE}) == 0 ||
bytes.Compare(conf[0:2], []byte{0xFE, 0xFF}) == 0 {
if bytes.Equal(conf[0:2], []byte{0xFF, 0xFE}) ||
bytes.Equal(conf[0:2], []byte{0xFE, 0xFF}) {
utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM)
decoder := utf.NewDecoder()
conf, err = decoder.Bytes(conf)
@ -221,25 +226,23 @@ func main() {
return
}
// Have we been asked for the node address yet? If so, print it and then stop.
getNodeID := func() *crypto.NodeID {
if pubkey, err := hex.DecodeString(cfg.EncryptionPublicKey); err == nil {
var box crypto.BoxPubKey
copy(box[:], pubkey[:])
return crypto.GetNodeID(&box)
getNodeKey := func() ed25519.PublicKey {
if pubkey, err := hex.DecodeString(cfg.PublicKey); err == nil {
return ed25519.PublicKey(pubkey)
}
return nil
}
switch {
case *getaddr:
if nodeid := getNodeID(); nodeid != nil {
addr := *address.AddrForNodeID(nodeid)
if key := getNodeKey(); key != nil {
addr := address.AddrForKey(key)
ip := net.IP(addr[:])
fmt.Println(ip.String())
}
return
case *getsnet:
if nodeid := getNodeID(); nodeid != nil {
snet := *address.SubnetForNodeID(nodeid)
if key := getNodeKey(); key != nil {
snet := address.SubnetForKey(key)
ipnet := net.IPNet{
IP: append(snet[:], 0, 0, 0, 0, 0, 0, 0, 0),
Mask: net.CIDRMask(len(snet)*8, 128),
@ -281,12 +284,12 @@ func main() {
panic(err)
}
// Register the session firewall gatekeeper function
n.core.SetSessionGatekeeper(n.sessionFirewall)
// Allocate our modules
n.admin = &admin.AdminSocket{}
n.multicast = &multicast.Multicast{}
n.mdns = &mdns.MDNS{}
n.tuntap = &tuntap.TunAdapter{}
n.tuntap.(*tuntap.TunAdapter).SetSessionGatekeeper(n.sessionFirewall)
// Start the admin socket
n.admin.Init(&n.core, n.state, logger, nil)
if err := n.admin.Start(); err != nil {
@ -306,19 +309,11 @@ func main() {
}
n.mdns.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
// Start the TUN/TAP interface
if listener, err := n.core.ConnListen(); err == nil {
if dialer, err := n.core.ConnDialer(); err == nil {
n.tuntap.Init(&n.core, n.state, logger, tuntap.TunOptions{Listener: listener, Dialer: dialer})
if err := n.tuntap.Start(); err != nil {
logger.Errorln("An error occurred starting TUN/TAP:", err)
}
n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
} else {
logger.Errorln("Unable to get Dialer:", err)
}
} else {
logger.Errorln("Unable to get Listener:", err)
n.tuntap.Init(&n.core, n.state, logger, nil)
if err := n.tuntap.Start(); err != nil {
logger.Errorln("An error occurred starting TUN/TAP:", err)
}
n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
// Make some nice output that tells us what our IPv6 address and subnet are.
// This is just logged to stdout for the user.
address := n.core.Address()
@ -327,11 +322,11 @@ func main() {
logger.Infof("Your IPv6 subnet is %s", subnet.String())
// Catch interrupts from the operating system to exit gracefully.
c := make(chan os.Signal, 1)
r := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
signal.Notify(r, os.Interrupt, syscall.SIGHUP)
// Capture the service being stopped on Windows.
<-c
minwinsvc.SetOnExit(n.shutdown)
<<<<<<< HEAD
defer n.shutdown()
// Wait for the terminate/interrupt signal. Once a signal is received, the
// deferred Stop function above will run which will shut down TUN/TAP.
@ -353,6 +348,9 @@ func main() {
}
}
exit:
=======
n.shutdown()
>>>>>>> future
}
func (n *node) shutdown() {
@ -362,7 +360,7 @@ func (n *node) shutdown() {
n.core.Stop()
}
func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
func (n *node) sessionFirewall(pubkey ed25519.PublicKey, initiator bool) bool {
n.state.Mutex.RLock()
defer n.state.Mutex.RUnlock()
@ -371,25 +369,21 @@ func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
return true
}
// Prepare for checking whitelist/blacklist
var box crypto.BoxPubKey
// Reject blacklisted nodes
for _, b := range n.state.Current.SessionFirewall.BlacklistEncryptionPublicKeys {
for _, b := range n.state.Current.SessionFirewall.BlacklistPublicKeys {
key, err := hex.DecodeString(b)
if err == nil {
copy(box[:crypto.BoxPubKeyLen], key)
if box == *pubkey {
if bytes.Equal(key, pubkey) {
return false
}
}
}
// Allow whitelisted nodes
for _, b := range n.state.Current.SessionFirewall.WhitelistEncryptionPublicKeys {
for _, b := range n.state.Current.SessionFirewall.WhitelistPublicKeys {
key, err := hex.DecodeString(b)
if err == nil {
copy(box[:crypto.BoxPubKeyLen], key)
if box == *pubkey {
if bytes.Equal(key, pubkey) {
return true
}
}
@ -405,7 +399,7 @@ func (n *node) sessionFirewall(pubkey *crypto.BoxPubKey, initiator bool) bool {
// Look and see if the pubkey is that of a direct peer
var isDirectPeer bool
for _, peer := range n.core.GetPeers() {
if peer.PublicKey == *pubkey {
if bytes.Equal(peer.Key[:], pubkey[:]) {
isDirectPeer = true
break
}

View file

@ -78,8 +78,8 @@ func run() int {
if *server == endpoint {
if config, err := ioutil.ReadFile(defaults.GetDefaults().DefaultConfigFile); err == nil {
if bytes.Compare(config[0:2], []byte{0xFF, 0xFE}) == 0 ||
bytes.Compare(config[0:2], []byte{0xFE, 0xFF}) == 0 {
if bytes.Equal(config[0:2], []byte{0xFF, 0xFE}) ||
bytes.Equal(config[0:2], []byte{0xFE, 0xFF}) {
utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM)
decoder := utf.NewDecoder()
config, err = decoder.Bytes(config)