mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-04-30 07:05:06 +03:00
Tidy some lint errors
This commit is contained in:
parent
b9f35c5530
commit
fb6b828916
33 changed files with 125 additions and 656 deletions
|
@ -54,9 +54,7 @@ func main() {
|
|||
if isBetter(currentBest, newKey.id[:]) || len(currentBest) == 0 {
|
||||
currentBest = newKey.id
|
||||
for _, channel := range threadChannels {
|
||||
select {
|
||||
case channel <- newKey.id:
|
||||
}
|
||||
channel <- newKey.id
|
||||
}
|
||||
fmt.Println("--------------------------------------------------------------------------------")
|
||||
switch {
|
||||
|
|
|
@ -106,7 +106,7 @@ func readConfig(useconf *bool, useconffile *string, normaliseconf *bool) *config
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
json.Unmarshal(confJson, &cfg)
|
||||
_ = json.Unmarshal(confJson, &cfg)
|
||||
// Overlay our newly mapped configuration onto the autoconf node config that
|
||||
// we generated above.
|
||||
if err = mapstructure.Decode(dat, &cfg); err != nil {
|
||||
|
@ -285,25 +285,29 @@ func main() {
|
|||
n.multicast = &multicast.Multicast{}
|
||||
n.tuntap = &tuntap.TunAdapter{}
|
||||
// Start the admin socket
|
||||
n.admin.Init(&n.core, n.state, logger, nil)
|
||||
if err := n.admin.Start(); err != nil {
|
||||
if err := n.admin.Init(&n.core, n.state, logger, nil); err != nil {
|
||||
logger.Errorln("An error occured initialising the admin module:", err)
|
||||
} else if err := n.admin.Start(); err != nil {
|
||||
logger.Errorln("An error occurred starting admin socket:", err)
|
||||
}
|
||||
n.admin.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
|
||||
// Start the multicast interface
|
||||
n.multicast.Init(&n.core, n.state, logger, nil)
|
||||
if err := n.multicast.Start(); err != nil {
|
||||
if err := n.multicast.Init(&n.core, n.state, logger, nil); err != nil {
|
||||
logger.Errorln("An error occured initialising the multicast module:", err)
|
||||
} else if err := n.multicast.Start(); err != nil {
|
||||
logger.Errorln("An error occurred starting multicast:", err)
|
||||
}
|
||||
n.multicast.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 {
|
||||
if err := n.tuntap.Init(&n.core, n.state, logger, tuntap.TunOptions{Listener: listener, Dialer: dialer}); err != nil {
|
||||
logger.Errorln("An error occured initialising the TUN module:", err)
|
||||
} else if err := n.tuntap.Start(); err != nil {
|
||||
logger.Errorln("An error occurred starting TUN/TAP:", err)
|
||||
} else {
|
||||
n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
|
||||
}
|
||||
n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
|
||||
} else {
|
||||
logger.Errorln("Unable to get Dialer:", err)
|
||||
}
|
||||
|
@ -346,9 +350,9 @@ exit:
|
|||
}
|
||||
|
||||
func (n *node) shutdown() {
|
||||
n.admin.Stop()
|
||||
n.multicast.Stop()
|
||||
n.tuntap.Stop()
|
||||
_ = n.admin.Stop()
|
||||
_ = n.multicast.Stop()
|
||||
_ = n.tuntap.Stop()
|
||||
n.core.Stop()
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,11 @@ func run() int {
|
|||
fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] command [key=value] [key=value] ...\n\n", os.Args[0])
|
||||
fmt.Println("Options:")
|
||||
flag.PrintDefaults()
|
||||
fmt.Println("\nPlease note that options must always specified BEFORE the command\non the command line or they will be ignored.\n")
|
||||
fmt.Println("Commands:\n - Use \"list\" for a list of available commands\n")
|
||||
fmt.Println()
|
||||
fmt.Println("Please note that options must always specified BEFORE the command\non the command line or they will be ignored.")
|
||||
fmt.Println()
|
||||
fmt.Println("Commands:\n - Use \"list\" for a list of available commands")
|
||||
fmt.Println()
|
||||
fmt.Println("Examples:")
|
||||
fmt.Println(" - ", os.Args[0], "list")
|
||||
fmt.Println(" - ", os.Args[0], "getPeers")
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
@ -29,7 +30,7 @@ func dialTest(sendNode, recvNode *simNode) {
|
|||
mask[idx] = 0xff
|
||||
}
|
||||
for {
|
||||
c, err := sendNode.dialer.DialByNodeIDandMask(nil, &recvNode.nodeID, &mask)
|
||||
c, err := sendNode.dialer.DialByNodeIDandMask(context.TODO(), &recvNode.nodeID, &mask)
|
||||
if c != nil {
|
||||
c.Close()
|
||||
return
|
||||
|
|
|
@ -20,7 +20,9 @@ type simNode struct {
|
|||
|
||||
func newNode(id int) *simNode {
|
||||
n := simNode{id: id}
|
||||
n.core.Start(config.GenerateConfig(), log.New(ioutil.Discard, "", 0))
|
||||
if _, err := n.core.Start(config.GenerateConfig(), log.New(ioutil.Discard, "", 0)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
n.nodeID = *n.core.NodeID()
|
||||
n.dialer, _ = n.core.ConnDialer()
|
||||
n.listener, _ = n.core.ConnListen()
|
||||
|
|
|
@ -2,19 +2,21 @@ package main
|
|||
|
||||
type nodeStore map[int]*simNode
|
||||
|
||||
func makeStoreSingle() nodeStore {
|
||||
s := make(nodeStore)
|
||||
s[0] = newNode(0)
|
||||
return s
|
||||
}
|
||||
|
||||
func linkNodes(a *simNode, b *simNode) {
|
||||
la := a.core.NewSimlink()
|
||||
lb := b.core.NewSimlink()
|
||||
la.SetDestination(lb)
|
||||
lb.SetDestination(la)
|
||||
la.Start()
|
||||
lb.Start()
|
||||
if err := la.SetDestination(lb); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := lb.SetDestination(la); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := la.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := lb.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func makeStoreSquareGrid(sideLength int) nodeStore {
|
||||
|
|
|
@ -1,459 +0,0 @@
|
|||
// +build !lint
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gologme/log"
|
||||
|
||||
. "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
||||
|
||||
. "github.com/yggdrasil-network/yggdrasil-go/src/crypto"
|
||||
)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type Node struct {
|
||||
index int
|
||||
core Core
|
||||
send chan<- []byte
|
||||
recv <-chan []byte
|
||||
}
|
||||
|
||||
func (n *Node) init(index int) {
|
||||
n.index = index
|
||||
n.core.Init()
|
||||
n.send = n.core.DEBUG_getSend()
|
||||
n.recv = n.core.DEBUG_getRecv()
|
||||
n.core.DEBUG_simFixMTU()
|
||||
}
|
||||
|
||||
func (n *Node) printTraffic() {
|
||||
for {
|
||||
packet := <-n.recv
|
||||
fmt.Println(n.index, packet)
|
||||
//panic("Got a packet")
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Node) startPeers() {
|
||||
//for _, p := range n.core.Peers.Ports {
|
||||
// go p.MainLoop()
|
||||
//}
|
||||
//go n.printTraffic()
|
||||
//n.core.Peers.DEBUG_startPeers()
|
||||
}
|
||||
|
||||
func linkNodes(m, n *Node) {
|
||||
// Don't allow duplicates
|
||||
if m.core.DEBUG_getPeers().DEBUG_hasPeer(n.core.DEBUG_getSigningPublicKey()) {
|
||||
return
|
||||
}
|
||||
// Create peers
|
||||
// Buffering reduces packet loss in the sim
|
||||
// This slightly speeds up testing (fewer delays before retrying a ping)
|
||||
pLinkPub, pLinkPriv := m.core.DEBUG_newBoxKeys()
|
||||
qLinkPub, qLinkPriv := m.core.DEBUG_newBoxKeys()
|
||||
p := m.core.DEBUG_getPeers().DEBUG_newPeer(n.core.DEBUG_getEncryptionPublicKey(),
|
||||
n.core.DEBUG_getSigningPublicKey(), *m.core.DEBUG_getSharedKey(pLinkPriv, qLinkPub))
|
||||
q := n.core.DEBUG_getPeers().DEBUG_newPeer(m.core.DEBUG_getEncryptionPublicKey(),
|
||||
m.core.DEBUG_getSigningPublicKey(), *n.core.DEBUG_getSharedKey(qLinkPriv, pLinkPub))
|
||||
DEBUG_simLinkPeers(p, q)
|
||||
return
|
||||
}
|
||||
|
||||
func makeStoreSquareGrid(sideLength int) map[int]*Node {
|
||||
store := make(map[int]*Node)
|
||||
nNodes := sideLength * sideLength
|
||||
idxs := make([]int, 0, nNodes)
|
||||
// TODO shuffle nodeIDs
|
||||
for idx := 1; idx <= nNodes; idx++ {
|
||||
idxs = append(idxs, idx)
|
||||
}
|
||||
for _, idx := range idxs {
|
||||
node := &Node{}
|
||||
node.init(idx)
|
||||
store[idx] = node
|
||||
}
|
||||
for idx := 0; idx < nNodes; idx++ {
|
||||
if (idx % sideLength) != 0 {
|
||||
linkNodes(store[idxs[idx]], store[idxs[idx-1]])
|
||||
}
|
||||
if idx >= sideLength {
|
||||
linkNodes(store[idxs[idx]], store[idxs[idx-sideLength]])
|
||||
}
|
||||
}
|
||||
//for _, node := range store { node.initPorts() }
|
||||
return store
|
||||
}
|
||||
|
||||
func makeStoreStar(nNodes int) map[int]*Node {
|
||||
store := make(map[int]*Node)
|
||||
center := &Node{}
|
||||
center.init(0)
|
||||
store[0] = center
|
||||
for idx := 1; idx < nNodes; idx++ {
|
||||
node := &Node{}
|
||||
node.init(idx)
|
||||
store[idx] = node
|
||||
linkNodes(center, node)
|
||||
}
|
||||
return store
|
||||
}
|
||||
|
||||
func loadGraph(path string) map[int]*Node {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
store := make(map[int]*Node)
|
||||
s := bufio.NewScanner(f)
|
||||
for s.Scan() {
|
||||
line := s.Text()
|
||||
nodeIdxstrs := strings.Split(line, " ")
|
||||
nodeIdx0, _ := strconv.Atoi(nodeIdxstrs[0])
|
||||
nodeIdx1, _ := strconv.Atoi(nodeIdxstrs[1])
|
||||
if store[nodeIdx0] == nil {
|
||||
node := &Node{}
|
||||
node.init(nodeIdx0)
|
||||
store[nodeIdx0] = node
|
||||
}
|
||||
if store[nodeIdx1] == nil {
|
||||
node := &Node{}
|
||||
node.init(nodeIdx1)
|
||||
store[nodeIdx1] = node
|
||||
}
|
||||
linkNodes(store[nodeIdx0], store[nodeIdx1])
|
||||
}
|
||||
//for _, node := range store { node.initPorts() }
|
||||
return store
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func startNetwork(store map[[32]byte]*Node) {
|
||||
for _, node := range store {
|
||||
node.startPeers()
|
||||
}
|
||||
}
|
||||
|
||||
func getKeyedStore(store map[int]*Node) map[[32]byte]*Node {
|
||||
newStore := make(map[[32]byte]*Node)
|
||||
for _, node := range store {
|
||||
newStore[node.core.DEBUG_getSigningPublicKey()] = node
|
||||
}
|
||||
return newStore
|
||||
}
|
||||
|
||||
func testPaths(store map[[32]byte]*Node) bool {
|
||||
nNodes := len(store)
|
||||
count := 0
|
||||
for _, source := range store {
|
||||
count++
|
||||
fmt.Printf("Testing paths from node %d / %d (%d)\n", count, nNodes, source.index)
|
||||
for _, dest := range store {
|
||||
//if source == dest { continue }
|
||||
destLoc := dest.core.DEBUG_getLocator()
|
||||
coords := destLoc.DEBUG_getCoords()
|
||||
temp := 0
|
||||
ttl := ^uint64(0)
|
||||
oldTTL := ttl
|
||||
for here := source; here != dest; {
|
||||
temp++
|
||||
if temp > 4096 {
|
||||
fmt.Println("Loop?")
|
||||
time.Sleep(time.Second)
|
||||
return false
|
||||
}
|
||||
nextPort := here.core.DEBUG_switchLookup(coords)
|
||||
// First check if "here" is accepting packets from the previous node
|
||||
// TODO explain how this works
|
||||
ports := here.core.DEBUG_getPeers().DEBUG_getPorts()
|
||||
nextPeer := ports[nextPort]
|
||||
if nextPeer == nil {
|
||||
fmt.Println("Peer associated with next port is nil")
|
||||
return false
|
||||
}
|
||||
next := store[nextPeer.DEBUG_getSigKey()]
|
||||
/*
|
||||
if next == here {
|
||||
//for idx, link := range here.links {
|
||||
// fmt.Println("DUMP:", idx, link.nodeID)
|
||||
//}
|
||||
if nextPort != 0 { panic("This should not be") }
|
||||
fmt.Println("Failed to route:", source.index, here.index, dest.index, oldTTL, ttl)
|
||||
//here.table.DEBUG_dumpTable()
|
||||
//fmt.Println("Ports:", here.nodeID, here.ports)
|
||||
return false
|
||||
panic(fmt.Sprintln("Routing Loop:",
|
||||
source.index,
|
||||
here.index,
|
||||
dest.index))
|
||||
}
|
||||
*/
|
||||
if temp > 4090 {
|
||||
fmt.Println("DEBUG:",
|
||||
source.index, source.core.DEBUG_getLocator(),
|
||||
here.index, here.core.DEBUG_getLocator(),
|
||||
dest.index, dest.core.DEBUG_getLocator())
|
||||
//here.core.DEBUG_getSwitchTable().DEBUG_dumpTable()
|
||||
}
|
||||
if here != source {
|
||||
// This is sufficient to check for routing loops or blackholes
|
||||
//break
|
||||
}
|
||||
if here == next {
|
||||
fmt.Println("Drop:", source.index, here.index, dest.index, oldTTL)
|
||||
return false
|
||||
}
|
||||
here = next
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func stressTest(store map[[32]byte]*Node) {
|
||||
fmt.Println("Stress testing network...")
|
||||
nNodes := len(store)
|
||||
dests := make([][]byte, 0, nNodes)
|
||||
for _, dest := range store {
|
||||
loc := dest.core.DEBUG_getLocator()
|
||||
coords := loc.DEBUG_getCoords()
|
||||
dests = append(dests, coords)
|
||||
}
|
||||
lookups := 0
|
||||
start := time.Now()
|
||||
for _, source := range store {
|
||||
for _, coords := range dests {
|
||||
source.core.DEBUG_switchLookup(coords)
|
||||
lookups++
|
||||
}
|
||||
}
|
||||
timed := time.Since(start)
|
||||
fmt.Printf("%d lookups in %s (%f lookups per second)\n",
|
||||
lookups,
|
||||
timed,
|
||||
float64(lookups)/timed.Seconds())
|
||||
}
|
||||
|
||||
func pingNodes(store map[[32]byte]*Node) {
|
||||
fmt.Println("Sending pings...")
|
||||
nNodes := len(store)
|
||||
count := 0
|
||||
equiv := func(a []byte, b []byte) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for idx := 0; idx < len(a); idx++ {
|
||||
if a[idx] != b[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
for _, source := range store {
|
||||
count++
|
||||
//if count > 16 { break }
|
||||
fmt.Printf("Sending packets from node %d/%d (%d)\n", count, nNodes, source.index)
|
||||
sourceKey := source.core.DEBUG_getEncryptionPublicKey()
|
||||
payload := sourceKey[:]
|
||||
sourceAddr := source.core.DEBUG_getAddr()[:]
|
||||
sendTo := func(bs []byte, destAddr []byte) {
|
||||
packet := make([]byte, 40+len(bs))
|
||||
copy(packet[8:24], sourceAddr)
|
||||
copy(packet[24:40], destAddr)
|
||||
copy(packet[40:], bs)
|
||||
packet[0] = 6 << 4
|
||||
source.send <- packet
|
||||
}
|
||||
destCount := 0
|
||||
for _, dest := range store {
|
||||
destCount += 1
|
||||
fmt.Printf("%d Nodes, %d Send, %d Recv\n", nNodes, count, destCount)
|
||||
if dest == source {
|
||||
fmt.Println("Skipping self")
|
||||
continue
|
||||
}
|
||||
destAddr := dest.core.DEBUG_getAddr()[:]
|
||||
ticker := time.NewTicker(150 * time.Millisecond)
|
||||
sendTo(payload, destAddr)
|
||||
for loop := true; loop; {
|
||||
select {
|
||||
case packet := <-dest.recv:
|
||||
{
|
||||
if equiv(payload, packet[len(packet)-len(payload):]) {
|
||||
loop = false
|
||||
}
|
||||
}
|
||||
case <-ticker.C:
|
||||
sendTo(payload, destAddr)
|
||||
//dumpDHTSize(store) // note that this uses racey functions to read things...
|
||||
}
|
||||
}
|
||||
ticker.Stop()
|
||||
}
|
||||
//break // Only try sending pings from 1 node
|
||||
// This is because, for some reason, stopTun() doesn't always close it
|
||||
// And if two tuns are up, bad things happen (sends via wrong interface)
|
||||
}
|
||||
fmt.Println("Finished pinging nodes")
|
||||
}
|
||||
|
||||
func pingBench(store map[[32]byte]*Node) {
|
||||
fmt.Println("Benchmarking pings...")
|
||||
nPings := 0
|
||||
payload := make([]byte, 1280+40) // MTU + ipv6 header
|
||||
var timed time.Duration
|
||||
//nNodes := len(store)
|
||||
count := 0
|
||||
for _, source := range store {
|
||||
count++
|
||||
//fmt.Printf("Sending packets from node %d/%d (%d)\n", count, nNodes, source.index)
|
||||
getPing := func(key [32]byte, decodedCoords []byte) []byte {
|
||||
// TODO write some function to do this the right way, put... somewhere...
|
||||
coords := DEBUG_wire_encode_coords(decodedCoords)
|
||||
packet := make([]byte, 0, len(key)+len(coords)+len(payload))
|
||||
packet = append(packet, key[:]...)
|
||||
packet = append(packet, coords...)
|
||||
packet = append(packet, payload[:]...)
|
||||
return packet
|
||||
}
|
||||
for _, dest := range store {
|
||||
key := dest.core.DEBUG_getEncryptionPublicKey()
|
||||
loc := dest.core.DEBUG_getLocator()
|
||||
coords := loc.DEBUG_getCoords()
|
||||
ping := getPing(key, coords)
|
||||
// TODO make sure the session is open first
|
||||
start := time.Now()
|
||||
for i := 0; i < 1000000; i++ {
|
||||
source.send <- ping
|
||||
nPings++
|
||||
}
|
||||
timed += time.Since(start)
|
||||
break
|
||||
}
|
||||
break
|
||||
}
|
||||
fmt.Printf("Sent %d pings in %s (%f per second)\n",
|
||||
nPings,
|
||||
timed,
|
||||
float64(nPings)/timed.Seconds())
|
||||
}
|
||||
|
||||
func dumpStore(store map[NodeID]*Node) {
|
||||
for _, node := range store {
|
||||
fmt.Println("DUMPSTORE:", node.index, node.core.DEBUG_getLocator())
|
||||
node.core.DEBUG_getSwitchTable().DEBUG_dumpTable()
|
||||
}
|
||||
}
|
||||
|
||||
func dumpDHTSize(store map[[32]byte]*Node) {
|
||||
var min, max, sum int
|
||||
for _, node := range store {
|
||||
num := node.core.DEBUG_getDHTSize()
|
||||
min = num
|
||||
max = num
|
||||
break
|
||||
}
|
||||
for _, node := range store {
|
||||
num := node.core.DEBUG_getDHTSize()
|
||||
if num < min {
|
||||
min = num
|
||||
}
|
||||
if num > max {
|
||||
max = num
|
||||
}
|
||||
sum += num
|
||||
}
|
||||
avg := float64(sum) / float64(len(store))
|
||||
fmt.Printf("DHT min %d / avg %f / max %d\n", min, avg, max)
|
||||
}
|
||||
|
||||
func (n *Node) startTCP(listen string) {
|
||||
n.core.DEBUG_setupAndStartGlobalTCPInterface(listen)
|
||||
}
|
||||
|
||||
func (n *Node) connectTCP(remoteAddr string) {
|
||||
n.core.AddPeer(remoteAddr, remoteAddr)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile `file`")
|
||||
var memprofile = flag.String("memprofile", "", "write memory profile to this file")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if *cpuprofile != "" {
|
||||
f, err := os.Create(*cpuprofile)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("could not create CPU profile: ", err))
|
||||
}
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
panic(fmt.Sprintf("could not start CPU profile: ", err))
|
||||
}
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
if *memprofile != "" {
|
||||
f, err := os.Create(*memprofile)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("could not create memory profile: ", err))
|
||||
}
|
||||
defer func() { pprof.WriteHeapProfile(f); f.Close() }()
|
||||
}
|
||||
fmt.Println("Test")
|
||||
Util_testAddrIDMask()
|
||||
idxstore := makeStoreSquareGrid(4)
|
||||
//idxstore := makeStoreStar(256)
|
||||
//idxstore := loadGraph("misc/sim/hype-2016-09-19.list")
|
||||
//idxstore := loadGraph("misc/sim/fc00-2017-08-12.txt")
|
||||
//idxstore := loadGraph("skitter")
|
||||
kstore := getKeyedStore(idxstore)
|
||||
//*
|
||||
logger := log.New(os.Stderr, "", log.Flags())
|
||||
for _, n := range kstore {
|
||||
n.core.DEBUG_setLogger(logger)
|
||||
}
|
||||
//*/
|
||||
startNetwork(kstore)
|
||||
//time.Sleep(10*time.Second)
|
||||
// Note that testPaths only works if pressure is turned off
|
||||
// Otherwise congestion can lead to routing loops?
|
||||
for finished := false; !finished; {
|
||||
finished = testPaths(kstore)
|
||||
}
|
||||
pingNodes(kstore)
|
||||
//pingBench(kstore) // Only after disabling debug output
|
||||
//stressTest(kstore)
|
||||
//time.Sleep(120 * time.Second)
|
||||
dumpDHTSize(kstore) // note that this uses racey functions to read things...
|
||||
if false {
|
||||
// This connects the sim to the local network
|
||||
for _, node := range kstore {
|
||||
node.startTCP("localhost:0")
|
||||
node.connectTCP("localhost:12345")
|
||||
break // just 1
|
||||
}
|
||||
for _, node := range kstore {
|
||||
go func() {
|
||||
// Just dump any packets sent to this node
|
||||
for range node.recv {
|
||||
}
|
||||
}()
|
||||
}
|
||||
var block chan struct{}
|
||||
<-block
|
||||
}
|
||||
runtime.GC()
|
||||
}
|
|
@ -42,15 +42,14 @@ type handler struct {
|
|||
}
|
||||
|
||||
// AddHandler is called for each admin function to add the handler and help documentation to the API.
|
||||
func (a *AdminSocket) AddHandler(name string, args []string, handlerfunc func(Info) (Info, error)) error {
|
||||
func (a *AdminSocket) AddHandler(name string, args []string, handlerfunc func(Info) (Info, error)) {
|
||||
if _, ok := a.handlers[strings.ToLower(name)]; ok {
|
||||
return errors.New("handler already exists")
|
||||
panic(fmt.Sprintf("admin handler %q already exists", name))
|
||||
}
|
||||
a.handlers[strings.ToLower(name)] = handler{
|
||||
args: args,
|
||||
handler: handlerfunc,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Init runs the initial admin setup.
|
||||
|
@ -75,9 +74,13 @@ func (a *AdminSocket) UpdateConfig(config *config.NodeConfig) {
|
|||
if a.listenaddr != config.AdminListen {
|
||||
a.listenaddr = config.AdminListen
|
||||
if a.IsStarted() {
|
||||
a.Stop()
|
||||
if err := a.Stop(); err != nil {
|
||||
a.log.Errorln("Failed to stop admin module:", err)
|
||||
}
|
||||
}
|
||||
if err := a.Start(); err != nil {
|
||||
a.log.Errorln("Failed to restart admin module:", err)
|
||||
}
|
||||
a.Start()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,11 +230,6 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
|
|||
},
|
||||
}, errors.New("Failed to remove peer")
|
||||
}
|
||||
return Info{
|
||||
"not_removed": []string{
|
||||
in["uri"].(string),
|
||||
},
|
||||
}, errors.New("Failed to remove peer")
|
||||
})
|
||||
a.AddHandler("getAllowedEncryptionPublicKeys", []string{}, func(in Info) (Info, error) {
|
||||
return Info{"allowed_box_pubs": a.core.GetAllowedEncryptionPublicKeys()}, nil
|
||||
|
|
|
@ -91,6 +91,7 @@ func (m *Multicast) _start() error {
|
|||
m.sock = ipv6.NewPacketConn(conn)
|
||||
if err = m.sock.SetControlMessage(ipv6.FlagDst, true); err != nil {
|
||||
// Windows can't set this flag, so we need to handle it in other ways
|
||||
m.log.Warnln("m.sock.SetControlMessage(ipv6.FlagDst) error:", err)
|
||||
}
|
||||
|
||||
m.isOpen = true
|
||||
|
@ -294,7 +295,10 @@ func (m *Multicast) _announce() {
|
|||
continue
|
||||
}
|
||||
// Join the multicast group
|
||||
m.sock.JoinGroup(&iface, groupAddr)
|
||||
if err := m.sock.JoinGroup(&iface, groupAddr); err != nil {
|
||||
m.log.Errorln("Failed to join multicast group on", iface.Name, "due to error:", err)
|
||||
continue
|
||||
}
|
||||
// Try and see if we already have a TCP listener for this interface
|
||||
var info *listenerInfo
|
||||
if nfo, ok := m.listeners[iface.Name]; !ok || nfo.listener.Listener == nil {
|
||||
|
@ -325,7 +329,9 @@ func (m *Multicast) _announce() {
|
|||
a.Zone = ""
|
||||
destAddr.Zone = iface.Name
|
||||
msg := []byte(a.String())
|
||||
m.sock.WriteTo(msg, nil, destAddr)
|
||||
if _, err = m.sock.WriteTo(msg, nil, destAddr); err != nil {
|
||||
m.log.Errorln("Failed to send multicast beacon on", iface.Name, "due to error:", err)
|
||||
}
|
||||
}
|
||||
if info.interval.Seconds() < 15 {
|
||||
info.interval += time.Second
|
||||
|
|
|
@ -29,8 +29,6 @@ import (
|
|||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var awdlGoroutineStarted bool
|
||||
|
||||
func (m *Multicast) _multicastStarted() {
|
||||
if !m.isOpen {
|
||||
return
|
||||
|
|
|
@ -93,8 +93,8 @@ func (c *cryptokey) configure() {
|
|||
|
||||
// Wipe the caches
|
||||
c.mutexcaches.Lock()
|
||||
c.ipv4cache = make(map[address.Address]cryptokey_route, 0)
|
||||
c.ipv6cache = make(map[address.Address]cryptokey_route, 0)
|
||||
c.ipv4cache = make(map[address.Address]cryptokey_route)
|
||||
c.ipv6cache = make(map[address.Address]cryptokey_route)
|
||||
c.mutexcaches.Unlock()
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ func (s *tunConn) _close_from_tun() {
|
|||
delete(s.tun.addrToConn, s.addr)
|
||||
delete(s.tun.subnetToConn, s.snet)
|
||||
func() {
|
||||
defer func() { recover() }()
|
||||
defer func() { _ = recover() }()
|
||||
close(s.stop) // Closes reader/writer goroutines
|
||||
}()
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ func (s *tunConn) _read(bs []byte) (err error) {
|
|||
|
||||
func (s *tunConn) writeFrom(from phony.Actor, bs []byte) {
|
||||
s.Act(from, func() {
|
||||
s._write(bs)
|
||||
_ = s._write(bs)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@ import (
|
|||
"golang.org/x/net/ipv6"
|
||||
)
|
||||
|
||||
const len_ETHER = 14
|
||||
|
||||
type ICMPv6 struct {
|
||||
tun *TunAdapter
|
||||
}
|
||||
|
|
|
@ -28,14 +28,13 @@ func (w *tunWriter) writeFrom(from phony.Actor, b []byte) {
|
|||
// write is pretty loose with the memory safety rules, e.g. it assumes it can
|
||||
// read w.tun.iface.IsTap() safely
|
||||
func (w *tunWriter) _write(b []byte) {
|
||||
var written int
|
||||
var err error
|
||||
n := len(b)
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
temp := append(w.buf[:TUN_OFFSET_BYTES], b...)
|
||||
written, err = w.tun.iface.Write(temp, TUN_OFFSET_BYTES)
|
||||
_, err = w.tun.iface.Write(temp, TUN_OFFSET_BYTES)
|
||||
if err != nil {
|
||||
w.tun.Act(w, func() {
|
||||
if !w.tun.isOpen {
|
||||
|
@ -43,10 +42,6 @@ func (w *tunWriter) _write(b []byte) {
|
|||
}
|
||||
})
|
||||
}
|
||||
if written != n+TUN_OFFSET_BYTES {
|
||||
// FIXME some platforms return the wrong number of bytes written, causing error spam
|
||||
//w.tun.log.Errorln("TUN iface write mismatch:", written, "bytes written vs", n+TUN_OFFSET_BYTES, "bytes given")
|
||||
}
|
||||
}
|
||||
|
||||
type tunReader struct {
|
||||
|
|
|
@ -42,13 +42,11 @@ type TunAdapter struct {
|
|||
reader tunReader
|
||||
config *config.NodeState
|
||||
log *log.Logger
|
||||
reconfigure chan chan error
|
||||
listener *yggdrasil.Listener
|
||||
dialer *yggdrasil.Dialer
|
||||
addr address.Address
|
||||
subnet address.Subnet
|
||||
ckr cryptokey
|
||||
icmpv6 ICMPv6
|
||||
mtu MTU
|
||||
iface tun.Device
|
||||
phony.Inbox // Currently only used for _handlePacket from the reader, TODO: all the stuff that currently needs a mutex below
|
||||
|
@ -170,7 +168,7 @@ func (tun *TunAdapter) _start() error {
|
|||
}
|
||||
tun.core.SetMaximumSessionMTU(tun.MTU())
|
||||
tun.isOpen = true
|
||||
go tun.handler()
|
||||
go tun.handler() // nolint:errcheck
|
||||
tun.reader.Act(nil, tun.reader._read) // Start the reader
|
||||
tun.ckr.init(tun)
|
||||
return nil
|
||||
|
@ -274,7 +272,7 @@ func (tun *TunAdapter) _wrap(conn *yggdrasil.Conn) (c *tunConn, err error) {
|
|||
// Set the read callback and start the timeout
|
||||
conn.SetReadCallback(func(bs []byte) {
|
||||
s.Act(conn, func() {
|
||||
s._read(bs)
|
||||
_ = s._read(bs)
|
||||
})
|
||||
})
|
||||
s.Act(nil, s.stillAlive)
|
||||
|
|
|
@ -41,8 +41,8 @@ const (
|
|||
)
|
||||
|
||||
type in6_addrlifetime struct {
|
||||
ia6t_expire float64
|
||||
ia6t_preferred float64
|
||||
ia6t_expire float64 // nolint:unused nolint:structcheck
|
||||
ia6t_preferred float64 // nolint:unused nolint:structcheck
|
||||
ia6t_vltime uint32
|
||||
ia6t_pltime uint32
|
||||
}
|
||||
|
@ -50,16 +50,16 @@ type in6_addrlifetime struct {
|
|||
type sockaddr_in6 struct {
|
||||
sin6_len uint8
|
||||
sin6_family uint8
|
||||
sin6_port uint8
|
||||
sin6_flowinfo uint32
|
||||
sin6_port uint8 // nolint:unused nolint:structcheck
|
||||
sin6_flowinfo uint32 // nolint:unused nolint:structcheck
|
||||
sin6_addr [8]uint16
|
||||
sin6_scope_id uint32
|
||||
sin6_scope_id uint32 // nolint:unused nolint:structcheck
|
||||
}
|
||||
|
||||
type in6_aliasreq struct {
|
||||
ifra_name [16]byte
|
||||
ifra_addr sockaddr_in6
|
||||
ifra_dstaddr sockaddr_in6
|
||||
ifra_dstaddr sockaddr_in6 // nolint:unused nolint:structcheck
|
||||
ifra_prefixmask sockaddr_in6
|
||||
ifra_flags uint32
|
||||
ifra_lifetime in6_addrlifetime
|
||||
|
|
|
@ -24,7 +24,7 @@ var CancellationTimeoutError = errors.New("timeout")
|
|||
|
||||
// CancellationFinalizer is set as a finalizer when creating a new cancellation with NewCancellation(), and generally shouldn't be needed by the user, but is included in case other implementations of the same interface want to make use of it.
|
||||
func CancellationFinalizer(c Cancellation) {
|
||||
c.Cancel(CancellationFinalized)
|
||||
_ = c.Cancel(CancellationFinalized)
|
||||
}
|
||||
|
||||
type cancellation struct {
|
||||
|
@ -76,7 +76,7 @@ func CancellationChild(parent Cancellation) Cancellation {
|
|||
select {
|
||||
case <-child.Finished():
|
||||
case <-parent.Finished():
|
||||
child.Cancel(parent.Error())
|
||||
_ = child.Cancel(parent.Error())
|
||||
}
|
||||
}()
|
||||
return child
|
||||
|
@ -91,7 +91,7 @@ func CancellationWithTimeout(parent Cancellation, timeout time.Duration) Cancell
|
|||
select {
|
||||
case <-child.Finished():
|
||||
case <-timer.C:
|
||||
child.Cancel(CancellationTimeoutError)
|
||||
_ = child.Cancel(CancellationTimeoutError)
|
||||
}
|
||||
}()
|
||||
return child
|
||||
|
@ -99,5 +99,5 @@ func CancellationWithTimeout(parent Cancellation, timeout time.Duration) Cancell
|
|||
|
||||
// CancellationWithTimeout returns a ChildCancellation that will automatically be Cancelled with a CancellationTimeoutError after the specified deadline.
|
||||
func CancellationWithDeadline(parent Cancellation, deadline time.Time) Cancellation {
|
||||
return CancellationWithTimeout(parent, deadline.Sub(time.Now()))
|
||||
return CancellationWithTimeout(parent, time.Until(deadline))
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ func (c *Core) GetSessions() []Session {
|
|||
MTU: sinfo._getMTU(),
|
||||
BytesSent: sinfo.bytesSent,
|
||||
BytesRecvd: sinfo.bytesRecvd,
|
||||
Uptime: time.Now().Sub(sinfo.timeOpened),
|
||||
Uptime: time.Since(sinfo.timeOpened),
|
||||
WasMTUFixed: sinfo.wasMTUFixed,
|
||||
}
|
||||
copy(session.PublicKey[:], sinfo.theirPermPub[:])
|
||||
|
@ -340,7 +340,7 @@ func (c *Core) MyNodeInfo() NodeInfoPayload {
|
|||
// SetNodeInfo sets the local nodeinfo. Note that nodeinfo can be any value or
|
||||
// struct, it will be serialised into JSON automatically.
|
||||
func (c *Core) SetNodeInfo(nodeinfo interface{}, nodeinfoprivacy bool) {
|
||||
c.router.nodeinfo.setNodeInfo(nodeinfo, nodeinfoprivacy)
|
||||
_ = c.router.nodeinfo.setNodeInfo(nodeinfo, nodeinfoprivacy)
|
||||
}
|
||||
|
||||
// GetMaximumSessionMTU returns the maximum allowed session MTU size.
|
||||
|
@ -371,7 +371,7 @@ func (c *Core) SetMaximumSessionMTU(mtu MTU) {
|
|||
func (c *Core) GetNodeInfo(key crypto.BoxPubKey, coords []uint64, nocache bool) (NodeInfoPayload, error) {
|
||||
response := make(chan *NodeInfoPayload, 1)
|
||||
c.router.nodeinfo.addCallback(key, func(nodeinfo *NodeInfoPayload) {
|
||||
defer func() { recover() }()
|
||||
defer func() { _ = recover() }()
|
||||
select {
|
||||
case response <- nodeinfo:
|
||||
default:
|
||||
|
|
|
@ -113,7 +113,7 @@ func (c *Conn) search() error {
|
|||
// Somehow this was called multiple times, TODO don't let that happen
|
||||
if sinfo != nil {
|
||||
// Need to clean up to avoid a session leak
|
||||
sinfo.cancel.Cancel(nil)
|
||||
_ = sinfo.cancel.Cancel(nil)
|
||||
sinfo.sessions.removeSession(sinfo)
|
||||
}
|
||||
default:
|
||||
|
@ -149,11 +149,10 @@ func (c *Conn) _doSearch() {
|
|||
s := fmt.Sprintf("conn=%p", c)
|
||||
routerWork := func() {
|
||||
// Check to see if there is a search already matching the destination
|
||||
sinfo, isIn := c.core.router.searches.searches[*c.nodeID]
|
||||
if !isIn {
|
||||
if _, isIn := c.core.router.searches.searches[*c.nodeID]; !isIn {
|
||||
// Nothing was found, so create a new search
|
||||
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", s, sinfo)
|
||||
// Start the search
|
||||
sinfo.startSearch()
|
||||
|
@ -217,7 +216,7 @@ func (c *Conn) readNoCopy() ([]byte, error) {
|
|||
var doCancel bool
|
||||
phony.Block(c, func() { cancel, doCancel = c._getDeadlineCancellation(c.readDeadline) })
|
||||
if doCancel {
|
||||
defer cancel.Cancel(nil)
|
||||
defer cancel.Cancel(nil) // nolint:errcheck
|
||||
}
|
||||
// Wait for some traffic to come through from the session
|
||||
select {
|
||||
|
@ -295,7 +294,7 @@ func (c *Conn) writeNoCopy(msg FlowKeyMessage) error {
|
|||
var doCancel bool
|
||||
phony.Block(c, func() { cancel, doCancel = c._getDeadlineCancellation(c.writeDeadline) })
|
||||
if doCancel {
|
||||
defer cancel.Cancel(nil)
|
||||
defer cancel.Cancel(nil) // nolint:errcheck
|
||||
}
|
||||
var err error
|
||||
select {
|
||||
|
@ -369,8 +368,8 @@ func (c *Conn) RemoteAddr() net.Addr {
|
|||
// that synchronous Read and Write operations can block for. If no deadline is
|
||||
// configured, Read and Write operations can potentially block indefinitely.
|
||||
func (c *Conn) SetDeadline(t time.Time) error {
|
||||
c.SetReadDeadline(t)
|
||||
c.SetWriteDeadline(t)
|
||||
_ = c.SetReadDeadline(t)
|
||||
_ = c.SetWriteDeadline(t)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -197,7 +197,9 @@ func (c *Core) _stop() {
|
|||
if c.addPeerTimer != nil {
|
||||
c.addPeerTimer.Stop()
|
||||
}
|
||||
c.links.stop()
|
||||
if err := c.links.stop(); err != nil {
|
||||
c.log.Warnln("Error stopping links:", err)
|
||||
}
|
||||
/* FIXME this deadlocks, need a waitgroup or something to coordinate shutdown
|
||||
for _, peer := range c.GetPeers() {
|
||||
c.DisconnectPeer(peer.Port)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// +build debug
|
||||
|
||||
package yggdrasil
|
||||
|
||||
import (
|
||||
|
|
|
@ -21,7 +21,7 @@ type Dialer struct {
|
|||
// "curve25519" or "nodeid" and the second parameter should contain a
|
||||
// hexadecimal representation of the target. It uses DialContext internally.
|
||||
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
|
||||
return d.DialContext(nil, network, address)
|
||||
return d.DialContext(context.TODO(), network, address)
|
||||
}
|
||||
|
||||
// DialContext is used internally by Dial, and should only be used with a
|
||||
|
|
|
@ -140,23 +140,6 @@ func (l *links) call(uri string, sintf string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (l *links) listen(uri string) error {
|
||||
u, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return fmt.Errorf("listener %s is not correctly formatted (%s)", uri, err)
|
||||
}
|
||||
switch u.Scheme {
|
||||
case "tcp":
|
||||
_, err := l.tcp.listen(u.Host, nil)
|
||||
return err
|
||||
case "tls":
|
||||
_, err := l.tcp.listen(u.Host, l.tcp.tls.forListener)
|
||||
return err
|
||||
default:
|
||||
return errors.New("unknown listen scheme: " + u.Scheme)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *links) create(msgIO linkMsgIO, name, linkType, local, remote string, incoming, force bool, options linkOptions) (*link, error) {
|
||||
// Technically anything unique would work for names, but let's pick something human readable, just for debugging
|
||||
intf := link{
|
||||
|
@ -191,7 +174,7 @@ func (intf *link) handler() error {
|
|||
// TODO split some of this into shorter functions, so it's easier to read, and for the FIXME duplicate peer issue mentioned later
|
||||
go func() {
|
||||
for bss := range intf.writer.worker {
|
||||
intf.msgIO.writeMsgs(bss)
|
||||
_, _ = intf.msgIO.writeMsgs(bss)
|
||||
}
|
||||
}()
|
||||
defer intf.writer.Act(nil, func() {
|
||||
|
@ -231,13 +214,13 @@ func (intf *link) handler() error {
|
|||
// 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.links.core.log.Errorf("Failed to connect to node: %q sent curve25519 key that does not match pinned keys", intf.name)
|
||||
intf.links.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.links.core.log.Errorf("Failed to connect to node: %q sent ed25519 key that does not match pinned keys", intf.name)
|
||||
intf.links.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")
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +239,7 @@ func (intf *link) handler() error {
|
|||
intf.links.mutex.Unlock()
|
||||
// FIXME we should really return an error and let the caller block instead
|
||||
// That lets them do things like close connections on its own, avoid printing a connection message in the first place, etc.
|
||||
intf.links.core.log.Debugln("DEBUG: found existing interface for", intf.name)
|
||||
intf.links.core.log.Debugln("DEBUG: found existing interface for", intf.name())
|
||||
intf.msgIO.close()
|
||||
if !intf.incoming {
|
||||
// Block outgoing connection attempts until the existing connection closes
|
||||
|
@ -272,7 +255,7 @@ func (intf *link) handler() error {
|
|||
intf.links.mutex.Unlock()
|
||||
close(intf.closed)
|
||||
}()
|
||||
intf.links.core.log.Debugln("DEBUG: registered interface for", intf.name)
|
||||
intf.links.core.log.Debugln("DEBUG: registered interface for", intf.name())
|
||||
}
|
||||
intf.links.mutex.Unlock()
|
||||
// Create peer
|
||||
|
|
|
@ -28,7 +28,7 @@ func (l *Listener) Accept() (net.Conn, error) {
|
|||
// Close will stop the listener
|
||||
func (l *Listener) Close() (err error) {
|
||||
defer func() {
|
||||
recover()
|
||||
_ = recover()
|
||||
err = errors.New("already closed")
|
||||
}()
|
||||
if l.core.router.sessions.listener == l {
|
||||
|
|
|
@ -156,14 +156,6 @@ func (m *nodeinfo) _addCachedNodeInfo(key crypto.BoxPubKey, payload NodeInfoPayl
|
|||
}
|
||||
}
|
||||
|
||||
// Get a nodeinfo entry from the cache
|
||||
func (m *nodeinfo) _getCachedNodeInfo(key crypto.BoxPubKey) (NodeInfoPayload, error) {
|
||||
if nodeinfo, ok := m.cache[key]; ok {
|
||||
return nodeinfo.payload, nil
|
||||
}
|
||||
return NodeInfoPayload{}, errors.New("No cache entry found")
|
||||
}
|
||||
|
||||
// Handles a nodeinfo request/response - called from the router
|
||||
func (m *nodeinfo) handleNodeInfo(from phony.Actor, nodeinfo *nodeinfoReqRes) {
|
||||
m.Act(from, func() {
|
||||
|
|
|
@ -87,7 +87,6 @@ type peer struct {
|
|||
sig crypto.SigPubKey
|
||||
shared crypto.BoxSharedKey
|
||||
linkShared crypto.BoxSharedKey
|
||||
endpoint string
|
||||
firstSeen time.Time // To track uptime for getPeers
|
||||
dinfo *dhtInfo // used to keep the DHT working
|
||||
// The below aren't actually useful internally, they're just gathered for getPeers statistics
|
||||
|
@ -186,18 +185,6 @@ func (ps *peers) sendSwitchMsgs(from phony.Actor) {
|
|||
})
|
||||
}
|
||||
|
||||
func (ps *peers) updateDHT(from phony.Actor) {
|
||||
ps.Act(from, func() {
|
||||
for _, peer := range ps.ports {
|
||||
p := peer
|
||||
if p.port == 0 {
|
||||
continue
|
||||
}
|
||||
p.Act(ps, p._updateDHT)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// This must be launched in a separate goroutine by whatever sets up the peer struct.
|
||||
func (p *peer) start() {
|
||||
// Just for good measure, immediately send a switch message to this peer when we start
|
||||
|
|
|
@ -66,7 +66,9 @@ func (r *router) init(core *Core) {
|
|||
}
|
||||
r.nodeinfo.init(r.core)
|
||||
r.core.config.Mutex.RLock()
|
||||
r.nodeinfo.setNodeInfo(r.core.config.Current.NodeInfo, r.core.config.Current.NodeInfoPrivacy)
|
||||
if err := r.nodeinfo.setNodeInfo(r.core.config.Current.NodeInfo, r.core.config.Current.NodeInfoPrivacy); err != nil {
|
||||
r.core.log.Errorln("Error setting NodeInfo:", err)
|
||||
}
|
||||
r.core.config.Mutex.RUnlock()
|
||||
r.dht.init(r)
|
||||
r.searches.init(r)
|
||||
|
|
|
@ -94,7 +94,7 @@ func (s *sessionInfo) _update(p *sessionPing) bool {
|
|||
s.time = time.Now()
|
||||
s.tstamp = p.Tstamp
|
||||
s.reset = false
|
||||
defer func() { recover() }() // Recover if the below panics
|
||||
defer func() { _ = recover() }() // Recover if the below panics
|
||||
select {
|
||||
case <-s.init:
|
||||
default:
|
||||
|
@ -285,20 +285,22 @@ func (ss *sessions) getSharedKey(myPriv *crypto.BoxPrivKey,
|
|||
theirPub *crypto.BoxPubKey) *crypto.BoxSharedKey {
|
||||
return crypto.GetSharedKey(myPriv, theirPub)
|
||||
// FIXME concurrency issues with the below, so for now we just burn the CPU every time
|
||||
if skey, isIn := ss.permShared[*theirPub]; isIn {
|
||||
return skey
|
||||
}
|
||||
// First do some cleanup
|
||||
const maxKeys = 1024
|
||||
for key := range ss.permShared {
|
||||
// Remove a random key until the store is small enough
|
||||
if len(ss.permShared) < maxKeys {
|
||||
break
|
||||
/*
|
||||
if skey, isIn := ss.permShared[*theirPub]; isIn {
|
||||
return skey
|
||||
}
|
||||
delete(ss.permShared, key)
|
||||
}
|
||||
ss.permShared[*theirPub] = crypto.GetSharedKey(myPriv, theirPub)
|
||||
return ss.permShared[*theirPub]
|
||||
// First do some cleanup
|
||||
const maxKeys = 1024
|
||||
for key := range ss.permShared {
|
||||
// Remove a random key until the store is small enough
|
||||
if len(ss.permShared) < maxKeys {
|
||||
break
|
||||
}
|
||||
delete(ss.permShared, key)
|
||||
}
|
||||
ss.permShared[*theirPub] = crypto.GetSharedKey(myPriv, theirPub)
|
||||
return ss.permShared[*theirPub]
|
||||
*/
|
||||
}
|
||||
|
||||
// Sends a session ping by calling sendPingPong in ping mode.
|
||||
|
|
|
@ -2,6 +2,7 @@ package yggdrasil
|
|||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Arceliar/phony"
|
||||
)
|
||||
|
||||
|
@ -31,7 +32,7 @@ func (s *Simlink) _sendMetaBytes(bs []byte) error {
|
|||
}
|
||||
|
||||
func (s *Simlink) close() error {
|
||||
defer func() { recover() }()
|
||||
defer func() { _ = recover() }()
|
||||
close(s.rch)
|
||||
return nil
|
||||
}
|
||||
|
@ -46,7 +47,7 @@ func (s *Simlink) writeMsgs(msgs [][]byte) (int, error) {
|
|||
bs := append([]byte(nil), msg...)
|
||||
phony.Block(s, func() {
|
||||
s.dest.Act(s, func() {
|
||||
defer func() { recover() }()
|
||||
defer func() { _ = recover() }()
|
||||
s.dest.rch <- bs
|
||||
})
|
||||
})
|
||||
|
@ -84,7 +85,7 @@ func (s *Simlink) Start() error {
|
|||
err = errors.New("already started")
|
||||
} else {
|
||||
s.started = true
|
||||
go s.link.handler()
|
||||
go s.link.handler() // nolint:errcheck
|
||||
}
|
||||
})
|
||||
return err
|
||||
|
|
|
@ -53,13 +53,11 @@ func (s *stream) writeMsgs(bss [][]byte) (int, error) {
|
|||
|
||||
// readMsg reads a message from the stream, accounting for stream padding, and is *not* thread safe.
|
||||
func (s *stream) readMsg() ([]byte, error) {
|
||||
for {
|
||||
bs, err := s.readMsgFromBuffer()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("message error: %v", err)
|
||||
}
|
||||
return bs, err
|
||||
bs, err := s.readMsgFromBuffer()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("message error: %v", err)
|
||||
}
|
||||
return bs, err
|
||||
}
|
||||
|
||||
// Writes metadata bytes without stream padding, meant to be temporary
|
||||
|
|
|
@ -117,28 +117,10 @@ func (l *switchLocator) getCoords() []byte {
|
|||
return bs
|
||||
}
|
||||
|
||||
// Returns true if this locator represents an ancestor of the locator given as an argument.
|
||||
// Ancestor means that it's the parent node, or the parent of parent, and so on...
|
||||
func (x *switchLocator) isAncestorOf(y *switchLocator) bool {
|
||||
if x.root != y.root {
|
||||
return false
|
||||
}
|
||||
if len(x.coords) > len(y.coords) {
|
||||
return false
|
||||
}
|
||||
for idx := range x.coords {
|
||||
if x.coords[idx] != y.coords[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Information about a peer, used by the switch to build the tree and eventually make routing decisions.
|
||||
type peerInfo struct {
|
||||
key crypto.SigPubKey // ID of this peer
|
||||
locator switchLocator // Should be able to respond with signatures upon request
|
||||
degree uint64 // Self-reported degree
|
||||
time time.Time // Time this node was last seen
|
||||
faster map[switchPort]uint64 // Counter of how often a node is faster than the current parent, penalized extra if slower
|
||||
port switchPort // Interface number of this peer
|
||||
|
@ -177,7 +159,6 @@ type switchData struct {
|
|||
// To be read/written with atomic.Value Store/Load calls
|
||||
locator switchLocator
|
||||
peers map[switchPort]peerInfo
|
||||
msg *switchMsg
|
||||
}
|
||||
|
||||
// All the information stored by the switch.
|
||||
|
@ -474,10 +455,7 @@ func (t *switchTable) _handleMsg(msg *switchMsg, fromPort switchPort, reprocessi
|
|||
return false
|
||||
}
|
||||
}
|
||||
if sender.locator.root == t.core.sigPub {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return sender.locator.root == t.core.sigPub
|
||||
}()
|
||||
dropTstamp, isIn := t.drop[sender.locator.root]
|
||||
// Decide if we need to update info about the root or change parents.
|
||||
|
|
|
@ -30,7 +30,6 @@ import (
|
|||
)
|
||||
|
||||
const default_timeout = 6 * time.Second
|
||||
const tcp_ping_interval = (default_timeout * 2 / 3)
|
||||
|
||||
// The TCP listener and information about active TCP connections, to avoid duplication.
|
||||
type tcp struct {
|
||||
|
@ -67,7 +66,7 @@ type tcpOptions struct {
|
|||
}
|
||||
|
||||
func (l *TcpListener) Stop() {
|
||||
defer func() { recover() }()
|
||||
defer func() { _ = recover() }()
|
||||
close(l.stop)
|
||||
}
|
||||
|
||||
|
@ -75,25 +74,14 @@ func (l *TcpListener) Stop() {
|
|||
func (t *tcp) setExtraOptions(c net.Conn) {
|
||||
switch sock := c.(type) {
|
||||
case *net.TCPConn:
|
||||
sock.SetNoDelay(true)
|
||||
if err := sock.SetNoDelay(true); err != nil {
|
||||
t.links.core.log.Errorln("Error setting no-delay:", err)
|
||||
}
|
||||
// TODO something for socks5
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the address of the listener.
|
||||
func (t *tcp) getAddr() *net.TCPAddr {
|
||||
// TODO: Fix this, because this will currently only give a single address
|
||||
// to multicast.go, which obviously is not great, but right now multicast.go
|
||||
// doesn't have the ability to send more than one address in a packet either
|
||||
t.mutex.Lock()
|
||||
defer t.mutex.Unlock()
|
||||
for _, l := range t.listeners {
|
||||
return l.Listener.Addr().(*net.TCPAddr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Initializes the struct.
|
||||
func (t *tcp) init(l *links) error {
|
||||
t.links = l
|
||||
|
|
|
@ -42,15 +42,6 @@ func wire_put_uint64(e uint64, out []byte) []byte {
|
|||
return append(out, b[i:]...)
|
||||
}
|
||||
|
||||
// Returns the length of a wire encoded uint64 of this value.
|
||||
func wire_uint64_len(elem uint64) int {
|
||||
l := 1
|
||||
for e := elem >> 7; e > 0; e >>= 7 {
|
||||
l++
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// Decode uint64 from a []byte slice.
|
||||
// Returns the decoded uint64 and the number of bytes used.
|
||||
func wire_decode_uint64(bs []byte) (uint64, int) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue