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"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
|
@ -18,11 +17,13 @@ import (
|
|||
gsyslog "github.com/hashicorp/go-syslog"
|
||||
"github.com/hjson/hjson-go/v4"
|
||||
"github.com/kardianos/minwinsvc"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/address"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/admin"
|
||||
"github.com/yggdrasil-network/yggdrasil-go/src/config"
|
||||
"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/multicast"
|
||||
|
@ -37,32 +38,245 @@ type node struct {
|
|||
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.
|
||||
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() {
|
||||
genconf := flag.Bool("genconf", false, "print a new config to stdout")
|
||||
useconf := flag.Bool("useconf", false, "read HJSON/JSON config from stdin")
|
||||
useconffile := flag.String("useconffile", "", "read HJSON/JSON config from specified file path")
|
||||
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()
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Catch interrupts from the operating system to exit gracefully.
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
func cmdGenconf(cmd *cobra.Command, args []string) (err error) {
|
||||
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.
|
||||
minwinsvc.SetOnExit(cancel)
|
||||
func cmdVersion(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("Build name:", version.BuildName())
|
||||
fmt.Println("Build version:", version.BuildVersion())
|
||||
}
|
||||
|
||||
// Create a new logger that logs output to stdout.
|
||||
var logger *log.Logger
|
||||
switch *logto {
|
||||
func cmdUseconffile(cmd *cobra.Command, args []string) (err error) {
|
||||
useconffile := args[0]
|
||||
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":
|
||||
logger = log.New(os.Stdout, "", log.Flags())
|
||||
|
||||
|
@ -72,120 +286,49 @@ func main() {
|
|||
}
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
if logger == nil {
|
||||
logger = log.New(os.Stdout, "", log.Flags())
|
||||
logger.Warnln("Logging defaulting to stdout")
|
||||
}
|
||||
if *normaliseconf {
|
||||
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)
|
||||
func cmdNormaliseconf(cmd *cobra.Command, args []string) (err error) {
|
||||
confjson, err := cmd.Flags().GetBool("json")
|
||||
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)
|
||||
return err
|
||||
}
|
||||
useconffile := args[0]
|
||||
err = ReadConfigFile(useconffile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return 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 {
|
||||
if confjson {
|
||||
bs, err = json.MarshalIndent(cfg, "", " ")
|
||||
} else {
|
||||
bs, err = hjson.Marshal(cfg)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
fmt.Println(string(bs))
|
||||
return
|
||||
|
||||
case *exportkey:
|
||||
pem, err := cfg.MarshalPEMPrivateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(string(pem))
|
||||
return
|
||||
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 {
|
||||
logger = log.New(os.Stdout, "", log.Flags())
|
||||
logger.Warnln("Logging defaulting to stdout")
|
||||
}
|
||||
setLogLevel("info", logger)
|
||||
n := &node{}
|
||||
|
||||
// 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.
|
||||
<-ctx.Done()
|
||||
|
||||
// Shut down the node.
|
||||
_ = m.Stop()
|
||||
_ = n.admin.Stop()
|
||||
_ = n.multicast.Stop()
|
||||
_ = n.tun.Stop()
|
||||
n.core.Stop()
|
||||
return nil
|
||||
}
|
||||
|
||||
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/kardianos/minwinsvc v1.0.2
|
||||
github.com/quic-go/quic-go v0.44.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/vishvananda/netlink v1.1.0
|
||||
golang.org/x/crypto v0.23.0
|
||||
golang.org/x/mobile v0.0.0-20240520174638-fa72addaaa1b
|
||||
|
@ -24,24 +25,34 @@ require (
|
|||
require (
|
||||
github.com/bits-and-blooms/bitset v1.13.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/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/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/spf13/pflag v1.0.5 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/tools v0.21.0 // 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 (
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2
|
||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // 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/spf13/cobra v1.8.0
|
||||
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/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/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/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
|
||||
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/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo=
|
||||
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/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
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/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-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/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/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
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/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/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20221103000818-d260c55eee4c h1:lvddKcYTQ545ADhBujtIJmqQrZBDsGo7XIMbAQe/sNY=
|
||||
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/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/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/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/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
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.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
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/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/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
|
||||
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/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/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/go.mod h1:z4cx/9Ny9UtGITIPzmPTXh1ULfOyWh4qGQlpnPcWmek=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
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/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.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/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
|
||||
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/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-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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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/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-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/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/go.mod h1:whfbyDBt09xhCYQWtO2+3UVjlaq6/9hDZrjg2ZE6SyA=
|
||||
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
|
||||
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.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
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 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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ed25519"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"sync/atomic"
|
||||
|
@ -250,3 +253,29 @@ func (c *Core) SetAdmin(a AddHandler) error {
|
|||
}
|
||||
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