Searches called from api.go, various other tweaks, searches now have a callback for success/failure, node ID now reported by admin socket

This commit is contained in:
Neil Alexander 2019-04-18 23:38:23 +01:00
parent eef2a02d0a
commit 160e01e84f
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
7 changed files with 177 additions and 81 deletions

View file

@ -15,6 +15,7 @@ package yggdrasil
// Some kind of max search steps, in case the node is offline, so we don't crawl through too much of the network looking for a destination that isn't there?
import (
"errors"
"sort"
"time"
@ -32,12 +33,13 @@ const search_RETRY_TIME = time.Second
// Information about an ongoing search.
// Includes the target NodeID, the bitmask to match it to an IP, and the list of nodes to visit / already visited.
type searchInfo struct {
dest crypto.NodeID
mask crypto.NodeID
time time.Time
packet []byte
toVisit []*dhtInfo
visited map[crypto.NodeID]bool
dest crypto.NodeID
mask crypto.NodeID
time time.Time
packet []byte
toVisit []*dhtInfo
visited map[crypto.NodeID]bool
callback func(*sessionInfo, error)
}
// This stores a map of active searches.
@ -61,7 +63,7 @@ func (s *searches) init(core *Core) {
}
// Creates a new search info, adds it to the searches struct, and returns a pointer to the info.
func (s *searches) createSearch(dest *crypto.NodeID, mask *crypto.NodeID) *searchInfo {
func (s *searches) createSearch(dest *crypto.NodeID, mask *crypto.NodeID, callback func(*sessionInfo, error)) *searchInfo {
now := time.Now()
for dest, sinfo := range s.searches {
if now.Sub(sinfo.time) > time.Minute {
@ -69,9 +71,10 @@ func (s *searches) createSearch(dest *crypto.NodeID, mask *crypto.NodeID) *searc
}
}
info := searchInfo{
dest: *dest,
mask: *mask,
time: now.Add(-time.Second),
dest: *dest,
mask: *mask,
time: now.Add(-time.Second),
callback: callback,
}
s.searches[*dest] = &info
return &info
@ -137,15 +140,15 @@ func (s *searches) doSearchStep(sinfo *searchInfo) {
if len(sinfo.toVisit) == 0 {
// Dead end, do cleanup
delete(s.searches, sinfo.dest)
sinfo.callback(nil, errors.New("search reached dead end"))
return
} else {
// Send to the next search target
var next *dhtInfo
next, sinfo.toVisit = sinfo.toVisit[0], sinfo.toVisit[1:]
rq := dhtReqKey{next.key, sinfo.dest}
s.core.dht.addCallback(&rq, s.handleDHTRes)
s.core.dht.ping(next, &sinfo.dest)
}
// Send to the next search target
var next *dhtInfo
next, sinfo.toVisit = sinfo.toVisit[0], sinfo.toVisit[1:]
rq := dhtReqKey{next.key, sinfo.dest}
s.core.dht.addCallback(&rq, s.handleDHTRes)
s.core.dht.ping(next, &sinfo.dest)
}
// If we've recenty sent a ping for this search, do nothing.
@ -173,8 +176,8 @@ func (s *searches) continueSearch(sinfo *searchInfo) {
}
// Calls create search, and initializes the iterative search parts of the struct before returning it.
func (s *searches) newIterSearch(dest *crypto.NodeID, mask *crypto.NodeID) *searchInfo {
sinfo := s.createSearch(dest, mask)
func (s *searches) newIterSearch(dest *crypto.NodeID, mask *crypto.NodeID, callback func(*sessionInfo, error)) *searchInfo {
sinfo := s.createSearch(dest, mask, callback)
sinfo.toVisit = s.core.dht.lookup(dest, true)
sinfo.visited = make(map[crypto.NodeID]bool)
return sinfo
@ -200,6 +203,7 @@ func (s *searches) checkDHTRes(info *searchInfo, res *dhtRes) bool {
sinfo = s.core.sessions.createSession(&res.Key)
if sinfo == nil {
// nil if the DHT search finished but the session wasn't allowed
info.callback(nil, errors.New("session not allowed"))
return true
}
_, isIn := s.core.sessions.getByTheirPerm(&res.Key)
@ -211,6 +215,7 @@ func (s *searches) checkDHTRes(info *searchInfo, res *dhtRes) bool {
sinfo.coords = res.Coords
sinfo.packet = info.packet
s.core.sessions.ping(sinfo)
info.callback(sinfo, nil)
// Cleanup
delete(s.searches, res.Dest)
return true