Tidy some lint errors

This commit is contained in:
Neil Alexander 2020-12-06 20:26:51 +00:00
parent b9f35c5530
commit fb6b828916
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
33 changed files with 125 additions and 656 deletions

View file

@ -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 {

View file

@ -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))
}
} 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()
}

View file

@ -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")

View file

@ -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

View file

@ -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()

View file

@ -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 {

View file

@ -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()
}

View file

@ -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

View file

@ -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

View file

@ -29,8 +29,6 @@ import (
"golang.org/x/sys/unix"
)
var awdlGoroutineStarted bool
func (m *Multicast) _multicastStarted() {
if !m.isOpen {
return

View file

@ -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()
}

View file

@ -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)
})
}

View file

@ -17,8 +17,6 @@ import (
"golang.org/x/net/ipv6"
)
const len_ETHER = 14
type ICMPv6 struct {
tun *TunAdapter
}

View file

@ -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 {

View file

@ -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)

View file

@ -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

View file

@ -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))
}

View file

@ -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:

View file

@ -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
}

View file

@ -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)

View file

@ -1,3 +1,5 @@
// +build debug
package yggdrasil
import (

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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() {

View file

@ -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

View file

@ -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)

View file

@ -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,6 +285,7 @@ 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
}
@ -299,6 +300,7 @@ func (ss *sessions) getSharedKey(myPriv *crypto.BoxPrivKey,
}
ss.permShared[*theirPub] = crypto.GetSharedKey(myPriv, theirPub)
return ss.permShared[*theirPub]
*/
}
// Sends a session ping by calling sendPingPong in ping mode.

View file

@ -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

View file

@ -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
}
}
// Writes metadata bytes without stream padding, meant to be temporary

View file

@ -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.

View file

@ -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

View file

@ -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) {