mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-12-22 18:45:40 +00:00
Run gofmt -s -w .
This commit is contained in:
parent
ae7b07ae6a
commit
b3ebe76b59
@ -22,15 +22,21 @@ var doSig = flag.Bool("sig", false, "generate new signing keys instead")
|
||||
func main() {
|
||||
flag.Parse()
|
||||
switch {
|
||||
case *doSig: doSigKeys()
|
||||
default: doBoxKeys()
|
||||
case *doSig:
|
||||
doSigKeys()
|
||||
default:
|
||||
doBoxKeys()
|
||||
}
|
||||
}
|
||||
|
||||
func isBetter(oldID, newID []byte) bool {
|
||||
for idx := range oldID {
|
||||
if newID[idx] > oldID[idx] { return true }
|
||||
if newID[idx] < oldID[idx] { return false }
|
||||
if newID[idx] > oldID[idx] {
|
||||
return true
|
||||
}
|
||||
if newID[idx] < oldID[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -45,7 +51,9 @@ func doBoxKeys() {
|
||||
for {
|
||||
pub, priv := c.DEBUG_newBoxKeys()
|
||||
id := c.DEBUG_getNodeID(pub)
|
||||
if !isBetter(bestID[:], id[:]) { continue }
|
||||
if !isBetter(bestID[:], id[:]) {
|
||||
continue
|
||||
}
|
||||
bestID = id
|
||||
ip := c.DEBUG_addrForNodeID(id)
|
||||
fmt.Println("--------------------------------------------------------------------------------")
|
||||
@ -66,7 +74,9 @@ func doSigKeys() {
|
||||
for {
|
||||
pub, priv := c.DEBUG_newSigKeys()
|
||||
id := c.DEBUG_getTreeID(pub)
|
||||
if !isBetter(bestID[:], id[:]) { continue }
|
||||
if !isBetter(bestID[:], id[:]) {
|
||||
continue
|
||||
}
|
||||
bestID = id
|
||||
fmt.Println("--------------------------------------------------------------------------------")
|
||||
fmt.Println("sigPriv:", hex.EncodeToString(priv[:]))
|
||||
@ -74,4 +84,3 @@ func doSigKeys() {
|
||||
fmt.Println("TreeID:", hex.EncodeToString(id[:]))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,9 @@ func makeStoreSquareGrid(sideLength int) map[router.NodeID]*Node {
|
||||
|
||||
func loadGraph(path string) map[router.NodeID]*Node {
|
||||
f, err := os.Open(path)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
store := make(map[router.NodeID]*Node)
|
||||
s := bufio.NewScanner(f)
|
||||
@ -136,7 +138,9 @@ func testPaths(store map[router.NodeID]*Node) {
|
||||
temp := 0
|
||||
for here := source; here != dest; {
|
||||
temp++
|
||||
if temp > 16 { panic("Loop?") }
|
||||
if temp > 16 {
|
||||
panic("Loop?")
|
||||
}
|
||||
next := here.links[here.table.Lookup(destLoc)]
|
||||
if next == here {
|
||||
//for idx, link := range here.links {
|
||||
|
@ -46,7 +46,9 @@ func (n *Node) startPeers() {
|
||||
|
||||
func linkNodes(m, n *Node) {
|
||||
// Don't allow duplicates
|
||||
if m.core.DEBUG_getPeers().DEBUG_hasPeer(n.core.DEBUG_getSigPub()) { return }
|
||||
if m.core.DEBUG_getPeers().DEBUG_hasPeer(n.core.DEBUG_getSigPub()) {
|
||||
return
|
||||
}
|
||||
// Create peers
|
||||
// Buffering reduces packet loss in the sim
|
||||
// This slightly speeds up testing (fewer delays before retrying a ping)
|
||||
@ -99,7 +101,9 @@ func makeStoreStar(nNodes int) map[int]*Node {
|
||||
|
||||
func loadGraph(path string) map[int]*Node {
|
||||
f, err := os.Open(path)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
store := make(map[int]*Node)
|
||||
s := bufio.NewScanner(f)
|
||||
@ -159,7 +163,9 @@ func testPaths(store map[[32]byte]*Node) bool {
|
||||
return false
|
||||
}
|
||||
temp++
|
||||
if temp > 4096 { panic("Loop?") }
|
||||
if temp > 4096 {
|
||||
panic("Loop?")
|
||||
}
|
||||
oldTTL = ttl
|
||||
nextPort, newTTL := here.core.DEBUG_switchLookup(coords, ttl)
|
||||
ttl = newTTL
|
||||
@ -195,7 +201,7 @@ func testPaths(store map[[32]byte]*Node) bool {
|
||||
dest.index, dest.core.DEBUG_getLocator())
|
||||
here.core.DEBUG_getSwitchTable().DEBUG_dumpTable()
|
||||
}
|
||||
if (here != source) {
|
||||
if here != source {
|
||||
// This is sufficient to check for routing loops or blackholes
|
||||
//break
|
||||
}
|
||||
@ -235,9 +241,13 @@ func pingNodes(store map[[32]byte]*Node) {
|
||||
nNodes := len(store)
|
||||
count := 0
|
||||
equiv := func(a []byte, b []byte) bool {
|
||||
if len(a) != len(b) { return false }
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for idx := 0; idx < len(a); idx++ {
|
||||
if a[idx] != b[idx] { return false }
|
||||
if a[idx] != b[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -268,7 +278,7 @@ func pingNodes(store map[[32]byte]*Node) {
|
||||
ch := make(chan bool, 1)
|
||||
ch <- true
|
||||
doTicker := func() {
|
||||
for _ = range ticker.C {
|
||||
for range ticker.C {
|
||||
select {
|
||||
case ch <- true:
|
||||
default:
|
||||
@ -278,12 +288,14 @@ func pingNodes(store map[[32]byte]*Node) {
|
||||
go doTicker()
|
||||
for loop := true; loop; {
|
||||
select {
|
||||
case packet := <-dest.recv: {
|
||||
case packet := <-dest.recv:
|
||||
{
|
||||
if equiv(payload, packet[len(packet)-len(payload):]) {
|
||||
loop = false
|
||||
}
|
||||
}
|
||||
case <-ch: sendTo(payload, destAddr)
|
||||
case <-ch:
|
||||
sendTo(payload, destAddr)
|
||||
}
|
||||
}
|
||||
ticker.Stop()
|
||||
@ -321,7 +333,10 @@ func pingBench(store map[[32]byte]*Node) {
|
||||
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++ }
|
||||
for i := 0; i < 1000000; i++ {
|
||||
source.send <- ping
|
||||
nPings++
|
||||
}
|
||||
timed += time.Since(start)
|
||||
break
|
||||
}
|
||||
@ -350,8 +365,12 @@ func dumpDHTSize(store map[[32]byte]*Node) {
|
||||
}
|
||||
for _, node := range store {
|
||||
num := node.core.DEBUG_getDHTSize()
|
||||
if num < min { min = num }
|
||||
if num > max { max = num }
|
||||
if num < min {
|
||||
min = num
|
||||
}
|
||||
if num > max {
|
||||
max = num
|
||||
}
|
||||
sum += num
|
||||
}
|
||||
avg := float64(sum) / float64(len(store))
|
||||
@ -400,11 +419,12 @@ func main() {
|
||||
//time.Sleep(10*time.Second)
|
||||
// Note that testPaths only works if pressure is turend off
|
||||
// Otherwise congestion can lead to routing loops?
|
||||
for finished := false; !finished ; { finished = testPaths(kstore) }
|
||||
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...
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,13 @@ import "time"
|
||||
|
||||
func main() {
|
||||
addr, err := net.ResolveTCPAddr("tcp", "[::1]:9001")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
listener, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
packetSize := 65535
|
||||
@ -16,27 +20,34 @@ func main () {
|
||||
|
||||
go func() {
|
||||
send, err := net.DialTCP("tcp", nil, addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
msg := make([]byte, packetSize)
|
||||
for idx := 0 ; idx < numPackets ; idx++ { send.Write(msg) }
|
||||
for idx := 0; idx < numPackets; idx++ {
|
||||
send.Write(msg)
|
||||
}
|
||||
}()
|
||||
|
||||
start := time.Now()
|
||||
//msg := make([]byte, 1280)
|
||||
sock, err := listener.AcceptTCP()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
read := 0
|
||||
buf := make([]byte, packetSize)
|
||||
for {
|
||||
n, err := sock.Read(buf)
|
||||
read += n
|
||||
if err != nil { break }
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
timed := time.Since(start)
|
||||
|
||||
fmt.Printf("%f packets per second\n", float64(numPackets)/timed.Seconds())
|
||||
fmt.Printf("%f bits/sec\n", 8*float64(read)/timed.Seconds())
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ type testStruct struct {
|
||||
Third []byte
|
||||
}
|
||||
|
||||
|
||||
func testFunc(tickerDuration time.Duration) {
|
||||
chn := make(chan []byte)
|
||||
ticker := time.NewTicker(tickerDuration)
|
||||
@ -22,7 +21,9 @@ func testFunc(tickerDuration time.Duration) {
|
||||
dec := gob.NewDecoder(buf)
|
||||
sendCall := func() {
|
||||
err := enc.EncodeValue(&send)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bs := make([]byte, buf.Len())
|
||||
buf.Read(bs)
|
||||
fmt.Println("send:", bs)
|
||||
@ -33,12 +34,16 @@ func testFunc(tickerDuration time.Duration) {
|
||||
recv := testStruct{}
|
||||
err := dec.DecodeValue(&recv)
|
||||
fmt.Println("recv:", bs)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case bs := <-chn : recvCall(bs)
|
||||
case <-ticker.C : sendCall()
|
||||
case bs := <-chn:
|
||||
recvCall(bs)
|
||||
case <-ticker.C:
|
||||
sendCall()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,4 +54,3 @@ func main() {
|
||||
go testFunc(time.Nanosecond) // Does crash
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
|
@ -11,16 +11,24 @@ func basic_test() {
|
||||
// TODO need a way to look up who our link-local neighbors are for each iface!
|
||||
//addr, err := net.ResolveUDPAddr("udp", "[ff02::1%veth0]:9001")
|
||||
addr, err := net.ResolveUDPAddr("udp", "[ff02::1]:9001")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sock, err := net.ListenMulticastUDP("udp", nil, addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
|
||||
go func() {
|
||||
saddr, err := net.ResolveUDPAddr("udp", "[::]:0")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
send, err := net.ListenUDP("udp", saddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
msg := make([]byte, 1280)
|
||||
for {
|
||||
|
@ -4,7 +4,6 @@ import "fmt"
|
||||
import "net"
|
||||
import "time"
|
||||
|
||||
|
||||
// TODO look into netmap + libpcap to bypass the kernel as much as possible
|
||||
|
||||
func basic_test() {
|
||||
@ -13,25 +12,37 @@ func basic_test() {
|
||||
|
||||
var ip *net.IP
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var zone string
|
||||
for _, iface := range ifaces {
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
addrIP, _, _ := net.ParseCIDR(addr.String())
|
||||
if addrIP.To4() != nil { continue } // IPv6 only
|
||||
if !addrIP.IsLinkLocalUnicast() { continue }
|
||||
if addrIP.To4() != nil {
|
||||
continue
|
||||
} // IPv6 only
|
||||
if !addrIP.IsLinkLocalUnicast() {
|
||||
continue
|
||||
}
|
||||
zone = iface.Name
|
||||
ip = &addrIP
|
||||
}
|
||||
addrs, err = iface.MulticastAddrs()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
fmt.Println(addr.String())
|
||||
}
|
||||
}
|
||||
if ip == nil { panic("No link-local IPv6 found") }
|
||||
if ip == nil {
|
||||
panic("No link-local IPv6 found")
|
||||
}
|
||||
fmt.Println("Using address:", *ip)
|
||||
|
||||
addr := net.UDPAddr{IP: *ip, Port: 9001, Zone: zone}
|
||||
@ -39,10 +50,14 @@ func basic_test() {
|
||||
saddr := net.UDPAddr{IP: *ip, Port: 9002, Zone: zone}
|
||||
send, err := net.ListenUDP("udp", &saddr)
|
||||
defer send.Close()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sock, err := net.ListenUDP("udp", &addr)
|
||||
defer sock.Close()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
const buffSize = 1048576 * 100
|
||||
|
||||
@ -50,7 +65,6 @@ func basic_test() {
|
||||
sock.SetReadBuffer(buffSize)
|
||||
sock.SetWriteBuffer(buffSize)
|
||||
|
||||
|
||||
go func() {
|
||||
msg := make([]byte, 1280)
|
||||
for {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
//import "net"
|
||||
import "time"
|
||||
import "runtime"
|
||||
@ -18,7 +19,8 @@ func poolbench() {
|
||||
f()
|
||||
select {
|
||||
case workers <- (ch):
|
||||
default: return
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
@ -26,8 +28,10 @@ func poolbench() {
|
||||
}
|
||||
getWorker := func() chan<- func() {
|
||||
select {
|
||||
case ch := <-workers: return ch
|
||||
default: return makeWorker()
|
||||
case ch := <-workers:
|
||||
return ch
|
||||
default:
|
||||
return makeWorker()
|
||||
}
|
||||
}
|
||||
dispatcher := func() {
|
||||
@ -44,7 +48,8 @@ func poolbench() {
|
||||
f := func() { atomic.AddUint64(&count, 1) }
|
||||
work <- f
|
||||
}
|
||||
for atomic.LoadUint64(&count) < nCounts {}
|
||||
for atomic.LoadUint64(&count) < nCounts {
|
||||
}
|
||||
}
|
||||
|
||||
func normalbench() {
|
||||
@ -67,7 +72,8 @@ func gobench() {
|
||||
f := func() { atomic.AddUint64(&count, 1) }
|
||||
go f()
|
||||
}
|
||||
for atomic.LoadUint64(&count) < nCounts {}
|
||||
for atomic.LoadUint64(&count) < nCounts {
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -1,17 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"bytes"
|
||||
"sync"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"math/big"
|
||||
"fmt"
|
||||
quic "github.com/lucas-clemente/quic-go"
|
||||
"math/big"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const addr = "[::1]:9001"
|
||||
@ -23,17 +23,25 @@ func main () {
|
||||
|
||||
func run_server() {
|
||||
listener, err := quic.ListenAddr(addr, generateTLSConfig(), nil)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ses, err := listener.Accept()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for {
|
||||
stream, err := ses.AcceptStream()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
defer stream.Close()
|
||||
bs := bytes.Buffer{}
|
||||
_, err := bs.ReadFrom(stream)
|
||||
if err != nil { panic(err) } //<-- TooManyOpenStreams
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} //<-- TooManyOpenStreams
|
||||
}()
|
||||
}
|
||||
}
|
||||
@ -42,7 +50,9 @@ func run_client() {
|
||||
msgSize := 1048576
|
||||
msgCount := 128
|
||||
ses, err := quic.DialAddr(addr, &tls.Config{InsecureSkipVerify: true}, nil)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bs := make([]byte, msgSize)
|
||||
wg := sync.WaitGroup{}
|
||||
start := time.Now()
|
||||
@ -51,7 +61,9 @@ func run_client() {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
stream, err := ses.OpenStreamSync()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer stream.Close()
|
||||
stream.Write(bs)
|
||||
}() // "go" this later
|
||||
@ -81,4 +93,3 @@ func generateTLSConfig() *tls.Config {
|
||||
}
|
||||
return &tls.Config{Certificates: []tls.Certificate{tlsCert}}
|
||||
}
|
||||
|
||||
|
@ -14,14 +14,20 @@ func basic_test() {
|
||||
// TODO need a way to look up who our link-local neighbors are for each iface!
|
||||
|
||||
addr, err := net.ResolveUDPAddr("udp", "[::1]:9001")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sock, err := net.ListenUDP("udp", addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
|
||||
go func() {
|
||||
send, err := net.DialUDP("udp", nil, addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
msg := make([]byte, 1280)
|
||||
for {
|
||||
@ -66,4 +72,3 @@ func main () {
|
||||
basic_test()
|
||||
|
||||
}
|
||||
|
||||
|
@ -14,14 +14,20 @@ func basic_test() {
|
||||
// TODO need a way to look up who our link-local neighbors are for each iface!
|
||||
|
||||
addr, err := net.ResolveUDPAddr("udp", "[::1]:9001")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sock, err := net.ListenUDP("udp", addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
|
||||
go func() {
|
||||
send, err := net.DialUDP("udp", nil, addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
msg := make([]byte, 1280)
|
||||
bss := make(net.Buffers, 0, 1024)
|
||||
@ -40,7 +46,9 @@ func basic_test() {
|
||||
msg := make([]byte, 2000)
|
||||
for i := 0; i < numPackets; i++ {
|
||||
n, err := sock.Read(msg)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(n)
|
||||
}
|
||||
timed := time.Since(start)
|
||||
@ -74,4 +82,3 @@ func main () {
|
||||
basic_test()
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,20 +15,30 @@ func basic_test() {
|
||||
|
||||
var ip *net.IP
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var zone string
|
||||
for _, iface := range ifaces {
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
addrIP, _, _ := net.ParseCIDR(addr.String())
|
||||
if addrIP.To4() != nil { continue } // IPv6 only
|
||||
if !addrIP.IsLinkLocalUnicast() { continue }
|
||||
if addrIP.To4() != nil {
|
||||
continue
|
||||
} // IPv6 only
|
||||
if !addrIP.IsLinkLocalUnicast() {
|
||||
continue
|
||||
}
|
||||
fmt.Println(iface.Name, addrIP)
|
||||
zone = iface.Name
|
||||
ip = &addrIP
|
||||
}
|
||||
if ip != nil { break }
|
||||
if ip != nil {
|
||||
break
|
||||
}
|
||||
/*
|
||||
addrs, err = iface.MulticastAddrs()
|
||||
if err != nil { panic(err) }
|
||||
@ -37,20 +47,28 @@ func basic_test() {
|
||||
}
|
||||
*/
|
||||
}
|
||||
if ip == nil { panic("No link-local IPv6 found") }
|
||||
if ip == nil {
|
||||
panic("No link-local IPv6 found")
|
||||
}
|
||||
fmt.Println("Using address:", *ip)
|
||||
addr := net.UDPAddr{IP: *ip, Port: 9001, Zone: zone}
|
||||
|
||||
laddr, err := net.ResolveUDPAddr("udp", "[::]:9001")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sock, err := net.ListenUDP("udp", laddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
|
||||
go func() {
|
||||
send, err := net.DialUDP("udp", nil, &addr)
|
||||
//send, err := net.ListenUDP("udp", nil)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
msg := make([]byte, 1280)
|
||||
for {
|
||||
@ -96,4 +114,3 @@ func main () {
|
||||
basic_test()
|
||||
|
||||
}
|
||||
|
||||
|
@ -16,14 +16,20 @@ func basic_test() {
|
||||
// TODO need a way to look up who our link-local neighbors are for each iface!
|
||||
|
||||
addr, err := net.ResolveTCPAddr("tcp", "[::1]:9001")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
listener, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
go func() {
|
||||
send, err := net.DialTCP("tcp", nil, addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
msg := make([]byte, 1280)
|
||||
bss := make(net.Buffers, 0, 1024)
|
||||
@ -41,12 +47,16 @@ func basic_test() {
|
||||
start := time.Now()
|
||||
//msg := make([]byte, 1280)
|
||||
sock, err := listener.AcceptTCP()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
for i := 0; i < numPackets; i++ {
|
||||
msg := make([]byte, 1280*buffSize)
|
||||
n, err := sock.Read(msg)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
msg = msg[:n]
|
||||
for len(msg) > 1286 {
|
||||
// handle message
|
||||
@ -60,7 +70,7 @@ func basic_test() {
|
||||
|
||||
fmt.Printf("%f packets per second\n", float64(numPackets)/timed.Seconds())
|
||||
|
||||
_ = func (in (chan<- int)) {
|
||||
_ = func(in chan<- int) {
|
||||
close(in)
|
||||
}
|
||||
|
||||
@ -91,4 +101,3 @@ func main () {
|
||||
basic_test()
|
||||
|
||||
}
|
||||
|
||||
|
@ -14,16 +14,22 @@ func basic_test() {
|
||||
// TODO need a way to look up who our link-local neighbors are for each iface!
|
||||
|
||||
addr, err := net.ResolveUDPAddr("udp", "[::1]:0")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sock, err := net.ListenUDP("udp", addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
|
||||
go func() {
|
||||
raddr := sock.LocalAddr().(*net.UDPAddr)
|
||||
send, err := net.DialUDP("udp", nil, raddr)
|
||||
//send, err := net.ListenUDP("udp", addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
msg := make([]byte, 1280)
|
||||
for {
|
||||
@ -69,4 +75,3 @@ func main () {
|
||||
basic_test()
|
||||
|
||||
}
|
||||
|
||||
|
@ -14,16 +14,24 @@ func basic_test() {
|
||||
// TODO need a way to look up who our link-local neighbors are for each iface!
|
||||
|
||||
saddr, err := net.ResolveUDPAddr("udp", "[::1]:9001")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
raddr, err := net.ResolveUDPAddr("udp", "[::1]:9002")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
send, err := net.DialUDP("udp", saddr, raddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
|
||||
recv, err := net.DialUDP("udp", raddr, saddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer recv.Close()
|
||||
|
||||
go func() {
|
||||
@ -69,4 +77,3 @@ func main () {
|
||||
basic_test()
|
||||
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,9 @@ func basic_test() {
|
||||
// TODO need a way to look up who our link-local neighbors are for each iface!
|
||||
|
||||
sock, err := net.ListenUDP("udp", nil)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
|
||||
ch := make(chan []byte, 1)
|
||||
@ -46,10 +48,13 @@ func basic_test() {
|
||||
for i := 0; i < numPackets; i++ {
|
||||
msg := make([]byte, 2048)
|
||||
n, _, err := sock.ReadFromUDP(msg)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
size += n
|
||||
select {
|
||||
case ch <- msg: success += 1
|
||||
case ch <- msg:
|
||||
success += 1
|
||||
default:
|
||||
}
|
||||
}
|
||||
@ -85,4 +90,3 @@ func main () {
|
||||
basic_test()
|
||||
|
||||
}
|
||||
|
||||
|
@ -16,15 +16,21 @@ func basic_test() {
|
||||
// TODO need a way to look up who our link-local neighbors are for each iface!
|
||||
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sock, err := net.ListenUDP("udp", udpAddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
|
||||
writer := func() {
|
||||
raddr := sock.LocalAddr().(*net.UDPAddr)
|
||||
send, err := net.ListenUDP("udp", nil)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
conn := ipv6.NewPacketConn(send)
|
||||
defer conn.Close()
|
||||
@ -79,7 +85,9 @@ func basic_test() {
|
||||
for ; count < numPackets; count++ {
|
||||
msg := make([]byte, 2048)
|
||||
n, _, err := sock.ReadFromUDP(msg)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
size += n
|
||||
}
|
||||
//*/
|
||||
@ -114,4 +122,3 @@ func main () {
|
||||
basic_test()
|
||||
|
||||
}
|
||||
|
||||
|
@ -16,14 +16,20 @@ func basic_test() {
|
||||
// TODO need a way to look up who our link-local neighbors are for each iface!
|
||||
|
||||
addr, err := net.ResolveTCPAddr("tcp", "[::1]:9001")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
listener, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
go func() {
|
||||
send, err := net.DialTCP("tcp", nil, addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer send.Close()
|
||||
msg := make([]byte, 1280)
|
||||
bss := make(net.Buffers, 0, 1024)
|
||||
@ -43,12 +49,16 @@ func basic_test() {
|
||||
start := time.Now()
|
||||
//msg := make([]byte, 1280)
|
||||
sock, err := listener.AcceptTCP()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sock.Close()
|
||||
for {
|
||||
msg := make([]byte, 1280*buffSize)
|
||||
n, err := sock.Read(msg)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
msg = msg[:n]
|
||||
fmt.Println("Read:", n)
|
||||
for len(msg) > 1280 {
|
||||
@ -62,7 +72,7 @@ func basic_test() {
|
||||
|
||||
fmt.Printf("%f packets per second\n", float64(numPackets)/timed.Seconds())
|
||||
|
||||
_ = func (in (chan<- int)) {
|
||||
_ = func(in chan<- int) {
|
||||
close(in)
|
||||
}
|
||||
|
||||
@ -93,4 +103,3 @@ func main () {
|
||||
basic_test()
|
||||
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,9 @@ func setup_dev1() *water.Interface {
|
||||
|
||||
func connect(ifce *water.Interface) {
|
||||
conn, err := net.DialTimeout("tcp", "192.168.2.2:9001", time.Second)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sock := conn.(*net.TCPConn)
|
||||
// TODO go a worker to move packets to/from the tun
|
||||
}
|
||||
@ -79,4 +81,3 @@ func main() {
|
||||
log.Printf("Packet Received: % x\n", packet[:n])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,4 +124,3 @@ func main() {
|
||||
log.Printf("Packet Received: % x\n", packet[:n])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,6 @@ func setup_dev2() *water.Interface {
|
||||
fmt.Println(string(out))
|
||||
panic("Failed to move tun to netns")
|
||||
}
|
||||
cmd =
|
||||
cmd = exec.Command(
|
||||
"ip", "-f", "inet6",
|
||||
"addr", "add", "fc00::2/8",
|
||||
@ -127,4 +126,3 @@ func main() {
|
||||
log.Printf("Packet Received: % x\n", packet[:n])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,12 +29,16 @@ func main() {
|
||||
|
||||
address := net.ParseIP("fc00::1")
|
||||
tuntap, err := tun.OpenTun(address)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer tuntap.Close()
|
||||
// read data from tun into rCh channel.
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
if err := tuntap.Read(rCh); err != nil { panic(err) }
|
||||
if err := tuntap.Read(rCh); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
|
@ -11,7 +11,9 @@ func main() {
|
||||
encoded := make([]byte, 10)
|
||||
length := wire.Encode_uint64(num, encoded)
|
||||
decoded, _ := wire.Decode_uint64(encoded[:length])
|
||||
if decoded != num { panic(fmt.Sprintf("%d != %d", decoded, num)) }
|
||||
if decoded != num {
|
||||
panic(fmt.Sprintf("%d != %d", decoded, num))
|
||||
}
|
||||
}
|
||||
const count = 1000000
|
||||
start := time.Now()
|
||||
@ -36,4 +38,3 @@ func main() {
|
||||
fmt.Println("Ops:", count/timed.Seconds())
|
||||
fmt.Println("Time:", timed.Nanoseconds()/count)
|
||||
}
|
||||
|
||||
|
@ -7,14 +7,18 @@ var address_prefix = [...]byte{0xfd} // For node addresses + local subnets
|
||||
|
||||
func (a *address) isValid() bool {
|
||||
for idx := range address_prefix {
|
||||
if (*a)[idx] != address_prefix[idx] { return false }
|
||||
if (*a)[idx] != address_prefix[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return (*a)[len(address_prefix)]&0x80 == 0
|
||||
}
|
||||
|
||||
func (s *subnet) isValid() bool {
|
||||
for idx := range address_prefix {
|
||||
if (*s)[idx] != address_prefix[idx] { return false }
|
||||
if (*s)[idx] != address_prefix[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return (*s)[len(address_prefix)]&0x80 != 0
|
||||
}
|
||||
@ -72,7 +76,9 @@ func (a *address) getNodeIDandMask() (*NodeID, *NodeID) {
|
||||
var nid NodeID
|
||||
var mask NodeID
|
||||
ones := int(a[len(address_prefix)] & 0x7f)
|
||||
for idx := 0 ; idx < ones ; idx++ { nid[idx/8] |= 0x80 >> byte(idx % 8) }
|
||||
for idx := 0; idx < ones; idx++ {
|
||||
nid[idx/8] |= 0x80 >> byte(idx%8)
|
||||
}
|
||||
nidOffset := ones + 1
|
||||
addrOffset := 8*len(address_prefix) + 8
|
||||
for idx := addrOffset; idx < 8*len(a); idx++ {
|
||||
@ -83,7 +89,9 @@ func (a *address) getNodeIDandMask() (*NodeID, *NodeID) {
|
||||
nid[nidIdx/8] |= bits
|
||||
}
|
||||
maxMask := 8*(len(a)-len(address_prefix)-1) + ones + 1
|
||||
for idx := 0 ; idx < maxMask ; idx++ { mask[idx/8] |= 0x80 >> byte(idx % 8) }
|
||||
for idx := 0; idx < maxMask; idx++ {
|
||||
mask[idx/8] |= 0x80 >> byte(idx%8)
|
||||
}
|
||||
return &nid, &mask
|
||||
}
|
||||
|
||||
@ -92,7 +100,9 @@ func (s *subnet) getNodeIDandMask() (*NodeID, *NodeID) {
|
||||
var nid NodeID
|
||||
var mask NodeID
|
||||
ones := int(s[len(address_prefix)] & 0x7f)
|
||||
for idx := 0 ; idx < ones ; idx++ { nid[idx/8] |= 0x80 >> byte(idx % 8) }
|
||||
for idx := 0; idx < ones; idx++ {
|
||||
nid[idx/8] |= 0x80 >> byte(idx%8)
|
||||
}
|
||||
nidOffset := ones + 1
|
||||
addrOffset := 8*len(address_prefix) + 8
|
||||
for idx := addrOffset; idx < 8*len(s); idx++ {
|
||||
@ -103,6 +113,8 @@ func (s *subnet) getNodeIDandMask() (*NodeID, *NodeID) {
|
||||
nid[nidIdx/8] |= bits
|
||||
}
|
||||
maxMask := 8*(len(s)-len(address_prefix)-1) + ones + 1
|
||||
for idx := 0 ; idx < maxMask ; idx++ { mask[idx/8] |= 0x80 >> byte(idx % 8) }
|
||||
for idx := 0; idx < maxMask; idx++ {
|
||||
mask[idx/8] |= 0x80 >> byte(idx%8)
|
||||
}
|
||||
return &nid, &mask
|
||||
}
|
||||
|
@ -61,4 +61,3 @@ func (c *Core) GetNodeID() *NodeID {
|
||||
func (c *Core) GetTreeID() *TreeID {
|
||||
return getTreeID(&c.sigPub)
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,9 @@ func getTreeID(pub *sigPubKey) *TreeID {
|
||||
func newHandle() *handle {
|
||||
var h handle
|
||||
_, err := rand.Read(h[:])
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &h
|
||||
}
|
||||
|
||||
@ -60,7 +62,9 @@ func newSigKeys() (*sigPubKey, *sigPrivKey) {
|
||||
var pub sigPubKey
|
||||
var priv sigPrivKey
|
||||
pubSlice, privSlice, err := ed25519.GenerateKey(rand.Reader)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
copy(pub[:], pubSlice)
|
||||
copy(priv[:], privSlice)
|
||||
return &pub, &priv
|
||||
@ -95,7 +99,9 @@ type boxNonce [boxNonceLen]byte
|
||||
|
||||
func newBoxKeys() (*boxPubKey, *boxPrivKey) {
|
||||
pubBytes, privBytes, err := box.GenerateKey(rand.Reader)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pub := (*boxPubKey)(pubBytes)
|
||||
priv := (*boxPrivKey)(privBytes)
|
||||
return pub, priv
|
||||
@ -122,7 +128,9 @@ func boxOpen(shared *boxSharedKey,
|
||||
}
|
||||
|
||||
func boxSeal(shared *boxSharedKey, unboxed []byte, nonce *boxNonce) ([]byte, *boxNonce) {
|
||||
if nonce == nil { nonce = newBoxNonce() }
|
||||
if nonce == nil {
|
||||
nonce = newBoxNonce()
|
||||
}
|
||||
nonce.update()
|
||||
out := util_getBytes()
|
||||
//return append(out, unboxed...), nonce // XXX HACK to test without encryption
|
||||
@ -140,7 +148,9 @@ func newBoxNonce() *boxNonce {
|
||||
// This is just to make rollover unlikely to happen
|
||||
// Rollover is fine, but it may kill the session and force it to reopen
|
||||
}
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &nonce
|
||||
}
|
||||
|
||||
@ -148,7 +158,8 @@ func (n *boxNonce) update() {
|
||||
oldNonce := *n
|
||||
n[len(n)-1] += 2
|
||||
for i := len(n) - 2; i >= 0; i-- {
|
||||
if n[i+1] < oldNonce[i+1] { n[i] += 1 }
|
||||
if n[i+1] < oldNonce[i+1] {
|
||||
n[i] += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,11 +22,11 @@ func (c *Core) DEBUG_getBoxPub() boxPubKey {
|
||||
return (boxPubKey)(c.boxPub)
|
||||
}
|
||||
|
||||
func (c *Core) DEBUG_getSend() (chan<- []byte) {
|
||||
func (c *Core) DEBUG_getSend() chan<- []byte {
|
||||
return c.tun.send
|
||||
}
|
||||
|
||||
func (c *Core) DEBUG_getRecv() (<-chan []byte) {
|
||||
func (c *Core) DEBUG_getRecv() <-chan []byte {
|
||||
return c.tun.recv
|
||||
}
|
||||
|
||||
@ -57,8 +57,12 @@ func (ps *peers) DEBUG_startPeers() {
|
||||
func (ps *peers) DEBUG_hasPeer(key sigPubKey) bool {
|
||||
ports := ps.ports.Load().(map[switchPort]*peer)
|
||||
for _, p := range ports {
|
||||
if p == nil { continue }
|
||||
if p.sig == key { return true }
|
||||
if p == nil {
|
||||
continue
|
||||
}
|
||||
if p.sig == key {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -127,9 +131,13 @@ func (t *switchTable) DEBUG_getReversePort(port switchPort) switchPort {
|
||||
t.mutex.RLock()
|
||||
defer t.mutex.RUnlock()
|
||||
data := t.data
|
||||
if port >= switchPort(len(data.peers)) { return switchPort(0) }
|
||||
if port >= switchPort(len(data.peers)) {
|
||||
return switchPort(0)
|
||||
}
|
||||
pinfo := data.peers[port]
|
||||
if len(pinfo.locator.coords) < 1 { return switchPort(0) }
|
||||
if len(pinfo.locator.coords) < 1 {
|
||||
return switchPort(0)
|
||||
}
|
||||
return pinfo.locator.coords[len(pinfo.locator.coords)-1]
|
||||
}
|
||||
|
||||
@ -204,7 +212,9 @@ func (c *Core) DEBUG_startTunWithMTU(ifname string, mtu int) {
|
||||
addr := c.DEBUG_getAddr()
|
||||
straddr := fmt.Sprintf("%s/%v", net.IP(addr[:]).String(), 8*len(address_prefix))
|
||||
err := c.tun.setup(ifname, straddr, mtu)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go c.tun.read()
|
||||
go c.tun.write()
|
||||
}
|
||||
@ -267,7 +277,9 @@ func (c *Core) DEBUG_maybeSendUDPKeys(saddr string) {
|
||||
c.udp.mutex.RLock()
|
||||
_, isIn := c.udp.conns[connAddr(addr)]
|
||||
c.udp.mutex.RUnlock()
|
||||
if !isIn { c.udp.sendKeys(addr) }
|
||||
if !isIn {
|
||||
c.udp.sendKeys(addr)
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -286,6 +298,7 @@ func (c *Core) DEBUG_getGlobalTCPAddr() *net.TCPAddr {
|
||||
func (c *Core) DEBUG_addTCPConn(saddr string) {
|
||||
c.tcp.call(saddr)
|
||||
}
|
||||
|
||||
//*/
|
||||
|
||||
/*
|
||||
@ -336,4 +349,3 @@ func DEBUG_simLinkPeers(p, q *peer) {
|
||||
go p.linkLoop(plinkIn)
|
||||
go q.linkLoop(qlinkIn)
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ Slight changes *do* make it blackhole hard, bootstrapping isn't an easy problem
|
||||
|
||||
import "sort"
|
||||
import "time"
|
||||
|
||||
//import "fmt"
|
||||
|
||||
// Maximum size for buckets and lookups
|
||||
@ -104,9 +105,13 @@ func (t *dht) handleReq(req *dhtReq) {
|
||||
|
||||
func (t *dht) handleRes(res *dhtRes) {
|
||||
reqs, isIn := t.reqs[res.key]
|
||||
if !isIn { return }
|
||||
if !isIn {
|
||||
return
|
||||
}
|
||||
_, isIn = reqs[res.dest]
|
||||
if !isIn { return }
|
||||
if !isIn {
|
||||
return
|
||||
}
|
||||
rinfo := dhtInfo{
|
||||
key: res.key,
|
||||
coords: res.coords,
|
||||
@ -115,14 +120,20 @@ func (t *dht) handleRes(res *dhtRes) {
|
||||
}
|
||||
// If they're already in the table, then keep the correct send time
|
||||
bidx, isOK := t.getBucketIndex(rinfo.getNodeID())
|
||||
if !isOK { return }
|
||||
if !isOK {
|
||||
return
|
||||
}
|
||||
b := t.getBucket(bidx)
|
||||
for _, oldinfo := range b.infos {
|
||||
if oldinfo.key == rinfo.key {rinfo.send = oldinfo.send }
|
||||
if oldinfo.key == rinfo.key {
|
||||
rinfo.send = oldinfo.send
|
||||
}
|
||||
}
|
||||
// Insert into table
|
||||
t.insert(&rinfo)
|
||||
if res.dest == *rinfo.getNodeID() { return } // No infinite recursions
|
||||
if res.dest == *rinfo.getNodeID() {
|
||||
return
|
||||
} // No infinite recursions
|
||||
// ping the nodes we were told about
|
||||
if len(res.infos) > dht_lookup_size {
|
||||
// Ignore any "extra" lookup results
|
||||
@ -130,9 +141,13 @@ func (t *dht) handleRes(res *dhtRes) {
|
||||
}
|
||||
for _, info := range res.infos {
|
||||
bidx, isOK := t.getBucketIndex(info.getNodeID())
|
||||
if !isOK { continue }
|
||||
if !isOK {
|
||||
continue
|
||||
}
|
||||
b := t.getBucket(bidx)
|
||||
if b.contains(info) { continue } // wait for maintenance cycle to get them
|
||||
if b.contains(info) {
|
||||
continue
|
||||
} // wait for maintenance cycle to get them
|
||||
t.ping(info, info.getNodeID())
|
||||
}
|
||||
}
|
||||
@ -140,9 +155,11 @@ func (t *dht) handleRes(res *dhtRes) {
|
||||
func (t *dht) lookup(nodeID *NodeID) []*dhtInfo {
|
||||
// FIXME this allocates a bunch, sorts, and keeps the part it likes
|
||||
// It would be better to only track the part it likes to begin with
|
||||
addInfos := func (res []*dhtInfo, infos []*dhtInfo) ([]*dhtInfo) {
|
||||
addInfos := func(res []*dhtInfo, infos []*dhtInfo) []*dhtInfo {
|
||||
for _, info := range infos {
|
||||
if info == nil { panic ("Should never happen!") }
|
||||
if info == nil {
|
||||
panic("Should never happen!")
|
||||
}
|
||||
if true || dht_firstCloserThanThird(info.getNodeID(), nodeID, &t.nodeID) {
|
||||
res = append(res, info)
|
||||
}
|
||||
@ -163,7 +180,9 @@ func (t *dht) lookup(nodeID *NodeID) []*dhtInfo {
|
||||
sort.SliceStable(infos, less)
|
||||
}
|
||||
doSort(res)
|
||||
if len(res) > dht_lookup_size { res = res[:dht_lookup_size] }
|
||||
if len(res) > dht_lookup_size {
|
||||
res = res[:dht_lookup_size]
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@ -180,7 +199,9 @@ func (t *dht) insertIfNew(info *dhtInfo) {
|
||||
// Insert a peer if and only if the bucket doesn't already contain it
|
||||
nodeID := info.getNodeID()
|
||||
bidx, isOK := t.getBucketIndex(nodeID)
|
||||
if !isOK { return }
|
||||
if !isOK {
|
||||
return
|
||||
}
|
||||
b := t.getBucket(bidx)
|
||||
if !b.contains(info) {
|
||||
// We've never heard this node before
|
||||
@ -199,25 +220,35 @@ func (t *dht) insert(info *dhtInfo) {
|
||||
// Get the bucket for this node
|
||||
nodeID := info.getNodeID()
|
||||
bidx, isOK := t.getBucketIndex(nodeID)
|
||||
if !isOK { return }
|
||||
if !isOK {
|
||||
return
|
||||
}
|
||||
b := t.getBucket(bidx)
|
||||
// First drop any existing entry from the bucket
|
||||
b.drop(&info.key)
|
||||
// Now add to the *end* of the bucket
|
||||
b.infos = append(b.infos, info)
|
||||
// Check if the next bucket is non-full and return early if it is
|
||||
if bidx+1 == t.nBuckets() { return }
|
||||
if bidx+1 == t.nBuckets() {
|
||||
return
|
||||
}
|
||||
bnext := t.getBucket(bidx + 1)
|
||||
if len(bnext.infos) < dht_bucket_size { return }
|
||||
if len(bnext.infos) < dht_bucket_size {
|
||||
return
|
||||
}
|
||||
// Shrink from the *front* to requied size
|
||||
for len(b.infos) > dht_bucket_size { b.infos = b.infos[1:] }
|
||||
for len(b.infos) > dht_bucket_size {
|
||||
b.infos = b.infos[1:]
|
||||
}
|
||||
}
|
||||
|
||||
func (t *dht) getBucketIndex(nodeID *NodeID) (int, bool) {
|
||||
for bidx := 0; bidx < t.nBuckets(); bidx++ {
|
||||
them := nodeID[bidx/8] & (0x80 >> byte(bidx%8))
|
||||
me := t.nodeID[bidx/8] & (0x80 >> byte(bidx%8))
|
||||
if them != me { return bidx, true }
|
||||
if them != me {
|
||||
return bidx, true
|
||||
}
|
||||
}
|
||||
return t.nBuckets(), false
|
||||
}
|
||||
@ -225,11 +256,17 @@ func (t *dht) getBucketIndex(nodeID *NodeID) (int, bool) {
|
||||
func (b *bucket) contains(ninfo *dhtInfo) bool {
|
||||
// Compares if key and coords match
|
||||
for _, info := range b.infos {
|
||||
if info == nil { panic("Should never happen") }
|
||||
if info == nil {
|
||||
panic("Should never happen")
|
||||
}
|
||||
if info.key == ninfo.key {
|
||||
if len(info.coords) != len(ninfo.coords) { return false }
|
||||
if len(info.coords) != len(ninfo.coords) {
|
||||
return false
|
||||
}
|
||||
for idx := 0; idx < len(info.coords); idx++ {
|
||||
if info.coords[idx] != ninfo.coords[idx] { return false }
|
||||
if info.coords[idx] != ninfo.coords[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -241,7 +278,9 @@ func (b *bucket) drop(key *boxPubKey) {
|
||||
clean := func(infos []*dhtInfo) []*dhtInfo {
|
||||
cleaned := infos[:0]
|
||||
for _, info := range infos {
|
||||
if info.key == *key { continue }
|
||||
if info.key == *key {
|
||||
continue
|
||||
}
|
||||
cleaned = append(cleaned, info)
|
||||
}
|
||||
return cleaned
|
||||
@ -268,7 +307,9 @@ func (t *dht) sendReq(req *dhtReq, dest *dhtInfo) {
|
||||
if !isIn {
|
||||
t.reqs[dest.key] = make(map[NodeID]time.Time)
|
||||
reqsToDest, isIn = t.reqs[dest.key]
|
||||
if !isIn { panic("This should never happen") }
|
||||
if !isIn {
|
||||
panic("This should never happen")
|
||||
}
|
||||
}
|
||||
reqsToDest[req.dest] = time.Now()
|
||||
}
|
||||
@ -302,8 +343,12 @@ func (b *bucket) nextToPing() *dhtInfo {
|
||||
// And time between traffic loss from short term congestion in the network
|
||||
var toPing *dhtInfo
|
||||
for _, next := range b.infos {
|
||||
if time.Since(next.send) < 6*time.Second { continue }
|
||||
if toPing == nil || next.recv.Before(toPing.recv) { toPing = next }
|
||||
if time.Since(next.send) < 6*time.Second {
|
||||
continue
|
||||
}
|
||||
if toPing == nil || next.recv.Before(toPing.recv) {
|
||||
toPing = next
|
||||
}
|
||||
}
|
||||
return toPing
|
||||
}
|
||||
@ -317,12 +362,16 @@ func (t *dht) getTarget(bidx int) *NodeID {
|
||||
func (t *dht) ping(info *dhtInfo, target *NodeID) {
|
||||
if info.pings > 2 {
|
||||
bidx, isOK := t.getBucketIndex(info.getNodeID())
|
||||
if !isOK { panic("This should never happen") }
|
||||
if !isOK {
|
||||
panic("This should never happen")
|
||||
}
|
||||
b := t.getBucket(bidx)
|
||||
b.drop(&info.key)
|
||||
return
|
||||
}
|
||||
if target == nil { target = &t.nodeID }
|
||||
if target == nil {
|
||||
target = &t.nodeID
|
||||
}
|
||||
loc := t.core.switchTable.getLocator()
|
||||
coords := loc.getCoords()
|
||||
req := dhtReq{
|
||||
@ -339,9 +388,13 @@ func (t *dht) doMaintenance() {
|
||||
// First clean up reqs
|
||||
for key, reqs := range t.reqs {
|
||||
for target, timeout := range reqs {
|
||||
if time.Since(timeout) > time.Minute { delete(reqs, target) }
|
||||
if time.Since(timeout) > time.Minute {
|
||||
delete(reqs, target)
|
||||
}
|
||||
}
|
||||
if len(reqs) == 0 {
|
||||
delete(t.reqs, key)
|
||||
}
|
||||
if len(reqs) == 0 { delete(t.reqs, key) }
|
||||
}
|
||||
// Ping the least recently contacted node
|
||||
// This is to make sure we eventually notice when someone times out
|
||||
@ -352,15 +405,21 @@ func (t *dht) doMaintenance() {
|
||||
if !b.isEmpty() {
|
||||
last = bidx
|
||||
toPing := b.nextToPing()
|
||||
if toPing == nil { continue } // We've recently pinged everyone in b
|
||||
if toPing == nil {
|
||||
continue
|
||||
} // We've recently pinged everyone in b
|
||||
if oldest == nil || toPing.recv.Before(oldest.recv) {
|
||||
oldest = toPing
|
||||
}
|
||||
}
|
||||
}
|
||||
if oldest != nil { t.ping(oldest, nil) } // if the DHT isn't empty
|
||||
if oldest != nil {
|
||||
t.ping(oldest, nil)
|
||||
} // if the DHT isn't empty
|
||||
// Refresh buckets
|
||||
if t.offset > last { t.offset = 0 }
|
||||
if t.offset > last {
|
||||
t.offset = 0
|
||||
}
|
||||
target := t.getTarget(t.offset)
|
||||
for _, info := range t.lookup(target) {
|
||||
t.ping(info, target)
|
||||
@ -375,9 +434,10 @@ func dht_firstCloserThanThird(first *NodeID,
|
||||
for idx := 0; idx < NodeIDLen; idx++ {
|
||||
f := first[idx] ^ second[idx]
|
||||
t := third[idx] ^ second[idx]
|
||||
if f == t { continue }
|
||||
if f == t {
|
||||
continue
|
||||
}
|
||||
return f < t
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ import "time"
|
||||
import "sync"
|
||||
import "sync/atomic"
|
||||
import "math"
|
||||
|
||||
//import "fmt"
|
||||
|
||||
type peers struct {
|
||||
@ -58,6 +59,7 @@ type peer struct {
|
||||
// Resets at the start of each tick
|
||||
throttle uint8
|
||||
}
|
||||
|
||||
const peer_Throttle = 1
|
||||
|
||||
func (p *peer) getBandwidth() float64 {
|
||||
@ -66,7 +68,9 @@ func (p *peer) getBandwidth() float64 {
|
||||
}
|
||||
|
||||
func (p *peer) updateBandwidth(bytes int, duration time.Duration) {
|
||||
if p == nil { return }
|
||||
if p == nil {
|
||||
return
|
||||
}
|
||||
for ok := false; !ok; {
|
||||
oldBits := atomic.LoadUint64(&p.bandwidth)
|
||||
oldBandwidth := math.Float64frombits(oldBits)
|
||||
@ -90,7 +94,9 @@ func (ps *peers) newPeer(box *boxPubKey,
|
||||
defer ps.mutex.Unlock()
|
||||
oldPorts := ps.getPorts()
|
||||
newPorts := make(map[switchPort]*peer)
|
||||
for k,v := range oldPorts{ newPorts[k] = v }
|
||||
for k, v := range oldPorts {
|
||||
newPorts[k] = v
|
||||
}
|
||||
for idx := switchPort(0); true; idx++ {
|
||||
if _, isIn := newPorts[idx]; !isIn {
|
||||
p.port = switchPort(idx)
|
||||
@ -108,11 +114,16 @@ func (p *peer) linkLoop(in <-chan []byte) {
|
||||
for {
|
||||
select {
|
||||
case packet, ok := <-in:
|
||||
if !ok { return }
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
p.handleLinkTraffic(packet)
|
||||
case <-ticker.C: {
|
||||
case <-ticker.C:
|
||||
{
|
||||
p.throttle = 0
|
||||
if p.port == 0 { continue } // Don't send announces on selfInterface
|
||||
if p.port == 0 {
|
||||
continue
|
||||
} // Don't send announces on selfInterface
|
||||
// Maybe we shouldn't time out, and instead wait for a kill signal?
|
||||
p.myMsg, p.mySigs = p.core.switchTable.createMessage(p.port)
|
||||
p.sendSwitchAnnounce()
|
||||
@ -121,19 +132,25 @@ func (p *peer) linkLoop(in <-chan []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *peer) handlePacket(packet []byte, linkIn (chan<- []byte)) {
|
||||
func (p *peer) handlePacket(packet []byte, linkIn chan<- []byte) {
|
||||
pType, pTypeLen := wire_decode_uint64(packet)
|
||||
if pTypeLen==0 { return }
|
||||
switch (pType) {
|
||||
case wire_Traffic: p.handleTraffic(packet, pTypeLen)
|
||||
case wire_ProtocolTraffic: p.handleTraffic(packet, pTypeLen)
|
||||
case wire_LinkProtocolTraffic: {
|
||||
if pTypeLen == 0 {
|
||||
return
|
||||
}
|
||||
switch pType {
|
||||
case wire_Traffic:
|
||||
p.handleTraffic(packet, pTypeLen)
|
||||
case wire_ProtocolTraffic:
|
||||
p.handleTraffic(packet, pTypeLen)
|
||||
case wire_LinkProtocolTraffic:
|
||||
{
|
||||
select {
|
||||
case linkIn <- packet:
|
||||
default:
|
||||
}
|
||||
}
|
||||
default: /*panic(pType) ;*/ return
|
||||
default: /*panic(pType) ;*/
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,11 +160,17 @@ func (p *peer) handleTraffic(packet []byte, pTypeLen int) {
|
||||
ttlEnd := pTypeLen + ttlLen
|
||||
coords, coordLen := wire_decode_coords(packet[ttlEnd:])
|
||||
coordEnd := ttlEnd + coordLen
|
||||
if coordEnd == len(packet) { return } // No payload
|
||||
if coordEnd == len(packet) {
|
||||
return
|
||||
} // No payload
|
||||
toPort, newTTL := p.core.switchTable.lookup(coords, ttl)
|
||||
if toPort == p.port { return } // FIXME? shouldn't happen, does it? would loop
|
||||
if toPort == p.port {
|
||||
return
|
||||
} // FIXME? shouldn't happen, does it? would loop
|
||||
to := p.core.peers.getPorts()[toPort]
|
||||
if to == nil { return }
|
||||
if to == nil {
|
||||
return
|
||||
}
|
||||
newTTLSlice := wire_encode_uint64(newTTL)
|
||||
// This mutates the packet in-place if the length of the TTL changes!
|
||||
shift := ttlLen - len(newTTLSlice)
|
||||
@ -178,17 +201,30 @@ func (p *peer) sendLinkPacket(packet []byte) {
|
||||
func (p *peer) handleLinkTraffic(bs []byte) {
|
||||
packet := wire_linkProtoTrafficPacket{}
|
||||
// TODO throttle on returns?
|
||||
if !packet.decode(bs) { return }
|
||||
if packet.toKey != p.core.boxPub { return }
|
||||
if packet.fromKey != p.box { return }
|
||||
if !packet.decode(bs) {
|
||||
return
|
||||
}
|
||||
if packet.toKey != p.core.boxPub {
|
||||
return
|
||||
}
|
||||
if packet.fromKey != p.box {
|
||||
return
|
||||
}
|
||||
payload, isOK := boxOpen(&p.shared, packet.payload, &packet.nonce)
|
||||
if !isOK { return }
|
||||
if !isOK {
|
||||
return
|
||||
}
|
||||
pType, pTypeLen := wire_decode_uint64(payload)
|
||||
if pTypeLen == 0 { return }
|
||||
if pTypeLen == 0 {
|
||||
return
|
||||
}
|
||||
switch pType {
|
||||
case wire_SwitchAnnounce: p.handleSwitchAnnounce(payload)
|
||||
case wire_SwitchHopRequest: p.handleSwitchHopRequest(payload)
|
||||
case wire_SwitchHop: p.handleSwitchHop(payload)
|
||||
case wire_SwitchAnnounce:
|
||||
p.handleSwitchAnnounce(payload)
|
||||
case wire_SwitchHopRequest:
|
||||
p.handleSwitchHopRequest(payload)
|
||||
case wire_SwitchHop:
|
||||
p.handleSwitchHop(payload)
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,12 +233,16 @@ func (p *peer) handleSwitchAnnounce(packet []byte) {
|
||||
anc := msgAnnounce{}
|
||||
//err := wire_decode_struct(packet, &anc)
|
||||
//if err != nil { return }
|
||||
if !anc.decode(packet) { return }
|
||||
if !anc.decode(packet) {
|
||||
return
|
||||
}
|
||||
//if p.msgAnc != nil && anc.Seq != p.msgAnc.Seq { p.msgHops = nil }
|
||||
if p.msgAnc == nil ||
|
||||
anc.root != p.msgAnc.root ||
|
||||
anc.tstamp != p.msgAnc.tstamp ||
|
||||
anc.seq != p.msgAnc.seq { p.msgHops = nil }
|
||||
anc.seq != p.msgAnc.seq {
|
||||
p.msgHops = nil
|
||||
}
|
||||
p.msgAnc = &anc
|
||||
p.processSwitchMessage()
|
||||
}
|
||||
@ -220,14 +260,28 @@ func (p *peer) requestHop(hop uint64) {
|
||||
|
||||
func (p *peer) handleSwitchHopRequest(packet []byte) {
|
||||
//p.core.log.Println("DEBUG: handleSwitchHopRequest")
|
||||
if p.throttle > peer_Throttle { return }
|
||||
if p.myMsg == nil { return }
|
||||
if p.throttle > peer_Throttle {
|
||||
return
|
||||
}
|
||||
if p.myMsg == nil {
|
||||
return
|
||||
}
|
||||
req := msgHopReq{}
|
||||
if !req.decode(packet) { return }
|
||||
if req.root != p.myMsg.locator.root { return }
|
||||
if req.tstamp != p.myMsg.locator.tstamp { return }
|
||||
if req.seq != p.myMsg.seq { return }
|
||||
if uint64(len(p.myMsg.locator.coords)) <= req.hop { return }
|
||||
if !req.decode(packet) {
|
||||
return
|
||||
}
|
||||
if req.root != p.myMsg.locator.root {
|
||||
return
|
||||
}
|
||||
if req.tstamp != p.myMsg.locator.tstamp {
|
||||
return
|
||||
}
|
||||
if req.seq != p.myMsg.seq {
|
||||
return
|
||||
}
|
||||
if uint64(len(p.myMsg.locator.coords)) <= req.hop {
|
||||
return
|
||||
}
|
||||
res := msgHop{}
|
||||
res.root = p.myMsg.locator.root
|
||||
res.tstamp = p.myMsg.locator.tstamp
|
||||
@ -244,21 +298,39 @@ func (p *peer) handleSwitchHopRequest(packet []byte) {
|
||||
|
||||
func (p *peer) handleSwitchHop(packet []byte) {
|
||||
//p.core.log.Println("DEBUG: handleSwitchHop")
|
||||
if p.throttle > peer_Throttle { return }
|
||||
if p.msgAnc == nil { return }
|
||||
if p.throttle > peer_Throttle {
|
||||
return
|
||||
}
|
||||
if p.msgAnc == nil {
|
||||
return
|
||||
}
|
||||
res := msgHop{}
|
||||
if !res.decode(packet) { return }
|
||||
if res.root != p.msgAnc.root { return }
|
||||
if res.tstamp != p.msgAnc.tstamp { return }
|
||||
if res.seq != p.msgAnc.seq { return }
|
||||
if res.hop != uint64(len(p.msgHops)) { return } // always process in order
|
||||
if !res.decode(packet) {
|
||||
return
|
||||
}
|
||||
if res.root != p.msgAnc.root {
|
||||
return
|
||||
}
|
||||
if res.tstamp != p.msgAnc.tstamp {
|
||||
return
|
||||
}
|
||||
if res.seq != p.msgAnc.seq {
|
||||
return
|
||||
}
|
||||
if res.hop != uint64(len(p.msgHops)) {
|
||||
return
|
||||
} // always process in order
|
||||
loc := switchLocator{coords: make([]switchPort, 0, len(p.msgHops)+1)}
|
||||
loc.root = res.root
|
||||
loc.tstamp = res.tstamp
|
||||
for _, hop := range p.msgHops { loc.coords = append(loc.coords, hop.port) }
|
||||
for _, hop := range p.msgHops {
|
||||
loc.coords = append(loc.coords, hop.port)
|
||||
}
|
||||
loc.coords = append(loc.coords, res.port)
|
||||
thisHopKey := &res.root
|
||||
if res.hop != 0 { thisHopKey = &p.msgHops[res.hop-1].next }
|
||||
if res.hop != 0 {
|
||||
thisHopKey = &p.msgHops[res.hop-1].next
|
||||
}
|
||||
bs := getBytesForSig(&res.next, &loc)
|
||||
if p.core.sigs.check(thisHopKey, &res.sig, bs) {
|
||||
p.msgHops = append(p.msgHops, &res)
|
||||
@ -270,23 +342,37 @@ func (p *peer) handleSwitchHop(packet []byte) {
|
||||
|
||||
func (p *peer) processSwitchMessage() {
|
||||
//p.core.log.Println("DEBUG: processSwitchMessage")
|
||||
if p.throttle > peer_Throttle { return }
|
||||
if p.msgAnc == nil { return }
|
||||
if p.throttle > peer_Throttle {
|
||||
return
|
||||
}
|
||||
if p.msgAnc == nil {
|
||||
return
|
||||
}
|
||||
if uint64(len(p.msgHops)) < p.msgAnc.len {
|
||||
p.requestHop(uint64(len(p.msgHops)))
|
||||
return
|
||||
}
|
||||
p.throttle++
|
||||
if p.msgAnc.len != uint64(len(p.msgHops)) { return }
|
||||
if p.msgAnc.len != uint64(len(p.msgHops)) {
|
||||
return
|
||||
}
|
||||
msg := switchMessage{}
|
||||
coords := make([]switchPort, 0, len(p.msgHops))
|
||||
sigs := make([]sigInfo, 0, len(p.msgHops))
|
||||
for idx, hop := range p.msgHops {
|
||||
// Consistency checks, should be redundant (already checked these...)
|
||||
if hop.root != p.msgAnc.root { return }
|
||||
if hop.tstamp != p.msgAnc.tstamp { return }
|
||||
if hop.seq != p.msgAnc.seq { return }
|
||||
if hop.hop != uint64(idx) { return }
|
||||
if hop.root != p.msgAnc.root {
|
||||
return
|
||||
}
|
||||
if hop.tstamp != p.msgAnc.tstamp {
|
||||
return
|
||||
}
|
||||
if hop.seq != p.msgAnc.seq {
|
||||
return
|
||||
}
|
||||
if hop.hop != uint64(idx) {
|
||||
return
|
||||
}
|
||||
coords = append(coords, hop.port)
|
||||
sigs = append(sigs, sigInfo{next: hop.next, sig: hop.sig})
|
||||
}
|
||||
@ -298,7 +384,9 @@ func (p *peer) processSwitchMessage() {
|
||||
//msg.RSeq = p.msgAnc.RSeq
|
||||
//msg.Degree = p.msgAnc.Deg
|
||||
p.core.switchTable.handleMessage(&msg, p.port, sigs)
|
||||
if len(coords) == 0 { return }
|
||||
if len(coords) == 0 {
|
||||
return
|
||||
}
|
||||
// Reuse locator, set the coords to the peer's coords, to use in dht
|
||||
msg.locator.coords = coords[:len(coords)-1]
|
||||
// Pass a mesage to the dht informing it that this peer (still) exists
|
||||
@ -323,7 +411,9 @@ func (p *peer) sendSwitchAnnounce() {
|
||||
|
||||
func (p *peer) getSig(hop uint64) sigInfo {
|
||||
//p.core.log.Println("DEBUG getSig:", len(p.mySigs), hop)
|
||||
if hop < uint64(len(p.mySigs)) { return p.mySigs[hop] }
|
||||
if hop < uint64(len(p.mySigs)) {
|
||||
return p.mySigs[hop]
|
||||
}
|
||||
bs := getBytesForSig(&p.sig, &p.myMsg.locator)
|
||||
sig := sigInfo{}
|
||||
sig.next = p.sig
|
||||
@ -342,4 +432,3 @@ func getBytesForSig(next *sigPubKey, loc *switchLocator) []byte {
|
||||
//bs = append(next[:], bs...)
|
||||
return bs
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ package yggdrasil
|
||||
// The router then runs some sanity checks before passing it to the tun
|
||||
|
||||
import "time"
|
||||
|
||||
//import "fmt"
|
||||
//import "net"
|
||||
|
||||
@ -64,11 +65,16 @@ func (r *router) mainLoop() {
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case p := <-r.in: r.handleIn(p)
|
||||
case p := <-r.send: r.sendPacket(p)
|
||||
case info := <-r.core.dht.peers: r.core.dht.insert(info) //r.core.dht.insertIfNew(info)
|
||||
case <-r.reset: r.core.sessions.resetInits()
|
||||
case <-ticker.C: {
|
||||
case p := <-r.in:
|
||||
r.handleIn(p)
|
||||
case p := <-r.send:
|
||||
r.sendPacket(p)
|
||||
case info := <-r.core.dht.peers:
|
||||
r.core.dht.insert(info) //r.core.dht.insertIfNew(info)
|
||||
case <-r.reset:
|
||||
r.core.sessions.resetInits()
|
||||
case <-ticker.C:
|
||||
{
|
||||
// Any periodic maintenance stuff goes here
|
||||
r.core.dht.doMaintenance()
|
||||
util_getBytes() // To slowly drain things
|
||||
@ -78,30 +84,48 @@ func (r *router) mainLoop() {
|
||||
}
|
||||
|
||||
func (r *router) sendPacket(bs []byte) {
|
||||
if len(bs) < 40 { panic("Tried to send a packet shorter than a header...") }
|
||||
if len(bs) < 40 {
|
||||
panic("Tried to send a packet shorter than a header...")
|
||||
}
|
||||
var sourceAddr address
|
||||
var sourceSubnet subnet
|
||||
copy(sourceAddr[:], bs[8:])
|
||||
copy(sourceSubnet[:], bs[8:])
|
||||
if !sourceAddr.isValid() && !sourceSubnet.isValid() { return }
|
||||
if !sourceAddr.isValid() && !sourceSubnet.isValid() {
|
||||
return
|
||||
}
|
||||
var dest address
|
||||
copy(dest[:], bs[24:])
|
||||
var snet subnet
|
||||
copy(snet[:], bs[24:])
|
||||
if !dest.isValid() && !snet.isValid() { return }
|
||||
if !dest.isValid() && !snet.isValid() {
|
||||
return
|
||||
}
|
||||
doSearch := func(packet []byte) {
|
||||
var nodeID, mask *NodeID
|
||||
if dest.isValid() { nodeID, mask = dest.getNodeIDandMask() }
|
||||
if snet.isValid() { nodeID, mask = snet.getNodeIDandMask() }
|
||||
if dest.isValid() {
|
||||
nodeID, mask = dest.getNodeIDandMask()
|
||||
}
|
||||
if snet.isValid() {
|
||||
nodeID, mask = snet.getNodeIDandMask()
|
||||
}
|
||||
sinfo, isIn := r.core.searches.searches[*nodeID]
|
||||
if !isIn { sinfo = r.core.searches.createSearch(nodeID, mask) }
|
||||
if packet != nil { sinfo.packet = packet }
|
||||
if !isIn {
|
||||
sinfo = r.core.searches.createSearch(nodeID, mask)
|
||||
}
|
||||
if packet != nil {
|
||||
sinfo.packet = packet
|
||||
}
|
||||
r.core.searches.sendSearch(sinfo)
|
||||
}
|
||||
var sinfo *sessionInfo
|
||||
var isIn bool
|
||||
if dest.isValid() { sinfo, isIn = r.core.sessions.getByTheirAddr(&dest) }
|
||||
if snet.isValid() { sinfo, isIn = r.core.sessions.getByTheirSubnet(&snet) }
|
||||
if dest.isValid() {
|
||||
sinfo, isIn = r.core.sessions.getByTheirAddr(&dest)
|
||||
}
|
||||
if snet.isValid() {
|
||||
sinfo, isIn = r.core.sessions.getByTheirSubnet(&snet)
|
||||
}
|
||||
switch {
|
||||
case !isIn || !sinfo.init:
|
||||
// No or unintiialized session, so we need to search first
|
||||
@ -113,7 +137,8 @@ func (r *router) sendPacket(bs []byte) {
|
||||
doSearch(nil)
|
||||
fallthrough
|
||||
//default: go func() { sinfo.send<-bs }()
|
||||
default: sinfo.send<-bs
|
||||
default:
|
||||
sinfo.send <- bs
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,33 +146,48 @@ func (r *router) recvPacket(bs []byte, theirAddr *address) {
|
||||
// TODO pass their NodeID, check *that* instead
|
||||
// Or store their address in the session?...
|
||||
//fmt.Println("Recv packet")
|
||||
if theirAddr == nil { panic("Should not happen ever") }
|
||||
if len(bs) < 24 { return }
|
||||
if theirAddr == nil {
|
||||
panic("Should not happen ever")
|
||||
}
|
||||
if len(bs) < 24 {
|
||||
return
|
||||
}
|
||||
var source address
|
||||
copy(source[:], bs[8:])
|
||||
var snet subnet
|
||||
copy(snet[:], bs[8:])
|
||||
if !source.isValid() && !snet.isValid() { return }
|
||||
if !source.isValid() && !snet.isValid() {
|
||||
return
|
||||
}
|
||||
//go func() { r.recv<-bs }()
|
||||
r.recv <- bs
|
||||
}
|
||||
|
||||
func (r *router) handleIn(packet []byte) {
|
||||
pType, pTypeLen := wire_decode_uint64(packet)
|
||||
if pTypeLen == 0 { return }
|
||||
if pTypeLen == 0 {
|
||||
return
|
||||
}
|
||||
switch pType {
|
||||
case wire_Traffic: r.handleTraffic(packet)
|
||||
case wire_ProtocolTraffic: r.handleProto(packet)
|
||||
default: /*panic("Should not happen in testing") ;*/ return
|
||||
case wire_Traffic:
|
||||
r.handleTraffic(packet)
|
||||
case wire_ProtocolTraffic:
|
||||
r.handleProto(packet)
|
||||
default: /*panic("Should not happen in testing") ;*/
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (r *router) handleTraffic(packet []byte) {
|
||||
defer util_putBytes(packet)
|
||||
p := wire_trafficPacket{}
|
||||
if !p.decode(packet) { return }
|
||||
if !p.decode(packet) {
|
||||
return
|
||||
}
|
||||
sinfo, isIn := r.core.sessions.getSessionForHandle(&p.handle)
|
||||
if !isIn { return }
|
||||
if !isIn {
|
||||
return
|
||||
}
|
||||
//go func () { sinfo.recv<-&p }()
|
||||
sinfo.recv <- &p
|
||||
}
|
||||
@ -155,36 +195,53 @@ func (r *router) handleTraffic(packet []byte) {
|
||||
func (r *router) handleProto(packet []byte) {
|
||||
// First parse the packet
|
||||
p := wire_protoTrafficPacket{}
|
||||
if !p.decode(packet) { return }
|
||||
if !p.decode(packet) {
|
||||
return
|
||||
}
|
||||
// Now try to open the payload
|
||||
var sharedKey *boxSharedKey
|
||||
//var theirPermPub *boxPubKey
|
||||
if p.toKey == r.core.boxPub {
|
||||
// Try to open using our permanent key
|
||||
sharedKey = r.core.sessions.getSharedKey(&r.core.boxPriv, &p.fromKey)
|
||||
} else { return }
|
||||
} else {
|
||||
return
|
||||
}
|
||||
bs, isOK := boxOpen(sharedKey, p.payload, &p.nonce)
|
||||
if !isOK { return }
|
||||
if !isOK {
|
||||
return
|
||||
}
|
||||
// Now do something with the bytes in bs...
|
||||
// send dht messages to dht, sessionRefresh to sessions, data to tun...
|
||||
// For data, should check that key and IP match...
|
||||
bsType, bsTypeLen := wire_decode_uint64(bs)
|
||||
if bsTypeLen == 0 { return }
|
||||
if bsTypeLen == 0 {
|
||||
return
|
||||
}
|
||||
//fmt.Println("RECV bytes:", bs)
|
||||
switch bsType {
|
||||
case wire_SessionPing: r.handlePing(bs, &p.fromKey)
|
||||
case wire_SessionPong: r.handlePong(bs, &p.fromKey)
|
||||
case wire_DHTLookupRequest: r.handleDHTReq(bs, &p.fromKey)
|
||||
case wire_DHTLookupResponse: r.handleDHTRes(bs, &p.fromKey)
|
||||
case wire_SearchRequest: r.handleSearchReq(bs)
|
||||
case wire_SearchResponse: r.handleSearchRes(bs)
|
||||
default: /*panic("Should not happen in testing") ;*/ return
|
||||
case wire_SessionPing:
|
||||
r.handlePing(bs, &p.fromKey)
|
||||
case wire_SessionPong:
|
||||
r.handlePong(bs, &p.fromKey)
|
||||
case wire_DHTLookupRequest:
|
||||
r.handleDHTReq(bs, &p.fromKey)
|
||||
case wire_DHTLookupResponse:
|
||||
r.handleDHTRes(bs, &p.fromKey)
|
||||
case wire_SearchRequest:
|
||||
r.handleSearchReq(bs)
|
||||
case wire_SearchResponse:
|
||||
r.handleSearchRes(bs)
|
||||
default: /*panic("Should not happen in testing") ;*/
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (r *router) handlePing(bs []byte, fromKey *boxPubKey) {
|
||||
ping := sessionPing{}
|
||||
if !ping.decode(bs) { return }
|
||||
if !ping.decode(bs) {
|
||||
return
|
||||
}
|
||||
ping.sendPermPub = *fromKey
|
||||
r.core.sessions.handlePing(&ping)
|
||||
}
|
||||
@ -195,26 +252,38 @@ func (r *router) handlePong(bs []byte, fromKey *boxPubKey) {
|
||||
|
||||
func (r *router) handleDHTReq(bs []byte, fromKey *boxPubKey) {
|
||||
req := dhtReq{}
|
||||
if !req.decode(bs) { return }
|
||||
if req.key != *fromKey { return }
|
||||
if !req.decode(bs) {
|
||||
return
|
||||
}
|
||||
if req.key != *fromKey {
|
||||
return
|
||||
}
|
||||
r.core.dht.handleReq(&req)
|
||||
}
|
||||
|
||||
func (r *router) handleDHTRes(bs []byte, fromKey *boxPubKey) {
|
||||
res := dhtRes{}
|
||||
if !res.decode(bs) { return }
|
||||
if res.key != *fromKey { return }
|
||||
if !res.decode(bs) {
|
||||
return
|
||||
}
|
||||
if res.key != *fromKey {
|
||||
return
|
||||
}
|
||||
r.core.dht.handleRes(&res)
|
||||
}
|
||||
|
||||
func (r *router) handleSearchReq(bs []byte) {
|
||||
req := searchReq{}
|
||||
if !req.decode(bs) { return }
|
||||
if !req.decode(bs) {
|
||||
return
|
||||
}
|
||||
r.core.searches.handleSearchReq(&req)
|
||||
}
|
||||
|
||||
func (r *router) handleSearchRes(bs []byte) {
|
||||
res := searchRes{}
|
||||
if !res.decode(bs) { return }
|
||||
if !res.decode(bs) {
|
||||
return
|
||||
}
|
||||
r.core.searches.handleSearchRes(&res)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package yggdrasil
|
||||
// This hides bugs, which I don't want to do right now
|
||||
|
||||
import "time"
|
||||
|
||||
//import "fmt"
|
||||
|
||||
type searchInfo struct {
|
||||
@ -68,7 +69,9 @@ type searchRes struct {
|
||||
|
||||
func (s *searches) sendSearch(info *searchInfo) {
|
||||
now := time.Now()
|
||||
if now.Sub(info.time) < time.Second { return }
|
||||
if now.Sub(info.time) < time.Second {
|
||||
return
|
||||
}
|
||||
loc := s.core.switchTable.getLocator()
|
||||
coords := loc.getCoords()
|
||||
req := searchReq{
|
||||
@ -94,7 +97,9 @@ func (s *searches) handleSearchReq(req *searchReq) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !sent { s.sendSearchRes(req) }
|
||||
if !sent {
|
||||
s.sendSearchRes(req)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *searches) forwardSearch(req *searchReq, next *dhtInfo) {
|
||||
@ -140,7 +145,9 @@ func (s *searches) sendSearchRes(req *searchReq) {
|
||||
|
||||
func (s *searches) handleSearchRes(res *searchRes) {
|
||||
info, isIn := s.searches[res.dest]
|
||||
if !isIn { return }
|
||||
if !isIn {
|
||||
return
|
||||
}
|
||||
them := getNodeID(&res.key)
|
||||
var destMasked NodeID
|
||||
var themMasked NodeID
|
||||
@ -150,13 +157,17 @@ func (s *searches) handleSearchRes(res *searchRes) {
|
||||
}
|
||||
//fmt.Println("DEBUG search res1:", themMasked, destMasked)
|
||||
//fmt.Println("DEBUG search res2:", *them, *info.dest, *info.mask)
|
||||
if themMasked != destMasked { return }
|
||||
if themMasked != destMasked {
|
||||
return
|
||||
}
|
||||
// They match, so create a session and send a sessionRequest
|
||||
sinfo, isIn := s.core.sessions.getByTheirPerm(&res.key)
|
||||
if !isIn {
|
||||
sinfo = s.core.sessions.createSession(&res.key)
|
||||
_, isIn := s.core.sessions.getByTheirPerm(&res.key)
|
||||
if !isIn { panic("This should never happen") }
|
||||
if !isIn {
|
||||
panic("This should never happen")
|
||||
}
|
||||
}
|
||||
// FIXME replay attacks could mess with coords?
|
||||
sinfo.coords = res.coords
|
||||
@ -165,4 +176,3 @@ func (s *searches) handleSearchRes(res *searchRes) {
|
||||
// Cleanup
|
||||
delete(s.searches, res.dest)
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,12 @@ type sessionPing struct {
|
||||
|
||||
// Returns true if the session was updated, false otherwise
|
||||
func (s *sessionInfo) update(p *sessionPing) bool {
|
||||
if !(p.tstamp > s.tstamp) { return false }
|
||||
if p.sendPermPub != s.theirPermPub { return false } // Shouldn't happen
|
||||
if !(p.tstamp > s.tstamp) {
|
||||
return false
|
||||
}
|
||||
if p.sendPermPub != s.theirPermPub {
|
||||
return false
|
||||
} // Shouldn't happen
|
||||
if p.sendSesPub != s.theirSesPub {
|
||||
// FIXME need to protect against replay attacks
|
||||
// Put a sequence number or a timestamp or something in the pings?
|
||||
@ -99,28 +103,36 @@ func (ss *sessions) getSessionForHandle(handle *handle) (*sessionInfo, bool) {
|
||||
|
||||
func (ss *sessions) getByMySes(key *boxPubKey) (*sessionInfo, bool) {
|
||||
h, isIn := ss.byMySes[*key]
|
||||
if !isIn { return nil, false }
|
||||
if !isIn {
|
||||
return nil, false
|
||||
}
|
||||
sinfo, isIn := ss.getSessionForHandle(h)
|
||||
return sinfo, isIn
|
||||
}
|
||||
|
||||
func (ss *sessions) getByTheirPerm(key *boxPubKey) (*sessionInfo, bool) {
|
||||
h, isIn := ss.byTheirPerm[*key]
|
||||
if !isIn { return nil, false }
|
||||
if !isIn {
|
||||
return nil, false
|
||||
}
|
||||
sinfo, isIn := ss.getSessionForHandle(h)
|
||||
return sinfo, isIn
|
||||
}
|
||||
|
||||
func (ss *sessions) getByTheirAddr(addr *address) (*sessionInfo, bool) {
|
||||
p, isIn := ss.addrToPerm[*addr]
|
||||
if !isIn { return nil, false }
|
||||
if !isIn {
|
||||
return nil, false
|
||||
}
|
||||
sinfo, isIn := ss.getByTheirPerm(p)
|
||||
return sinfo, isIn
|
||||
}
|
||||
|
||||
func (ss *sessions) getByTheirSubnet(snet *subnet) (*sessionInfo, bool) {
|
||||
p, isIn := ss.subnetToPerm[*snet]
|
||||
if !isIn { return nil, false }
|
||||
if !isIn {
|
||||
return nil, false
|
||||
}
|
||||
sinfo, isIn := ss.getByTheirPerm(p)
|
||||
return sinfo, isIn
|
||||
}
|
||||
@ -159,7 +171,9 @@ func (ss *sessions) createSession(theirPermKey *boxPubKey) *sessionInfo {
|
||||
// Do some cleanup
|
||||
// Time thresholds almost certainly could use some adjusting
|
||||
for _, s := range ss.sinfos {
|
||||
if s.timedout() { s.close() }
|
||||
if s.timedout() {
|
||||
s.close()
|
||||
}
|
||||
}
|
||||
ss.sinfos[sinfo.myHandle] = &sinfo
|
||||
ss.byMySes[sinfo.mySesPub] = &sinfo.myHandle
|
||||
@ -195,12 +209,16 @@ func (ss *sessions) getPing(sinfo *sessionInfo) sessionPing {
|
||||
|
||||
func (ss *sessions) getSharedKey(myPriv *boxPrivKey,
|
||||
theirPub *boxPubKey) *boxSharedKey {
|
||||
if skey, isIn := ss.permShared[*theirPub] ; isIn { return skey }
|
||||
if skey, isIn := ss.permShared[*theirPub]; isIn {
|
||||
return skey
|
||||
}
|
||||
// First do some cleanup
|
||||
const maxKeys = dht_bucket_number * dht_bucket_size
|
||||
for key := range ss.permShared {
|
||||
// Remove a random key until the store is small enough
|
||||
if len(ss.permShared) < maxKeys { break }
|
||||
if len(ss.permShared) < maxKeys {
|
||||
break
|
||||
}
|
||||
delete(ss.permShared, key)
|
||||
}
|
||||
ss.permShared[*theirPub] = getSharedKey(myPriv, theirPub)
|
||||
@ -233,14 +251,22 @@ func (ss *sessions) handlePing(ping *sessionPing) {
|
||||
// Get the corresponding session (or create a new session)
|
||||
sinfo, isIn := ss.getByTheirPerm(&ping.sendPermPub)
|
||||
if !isIn || sinfo.timedout() {
|
||||
if isIn { sinfo.close() }
|
||||
if isIn {
|
||||
sinfo.close()
|
||||
}
|
||||
ss.createSession(&ping.sendPermPub)
|
||||
sinfo, isIn = ss.getByTheirPerm(&ping.sendPermPub)
|
||||
if !isIn { panic("This should not happen") }
|
||||
if !isIn {
|
||||
panic("This should not happen")
|
||||
}
|
||||
}
|
||||
// Update the session
|
||||
if !sinfo.update(ping) { /*panic("Should not happen in testing")*/ ; return }
|
||||
if !ping.isPong{ ss.sendPingPong(sinfo, true) }
|
||||
if !sinfo.update(ping) { /*panic("Should not happen in testing")*/
|
||||
return
|
||||
}
|
||||
if !ping.isPong {
|
||||
ss.sendPingPong(sinfo, true)
|
||||
}
|
||||
if sinfo.packet != nil {
|
||||
// send
|
||||
var bs []byte
|
||||
@ -254,8 +280,12 @@ func (n *boxNonce) minus(m *boxNonce) int64 {
|
||||
for idx := range n {
|
||||
diff *= 256
|
||||
diff += int64(n[idx]) - int64(m[idx])
|
||||
if diff > 64 { diff = 64 }
|
||||
if diff < -64 { diff = -64 }
|
||||
if diff > 64 {
|
||||
diff = 64
|
||||
}
|
||||
if diff < -64 {
|
||||
diff = -64
|
||||
}
|
||||
}
|
||||
return diff
|
||||
}
|
||||
@ -263,7 +293,9 @@ func (n *boxNonce) minus(m *boxNonce) int64 {
|
||||
func (sinfo *sessionInfo) nonceIsOK(theirNonce *boxNonce) bool {
|
||||
// The bitmask is to allow for some non-duplicate out-of-order packets
|
||||
diff := theirNonce.minus(&sinfo.theirNonce)
|
||||
if diff > 0 { return true }
|
||||
if diff > 0 {
|
||||
return true
|
||||
}
|
||||
return ^sinfo.nonceMask&(0x01<<uint64(-diff)) != 0
|
||||
}
|
||||
|
||||
@ -281,7 +313,9 @@ func (sinfo *sessionInfo) updateNonce(theirNonce *boxNonce) {
|
||||
}
|
||||
|
||||
func (ss *sessions) resetInits() {
|
||||
for _, sinfo := range ss.sinfos { sinfo.init = false }
|
||||
for _, sinfo := range ss.sinfos {
|
||||
sinfo.init = false
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -293,15 +327,27 @@ func (ss *sessions) resetInits() {
|
||||
func (sinfo *sessionInfo) doWorker() {
|
||||
for {
|
||||
select {
|
||||
case p, ok := <-sinfo.recv: if ok { sinfo.doRecv(p) } else { return }
|
||||
case bs, ok := <-sinfo.send: if ok { sinfo.doSend(bs) } else { return }
|
||||
case p, ok := <-sinfo.recv:
|
||||
if ok {
|
||||
sinfo.doRecv(p)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
case bs, ok := <-sinfo.send:
|
||||
if ok {
|
||||
sinfo.doSend(bs)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (sinfo *sessionInfo) doSend(bs []byte) {
|
||||
defer util_putBytes(bs)
|
||||
if !sinfo.init { return } // To prevent using empty session keys
|
||||
if !sinfo.init {
|
||||
return
|
||||
} // To prevent using empty session keys
|
||||
payload, nonce := boxSeal(&sinfo.sharedSesKey, bs, &sinfo.myNonce)
|
||||
defer util_putBytes(payload)
|
||||
p := wire_trafficPacket{
|
||||
@ -317,11 +363,15 @@ func (sinfo *sessionInfo) doSend(bs []byte) {
|
||||
|
||||
func (sinfo *sessionInfo) doRecv(p *wire_trafficPacket) {
|
||||
defer util_putBytes(p.payload)
|
||||
if !sinfo.nonceIsOK(&p.nonce) { return }
|
||||
if !sinfo.nonceIsOK(&p.nonce) {
|
||||
return
|
||||
}
|
||||
bs, isOK := boxOpen(&sinfo.sharedSesKey, p.payload, &p.nonce)
|
||||
if !isOK { util_putBytes(bs) ; return }
|
||||
if !isOK {
|
||||
util_putBytes(bs)
|
||||
return
|
||||
}
|
||||
sinfo.updateNonce(&p.nonce)
|
||||
sinfo.time = time.Now()
|
||||
sinfo.core.router.recvPacket(bs, &sinfo.theirAddr)
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,13 @@ func (m *sigManager) init() {
|
||||
}
|
||||
|
||||
func (m *sigManager) check(key *sigPubKey, sig *sigBytes, bs []byte) bool {
|
||||
if m.isChecked(sig, bs) { return true }
|
||||
if m.isChecked(sig, bs) {
|
||||
return true
|
||||
}
|
||||
verified := verify(key, bs, sig)
|
||||
if verified { m.putChecked(sig, bs) }
|
||||
if verified {
|
||||
m.putChecked(sig, bs)
|
||||
}
|
||||
return verified
|
||||
}
|
||||
|
||||
@ -32,10 +36,16 @@ func (m *sigManager) isChecked(sig *sigBytes, bs []byte) bool {
|
||||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
k, isIn := m.checked[*sig]
|
||||
if !isIn { return false }
|
||||
if len(bs) != len(k.bs) { return false }
|
||||
if !isIn {
|
||||
return false
|
||||
}
|
||||
if len(bs) != len(k.bs) {
|
||||
return false
|
||||
}
|
||||
for idx := 0; idx < len(bs); idx++ {
|
||||
if bs[idx] != k.bs[idx] { return false }
|
||||
if bs[idx] != k.bs[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
k.time = time.Now()
|
||||
return true
|
||||
@ -48,11 +58,12 @@ func (m *sigManager) putChecked(newsig *sigBytes, bs []byte) {
|
||||
if time.Since(m.lastCleaned) > 60*time.Second {
|
||||
// Since we have the write lock anyway, do some cleanup
|
||||
for s, k := range m.checked {
|
||||
if time.Since(k.time) > 60*time.Second { delete(m.checked, s) }
|
||||
if time.Since(k.time) > 60*time.Second {
|
||||
delete(m.checked, s)
|
||||
}
|
||||
}
|
||||
m.lastCleaned = now
|
||||
}
|
||||
k := knownSig{bs: bs, time: now}
|
||||
m.checked[*newsig] = k
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,9 @@ func firstIsBetter(first, second *sigPubKey) bool {
|
||||
ftid := getTreeID(first)
|
||||
stid := getTreeID(second)
|
||||
for idx := 0; idx < len(ftid); idx++ {
|
||||
if ftid[idx] == stid[idx] { continue }
|
||||
if ftid[idx] == stid[idx] {
|
||||
continue
|
||||
}
|
||||
return ftid[idx] > stid[idx]
|
||||
}
|
||||
// Edge case, when comparing identical IDs
|
||||
@ -55,17 +57,25 @@ func (l *switchLocator) dist(dest []byte) int {
|
||||
offset := 0
|
||||
fdc := 0
|
||||
for {
|
||||
if fdc >= len(l.coords) { break }
|
||||
if fdc >= len(l.coords) {
|
||||
break
|
||||
}
|
||||
coord, length := wire_decode_uint64(dest[offset:])
|
||||
if length == 0 { break }
|
||||
if l.coords[fdc] != switchPort(coord) { break }
|
||||
if length == 0 {
|
||||
break
|
||||
}
|
||||
if l.coords[fdc] != switchPort(coord) {
|
||||
break
|
||||
}
|
||||
fdc++
|
||||
offset += length
|
||||
}
|
||||
dist := len(l.coords[fdc:])
|
||||
for {
|
||||
_, length := wire_decode_uint64(dest[offset:])
|
||||
if length == 0 { break }
|
||||
if length == 0 {
|
||||
break
|
||||
}
|
||||
dist++
|
||||
offset += length
|
||||
}
|
||||
@ -82,10 +92,16 @@ func (l *switchLocator) getCoords() []byte {
|
||||
}
|
||||
|
||||
func (x *switchLocator) isAncestorOf(y *switchLocator) bool {
|
||||
if x.root != y.root { return false }
|
||||
if len(x.coords) > len(y.coords) { return false }
|
||||
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 }
|
||||
if x.coords[idx] != y.coords[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -227,13 +243,17 @@ func (t *switchTable) cleanPeers() {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if changed { t.updater.Store(&sync.Once{}) }
|
||||
if changed {
|
||||
t.updater.Store(&sync.Once{})
|
||||
}
|
||||
}
|
||||
|
||||
func (t *switchTable) cleanDropped() {
|
||||
// TODO only call this after root changes, not periodically
|
||||
for root, _ := range t.drop {
|
||||
if !firstIsBetter(&root, &t.data.locator.root) { delete(t.drop, root) }
|
||||
for root := range t.drop {
|
||||
if !firstIsBetter(&root, &t.data.locator.root) {
|
||||
delete(t.drop, root)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,9 +270,13 @@ func (t *switchTable) handleMessage(msg *switchMessage, fromPort switchPort, sig
|
||||
t.mutex.Lock()
|
||||
defer t.mutex.Unlock()
|
||||
now := time.Now()
|
||||
if len(msg.locator.coords) == 0 { return } // Should always have >=1 links
|
||||
if len(msg.locator.coords) == 0 {
|
||||
return
|
||||
} // Should always have >=1 links
|
||||
oldSender, isIn := t.data.peers[fromPort]
|
||||
if !isIn { oldSender.firstSeen = now }
|
||||
if !isIn {
|
||||
oldSender.firstSeen = now
|
||||
}
|
||||
sender := peerInfo{key: msg.from,
|
||||
locator: msg.locator,
|
||||
coords: msg.locator.coords[:len(msg.locator.coords)-1],
|
||||
@ -261,10 +285,16 @@ func (t *switchTable) handleMessage(msg *switchMessage, fromPort switchPort, sig
|
||||
port: fromPort,
|
||||
seq: msg.seq}
|
||||
equiv := func(x *switchLocator, y *switchLocator) bool {
|
||||
if x.root != y.root { return false }
|
||||
if len(x.coords) != len(y.coords) { return false }
|
||||
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 }
|
||||
if x.coords[idx] != y.coords[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -279,9 +309,13 @@ func (t *switchTable) handleMessage(msg *switchMessage, fromPort switchPort, sig
|
||||
noParent := !isIn
|
||||
noLoop := func() bool {
|
||||
for idx := 0; idx < len(sigs)-1; idx++ {
|
||||
if sigs[idx].next == t.core.sigPub { return false }
|
||||
if sigs[idx].next == t.core.sigPub {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if msg.locator.root == t.core.sigPub {
|
||||
return false
|
||||
}
|
||||
if msg.locator.root == t.core.sigPub { return false }
|
||||
return true
|
||||
}()
|
||||
sTime := now.Sub(sender.firstSeen)
|
||||
@ -295,14 +329,18 @@ func (t *switchTable) handleMessage(msg *switchMessage, fromPort switchPort, sig
|
||||
switch {
|
||||
case !noLoop: // do nothing
|
||||
case isIn && dropTstamp >= msg.locator.tstamp: // do nothing
|
||||
case firstIsBetter(&msg.locator.root, &t.data.locator.root): updateRoot = true
|
||||
case firstIsBetter(&msg.locator.root, &t.data.locator.root):
|
||||
updateRoot = true
|
||||
case t.data.locator.root != msg.locator.root: // do nothing
|
||||
case t.data.locator.tstamp > msg.locator.tstamp: // do nothing
|
||||
case noParent: updateRoot = true
|
||||
case cost < pCost: updateRoot = true
|
||||
case noParent:
|
||||
updateRoot = true
|
||||
case cost < pCost:
|
||||
updateRoot = true
|
||||
case sender.port == t.parent &&
|
||||
(msg.locator.tstamp > t.data.locator.tstamp ||
|
||||
!equiv(&msg.locator, &t.data.locator)): updateRoot = true
|
||||
!equiv(&msg.locator, &t.data.locator)):
|
||||
updateRoot = true
|
||||
}
|
||||
if updateRoot {
|
||||
if !equiv(&msg.locator, &t.data.locator) {
|
||||
@ -315,13 +353,17 @@ func (t *switchTable) handleMessage(msg *switchMessage, fromPort switchPort, sig
|
||||
//t.core.log.Println("Switch update:", msg.Locator.Root, msg.Locator.Tstamp, msg.Locator.Coords)
|
||||
//fmt.Println("Switch update:", msg.Locator.Root, msg.Locator.Tstamp, msg.Locator.Coords)
|
||||
}
|
||||
if t.data.locator.tstamp != msg.locator.tstamp { t.time = now }
|
||||
if t.data.locator.tstamp != msg.locator.tstamp {
|
||||
t.time = now
|
||||
}
|
||||
t.data.locator = msg.locator
|
||||
t.parent = sender.port
|
||||
t.data.sigs = sigs
|
||||
//t.core.log.Println("Switch update:", msg.Locator.Root, msg.Locator.Tstamp, msg.Locator.Coords)
|
||||
}
|
||||
if doUpdate { t.updater.Store(&sync.Once{}) }
|
||||
if doUpdate {
|
||||
t.updater.Store(&sync.Once{})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -367,13 +409,19 @@ func (t *switchTable) lookup(dest []byte, ttl uint64) (switchPort, uint64) {
|
||||
}
|
||||
var best switchPort
|
||||
myDist := table.self.dist(dest) //getDist(table.self.coords)
|
||||
if !(uint64(myDist) < ttl) { return 0, 0 }
|
||||
if !(uint64(myDist) < ttl) {
|
||||
return 0, 0
|
||||
}
|
||||
// score is in units of bandwidth / distance
|
||||
bestScore := float64(-1)
|
||||
for port, info := range table.elems {
|
||||
if info.locator.root != table.self.root { continue }
|
||||
if info.locator.root != table.self.root {
|
||||
continue
|
||||
}
|
||||
dist := info.locator.dist(dest) //getDist(info.locator.coords)
|
||||
if !(dist < myDist) { continue }
|
||||
if !(dist < myDist) {
|
||||
continue
|
||||
}
|
||||
score := getBandwidth(port)
|
||||
score /= float64(1 + dist)
|
||||
if score > bestScore {
|
||||
@ -395,4 +443,3 @@ type sigInfo struct {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -33,9 +33,13 @@ type tcpKeys struct {
|
||||
func (iface *tcpInterface) init(core *Core, addr string) {
|
||||
iface.core = core
|
||||
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
iface.serv, err = net.ListenTCP("tcp", tcpAddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
iface.calls = make(map[string]struct{})
|
||||
go iface.listener()
|
||||
}
|
||||
@ -45,7 +49,9 @@ func (iface *tcpInterface) listener() {
|
||||
iface.core.log.Println("Listening on:", iface.serv.Addr().String())
|
||||
for {
|
||||
sock, err := iface.serv.AcceptTCP()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go iface.handler(sock)
|
||||
}
|
||||
}
|
||||
@ -67,7 +73,9 @@ func (iface *tcpInterface) call(saddr string) {
|
||||
iface.mutex.Unlock()
|
||||
if !quit {
|
||||
conn, err := net.DialTimeout("tcp", saddr, 6*time.Second)
|
||||
if err != nil { return }
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
sock := conn.(*net.TCPConn)
|
||||
iface.handler(sock)
|
||||
}
|
||||
@ -82,23 +90,37 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
keys = append(keys, iface.core.boxPub[:]...)
|
||||
keys = append(keys, iface.core.sigPub[:]...)
|
||||
_, err := sock.Write(keys)
|
||||
if err != nil { return }
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
timeout := time.Now().Add(6 * time.Second)
|
||||
sock.SetReadDeadline(timeout)
|
||||
n, err := sock.Read(keys)
|
||||
if err != nil { return }
|
||||
if n < len(keys) { /*panic("Partial key packet?") ;*/ return }
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n < len(keys) { /*panic("Partial key packet?") ;*/
|
||||
return
|
||||
}
|
||||
ks := tcpKeys{}
|
||||
if !tcp_chop_keys(&ks.box, &ks.sig, &keys) { /*panic("Invalid key packet?") ;*/ return }
|
||||
if !tcp_chop_keys(&ks.box, &ks.sig, &keys) { /*panic("Invalid key packet?") ;*/
|
||||
return
|
||||
}
|
||||
// Quit the parent call if this is a connection to ourself
|
||||
equiv := func(k1, k2 []byte) bool {
|
||||
for idx := range k1 {
|
||||
if k1[idx] != k2[idx] { return false }
|
||||
if k1[idx] != k2[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
if equiv(ks.box[:], iface.core.boxPub[:]) { return } // testing
|
||||
if equiv(ks.sig[:], iface.core.sigPub[:]) { return }
|
||||
if equiv(ks.box[:], iface.core.boxPub[:]) {
|
||||
return
|
||||
} // testing
|
||||
if equiv(ks.sig[:], iface.core.sigPub[:]) {
|
||||
return
|
||||
}
|
||||
// Note that multiple connections to the same node are allowed
|
||||
// E.g. over different interfaces
|
||||
linkIn := make(chan []byte, 1)
|
||||
@ -124,7 +146,9 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
wire_encode_uint64(uint64(len(msg))),
|
||||
msg}
|
||||
size := 0
|
||||
for _, bs := range buf { size += len(bs) }
|
||||
for _, bs := range buf {
|
||||
size += len(bs)
|
||||
}
|
||||
start := time.Now()
|
||||
buf.WriteTo(sock)
|
||||
timed := time.Since(start)
|
||||
@ -140,9 +164,12 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
// Keep trying to fill the stack (LIFO order) while sending
|
||||
select {
|
||||
case msg, ok := <-out:
|
||||
if !ok { return }
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
put(msg)
|
||||
default: send()
|
||||
default:
|
||||
send()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,8 +178,10 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
defer func() { recover() }()
|
||||
for {
|
||||
select {
|
||||
case out<-msg: return
|
||||
default: util_putBytes(<-out)
|
||||
case out <- msg:
|
||||
return
|
||||
default:
|
||||
util_putBytes(<-out)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -163,7 +192,9 @@ func (iface *tcpInterface) handler(sock *net.TCPConn) {
|
||||
p.core.peers.mutex.Lock()
|
||||
oldPorts := p.core.peers.getPorts()
|
||||
newPorts := make(map[switchPort]*peer)
|
||||
for k,v := range oldPorts{ newPorts[k] = v }
|
||||
for k, v := range oldPorts {
|
||||
newPorts[k] = v
|
||||
}
|
||||
delete(newPorts, p.port)
|
||||
p.core.peers.putPorts(newPorts)
|
||||
p.core.peers.mutex.Unlock()
|
||||
@ -187,12 +218,18 @@ func (iface *tcpInterface) reader(sock *net.TCPConn, in func([]byte)) {
|
||||
timeout := time.Now().Add(6 * time.Second)
|
||||
sock.SetReadDeadline(timeout)
|
||||
n, err := sock.Read(bs[len(frag):])
|
||||
if err != nil || n == 0 { break }
|
||||
if err != nil || n == 0 {
|
||||
break
|
||||
}
|
||||
frag = bs[:len(frag)+n]
|
||||
for {
|
||||
msg, ok, err := tcp_chop_msg(&frag)
|
||||
if err != nil { return }
|
||||
if !ok { break } // We didn't get the whole message yet
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !ok {
|
||||
break
|
||||
} // We didn't get the whole message yet
|
||||
newMsg := append(util_getBytes(), msg...)
|
||||
in(newMsg)
|
||||
util_yield()
|
||||
@ -210,9 +247,13 @@ var tcp_msg = [...]byte{0xde, 0xad, 0xb1, 0x75} // "dead bits"
|
||||
func tcp_chop_keys(box *boxPubKey, sig *sigPubKey, bs *[]byte) bool {
|
||||
// This one is pretty simple: we know how long the message should be
|
||||
// So don't call this with a message that's too short
|
||||
if len(*bs) < len(tcp_key) + len(*box) + len(*sig) { return false }
|
||||
if len(*bs) < len(tcp_key)+len(*box)+len(*sig) {
|
||||
return false
|
||||
}
|
||||
for idx := range tcp_key {
|
||||
if (*bs)[idx] != tcp_key[idx] { return false }
|
||||
if (*bs)[idx] != tcp_key[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
(*bs) = (*bs)[len(tcp_key):]
|
||||
copy(box[:], *bs)
|
||||
@ -224,14 +265,18 @@ func tcp_chop_keys(box *boxPubKey, sig *sigPubKey, bs *[]byte) bool {
|
||||
|
||||
func tcp_chop_msg(bs *[]byte) ([]byte, bool, error) {
|
||||
// Returns msg, ok, err
|
||||
if len(*bs) < len(tcp_msg) { return nil, false, nil }
|
||||
if len(*bs) < len(tcp_msg) {
|
||||
return nil, false, nil
|
||||
}
|
||||
for idx := range tcp_msg {
|
||||
if (*bs)[idx] != tcp_msg[idx] {
|
||||
return nil, false, errors.New("Bad message!")
|
||||
}
|
||||
}
|
||||
msgLen, msgLenLen := wire_decode_uint64((*bs)[len(tcp_msg):])
|
||||
if msgLen > tcp_msgSize { return nil, false, errors.New("Oversized message!") }
|
||||
if msgLen > tcp_msgSize {
|
||||
return nil, false, errors.New("Oversized message!")
|
||||
}
|
||||
msgBegin := len(tcp_msg) + msgLenLen
|
||||
msgEnd := msgBegin + int(msgLen)
|
||||
if msgLenLen == 0 || len(*bs) < msgEnd {
|
||||
@ -243,4 +288,3 @@ func tcp_chop_msg(bs *[]byte) ([]byte, bool, error) {
|
||||
(*bs) = (*bs)[msgEnd:]
|
||||
return msg, true, nil
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,9 @@ func (tun *tunDevice) init(core *Core) {
|
||||
func (tun *tunDevice) write() error {
|
||||
for {
|
||||
data := <-tun.recv
|
||||
if _, err := tun.iface.Write(data); err != nil { return err }
|
||||
if _, err := tun.iface.Write(data); err != nil {
|
||||
return err
|
||||
}
|
||||
util_putBytes(data)
|
||||
}
|
||||
}
|
||||
@ -30,7 +32,9 @@ func (tun *tunDevice) read() error {
|
||||
buf := make([]byte, tun.mtu)
|
||||
for {
|
||||
n, err := tun.iface.Read(buf)
|
||||
if err != nil { return err }
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if buf[0]&0xf0 != 0x60 ||
|
||||
n != 256*int(buf[4])+int(buf[5])+IPv6_HEADER_LENGTH {
|
||||
// Either not an IPv6 packet or not the complete packet for some reason
|
||||
|
@ -15,7 +15,9 @@ func (tun *tunDevice) setup(ifname string, addr string, mtu int) error {
|
||||
config.Name = ifname
|
||||
}
|
||||
iface, err := water.New(config)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tun.iface = iface
|
||||
tun.mtu = mtu //1280 // Lets default to the smallest thing allowed for now
|
||||
return tun.setupAddress(addr)
|
||||
|
@ -10,7 +10,9 @@ import water "github.com/songgao/water"
|
||||
func (tun *tunDevice) setup(ifname string, addr string, mtu int) error {
|
||||
config := water.Config{DeviceType: water.TUN}
|
||||
iface, err := water.New(config)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tun.iface = iface
|
||||
tun.mtu = mtu //1280 // Lets default to the smallest thing allowed for now
|
||||
return tun.setupAddress(addr)
|
||||
|
@ -42,16 +42,22 @@ type udpKeys struct {
|
||||
func (iface *udpInterface) init(core *Core, addr string) {
|
||||
iface.core = core
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", addr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
iface.sock, err = net.ListenUDP("udp", udpAddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
iface.conns = make(map[connAddr]*connInfo)
|
||||
go iface.reader()
|
||||
}
|
||||
|
||||
func (iface *udpInterface) sendKeys(addr connAddr) {
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", string(addr))
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
msg := []byte{}
|
||||
msg = udp_encode(msg, 0, 0, 0, nil)
|
||||
msg = append(msg, iface.core.boxPub[:]...)
|
||||
@ -76,7 +82,9 @@ func (iface *udpInterface) startConn(info *connInfo) {
|
||||
iface.core.peers.mutex.Lock()
|
||||
oldPorts := iface.core.peers.getPorts()
|
||||
newPorts := make(map[switchPort]*peer)
|
||||
for k,v := range oldPorts{ newPorts[k] = v }
|
||||
for k, v := range oldPorts {
|
||||
newPorts[k] = v
|
||||
}
|
||||
delete(newPorts, info.peer.port)
|
||||
iface.core.peers.putPorts(newPorts)
|
||||
iface.core.peers.mutex.Unlock()
|
||||
@ -87,15 +95,19 @@ func (iface *udpInterface) startConn(info *connInfo) {
|
||||
}()
|
||||
for {
|
||||
select {
|
||||
case ks := <-info.keysIn: {
|
||||
case ks := <-info.keysIn:
|
||||
{
|
||||
// FIXME? need signatures/sequence-numbers or something
|
||||
// Spoofers could lock out a peer with fake/bad keys
|
||||
if ks.box == info.peer.box && ks.sig == info.peer.sig {
|
||||
info.timeout = 0
|
||||
}
|
||||
}
|
||||
case <-ticker.C: {
|
||||
if info.timeout > 10 { return }
|
||||
case <-ticker.C:
|
||||
{
|
||||
if info.timeout > 10 {
|
||||
return
|
||||
}
|
||||
info.timeout++
|
||||
iface.sendKeys(info.addr)
|
||||
}
|
||||
@ -108,17 +120,25 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
|
||||
var ks udpKeys
|
||||
_, _, _, bs := udp_decode(msg)
|
||||
switch {
|
||||
case !wire_chop_slice(ks.box[:], &bs): return
|
||||
case !wire_chop_slice(ks.sig[:], &bs): return
|
||||
case !wire_chop_slice(ks.box[:], &bs):
|
||||
return
|
||||
case !wire_chop_slice(ks.sig[:], &bs):
|
||||
return
|
||||
}
|
||||
if ks.box == iface.core.boxPub {
|
||||
return
|
||||
}
|
||||
if ks.sig == iface.core.sigPub {
|
||||
return
|
||||
}
|
||||
if ks.box == iface.core.boxPub { return }
|
||||
if ks.sig == iface.core.sigPub { return }
|
||||
iface.mutex.RLock()
|
||||
conn, isIn := iface.conns[addr]
|
||||
iface.mutex.RUnlock() // TODO? keep the lock longer?...
|
||||
if !isIn {
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", string(addr))
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
conn = &connInfo{
|
||||
addr: connAddr(addr),
|
||||
peer: iface.core.peers.newPeer(&ks.box, &ks.sig),
|
||||
@ -171,7 +191,9 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
|
||||
//iface.core.log.Println("GOING:", addr, chunks, chunk, count, len(payload))
|
||||
inChunks += 1
|
||||
inBuf = append(inBuf, payload...)
|
||||
if chunks != chunk { return }
|
||||
if chunks != chunk {
|
||||
return
|
||||
}
|
||||
msg := append(util_getBytes(), inBuf...)
|
||||
conn.peer.handlePacket(msg, conn.linkIn)
|
||||
//iface.core.log.Println("DONE:", addr, chunks, chunk, count, len(payload))
|
||||
@ -181,7 +203,8 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
|
||||
defer func() { recover() }()
|
||||
select {
|
||||
case conn.out <- msg:
|
||||
default: util_putBytes(msg)
|
||||
default:
|
||||
util_putBytes(msg)
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
@ -195,7 +218,9 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) {
|
||||
}
|
||||
chunks = append(chunks, bs)
|
||||
//iface.core.log.Println("DEBUG: out chunks:", len(chunks), len(msg))
|
||||
if len(chunks) > 255 { continue }
|
||||
if len(chunks) > 255 {
|
||||
continue
|
||||
}
|
||||
start := time.Now()
|
||||
for idx, bs := range chunks {
|
||||
nChunks, nChunk, count := uint8(len(chunks)), uint8(idx)+1, conn.countOut
|
||||
@ -245,8 +270,13 @@ func (iface *udpInterface) reader() {
|
||||
//iface.core.log.Println("Starting read")
|
||||
n, udpAddr, err := iface.sock.ReadFromUDP(bs)
|
||||
//iface.core.log.Println("Read", n, udpAddr.String(), err)
|
||||
if err != nil { panic(err) ; break }
|
||||
if n > 1500 { panic(n) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
break
|
||||
}
|
||||
if n > 1500 {
|
||||
panic(n)
|
||||
}
|
||||
//msg := append(util_getBytes(), bs[:n]...)
|
||||
msg := bs[:n]
|
||||
addr := connAddr(udpAddr.String())
|
||||
@ -272,4 +302,3 @@ func udp_decode(bs []byte) (chunks, chunk, count uint8, payload []byte) {
|
||||
func udp_encode(out []byte, chunks, chunk, count uint8, payload []byte) []byte {
|
||||
return append(append(out, chunks, chunk, count), payload...)
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ package yggdrasil
|
||||
|
||||
import "fmt"
|
||||
import "runtime"
|
||||
|
||||
//import "sync"
|
||||
|
||||
func Util_testAddrIDMask() {
|
||||
@ -65,8 +66,10 @@ func util_initByteStore() {
|
||||
|
||||
func util_getBytes() []byte {
|
||||
select {
|
||||
case bs := <-byteStore: return bs[:0]
|
||||
default: return nil
|
||||
case bs := <-byteStore:
|
||||
return bs[:0]
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,4 +79,3 @@ func util_putBytes(bs []byte) {
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,9 @@ func wire_decode_uint64(bs []byte) (uint64, int) {
|
||||
elem <<= 7
|
||||
elem |= uint64(b & 0x7f)
|
||||
length++
|
||||
if b & 0x80 == 0 { break }
|
||||
if b&0x80 == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return elem, length
|
||||
}
|
||||
@ -72,14 +74,16 @@ func wire_intToUint(i int64) uint64 {
|
||||
func wire_intFromUint(u uint64) int64 {
|
||||
var i int64
|
||||
i = int64(u >> 1)
|
||||
if u & 0x01 != 0 { i *= -1 }
|
||||
if u&0x01 != 0 {
|
||||
i *= -1
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Takes coords, returns coords prefixed with encoded coord length
|
||||
func wire_encode_coords(coords []byte) ([]byte) {
|
||||
func wire_encode_coords(coords []byte) []byte {
|
||||
coordLen := wire_encode_uint64(uint64(len(coords)))
|
||||
bs := make([]byte, 0, len(coordLen)+len(coords))
|
||||
bs = append(bs, coordLen...)
|
||||
@ -87,7 +91,7 @@ func wire_encode_coords(coords []byte) ([]byte) {
|
||||
return bs
|
||||
}
|
||||
|
||||
func wire_put_coords(coords []byte, bs []byte) ([]byte) {
|
||||
func wire_put_coords(coords []byte, bs []byte) []byte {
|
||||
bs = wire_put_uint64(uint64(len(coords)), bs)
|
||||
bs = append(bs, coords...)
|
||||
return bs
|
||||
@ -100,7 +104,9 @@ func wire_decode_coords(packet []byte) ([]byte, int) {
|
||||
coordEnd := coordBegin + int(coordLen)
|
||||
//if coordBegin == 0 { panic("No coords found") } // Testing
|
||||
//if coordEnd > len(packet) { panic("Packet too short") } // Testing
|
||||
if coordBegin == 0 || coordEnd > len(packet) { return nil, 0 }
|
||||
if coordBegin == 0 || coordEnd > len(packet) {
|
||||
return nil, 0
|
||||
}
|
||||
return packet[coordBegin:coordEnd], coordEnd
|
||||
}
|
||||
|
||||
@ -132,12 +138,18 @@ func (m *msgAnnounce) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
var tstamp uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_SwitchAnnounce: return false
|
||||
case !wire_chop_slice(m.root[:], &bs): return false
|
||||
case !wire_chop_uint64(&tstamp, &bs): return false
|
||||
case !wire_chop_uint64(&m.seq, &bs): return false
|
||||
case !wire_chop_uint64(&m.len, &bs): return false
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_SwitchAnnounce:
|
||||
return false
|
||||
case !wire_chop_slice(m.root[:], &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&tstamp, &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&m.seq, &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&m.len, &bs):
|
||||
return false
|
||||
//case !wire_chop_uint64(&m.Deg, &bs): return false
|
||||
//case !wire_chop_uint64(&m.RSeq, &bs): return false
|
||||
}
|
||||
@ -165,12 +177,18 @@ func (m *msgHopReq) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
var tstamp uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_SwitchHopRequest: return false
|
||||
case !wire_chop_slice(m.root[:], &bs): return false
|
||||
case !wire_chop_uint64(&tstamp, &bs): return false
|
||||
case !wire_chop_uint64(&m.seq, &bs): return false
|
||||
case !wire_chop_uint64(&m.hop, &bs): return false
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_SwitchHopRequest:
|
||||
return false
|
||||
case !wire_chop_slice(m.root[:], &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&tstamp, &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&m.seq, &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&m.hop, &bs):
|
||||
return false
|
||||
}
|
||||
m.tstamp = wire_intFromUint(tstamp)
|
||||
return true
|
||||
@ -202,15 +220,24 @@ func (m *msgHop) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
var tstamp uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_SwitchHop: return false
|
||||
case !wire_chop_slice(m.root[:], &bs): return false
|
||||
case !wire_chop_uint64(&tstamp, &bs): return false
|
||||
case !wire_chop_uint64(&m.seq, &bs): return false
|
||||
case !wire_chop_uint64(&m.hop, &bs): return false
|
||||
case !wire_chop_uint64((*uint64)(&m.port), &bs): return false
|
||||
case !wire_chop_slice(m.next[:], &bs): return false
|
||||
case !wire_chop_slice(m.sig[:], &bs): return false
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_SwitchHop:
|
||||
return false
|
||||
case !wire_chop_slice(m.root[:], &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&tstamp, &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&m.seq, &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&m.hop, &bs):
|
||||
return false
|
||||
case !wire_chop_uint64((*uint64)(&m.port), &bs):
|
||||
return false
|
||||
case !wire_chop_slice(m.next[:], &bs):
|
||||
return false
|
||||
case !wire_chop_slice(m.sig[:], &bs):
|
||||
return false
|
||||
}
|
||||
m.tstamp = wire_intFromUint(tstamp)
|
||||
return true
|
||||
@ -227,7 +254,9 @@ func wire_encode_locator(loc *switchLocator) []byte {
|
||||
}
|
||||
|
||||
func wire_chop_slice(toSlice []byte, fromSlice *[]byte) bool {
|
||||
if len(*fromSlice) < len(toSlice) { return false }
|
||||
if len(*fromSlice) < len(toSlice) {
|
||||
return false
|
||||
}
|
||||
copy(toSlice, *fromSlice)
|
||||
*fromSlice = (*fromSlice)[len(toSlice):]
|
||||
return true
|
||||
@ -235,7 +264,9 @@ func wire_chop_slice(toSlice []byte, fromSlice *[]byte) bool {
|
||||
|
||||
func wire_chop_coords(toCoords *[]byte, fromSlice *[]byte) bool {
|
||||
coords, coordLen := wire_decode_coords(*fromSlice)
|
||||
if coordLen == 0 { return false }
|
||||
if coordLen == 0 {
|
||||
return false
|
||||
}
|
||||
*toCoords = append((*toCoords)[:0], coords...)
|
||||
*fromSlice = (*fromSlice)[coordLen:]
|
||||
return true
|
||||
@ -243,7 +274,9 @@ func wire_chop_coords(toCoords *[]byte, fromSlice *[]byte) bool {
|
||||
|
||||
func wire_chop_uint64(toUInt64 *uint64, fromSlice *[]byte) bool {
|
||||
dec, decLen := wire_decode_uint64(*fromSlice)
|
||||
if decLen == 0 { return false }
|
||||
if decLen == 0 {
|
||||
return false
|
||||
}
|
||||
*toUInt64 = dec
|
||||
*fromSlice = (*fromSlice)[decLen:]
|
||||
return true
|
||||
@ -277,12 +310,18 @@ func (p *wire_trafficPacket) encode() []byte {
|
||||
func (p *wire_trafficPacket) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_Traffic: return false
|
||||
case !wire_chop_uint64(&p.ttl, &bs): return false
|
||||
case !wire_chop_coords(&p.coords, &bs): return false
|
||||
case !wire_chop_slice(p.handle[:], &bs): return false
|
||||
case !wire_chop_slice(p.nonce[:], &bs): return false
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_Traffic:
|
||||
return false
|
||||
case !wire_chop_uint64(&p.ttl, &bs):
|
||||
return false
|
||||
case !wire_chop_coords(&p.coords, &bs):
|
||||
return false
|
||||
case !wire_chop_slice(p.handle[:], &bs):
|
||||
return false
|
||||
case !wire_chop_slice(p.nonce[:], &bs):
|
||||
return false
|
||||
}
|
||||
p.payload = append(util_getBytes(), bs...)
|
||||
return true
|
||||
@ -312,13 +351,20 @@ func (p *wire_protoTrafficPacket) encode() []byte {
|
||||
func (p *wire_protoTrafficPacket) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_ProtocolTraffic: return false
|
||||
case !wire_chop_uint64(&p.ttl, &bs): return false
|
||||
case !wire_chop_coords(&p.coords, &bs): return false
|
||||
case !wire_chop_slice(p.toKey[:], &bs): return false
|
||||
case !wire_chop_slice(p.fromKey[:], &bs): return false
|
||||
case !wire_chop_slice(p.nonce[:], &bs): return false
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_ProtocolTraffic:
|
||||
return false
|
||||
case !wire_chop_uint64(&p.ttl, &bs):
|
||||
return false
|
||||
case !wire_chop_coords(&p.coords, &bs):
|
||||
return false
|
||||
case !wire_chop_slice(p.toKey[:], &bs):
|
||||
return false
|
||||
case !wire_chop_slice(p.fromKey[:], &bs):
|
||||
return false
|
||||
case !wire_chop_slice(p.nonce[:], &bs):
|
||||
return false
|
||||
}
|
||||
p.payload = bs
|
||||
return true
|
||||
@ -343,11 +389,16 @@ func (p *wire_linkProtoTrafficPacket) encode() []byte {
|
||||
func (p *wire_linkProtoTrafficPacket) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_LinkProtocolTraffic: return false
|
||||
case !wire_chop_slice(p.toKey[:], &bs): return false
|
||||
case !wire_chop_slice(p.fromKey[:], &bs): return false
|
||||
case !wire_chop_slice(p.nonce[:], &bs): return false
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_LinkProtocolTraffic:
|
||||
return false
|
||||
case !wire_chop_slice(p.toKey[:], &bs):
|
||||
return false
|
||||
case !wire_chop_slice(p.fromKey[:], &bs):
|
||||
return false
|
||||
case !wire_chop_slice(p.nonce[:], &bs):
|
||||
return false
|
||||
}
|
||||
p.payload = bs
|
||||
return true
|
||||
@ -376,16 +427,24 @@ func (p *sessionPing) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
var tstamp uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_SessionPing && pType != wire_SessionPong: return false
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_SessionPing && pType != wire_SessionPong:
|
||||
return false
|
||||
//p.sendPermPub used in top level (crypto), so skipped here
|
||||
case !wire_chop_slice(p.handle[:], &bs): return false
|
||||
case !wire_chop_slice(p.sendSesPub[:], &bs): return false
|
||||
case !wire_chop_uint64(&tstamp, &bs): return false
|
||||
case !wire_chop_coords(&p.coords, &bs): return false
|
||||
case !wire_chop_slice(p.handle[:], &bs):
|
||||
return false
|
||||
case !wire_chop_slice(p.sendSesPub[:], &bs):
|
||||
return false
|
||||
case !wire_chop_uint64(&tstamp, &bs):
|
||||
return false
|
||||
case !wire_chop_coords(&p.coords, &bs):
|
||||
return false
|
||||
}
|
||||
p.tstamp = wire_intFromUint(tstamp)
|
||||
if pType == wire_SessionPong { p.isPong = true }
|
||||
if pType == wire_SessionPong {
|
||||
p.isPong = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -403,12 +462,18 @@ func (r *dhtReq) encode() []byte {
|
||||
func (r *dhtReq) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_DHTLookupRequest: return false
|
||||
case !wire_chop_slice(r.key[:], &bs): return false
|
||||
case !wire_chop_coords(&r.coords, &bs): return false
|
||||
case !wire_chop_slice(r.dest[:], &bs): return false
|
||||
default: return true
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_DHTLookupRequest:
|
||||
return false
|
||||
case !wire_chop_slice(r.key[:], &bs):
|
||||
return false
|
||||
case !wire_chop_coords(&r.coords, &bs):
|
||||
return false
|
||||
case !wire_chop_slice(r.dest[:], &bs):
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,17 +494,24 @@ func (r *dhtRes) encode() []byte {
|
||||
func (r *dhtRes) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_DHTLookupResponse: return false
|
||||
case !wire_chop_slice(r.key[:], &bs): return false
|
||||
case !wire_chop_coords(&r.coords, &bs): return false
|
||||
case !wire_chop_slice(r.dest[:], &bs): return false
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_DHTLookupResponse:
|
||||
return false
|
||||
case !wire_chop_slice(r.key[:], &bs):
|
||||
return false
|
||||
case !wire_chop_coords(&r.coords, &bs):
|
||||
return false
|
||||
case !wire_chop_slice(r.dest[:], &bs):
|
||||
return false
|
||||
}
|
||||
for len(bs) > 0 {
|
||||
info := dhtInfo{}
|
||||
switch {
|
||||
case !wire_chop_slice(info.key[:], &bs): return false
|
||||
case !wire_chop_coords(&info.coords, &bs): return false
|
||||
case !wire_chop_slice(info.key[:], &bs):
|
||||
return false
|
||||
case !wire_chop_coords(&info.coords, &bs):
|
||||
return false
|
||||
}
|
||||
r.infos = append(r.infos, &info)
|
||||
}
|
||||
@ -460,12 +532,18 @@ func (r *searchReq) encode() []byte {
|
||||
func (r *searchReq) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_SearchRequest: return false
|
||||
case !wire_chop_slice(r.key[:], &bs): return false
|
||||
case !wire_chop_coords(&r.coords, &bs): return false
|
||||
case !wire_chop_slice(r.dest[:], &bs): return false
|
||||
default: return true
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_SearchRequest:
|
||||
return false
|
||||
case !wire_chop_slice(r.key[:], &bs):
|
||||
return false
|
||||
case !wire_chop_coords(&r.coords, &bs):
|
||||
return false
|
||||
case !wire_chop_slice(r.dest[:], &bs):
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@ -481,12 +559,17 @@ func (r *searchRes) encode() []byte {
|
||||
func (r *searchRes) decode(bs []byte) bool {
|
||||
var pType uint64
|
||||
switch {
|
||||
case !wire_chop_uint64(&pType, &bs): return false
|
||||
case pType != wire_SearchResponse: return false
|
||||
case !wire_chop_slice(r.key[:], &bs): return false
|
||||
case !wire_chop_coords(&r.coords, &bs): return false
|
||||
case !wire_chop_slice(r.dest[:], &bs): return false
|
||||
default: return true
|
||||
case !wire_chop_uint64(&pType, &bs):
|
||||
return false
|
||||
case pType != wire_SearchResponse:
|
||||
return false
|
||||
case !wire_chop_slice(r.key[:], &bs):
|
||||
return false
|
||||
case !wire_chop_coords(&r.coords, &bs):
|
||||
return false
|
||||
case !wire_chop_slice(r.dest[:], &bs):
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
111
yggdrasil.go
111
yggdrasil.go
@ -45,20 +45,30 @@ type node struct {
|
||||
|
||||
func (n *node) init(cfg *nodeConfig, logger *log.Logger) {
|
||||
boxPub, err := hex.DecodeString(cfg.BoxPub)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
boxPriv, err := hex.DecodeString(cfg.BoxPriv)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sigPub, err := hex.DecodeString(cfg.SigPub)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sigPriv, err := hex.DecodeString(cfg.SigPriv)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
n.core.DEBUG_init(boxPub, boxPriv, sigPub, sigPriv)
|
||||
n.core.DEBUG_setLogger(logger)
|
||||
logger.Println("Starting interface...")
|
||||
n.core.DEBUG_setupAndStartGlobalUDPInterface(cfg.Listen)
|
||||
logger.Println("Started interface")
|
||||
go func() {
|
||||
if len(cfg.Peers) == 0 { return }
|
||||
if len(cfg.Peers) == 0 {
|
||||
return
|
||||
}
|
||||
for {
|
||||
for _, p := range cfg.Peers {
|
||||
n.core.DEBUG_maybeSendUDPKeys(p)
|
||||
@ -88,7 +98,9 @@ func generateConfig() *nodeConfig {
|
||||
func doGenconf() string {
|
||||
cfg := generateConfig()
|
||||
bs, err := json.MarshalIndent(cfg, "", " ")
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(bs)
|
||||
}
|
||||
|
||||
@ -96,21 +108,34 @@ var multicastAddr = "[ff02::114]:9001"
|
||||
|
||||
func (n *node) listen() {
|
||||
groupAddr, err := net.ResolveUDPAddr("udp6", multicastAddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bs := make([]byte, 2048)
|
||||
for {
|
||||
nBytes, rcm, fromAddr, err := n.sock.ReadFrom(bs)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
//if rcm == nil { continue } // wat
|
||||
//fmt.Println("DEBUG:", "packet from:", fromAddr.String())
|
||||
if !rcm.Dst.IsLinkLocalMulticast() { continue }
|
||||
if !rcm.Dst.Equal(groupAddr.IP) { continue }
|
||||
if !rcm.Dst.IsLinkLocalMulticast() {
|
||||
continue
|
||||
}
|
||||
if !rcm.Dst.Equal(groupAddr.IP) {
|
||||
continue
|
||||
}
|
||||
anAddr := string(bs[:nBytes])
|
||||
addr, err := net.ResolveUDPAddr("udp6", anAddr)
|
||||
if err != nil { panic(err) ; continue } // Panic for testing, remove later
|
||||
if err != nil {
|
||||
panic(err)
|
||||
continue
|
||||
} // Panic for testing, remove later
|
||||
from := fromAddr.(*net.UDPAddr)
|
||||
//fmt.Println("DEBUG:", "heard:", addr.IP.String(), "from:", from.IP.String())
|
||||
if addr.IP.String() != from.IP.String() { continue }
|
||||
if addr.IP.String() != from.IP.String() {
|
||||
continue
|
||||
}
|
||||
addr.Zone = from.Zone
|
||||
saddr := addr.String()
|
||||
//if _, isIn := n.peers[saddr]; isIn { continue }
|
||||
@ -122,25 +147,39 @@ func (n *node) listen() {
|
||||
|
||||
func (n *node) announce() {
|
||||
groupAddr, err := net.ResolveUDPAddr("udp6", multicastAddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
udpaddr := n.core.DEBUG_getGlobalUDPAddr()
|
||||
anAddr, err := net.ResolveUDPAddr("udp6", udpaddr.String())
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
destAddr, err := net.ResolveUDPAddr("udp6", multicastAddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, iface := range ifaces {
|
||||
n.sock.JoinGroup(&iface, groupAddr)
|
||||
//err := n.sock.JoinGroup(&iface, groupAddr)
|
||||
//if err != nil { panic(err) }
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
addrIP, _, _ := net.ParseCIDR(addr.String())
|
||||
if addrIP.To4() != nil { continue } // IPv6 only
|
||||
if !addrIP.IsLinkLocalUnicast() { continue }
|
||||
if addrIP.To4() != nil {
|
||||
continue
|
||||
} // IPv6 only
|
||||
if !addrIP.IsLinkLocalUnicast() {
|
||||
continue
|
||||
}
|
||||
anAddr.IP = addrIP
|
||||
anAddr.Zone = iface.Name
|
||||
destAddr.Zone = iface.Name
|
||||
@ -163,17 +202,26 @@ func main() {
|
||||
flag.Parse()
|
||||
var cfg *nodeConfig
|
||||
switch {
|
||||
case *autoconf: cfg = generateConfig()
|
||||
case *autoconf:
|
||||
cfg = generateConfig()
|
||||
case *useconf:
|
||||
config, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(config))
|
||||
err = decoder.Decode(&cfg)
|
||||
if err != nil { panic(err) }
|
||||
case *genconf: fmt.Println(doGenconf())
|
||||
default: flag.PrintDefaults()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
case *genconf:
|
||||
fmt.Println(doGenconf())
|
||||
default:
|
||||
flag.PrintDefaults()
|
||||
}
|
||||
if cfg == nil {
|
||||
return
|
||||
}
|
||||
if cfg == nil { return }
|
||||
logger := log.New(os.Stdout, "", log.Flags())
|
||||
if *pprof {
|
||||
runtime.SetBlockProfileRate(1)
|
||||
@ -193,13 +241,19 @@ func main() {
|
||||
logger.Println("Started...")
|
||||
if cfg.Multicast {
|
||||
addr, err := net.ResolveUDPAddr("udp", multicastAddr)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
listenString := fmt.Sprintf("[::]:%v", addr.Port)
|
||||
conn, err := net.ListenPacket("udp6", listenString)
|
||||
if err != nil { panic(err) }
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
//defer conn.Close() // Let it close on its own when the application exits
|
||||
n.sock = ipv6.NewPacketConn(conn)
|
||||
if err = n.sock.SetControlMessage(ipv6.FlagDst, true) ; err != nil { panic(err) }
|
||||
if err = n.sock.SetControlMessage(ipv6.FlagDst, true); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go n.listen()
|
||||
go n.announce()
|
||||
}
|
||||
@ -209,4 +263,3 @@ func main() {
|
||||
<-c
|
||||
logger.Println("Stopping...")
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user