github.com/yggdrasil-network/yggdrasil-go@v0.5.6/src/admin/options.go (about)

     1  package admin
     2  
     3  import (
     4  	"crypto/ed25519"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"net"
     8  	"sync"
     9  	"time"
    10  
    11  	"github.com/Arceliar/ironwood/network"
    12  
    13  	"github.com/yggdrasil-network/yggdrasil-go/src/address"
    14  )
    15  
    16  func (c *AdminSocket) _applyOption(opt SetupOption) {
    17  	switch v := opt.(type) {
    18  	case ListenAddress:
    19  		c.config.listenaddr = v
    20  	case LogLookups:
    21  		c.logLookups()
    22  	}
    23  }
    24  
    25  type SetupOption interface {
    26  	isSetupOption()
    27  }
    28  
    29  type ListenAddress string
    30  
    31  func (a ListenAddress) isSetupOption() {}
    32  
    33  type LogLookups struct{}
    34  
    35  func (l LogLookups) isSetupOption() {}
    36  
    37  func (a *AdminSocket) logLookups() {
    38  	type resi struct {
    39  		Address string   `json:"addr"`
    40  		Key     string   `json:"key"`
    41  		Path    []uint64 `json:"path"`
    42  		Time    int64    `json:"time"`
    43  	}
    44  	type res struct {
    45  		Infos []resi `json:"infos"`
    46  	}
    47  	type info struct {
    48  		path []uint64
    49  		time time.Time
    50  	}
    51  	type edk [ed25519.PublicKeySize]byte
    52  	infos := make(map[edk]info)
    53  	var m sync.Mutex
    54  	a.core.PacketConn.PacketConn.Debug.SetDebugLookupLogger(func(l network.DebugLookupInfo) {
    55  		var k edk
    56  		copy(k[:], l.Key[:])
    57  		m.Lock()
    58  		infos[k] = info{path: l.Path, time: time.Now()}
    59  		m.Unlock()
    60  	})
    61  	_ = a.AddHandler(
    62  		"lookups", "Dump a record of lookups received in the past hour", []string{},
    63  		func(in json.RawMessage) (interface{}, error) {
    64  			m.Lock()
    65  			rs := make([]resi, 0, len(infos))
    66  			for k, v := range infos {
    67  				if time.Since(v.time) > 24*time.Hour {
    68  					// TODO? automatic cleanup, so we don't need to call lookups periodically to prevent leaks
    69  					delete(infos, k)
    70  				}
    71  				a := address.AddrForKey(ed25519.PublicKey(k[:]))
    72  				addr := net.IP(a[:]).String()
    73  				rs = append(rs, resi{Address: addr, Key: hex.EncodeToString(k[:]), Path: v.path, Time: v.time.Unix()})
    74  			}
    75  			m.Unlock()
    76  			return &res{Infos: rs}, nil
    77  		},
    78  	)
    79  }