From 0ba2ad74fec7d23fcc4aee0788ac8f4de95700be Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 19 Dec 2020 06:03:28 -0600 Subject: [PATCH] use source routes in the dht (when available) --- src/yggdrasil/dht.go | 20 +++++++++++++++++--- src/yggdrasil/router.go | 6 +++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/yggdrasil/dht.go b/src/yggdrasil/dht.go index 21ff8472..2ce18576 100644 --- a/src/yggdrasil/dht.go +++ b/src/yggdrasil/dht.go @@ -28,7 +28,8 @@ type dhtInfo struct { recv time.Time // When we last received a message pings int // Time out if at least 3 consecutive maintenance pings drop throttle time.Duration - dirty bool // Set to true if we've used this node in ping responses (for queries about someone other than the person doing the asking, i.e. real searches) since the last time we heard from the node + path []byte // source route the destination, learned from response rpath + dirty bool // Set to true if we've used this node in ping responses (for queries about someone other than the person doing the asking, i.e. real searches) since the last time we heard from the node } // Returns the *NodeID associated with dhtInfo.key, calculating it on the fly the first time or from a cache all subsequent times. @@ -91,7 +92,12 @@ func (t *dht) reconfigure() { func (t *dht) reset() { for _, info := range t.table { if t.isImportant(info) { - t.ping(info, nil) + t.ping(info, nil) // This will source route if a path is already known + if info.path != nil { + // In case the source route died, but the dest coords are still OK... + info.path = nil + t.ping(info, nil) + } } } t.table = make(map[crypto.NodeID]*dhtInfo) @@ -116,6 +122,9 @@ func (t *dht) lookup(nodeID *crypto.NodeID, everything bool) []*dhtInfo { results = newRes results = results[:dht_lookup_size] } + for _, info := range results { + info.dirty = true + } return results } @@ -243,7 +252,7 @@ func (t *dht) addCallback(rq *dhtReqKey, callback func(*dhtRes)) { // Reads a lookup response, checks that we had sent a matching request, and processes the response info. // This mainly consists of updating the node we asked in our DHT (they responded, so we know they're still alive), and deciding if we want to do anything with their responses -func (t *dht) handleRes(res *dhtRes) { +func (t *dht) handleRes(res *dhtRes, rpath []byte) { rq := dhtReqKey{res.Key, res.Dest} if callbacks, isIn := t.callbacks[rq]; isIn { for _, callback := range callbacks { @@ -259,6 +268,7 @@ func (t *dht) handleRes(res *dhtRes) { rinfo := dhtInfo{ key: res.Key, coords: res.Coords, + path: switch_reverseCoordBytes(rpath), } if t.isImportant(&rinfo) { t.insert(&rinfo) @@ -290,6 +300,10 @@ func (t *dht) sendReq(req *dhtReq, dest *dhtInfo) { Nonce: *nonce, Payload: payload, } + if dest.path != nil { + p.Coords = append([]byte{0}, dest.path...) + p.Offset += 1 + } packet := p.encode() t.router.out(packet) rq := dhtReqKey{dest.key, req.Dest} diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index 089c49e7..db81068a 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -206,7 +206,7 @@ func (r *router) _handleProto(packet []byte) { case wire_DHTLookupRequest: r._handleDHTReq(bs, &p.FromKey, p.RPath) case wire_DHTLookupResponse: - r._handleDHTRes(bs, &p.FromKey) + r._handleDHTRes(bs, &p.FromKey, p.RPath) default: } } @@ -237,13 +237,13 @@ func (r *router) _handleDHTReq(bs []byte, fromKey *crypto.BoxPubKey, rpath []byt } // Decodes dht responses and passes them to dht.handleRes to update the DHT table and further pass them to the search code (if applicable). -func (r *router) _handleDHTRes(bs []byte, fromKey *crypto.BoxPubKey) { +func (r *router) _handleDHTRes(bs []byte, fromKey *crypto.BoxPubKey, rpath []byte) { res := dhtRes{} if !res.decode(bs) { return } res.Key = *fromKey - r.dht.handleRes(&res) + r.dht.handleRes(&res, rpath) } // Decodes nodeinfo request