mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-04-28 14:15:06 +03:00
MarshalPEMPrivateKey
This commit is contained in:
parent
24198d353a
commit
4f412a2b6d
10 changed files with 1137 additions and 140 deletions
|
@ -5,7 +5,6 @@ import (
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
@ -18,11 +17,13 @@ import (
|
||||||
gsyslog "github.com/hashicorp/go-syslog"
|
gsyslog "github.com/hashicorp/go-syslog"
|
||||||
"github.com/hjson/hjson-go/v4"
|
"github.com/hjson/hjson-go/v4"
|
||||||
"github.com/kardianos/minwinsvc"
|
"github.com/kardianos/minwinsvc"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/admin"
|
"github.com/yggdrasil-network/yggdrasil-go/src/admin"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc"
|
"github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc"
|
||||||
|
monitoring "github.com/yggdrasil-network/yggdrasil-go/src/monitoring"
|
||||||
|
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/core"
|
"github.com/yggdrasil-network/yggdrasil-go/src/core"
|
||||||
"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
|
"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
|
||||||
|
@ -37,32 +38,245 @@ type node struct {
|
||||||
admin *admin.AdminSocket
|
admin *admin.AdminSocket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
cfg *config.NodeConfig
|
||||||
|
logger *log.Logger
|
||||||
|
ctx context.Context
|
||||||
|
cancel context.CancelFunc
|
||||||
|
|
||||||
|
rootCmd = &cobra.Command{
|
||||||
|
Use: "yggdrasil",
|
||||||
|
Short: "Yggdrasil managment",
|
||||||
|
}
|
||||||
|
|
||||||
|
genconfCmd = &cobra.Command{
|
||||||
|
Use: "genconf",
|
||||||
|
Short: "Print a new config to stdout",
|
||||||
|
RunE: cmdGenconf,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
versionCmd = &cobra.Command{
|
||||||
|
Use: "version",
|
||||||
|
Short: "Prints the version of this build",
|
||||||
|
Run: cmdVersion,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
useconffileCmd = &cobra.Command{
|
||||||
|
Use: "useconffile <path>",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Short: "Read HJSON/JSON config from specified file path",
|
||||||
|
RunE: cmdUseconffile,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
addressCmd = &cobra.Command{
|
||||||
|
Use: "address <path>",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Short: "Outputs your IPv6 address",
|
||||||
|
RunE: cmdAddress,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
snetCmd = &cobra.Command{
|
||||||
|
Use: "subnet <path>",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Short: "Outputs your IPv6 subnet",
|
||||||
|
RunE: cmdSnet,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
pkeyCmd = &cobra.Command{
|
||||||
|
Use: "publickey <path>",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Short: "Outputs your public key",
|
||||||
|
RunE: cmdPkey,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
exportKeyCmd = &cobra.Command{
|
||||||
|
Use: "exportkey <path>",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Short: "Outputs your private key in PEM format",
|
||||||
|
RunE: cmdExportKey,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
logtoCmd = &cobra.Command{
|
||||||
|
Use: "logto <path>",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Short: "File path to log to, \"syslog\" or \"stdout\"",
|
||||||
|
Run: cmdLogto,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
autoconfCmd = &cobra.Command{
|
||||||
|
Use: "autoconf",
|
||||||
|
Short: "Automatic mode (dynamic IP, peer with IPv6 neighbors)",
|
||||||
|
RunE: cmdAutoconf,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
useconfCmd = &cobra.Command{
|
||||||
|
Use: "useconf",
|
||||||
|
Short: "Read HJSON/JSON config from stdin",
|
||||||
|
RunE: cmdUseconf,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
|
||||||
|
normaliseconfCmd = &cobra.Command{
|
||||||
|
Use: "normaliseconf <path>",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
Short: "Outputs your configuration normalised",
|
||||||
|
RunE: cmdNormaliseconf,
|
||||||
|
Annotations: map[string]string{"type": "setup"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// The main function is responsible for configuring and starting Yggdrasil.
|
// The main function is responsible for configuring and starting Yggdrasil.
|
||||||
|
func init() {
|
||||||
|
cfg = config.GenerateConfig()
|
||||||
|
genconfCmd.Flags().BoolP("json", "j", false, "print configuration as JSON instead of HJSON")
|
||||||
|
normaliseconfCmd.Flags().BoolP("json", "j", false, "print configuration as JSON instead of HJSON")
|
||||||
|
autoconfCmd.AddCommand(logtoCmd)
|
||||||
|
useconffileCmd.AddCommand(logtoCmd)
|
||||||
|
useconfCmd.AddCommand(logtoCmd)
|
||||||
|
rootCmd.AddCommand(genconfCmd)
|
||||||
|
rootCmd.AddCommand(versionCmd)
|
||||||
|
rootCmd.AddCommand(useconffileCmd)
|
||||||
|
rootCmd.AddCommand(addressCmd)
|
||||||
|
rootCmd.AddCommand(snetCmd)
|
||||||
|
rootCmd.AddCommand(pkeyCmd)
|
||||||
|
rootCmd.AddCommand(exportKeyCmd)
|
||||||
|
rootCmd.AddCommand(autoconfCmd)
|
||||||
|
rootCmd.AddCommand(useconfCmd)
|
||||||
|
rootCmd.AddCommand(normaliseconfCmd)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
genconf := flag.Bool("genconf", false, "print a new config to stdout")
|
if err := rootCmd.Execute(); err != nil {
|
||||||
useconf := flag.Bool("useconf", false, "read HJSON/JSON config from stdin")
|
fmt.Println(err)
|
||||||
useconffile := flag.String("useconffile", "", "read HJSON/JSON config from specified file path")
|
os.Exit(1)
|
||||||
normaliseconf := flag.Bool("normaliseconf", false, "use in combination with either -useconf or -useconffile, outputs your configuration normalised")
|
}
|
||||||
exportkey := flag.Bool("exportkey", false, "use in combination with either -useconf or -useconffile, outputs your private key in PEM format")
|
}
|
||||||
confjson := flag.Bool("json", false, "print configuration from -genconf or -normaliseconf as JSON instead of HJSON")
|
|
||||||
autoconf := flag.Bool("autoconf", false, "automatic mode (dynamic IP, peer with IPv6 neighbors)")
|
|
||||||
ver := flag.Bool("version", false, "prints the version of this build")
|
|
||||||
logto := flag.String("logto", "stdout", "file path to log to, \"syslog\" or \"stdout\"")
|
|
||||||
getaddr := flag.Bool("address", false, "use in combination with either -useconf or -useconffile, outputs your IPv6 address")
|
|
||||||
getsnet := flag.Bool("subnet", false, "use in combination with either -useconf or -useconffile, outputs your IPv6 subnet")
|
|
||||||
getpkey := flag.Bool("publickey", false, "use in combination with either -useconf or -useconffile, outputs your public key")
|
|
||||||
loglevel := flag.String("loglevel", "info", "loglevel to enable")
|
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
// Catch interrupts from the operating system to exit gracefully.
|
func cmdGenconf(cmd *cobra.Command, args []string) (err error) {
|
||||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
confjson, err := cmd.Flags().GetBool("json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cfg.AdminListen = ""
|
||||||
|
var bs []byte
|
||||||
|
if confjson {
|
||||||
|
bs, err = json.MarshalIndent(cfg, "", " ")
|
||||||
|
} else {
|
||||||
|
bs, err = hjson.Marshal(cfg)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Capture the service being stopped on Windows.
|
func cmdVersion(cmd *cobra.Command, args []string) {
|
||||||
minwinsvc.SetOnExit(cancel)
|
fmt.Println("Build name:", version.BuildName())
|
||||||
|
fmt.Println("Build version:", version.BuildVersion())
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new logger that logs output to stdout.
|
func cmdUseconffile(cmd *cobra.Command, args []string) (err error) {
|
||||||
var logger *log.Logger
|
useconffile := args[0]
|
||||||
switch *logto {
|
err = ReadConfigFile(useconffile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdAutoconf(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
err = run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdUseconf(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
if _, err := cfg.ReadFrom(os.Stdin); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdAddress(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
useconffile := args[0]
|
||||||
|
err = ReadConfigFile(useconffile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
privateKey := ed25519.PrivateKey(cfg.PrivateKey)
|
||||||
|
publicKey := privateKey.Public().(ed25519.PublicKey)
|
||||||
|
addr := address.AddrForKey(publicKey)
|
||||||
|
ip := net.IP(addr[:])
|
||||||
|
fmt.Println(ip.String())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdSnet(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
useconffile := args[0]
|
||||||
|
err = ReadConfigFile(useconffile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
privateKey := ed25519.PrivateKey(cfg.PrivateKey)
|
||||||
|
publicKey := privateKey.Public().(ed25519.PublicKey)
|
||||||
|
snet := address.SubnetForKey(publicKey)
|
||||||
|
ipnet := net.IPNet{
|
||||||
|
IP: append(snet[:], 0, 0, 0, 0, 0, 0, 0, 0),
|
||||||
|
Mask: net.CIDRMask(len(snet)*8, 128),
|
||||||
|
}
|
||||||
|
fmt.Println(ipnet.String())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdPkey(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
useconffile := args[0]
|
||||||
|
err = ReadConfigFile(useconffile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
privateKey := ed25519.PrivateKey(cfg.PrivateKey)
|
||||||
|
publicKey := privateKey.Public().(ed25519.PublicKey)
|
||||||
|
fmt.Println(hex.EncodeToString(publicKey))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdExportKey(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
useconffile := args[0]
|
||||||
|
err = ReadConfigFile(useconffile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pem, err := cfg.MarshalPEMPrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(pem))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdLogto(cmd *cobra.Command, args []string) {
|
||||||
|
logto := args[0]
|
||||||
|
switch logto {
|
||||||
case "stdout":
|
case "stdout":
|
||||||
logger = log.New(os.Stdout, "", log.Flags())
|
logger = log.New(os.Stdout, "", log.Flags())
|
||||||
|
|
||||||
|
@ -72,120 +286,49 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if logfd, err := os.OpenFile(*logto, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
|
if logfd, err := os.OpenFile(logto, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
|
||||||
logger = log.New(logfd, "", log.Flags())
|
logger = log.New(logfd, "", log.Flags())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdNormaliseconf(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
confjson, err := cmd.Flags().GetBool("json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
useconffile := args[0]
|
||||||
|
err = ReadConfigFile(useconffile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cfg.AdminListen = ""
|
||||||
|
if cfg.PrivateKeyPath != "" {
|
||||||
|
cfg.PrivateKey = nil
|
||||||
|
}
|
||||||
|
var bs []byte
|
||||||
|
if confjson {
|
||||||
|
bs, err = json.MarshalIndent(cfg, "", " ")
|
||||||
|
} else {
|
||||||
|
bs, err = hjson.Marshal(cfg)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(bs))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func run() (err error) {
|
||||||
|
ctx, cancel = signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||||
|
// Capture the service being stopped on Windows.
|
||||||
|
minwinsvc.SetOnExit(cancel)
|
||||||
|
|
||||||
if logger == nil {
|
if logger == nil {
|
||||||
logger = log.New(os.Stdout, "", log.Flags())
|
logger = log.New(os.Stdout, "", log.Flags())
|
||||||
logger.Warnln("Logging defaulting to stdout")
|
logger.Warnln("Logging defaulting to stdout")
|
||||||
}
|
}
|
||||||
if *normaliseconf {
|
setLogLevel("info", logger)
|
||||||
setLogLevel("error", logger)
|
|
||||||
} else {
|
|
||||||
setLogLevel(*loglevel, logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := config.GenerateConfig()
|
|
||||||
var err error
|
|
||||||
switch {
|
|
||||||
case *ver:
|
|
||||||
fmt.Println("Build name:", version.BuildName())
|
|
||||||
fmt.Println("Build version:", version.BuildVersion())
|
|
||||||
return
|
|
||||||
|
|
||||||
case *autoconf:
|
|
||||||
// Use an autoconf-generated config, this will give us random keys and
|
|
||||||
// port numbers, and will use an automatically selected TUN interface.
|
|
||||||
|
|
||||||
case *useconf:
|
|
||||||
if _, err := cfg.ReadFrom(os.Stdin); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
case *useconffile != "":
|
|
||||||
f, err := os.Open(*useconffile)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if _, err := cfg.ReadFrom(f); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
_ = f.Close()
|
|
||||||
|
|
||||||
case *genconf:
|
|
||||||
cfg.AdminListen = ""
|
|
||||||
var bs []byte
|
|
||||||
if *confjson {
|
|
||||||
bs, err = json.MarshalIndent(cfg, "", " ")
|
|
||||||
} else {
|
|
||||||
bs, err = hjson.Marshal(cfg)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fmt.Println(string(bs))
|
|
||||||
return
|
|
||||||
|
|
||||||
default:
|
|
||||||
fmt.Println("Usage:")
|
|
||||||
flag.PrintDefaults()
|
|
||||||
|
|
||||||
if *getaddr || *getsnet {
|
|
||||||
fmt.Println("\nError: You need to specify some config data using -useconf or -useconffile.")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
privateKey := ed25519.PrivateKey(cfg.PrivateKey)
|
|
||||||
publicKey := privateKey.Public().(ed25519.PublicKey)
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case *getaddr:
|
|
||||||
addr := address.AddrForKey(publicKey)
|
|
||||||
ip := net.IP(addr[:])
|
|
||||||
fmt.Println(ip.String())
|
|
||||||
return
|
|
||||||
|
|
||||||
case *getsnet:
|
|
||||||
snet := address.SubnetForKey(publicKey)
|
|
||||||
ipnet := net.IPNet{
|
|
||||||
IP: append(snet[:], 0, 0, 0, 0, 0, 0, 0, 0),
|
|
||||||
Mask: net.CIDRMask(len(snet)*8, 128),
|
|
||||||
}
|
|
||||||
fmt.Println(ipnet.String())
|
|
||||||
return
|
|
||||||
|
|
||||||
case *getpkey:
|
|
||||||
fmt.Println(hex.EncodeToString(publicKey))
|
|
||||||
return
|
|
||||||
|
|
||||||
case *normaliseconf:
|
|
||||||
cfg.AdminListen = ""
|
|
||||||
if cfg.PrivateKeyPath != "" {
|
|
||||||
cfg.PrivateKey = nil
|
|
||||||
}
|
|
||||||
var bs []byte
|
|
||||||
if *confjson {
|
|
||||||
bs, err = json.MarshalIndent(cfg, "", " ")
|
|
||||||
} else {
|
|
||||||
bs, err = hjson.Marshal(cfg)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fmt.Println(string(bs))
|
|
||||||
return
|
|
||||||
|
|
||||||
case *exportkey:
|
|
||||||
pem, err := cfg.MarshalPEMPrivateKey()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fmt.Println(string(pem))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
n := &node{}
|
n := &node{}
|
||||||
|
|
||||||
// Set up the Yggdrasil node itself.
|
// Set up the Yggdrasil node itself.
|
||||||
|
@ -272,14 +415,18 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m, _ := monitoring.New(n.core, logger)
|
||||||
|
|
||||||
// Block until we are told to shut down.
|
// Block until we are told to shut down.
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
|
|
||||||
// Shut down the node.
|
// Shut down the node.
|
||||||
|
_ = m.Stop()
|
||||||
_ = n.admin.Stop()
|
_ = n.admin.Stop()
|
||||||
_ = n.multicast.Stop()
|
_ = n.multicast.Stop()
|
||||||
_ = n.tun.Stop()
|
_ = n.tun.Stop()
|
||||||
n.core.Stop()
|
n.core.Stop()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLogLevel(loglevel string, logger *log.Logger) {
|
func setLogLevel(loglevel string, logger *log.Logger) {
|
||||||
|
@ -307,3 +454,15 @@ func setLogLevel(loglevel string, logger *log.Logger) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReadConfigFile(filepath string) error {
|
||||||
|
f, err := os.Open(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := cfg.ReadFrom(f); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_ = f.Close()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
BIN
contrib/.DS_Store
vendored
BIN
contrib/.DS_Store
vendored
Binary file not shown.
13
go.mod
13
go.mod
|
@ -11,6 +11,7 @@ require (
|
||||||
github.com/hjson/hjson-go/v4 v4.4.0
|
github.com/hjson/hjson-go/v4 v4.4.0
|
||||||
github.com/kardianos/minwinsvc v1.0.2
|
github.com/kardianos/minwinsvc v1.0.2
|
||||||
github.com/quic-go/quic-go v0.44.0
|
github.com/quic-go/quic-go v0.44.0
|
||||||
|
github.com/stretchr/testify v1.8.2
|
||||||
github.com/vishvananda/netlink v1.1.0
|
github.com/vishvananda/netlink v1.1.0
|
||||||
golang.org/x/crypto v0.23.0
|
golang.org/x/crypto v0.23.0
|
||||||
golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b
|
golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b
|
||||||
|
@ -24,24 +25,34 @@ require (
|
||||||
require (
|
require (
|
||||||
github.com/bits-and-blooms/bitset v1.13.0 // indirect
|
github.com/bits-and-blooms/bitset v1.13.0 // indirect
|
||||||
github.com/bits-and-blooms/bloom/v3 v3.7.0 // indirect
|
github.com/bits-and-blooms/bloom/v3 v3.7.0 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
github.com/google/pprof v0.0.0-20221103000818-d260c55eee4c // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
|
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/rivo/uniseg v0.2.0 // indirect
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
go.uber.org/mock v0.4.0 // indirect
|
go.uber.org/mock v0.4.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
||||||
golang.org/x/mod v0.17.0 // indirect
|
golang.org/x/mod v0.17.0 // indirect
|
||||||
golang.org/x/sync v0.7.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/tools v0.21.0 // indirect
|
golang.org/x/tools v0.21.0 // indirect
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||||
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.2
|
||||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||||
github.com/fatih/color v1.15.0 // indirect
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22
|
||||||
github.com/olekukonko/tablewriter v0.0.5
|
github.com/olekukonko/tablewriter v0.0.5
|
||||||
|
github.com/spf13/cobra v1.8.0
|
||||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
||||||
)
|
)
|
||||||
|
|
47
go.sum
47
go.sum
|
@ -2,6 +2,8 @@ github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2 h1:SBdYBKeXYUUFe
|
||||||
github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk=
|
github.com/Arceliar/ironwood v0.0.0-20240529054413-b8e59574e2b2/go.mod h1:6WP4799FX0OuWdENGQAh+0RXp9FLh0y7NZ7tM9cJyXk=
|
||||||
github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM=
|
github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d h1:UK9fsWbWqwIQkMCz1CP+v5pGbsGoWAw6g4AyvMpm1EM=
|
||||||
github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q=
|
github.com/Arceliar/phony v0.0.0-20220903101357-530938a4b13d/go.mod h1:BCnxhRf47C/dy/e/D2pmB8NkB3dQVIrkD98b220rx5Q=
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||||
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
|
||||||
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||||
github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||||
|
@ -11,9 +13,8 @@ github.com/bits-and-blooms/bloom/v3 v3.7.0 h1:VfknkqV4xI+PsaDIsoHueyxVDZrfvMn56j
|
||||||
github.com/bits-and-blooms/bloom/v3 v3.7.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg=
|
github.com/bits-and-blooms/bloom/v3 v3.7.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg=
|
||||||
github.com/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo=
|
github.com/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo=
|
||||||
github.com/cheggaaa/pb/v3 v3.1.4/go.mod h1:6wVjILNBaXMs8c21qRiaUM8BR82erfgau1DQ4iUXmSA=
|
github.com/cheggaaa/pb/v3 v3.1.4/go.mod h1:6wVjILNBaXMs8c21qRiaUM8BR82erfgau1DQ4iUXmSA=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -23,21 +24,29 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||||
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/gologme/log v1.3.0 h1:l781G4dE+pbigClDSDzSaaYKtiueHCILUa/qSDsmHAo=
|
github.com/gologme/log v1.3.0 h1:l781G4dE+pbigClDSDzSaaYKtiueHCILUa/qSDsmHAo=
|
||||||
github.com/gologme/log v1.3.0/go.mod h1:yKT+DvIPdDdDoPtqFrFxheooyVmoqi0BAsw+erN3wA4=
|
github.com/gologme/log v1.3.0/go.mod h1:yKT+DvIPdDdDoPtqFrFxheooyVmoqi0BAsw+erN3wA4=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
github.com/google/pprof v0.0.0-20221103000818-d260c55eee4c h1:lvddKcYTQ545ADhBujtIJmqQrZBDsGo7XIMbAQe/sNY=
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
github.com/google/pprof v0.0.0-20221103000818-d260c55eee4c/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||||
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
|
github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=
|
||||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||||
github.com/hjson/hjson-go/v4 v4.4.0 h1:D/NPvqOCH6/eisTb5/ztuIS8GUvmpHaLOcNk1Bjr298=
|
github.com/hjson/hjson-go/v4 v4.4.0 h1:D/NPvqOCH6/eisTb5/ztuIS8GUvmpHaLOcNk1Bjr298=
|
||||||
github.com/hjson/hjson-go/v4 v4.4.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E=
|
github.com/hjson/hjson-go/v4 v4.4.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/kardianos/minwinsvc v1.0.2 h1:JmZKFJQrmTGa/WiW+vkJXKmfzdjabuEW4Tirj5lLdR0=
|
github.com/kardianos/minwinsvc v1.0.2 h1:JmZKFJQrmTGa/WiW+vkJXKmfzdjabuEW4Tirj5lLdR0=
|
||||||
github.com/kardianos/minwinsvc v1.0.2/go.mod h1:LUZNYhNmxujx2tR7FbdxqYJ9XDDoCd3MQcl1o//FWl4=
|
github.com/kardianos/minwinsvc v1.0.2/go.mod h1:LUZNYhNmxujx2tR7FbdxqYJ9XDDoCd3MQcl1o//FWl4=
|
||||||
|
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
@ -46,21 +55,36 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
|
||||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
|
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
|
||||||
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
|
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
|
||||||
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
|
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
|
||||||
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
|
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
|
||||||
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0=
|
github.com/quic-go/quic-go v0.44.0 h1:So5wOr7jyO4vzL2sd8/pD9Kesciv91zSk8BoFngItQ0=
|
||||||
github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek=
|
github.com/quic-go/quic-go v0.44.0/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek=
|
||||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||||
|
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg=
|
github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg=
|
||||||
github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
|
github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
|
||||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
||||||
|
@ -99,7 +123,6 @@ golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
@ -135,15 +158,19 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||||
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 h1:/J/RVnr7ng4fWPRH3xa4WtBJ1Jp+Auu4YNLmGiPv5QU=
|
golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675 h1:/J/RVnr7ng4fWPRH3xa4WtBJ1Jp+Auu4YNLmGiPv5QU=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675/go.mod h1:whfbyDBt09xhCYQWtO2+3UVjlaq6/9hDZrjg2ZE6SyA=
|
golang.zx2c4.com/wireguard v0.0.0-20230223181233-21636207a675/go.mod h1:whfbyDBt09xhCYQWtO2+3UVjlaq6/9hDZrjg2ZE6SyA=
|
||||||
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
|
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
|
||||||
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
|
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
|
||||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||||
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -250,3 +253,29 @@ func (c *Core) SetAdmin(a AddHandler) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (peerinfo PeerInfo) GetCoordinates() *[]byte {
|
||||||
|
var coordsBlob []byte
|
||||||
|
if peerinfo.Coords != nil {
|
||||||
|
coordsBlob = make([]byte, len(peerinfo.Coords)*8)
|
||||||
|
for i, coord := range peerinfo.Coords {
|
||||||
|
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &coordsBlob
|
||||||
|
}
|
||||||
|
|
||||||
|
func (peerinfo PeerInfo) SetCoordinates(coords *[]byte) error {
|
||||||
|
if len(*coords)%8 != 0 {
|
||||||
|
return fmt.Errorf("length of byte slice must be a multiple of 8")
|
||||||
|
}
|
||||||
|
numUint64 := len(*coords) / 8
|
||||||
|
buf := bytes.NewReader(*coords)
|
||||||
|
for i := 0; i < numUint64; i++ {
|
||||||
|
err := binary.Read(buf, binary.LittleEndian, &peerinfo.Coords[i])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
211
src/db/PeerInfoDB/PeerInfoDB.go
Normal file
211
src/db/PeerInfoDB/PeerInfoDB.go
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
package peerinfodb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/core"
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PeerInfoDBConfig struct {
|
||||||
|
DbConfig *db.DbConfig
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
var Name = "PeerInfo"
|
||||||
|
|
||||||
|
func New() (*PeerInfoDBConfig, error) {
|
||||||
|
dir, _ := os.Getwd()
|
||||||
|
fileName := fmt.Sprintf("%s.db", Name)
|
||||||
|
filePath := filepath.Join(dir, fileName)
|
||||||
|
schemas := []string{
|
||||||
|
`CREATE TABLE IF NOT EXISTS peer_infos (
|
||||||
|
uri TEXT,
|
||||||
|
up BOOLEAN,
|
||||||
|
inbound BOOLEAN,
|
||||||
|
last_error VARCHAR,
|
||||||
|
last_error_time TIMESTAMP,
|
||||||
|
key VARCHAR,
|
||||||
|
root VARCHAR,
|
||||||
|
coords VARCHAR,
|
||||||
|
port INT,
|
||||||
|
priority TINYINT,
|
||||||
|
Rxbytes BIGINT,
|
||||||
|
Txbytes BIGINT,
|
||||||
|
uptime BIGINT,
|
||||||
|
latency SMALLINT
|
||||||
|
);`}
|
||||||
|
dbcfg, err := db.New("sqlite3", &schemas, filePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cfg := &PeerInfoDBConfig{
|
||||||
|
name: Name,
|
||||||
|
DbConfig: dbcfg,
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *PeerInfoDBConfig) AddPeer(peer core.PeerInfo) (err error) {
|
||||||
|
var key, root []byte
|
||||||
|
if peer.Key != nil {
|
||||||
|
key, err = x509.MarshalPKIXPublicKey(peer.Key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if peer.Root != nil {
|
||||||
|
root, err = x509.MarshalPKIXPublicKey(peer.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var peerErr interface{}
|
||||||
|
if peer.LastError != nil {
|
||||||
|
peerErr = peer.LastError.Error()
|
||||||
|
} else {
|
||||||
|
peerErr = nil
|
||||||
|
}
|
||||||
|
var coordsBlob []byte
|
||||||
|
if peer.Coords != nil {
|
||||||
|
coordsBlob = make([]byte, len(peer.Coords)*8)
|
||||||
|
for i, coord := range peer.Coords {
|
||||||
|
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !cfg.DbConfig.DBIsOpened() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
_, err = cfg.DbConfig.DB.Exec(`
|
||||||
|
INSERT OR REPLACE INTO peer_infos
|
||||||
|
(
|
||||||
|
uri,
|
||||||
|
up,
|
||||||
|
inbound,
|
||||||
|
last_error,
|
||||||
|
last_error_time,
|
||||||
|
key,
|
||||||
|
root,
|
||||||
|
coords,
|
||||||
|
port,
|
||||||
|
priority,
|
||||||
|
Rxbytes,
|
||||||
|
Txbytes,
|
||||||
|
uptime,
|
||||||
|
latency
|
||||||
|
)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||||
|
peer.URI, peer.Up, peer.Inbound, peerErr, peer.LastErrorTime, key, root, coordsBlob, peer.Port, peer.Priority, peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *PeerInfoDBConfig) RemovePeer(peer core.PeerInfo) (err error) {
|
||||||
|
key, err := x509.MarshalPKIXPublicKey(peer.Key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
root, err := x509.MarshalPKIXPublicKey(peer.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = cfg.DbConfig.DB.Exec("DELETE FROM peer_infos WHERE uri = ? AND key = ? AND root = ?",
|
||||||
|
peer.URI, key, root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *PeerInfoDBConfig) GetPeer(peer *core.PeerInfo) (err error) {
|
||||||
|
key, err := x509.MarshalPKIXPublicKey(peer.Key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
root, err := x509.MarshalPKIXPublicKey(peer.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
row := cfg.DbConfig.DB.QueryRow("SELECT * FROM peer_infos WHERE uri = ? AND key = ? AND root = ?",
|
||||||
|
peer.URI, key, root)
|
||||||
|
var coord []byte
|
||||||
|
var peerErr interface{}
|
||||||
|
err = row.Scan(&peer.URI, &peer.Up, &peer.Inbound, &peerErr, &peer.LastErrorTime, &key, &root, &coord, &peer.Port, &peer.Priority, &peer.RXBytes, &peer.TXBytes, &peer.Uptime, &peer.Latency)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedKey, err := x509.ParsePKCS8PrivateKey(key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ParsedRoot, err := x509.ParsePKCS8PrivateKey(root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
peer.Key = parsedKey.(ed25519.PublicKey)
|
||||||
|
peer.Root = ParsedRoot.(ed25519.PublicKey)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *PeerInfoDBConfig) UpdatePeer(peer core.PeerInfo) (err error) {
|
||||||
|
key, err := x509.MarshalPKIXPublicKey(peer.Key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
root, err := x509.MarshalPKIXPublicKey(peer.Root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var peerErr interface{}
|
||||||
|
if peer.LastError != nil {
|
||||||
|
peerErr = peer.LastError.Error()
|
||||||
|
} else {
|
||||||
|
peerErr = nil
|
||||||
|
}
|
||||||
|
var coordsBlob []byte
|
||||||
|
if peer.Coords != nil {
|
||||||
|
coordsBlob = make([]byte, len(peer.Coords)*8)
|
||||||
|
for i, coord := range peer.Coords {
|
||||||
|
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = cfg.DbConfig.DB.Exec(`UPDATE peer_infos
|
||||||
|
SET
|
||||||
|
up = ?,
|
||||||
|
inbound = ?,
|
||||||
|
last_error = ?,
|
||||||
|
last_error_time = ?,
|
||||||
|
coords = ?,
|
||||||
|
port = ?,
|
||||||
|
priority = ?,
|
||||||
|
RXBytes = RXBytes + ?,
|
||||||
|
TXBytes = TXBytes + ?,
|
||||||
|
uptime = ?,
|
||||||
|
latency = ?
|
||||||
|
WHERE
|
||||||
|
uri = ? AND key = ? AND root = ?`,
|
||||||
|
peer.Up, peer.Inbound, peerErr, peer.LastErrorTime, coordsBlob, peer.Port, peer.Priority,
|
||||||
|
peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency, peer.URI, key, root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *PeerInfoDBConfig) Count() (int, error) {
|
||||||
|
var count int
|
||||||
|
err := cfg.DbConfig.DB.QueryRow("SELECT COUNT(*) FROM peer_infos").Scan(&count)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return count, nil
|
||||||
|
}
|
90
src/db/db.go
Normal file
90
src/db/db.go
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DbConfig struct {
|
||||||
|
Uri string
|
||||||
|
DB *sql.DB
|
||||||
|
Name string
|
||||||
|
Driver string
|
||||||
|
}
|
||||||
|
|
||||||
|
var IsOpened = false
|
||||||
|
|
||||||
|
func New(driver string, schemas *[]string, uri string) (*DbConfig, error) {
|
||||||
|
name := path.Base(uri)
|
||||||
|
db, err := initDB(driver, schemas, uri)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cfg := &DbConfig{
|
||||||
|
DB: db,
|
||||||
|
Uri: uri,
|
||||||
|
Name: name,
|
||||||
|
Driver: driver,
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func initDB(driver string, schemas *[]string, uri string) (*sql.DB, error) {
|
||||||
|
database, err := sql.Open(driver, uri)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer database.Close()
|
||||||
|
tx, err := database.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, schema := range *schemas {
|
||||||
|
_, err := tx.Exec(schema)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tx.Commit()
|
||||||
|
return database, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *DbConfig) DeleteDb() error {
|
||||||
|
err := os.Remove(cfg.Uri)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *DbConfig) OpenDb() error {
|
||||||
|
db, err := sql.Open(cfg.Driver, cfg.Uri)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cfg.DB = db
|
||||||
|
IsOpened = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *DbConfig) CloseDb() error {
|
||||||
|
if IsOpened {
|
||||||
|
err := cfg.DB.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
IsOpened = false
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *DbConfig) DBIsOpened() bool {
|
||||||
|
return IsOpened
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *DbConfig) DBIsExist() bool {
|
||||||
|
_, err := os.Stat(cfg.Uri)
|
||||||
|
return !os.IsNotExist(err)
|
||||||
|
}
|
BIN
src/db/test/PeerInfo.db
Normal file
BIN
src/db/test/PeerInfo.db
Normal file
Binary file not shown.
396
src/db/test/db_test.go
Normal file
396
src/db/test/db_test.go
Normal file
|
@ -0,0 +1,396 @@
|
||||||
|
package db_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/DATA-DOG/go-sqlmock"
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/core"
|
||||||
|
peerinfodb "github.com/yggdrasil-network/yggdrasil-go/src/db/PeerInfoDB"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPeerGetCoords(t *testing.T) {
|
||||||
|
peer := core.PeerInfo{
|
||||||
|
Coords: []uint64{1, 2, 3, 4},
|
||||||
|
}
|
||||||
|
target := []byte{1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0}
|
||||||
|
var coordinates = peer.GetCoordinates()
|
||||||
|
if reflect.DeepEqual(target, coordinates) {
|
||||||
|
t.Error(fmt.Errorf("Not equal"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPeerSetCoords(t *testing.T) {
|
||||||
|
peer := core.PeerInfo{
|
||||||
|
Coords: []uint64{1, 2, 3, 4},
|
||||||
|
}
|
||||||
|
target := []byte{4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}
|
||||||
|
var coordinates = peer.SetCoordinates(&target)
|
||||||
|
if reflect.DeepEqual(target, coordinates) {
|
||||||
|
t.Error(fmt.Errorf("Not equal"))
|
||||||
|
}
|
||||||
|
fmt.Print(peer.Coords)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddPeer(t *testing.T) {
|
||||||
|
mockDB, mock, err := sqlmock.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer mockDB.Close()
|
||||||
|
|
||||||
|
cfg, err := peerinfodb.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
cfg.DbConfig.DB = mockDB
|
||||||
|
|
||||||
|
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
peer := core.PeerInfo{
|
||||||
|
URI: "test.test",
|
||||||
|
Up: true,
|
||||||
|
Inbound: true,
|
||||||
|
LastError: nil,
|
||||||
|
LastErrorTime: time.Now(),
|
||||||
|
Key: pubkey,
|
||||||
|
Root: rootPubKey,
|
||||||
|
Coords: []uint64{0, 0, 0, 0},
|
||||||
|
Port: 8080,
|
||||||
|
Priority: 1,
|
||||||
|
RXBytes: 1024,
|
||||||
|
TXBytes: 2048,
|
||||||
|
Uptime: 3600,
|
||||||
|
Latency: 50.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
pKey, err := x509.MarshalPKIXPublicKey(peer.Key)
|
||||||
|
require.NoError(t, err)
|
||||||
|
pKeyRoot, err := x509.MarshalPKIXPublicKey(peer.Root)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var coordsBlob []byte
|
||||||
|
if peer.Coords != nil {
|
||||||
|
coordsBlob = make([]byte, len(peer.Coords)*8)
|
||||||
|
for i, coord := range peer.Coords {
|
||||||
|
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mock.ExpectExec("INSERT OR REPLACE INTO peer_infos").
|
||||||
|
WithArgs(
|
||||||
|
peer.URI,
|
||||||
|
peer.Up,
|
||||||
|
peer.Inbound,
|
||||||
|
nil,
|
||||||
|
peer.LastErrorTime,
|
||||||
|
pKey,
|
||||||
|
pKeyRoot,
|
||||||
|
coordsBlob,
|
||||||
|
peer.Port,
|
||||||
|
peer.Priority,
|
||||||
|
peer.RXBytes,
|
||||||
|
peer.TXBytes,
|
||||||
|
peer.Uptime,
|
||||||
|
peer.Latency,
|
||||||
|
).
|
||||||
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
|
|
||||||
|
err = cfg.AddPeer(peer)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = mock.ExpectationsWereMet()
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemovePeer(t *testing.T) {
|
||||||
|
mockDB, mock, err := sqlmock.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer mockDB.Close()
|
||||||
|
|
||||||
|
cfg, err := peerinfodb.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
cfg.DbConfig.DB = mockDB
|
||||||
|
|
||||||
|
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
peer := core.PeerInfo{
|
||||||
|
URI: "test.test",
|
||||||
|
Up: true,
|
||||||
|
Inbound: true,
|
||||||
|
LastError: nil,
|
||||||
|
LastErrorTime: time.Now(),
|
||||||
|
Key: pubkey,
|
||||||
|
Root: rootPubKey,
|
||||||
|
Coords: []uint64{0, 0, 0, 0},
|
||||||
|
Port: 8080,
|
||||||
|
Priority: 1,
|
||||||
|
RXBytes: 1024,
|
||||||
|
TXBytes: 2048,
|
||||||
|
Uptime: 3600,
|
||||||
|
Latency: 50.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
pKey, err := x509.MarshalPKIXPublicKey(peer.Key)
|
||||||
|
require.NoError(t, err)
|
||||||
|
pKeyRoot, err := x509.MarshalPKIXPublicKey(peer.Root)
|
||||||
|
require.NoError(t, err)
|
||||||
|
mock.ExpectExec("DELETE FROM peer_infos WHERE uri = \\? AND key = \\? AND root = \\?").
|
||||||
|
WithArgs(peer.URI, pKey, pKeyRoot).
|
||||||
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
|
|
||||||
|
err = cfg.RemovePeer(peer)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = mock.ExpectationsWereMet()
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetPeer(t *testing.T) {
|
||||||
|
mockDB, mock, err := sqlmock.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer mockDB.Close()
|
||||||
|
|
||||||
|
cfg, err := peerinfodb.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
cfg.DbConfig.DB = mockDB
|
||||||
|
|
||||||
|
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
peer := core.PeerInfo{
|
||||||
|
URI: "test.test",
|
||||||
|
Up: true,
|
||||||
|
Inbound: true,
|
||||||
|
LastError: nil,
|
||||||
|
LastErrorTime: time.Now(),
|
||||||
|
Key: pubkey,
|
||||||
|
Root: rootPubKey,
|
||||||
|
Coords: []uint64{0, 0, 0, 0},
|
||||||
|
Port: 8080,
|
||||||
|
Priority: 1,
|
||||||
|
RXBytes: 1024,
|
||||||
|
TXBytes: 2048,
|
||||||
|
Uptime: 3600,
|
||||||
|
Latency: 50.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
pKey, err := x509.MarshalPKIXPublicKey(peer.Key)
|
||||||
|
require.NoError(t, err)
|
||||||
|
pKeyRoot, err := x509.MarshalPKIXPublicKey(peer.Root)
|
||||||
|
require.NoError(t, err)
|
||||||
|
var coords []byte
|
||||||
|
rows := sqlmock.NewRows([]string{"uri", "up", "Inbound", "LastError", "LastErrorTime", "Key", "Root", "Coords", "Port", "Priority", "Rxbytes", "Txbytes", "Uptime", "Latency"}).
|
||||||
|
AddRow(peer.URI, peer.Up, peer.Inbound, peer.LastError, peer.LastErrorTime, peer.Key, peer.Root, coords, peer.Port, peer.Priority, peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency)
|
||||||
|
|
||||||
|
mock.ExpectQuery("SELECT * FROM peer_infos WHERE uri = ? AND key = ? AND root = ?").
|
||||||
|
WithArgs(peer.URI, pKey, pKeyRoot).
|
||||||
|
WillReturnRows(rows)
|
||||||
|
|
||||||
|
err = cfg.GetPeer(&peer)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = mock.ExpectationsWereMet()
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdatePeer(t *testing.T) {
|
||||||
|
mockDB, mock, err := sqlmock.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer mockDB.Close()
|
||||||
|
|
||||||
|
cfg, err := peerinfodb.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
cfg.DbConfig.DB = mockDB
|
||||||
|
|
||||||
|
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
peer := core.PeerInfo{
|
||||||
|
URI: "test.test",
|
||||||
|
Up: true,
|
||||||
|
Inbound: true,
|
||||||
|
LastError: nil,
|
||||||
|
LastErrorTime: time.Now(),
|
||||||
|
Key: pubkey,
|
||||||
|
Root: rootPubKey,
|
||||||
|
Coords: []uint64{0, 0, 0, 0},
|
||||||
|
Port: 8080,
|
||||||
|
Priority: 1,
|
||||||
|
RXBytes: 1024,
|
||||||
|
TXBytes: 2048,
|
||||||
|
Uptime: 3600,
|
||||||
|
Latency: 50.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
pKey, err := x509.MarshalPKIXPublicKey(peer.Key)
|
||||||
|
require.NoError(t, err)
|
||||||
|
pKeyRoot, err := x509.MarshalPKIXPublicKey(peer.Root)
|
||||||
|
var coordsBlob []byte
|
||||||
|
if peer.Coords != nil {
|
||||||
|
coordsBlob = make([]byte, len(peer.Coords)*8)
|
||||||
|
for i, coord := range peer.Coords {
|
||||||
|
binary.LittleEndian.PutUint64(coordsBlob[i*8:], coord)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
mock.ExpectExec(`UPDATE peer_infos
|
||||||
|
SET
|
||||||
|
up = \?,
|
||||||
|
inbound = \?,
|
||||||
|
last_error = \?,
|
||||||
|
last_error_time = \?,
|
||||||
|
coords = \?,
|
||||||
|
port = \?,
|
||||||
|
priority = \?,
|
||||||
|
RXBytes = RXBytes \+ \?,
|
||||||
|
TXBytes = TXBytes \+ \?,
|
||||||
|
uptime = \?,
|
||||||
|
latency = \?
|
||||||
|
WHERE
|
||||||
|
uri = \? AND key = \? AND root = \?`).
|
||||||
|
WithArgs(
|
||||||
|
peer.Up, peer.Inbound, peer.LastError, peer.LastErrorTime, coordsBlob, peer.Port, peer.Priority,
|
||||||
|
peer.RXBytes, peer.TXBytes, peer.Uptime, peer.Latency, peer.URI, pKey, pKeyRoot).
|
||||||
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||||
|
|
||||||
|
err = cfg.UpdatePeer(peer)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = mock.ExpectationsWereMet()
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// One more test here
|
||||||
|
func TestMain(t *testing.T) {
|
||||||
|
peerinfodb.Name = fmt.Sprintf(
|
||||||
|
"%s.%s",
|
||||||
|
peerinfodb.Name,
|
||||||
|
strconv.Itoa(int(time.Now().Unix())),
|
||||||
|
)
|
||||||
|
|
||||||
|
peerdb, err := peerinfodb.New()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
peerdb.DbConfig.OpenDb()
|
||||||
|
isOpened := peerdb.DbConfig.DBIsOpened()
|
||||||
|
condition := func() bool {
|
||||||
|
return isOpened
|
||||||
|
}
|
||||||
|
require.Condition(t, condition, "Expected db is opened", isOpened)
|
||||||
|
|
||||||
|
pubkey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
rootPubKey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
peer := core.PeerInfo{
|
||||||
|
URI: "test.test",
|
||||||
|
Up: true,
|
||||||
|
Inbound: true,
|
||||||
|
LastError: nil,
|
||||||
|
LastErrorTime: time.Now(),
|
||||||
|
Key: pubkey,
|
||||||
|
Root: rootPubKey,
|
||||||
|
Coords: []uint64{0, 0, 0, 0},
|
||||||
|
Port: 8080,
|
||||||
|
Priority: 1,
|
||||||
|
RXBytes: 1024,
|
||||||
|
TXBytes: 2048,
|
||||||
|
Uptime: 3600,
|
||||||
|
Latency: 50.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
root2PubKey, _, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
peer2 := core.PeerInfo{
|
||||||
|
URI: "new.test",
|
||||||
|
Up: true,
|
||||||
|
Inbound: true,
|
||||||
|
LastError: nil,
|
||||||
|
LastErrorTime: time.Now(),
|
||||||
|
Key: pubkey,
|
||||||
|
Root: root2PubKey,
|
||||||
|
Coords: []uint64{0, 0, 0, 0},
|
||||||
|
Port: 8080,
|
||||||
|
Priority: 1,
|
||||||
|
RXBytes: 1024,
|
||||||
|
TXBytes: 2048,
|
||||||
|
Uptime: 3600,
|
||||||
|
Latency: 50.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
peerdb.AddPeer(peer)
|
||||||
|
peerdb.AddPeer(peer2)
|
||||||
|
count, err := peerdb.Count()
|
||||||
|
require.NoError(t, err)
|
||||||
|
condition = func() bool {
|
||||||
|
return count == 2
|
||||||
|
}
|
||||||
|
require.Condition(t, condition, "Expected count to be 2", count)
|
||||||
|
|
||||||
|
peerdb.RemovePeer(peer)
|
||||||
|
count, err = peerdb.Count()
|
||||||
|
require.NoError(t, err)
|
||||||
|
condition = func() bool {
|
||||||
|
return count == 1
|
||||||
|
}
|
||||||
|
require.Condition(t, condition, "Expected count to be 1", count)
|
||||||
|
|
||||||
|
peer2.Latency = 10
|
||||||
|
peer2.RXBytes = 1024
|
||||||
|
peer2.TXBytes = 1024
|
||||||
|
peer2.Port = 80
|
||||||
|
peerdb.UpdatePeer(peer2)
|
||||||
|
peerdb.GetPeer(&peer2)
|
||||||
|
condition = func() bool {
|
||||||
|
return peer2.Latency == 10 &&
|
||||||
|
peer2.RXBytes == 2048 &&
|
||||||
|
peer2.TXBytes == 3072 &&
|
||||||
|
peer2.Port == 80 && peer2.URI == "new.test" && bytes.Equal(peer.Key, pubkey)
|
||||||
|
}
|
||||||
|
require.Condition(t, condition, "Inner exception")
|
||||||
|
|
||||||
|
peerdb.RemovePeer(peer2)
|
||||||
|
count, err = peerdb.Count()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
condition = func() bool {
|
||||||
|
return count == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Condition(t, condition, "Expected count to be 0", count)
|
||||||
|
|
||||||
|
err = peerdb.DbConfig.CloseDb()
|
||||||
|
isOpened = peerdb.DbConfig.DBIsOpened()
|
||||||
|
|
||||||
|
condition = func() bool {
|
||||||
|
return !isOpened
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Condition(t, condition, "Expected db is not opened", isOpened)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = peerdb.DbConfig.DeleteDb()
|
||||||
|
require.NoError(t, err)
|
||||||
|
isExist := peerdb.DbConfig.DBIsExist()
|
||||||
|
|
||||||
|
condition = func() bool {
|
||||||
|
return !isExist
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Condition(t, condition, "Expected db is not exist", isExist)
|
||||||
|
}
|
74
src/monitoring/monitoring.go
Normal file
74
src/monitoring/monitoring.go
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package monitoring
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||||
|
"github.com/yggdrasil-network/yggdrasil-go/src/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Monitoring struct {
|
||||||
|
core *core.Core
|
||||||
|
done chan struct{}
|
||||||
|
log core.Logger
|
||||||
|
once sync.Once
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(c *core.Core, log core.Logger) (*Monitoring, error) {
|
||||||
|
m := &Monitoring{
|
||||||
|
core: c,
|
||||||
|
log: log,
|
||||||
|
}
|
||||||
|
m.done = make(chan struct{})
|
||||||
|
go m.Monitoring(func(peer core.PeerInfo) {
|
||||||
|
log.Printf("Peers: %s", peer.URI)
|
||||||
|
}, func(session core.SessionInfo) {
|
||||||
|
addr := address.AddrForKey(session.Key)
|
||||||
|
addrStr := net.IP(addr[:]).String()
|
||||||
|
log.Printf("Session: %s", addrStr)
|
||||||
|
})
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Monitoring) Stop() error {
|
||||||
|
if m == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m.once.Do(func() {
|
||||||
|
close(m.done)
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type PeerMonitoring func(peer core.PeerInfo)
|
||||||
|
type SessionMonitoring func(peer core.SessionInfo)
|
||||||
|
|
||||||
|
func (m *Monitoring) Monitoring(PeerMonitoringCallBack PeerMonitoring, SessionMonitoringCallBack SessionMonitoring) {
|
||||||
|
peers := make(map[string]struct{})
|
||||||
|
sessions := make(map[string]struct{})
|
||||||
|
for {
|
||||||
|
APIpeers := m.core.GetPeers()
|
||||||
|
for _, peer := range APIpeers {
|
||||||
|
if _, exist := peers[peer.URI]; !exist {
|
||||||
|
PeerMonitoringCallBack(peer)
|
||||||
|
peers[peer.URI] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
APIsessions := m.core.GetSessions()
|
||||||
|
for _, session := range APIsessions {
|
||||||
|
addr := address.AddrForKey(session.Key)
|
||||||
|
addrStr := net.IP(addr[:]).String()
|
||||||
|
if _, exist := sessions[addrStr]; !exist {
|
||||||
|
SessionMonitoringCallBack(session)
|
||||||
|
sessions[addrStr] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-m.done:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue