From c7b004d36fa38e6447ddbf7051702cb916c9f072 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 22 May 2021 20:25:14 -0500 Subject: [PATCH] get debugGetPeers and debugGetDHT working in the admin socket --- src/tuntap/admin.go | 2 + src/tuntap/debug.go | 147 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 145 insertions(+), 4 deletions(-) diff --git a/src/tuntap/admin.go b/src/tuntap/admin.go index 01cb56fa..800703c4 100644 --- a/src/tuntap/admin.go +++ b/src/tuntap/admin.go @@ -35,4 +35,6 @@ func (t *TunAdapter) SetupAdminHandlers(a *admin.AdminSocket) { return res, nil }) _ = a.AddHandler("getNodeInfo", []string{"key"}, t.nodeinfo.nodeInfoAdminHandler) + _ = a.AddHandler("debugGetPeers", []string{"key"}, t.debug.getPeersHandler) + _ = a.AddHandler("debugGetDHT", []string{"key"}, t.debug.getDHTHandler) } diff --git a/src/tuntap/debug.go b/src/tuntap/debug.go index ee19d3f0..9b1bd512 100644 --- a/src/tuntap/debug.go +++ b/src/tuntap/debug.go @@ -1,6 +1,9 @@ package tuntap import ( + "encoding/hex" + "encoding/json" + "errors" "time" iwt "github.com/Arceliar/ironwood/types" @@ -18,8 +21,8 @@ const ( ) type reqInfo struct { - ch chan []byte - timer time.Timer // time.AfterFunc cleanup + callback func([]byte) + timer *time.Timer // time.AfterFunc cleanup } type debugHandler struct { @@ -72,6 +75,26 @@ func (d *debugHandler) _handleGetSelfResponse(key keyArray, bs []byte) { // TODO } +func (d *debugHandler) sendGetPeersRequest(key keyArray, callback func([]byte)) { + d.Act(nil, func() { + if info := d.preqs[key]; info != nil { + info.timer.Stop() + delete(d.preqs, key) + } + info := new(reqInfo) + info.callback = callback + info.timer = time.AfterFunc(time.Minute, func() { + d.Act(nil, func() { + if d.preqs[key] == info { + delete(d.preqs, key) + } + }) + }) + d.preqs[key] = info + d._sendDebug(key, typeDebugGetPeersRequest, nil) + }) +} + func (d *debugHandler) _handleGetPeersRequest(key keyArray) { peers := d.tun.core.GetPeers() var bs []byte @@ -89,11 +112,31 @@ func (d *debugHandler) _handleGetPeersRequest(key keyArray) { func (d *debugHandler) _handleGetPeersResponse(key keyArray, bs []byte) { if info := d.preqs[key]; info != nil { info.timer.Stop() - info.ch <- bs + info.callback(bs) delete(d.preqs, key) } } +func (d *debugHandler) sendGetDHTRequest(key keyArray, callback func([]byte)) { + d.Act(nil, func() { + if info := d.dreqs[key]; info != nil { + info.timer.Stop() + delete(d.dreqs, key) + } + info := new(reqInfo) + info.callback = callback + info.timer = time.AfterFunc(time.Minute, func() { + d.Act(nil, func() { + if d.dreqs[key] == info { + delete(d.dreqs, key) + } + }) + }) + d.dreqs[key] = info + d._sendDebug(key, typeDebugGetDHTRequest, nil) + }) +} + func (d *debugHandler) _handleGetDHTRequest(key keyArray) { dinfos := d.tun.core.GetDHT() var bs []byte @@ -111,7 +154,7 @@ func (d *debugHandler) _handleGetDHTRequest(key keyArray) { func (d *debugHandler) _handleGetDHTResponse(key keyArray, bs []byte) { if info := d.dreqs[key]; info != nil { info.timer.Stop() - info.ch <- bs + info.callback(bs) delete(d.dreqs, key) } } @@ -120,3 +163,99 @@ func (d *debugHandler) _sendDebug(key keyArray, dType uint8, data []byte) { bs := append([]byte{typeSessionDebug, dType}, data...) d.tun.core.WriteTo(bs, iwt.Addr(key[:])) } + +// Admin socket stuff + +type DebugGetPeersRequest struct { + Key string `json:"key"` +} + +type DebugGetPeersResponse map[string]interface{} + +func (d *debugHandler) getPeersHandler(in json.RawMessage) (interface{}, error) { + var req DebugGetPeersRequest + if err := json.Unmarshal(in, &req); err != nil { + return nil, err + } + var key keyArray + var kbs []byte + var err error + if kbs, err = hex.DecodeString(req.Key); err != nil { + return nil, err + } + copy(key[:], kbs) + ch := make(chan []byte, 1) + d.sendGetPeersRequest(key, func(info []byte) { + ch <- info + }) + timer := time.NewTimer(6 * time.Second) + defer timer.Stop() + select { + case <-timer.C: + return nil, errors.New("timeout") + case info := <-ch: + ks := make(map[string][]string) + bs := info + for len(bs) >= len(key) { + ks["keys"] = append(ks["keys"], hex.EncodeToString(bs[:len(key)])) + bs = bs[len(key):] + } + js, err := json.Marshal(ks) + if err != nil { + return nil, err + } + var msg json.RawMessage + if err := msg.UnmarshalJSON(js); err != nil { + return nil, err + } + res := GetNodeInfoResponse{req.Key: msg} + return res, nil + } +} + +type DebugGetDHTRequest struct { + Key string `json:"key"` +} + +type DebugGetDHTResponse map[string]interface{} + +func (d *debugHandler) getDHTHandler(in json.RawMessage) (interface{}, error) { + var req DebugGetDHTRequest + if err := json.Unmarshal(in, &req); err != nil { + return nil, err + } + var key keyArray + var kbs []byte + var err error + if kbs, err = hex.DecodeString(req.Key); err != nil { + return nil, err + } + copy(key[:], kbs) + ch := make(chan []byte, 1) + d.sendGetDHTRequest(key, func(info []byte) { + ch <- info + }) + timer := time.NewTimer(6 * time.Second) + defer timer.Stop() + select { + case <-timer.C: + return nil, errors.New("timeout") + case info := <-ch: + ks := make(map[string][]string) + bs := info + for len(bs) >= len(key) { + ks["keys"] = append(ks["keys"], hex.EncodeToString(bs[:len(key)])) + bs = bs[len(key):] + } + js, err := json.Marshal(ks) + if err != nil { + return nil, err + } + var msg json.RawMessage + if err := msg.UnmarshalJSON(js); err != nil { + return nil, err + } + res := GetNodeInfoResponse{req.Key: msg} + return res, nil + } +}