DampingResistance

This commit is contained in:
Kusakabe Si 2021-12-07 20:39:19 +00:00
parent fb2a967a60
commit 0be4e84f8d
19 changed files with 762 additions and 493 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
go.sum
etherguard-go
etherguard-go-vpp
vendor

14
.vscode/launch.json vendored
View File

@ -12,7 +12,7 @@
"program": "${workspaceFolder}",
"buildFlags": "-tags 'novpp'",
"env": {"CGO_CFLAGS":"-I/usr/include/memif"},
"args":["-config","example_config/super_mode/s1.yaml","-mode","super","-example"],
"args":["-config","example_config/super_mode/s1.yaml","-mode","super"/*,"-example"*/],
},
{
"name": "Launch Edge",
@ -22,7 +22,17 @@
"program": "${workspaceFolder}",
"buildFlags": "-tags 'novpp'",
"env": {"CGO_CFLAGS":"-I/usr/include/memif"},
"args":["-config","example_config/super_mode/n1.yaml","-mode","edge","-example"],
"args":["-config","example_config/super_mode/n1.yaml","-mode","edge"/*,"-example"*/],
}
{
"name": "Launch GenCfg",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"buildFlags": "-tags 'novpp'",
"env": {"CGO_CFLAGS":"-I/usr/include/memif"},
"args":["-config","example_config/super_mode/gensuper.yaml","-mode","gencfg","-cfgmode","super"/*,"-example"*/],
}
]
}

View File

@ -53,27 +53,10 @@ Usage of ./etherguard-go-vpp:
內建小工具可以快速生成設定檔搞定私鑰公鑰等等暫時只支援Super模式
可以參考下面的配置,但是 `/tmp/test` , `example.com` , `192.168.76.0/24` , `fd95:71cb:a3df:e586::/64` , `fe80::a3df:0/112` 請記得換掉
首先按需求修改`example_config/super_mode/gensuper.yaml`
```
$ ./etherguard-go -mode gencfg -cfgmode super
```
然後按照提示輸入即可
```
Config save path (eg_generated_configs) :/tmp/test
SuperConfig template path(optional) :
EdgeTamplatePath template path(optional) :
Network name (eg_net) :
SuperNode ListenPort (12369) : 3456
EdgeAPI prefix (/eg_net/eg_api) :
IPv4/domain of your supernode (optional) :example.com
IPv6/domain of your supernode (optional) :example.com
URL(use domain would be better) of the EdgeAPI provided by supernode (http://example.com:3456/eg_net/eg_api) :
Number of your nodes :100
MacAddress Prefix (36:23:DA:2D) :
IPv4 block(optional) :192.168.76.0/24
IPv6 block(optional) :fd95:71cb:a3df:e586::/64
IPv6LL block(optional) :fe80::a3df:0/112
$ ./etherguard-go -mode gencfg -cfgmode super -config example_config/super_mode/gensuper.yaml
```
順帶一提最後三個欄位IP的部分可以直接省略沒關係
@ -81,6 +64,18 @@ IPv6LL block(optional) :fe80::a3df:0/112
和VPN本身運作完全無關
VPN起來以後自己手動加ip也行
把一個super2個edge分別搬去三台機器
或是2台機器super和edge可以是同一台
然後在Supernode執行
```
./etherguard-go -config [設定檔位置] -mode super
```
然後在EdgeNode執行
```
./etherguard-go -config [設定檔位置] -mode edge
```
## Build
### No-vpp version

View File

@ -0,0 +1,16 @@
Config output dir: /tmp/eg_gen
ConfigTemplate for super node: ""
ConfigTemplate for edge node: ""
Network name: eg_net
Super Node:
Listen port: 3456
EdgeAPI prefix: /eg_net/eg_api
Endpoint(IPv4)(optional): example.com
Endpoint(IPv6)(optional): example.com
Endpoint(EdgeAPI): http://example.com:3456/eg_net/eg_api
Edge Node:
Node IDs: "[1~100]"
MacAddress prefix: ""
IPv4 range: 192.168.76.0/24
IPv6 range: fd95:71cb:a3df:e586::/64
IPv6 LL range: fe80::a3df:0/112

View File

@ -8,7 +8,7 @@ After=network.target
User=root
Group=root
WorkingDirectory=/etc/eggo
Type=simple
Type=notify
ExecStart=etherguard-go -config /etc/eggo/edge.yaml -mode edge
Nice=5

View File

@ -8,7 +8,7 @@ After=network.target
User=nobody
Group=nogroup
WorkingDirectory=/etc/eggo
Type=simple
Type=notify
#ExecStartPre=+chgrp nogroup /var/run/wireguard
#ExecStartPre=+chmod 775 /var/run/wireguard
ExecStart=etherguard-go -config /etc/eggo/super.yaml -mode super -no-uapi

226
gencfg/example_conf.go Normal file
View File

@ -0,0 +1,226 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package gencfg
import (
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/path"
)
func GetExampleEdgeConf(templatePath string) mtypes.EdgeConfig {
tconfig := mtypes.EdgeConfig{}
if templatePath != "" {
err := mtypes.ReadYaml(templatePath, &tconfig)
if err == nil {
return tconfig
}
}
v1 := mtypes.Vertex(1)
v2 := mtypes.Vertex(2)
tconfig = mtypes.EdgeConfig{
Interface: mtypes.InterfaceConf{
IType: "tap",
Name: "tap1",
VPPIFaceID: 1,
VPPBridgeID: 4242,
MacAddrPrefix: "AA:BB:CC:DD",
MTU: 1416,
RecvAddr: "127.0.0.1:4001",
SendAddr: "127.0.0.1:5001",
L2HeaderMode: "nochg",
},
NodeID: 1,
NodeName: "Node01",
PostScript: "",
DefaultTTL: 200,
L2FIBTimeout: 3600,
PrivKey: "6GyDagZKhbm5WNqMiRHhkf43RlbMJ34IieTlIuvfJ1M=",
ListenPort: 0,
LogLevel: mtypes.LoggerInfo{
LogLevel: "error",
LogTransit: false,
LogControl: true,
LogNormal: false,
LogInternal: true,
LogNTP: true,
},
DynamicRoute: mtypes.DynamicRouteInfo{
SendPingInterval: 16,
PeerAliveTimeout: 70,
DupCheckTimeout: 40,
ConnTimeOut: 20,
ConnNextTry: 5,
AdditionalCost: 10,
SaveNewPeers: true,
SuperNode: mtypes.SuperInfo{
UseSuperNode: true,
PSKey: "iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=",
EndpointV4: "127.0.0.1:3000",
PubKeyV4: "LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=",
EndpointV6: "[::1]:3000",
PubKeyV6: "HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=",
EndpointEdgeAPIUrl: "http://127.0.0.1:3000/eg_api",
SuperNodeInfoTimeout: 50,
SkipLocalIP: false,
},
P2P: mtypes.P2PInfo{
UseP2P: false,
SendPeerInterval: 20,
GraphRecalculateSetting: mtypes.GraphRecalculateSetting{
StaticMode: false,
JitterTolerance: 50,
JitterToleranceMultiplier: 1.1,
DampingResistance: 0.8,
TimeoutCheckInterval: 5,
RecalculateCoolDown: 5,
},
},
NTPConfig: mtypes.NTPInfo{
UseNTP: true,
MaxServerUse: 8,
SyncTimeInterval: 3600,
NTPTimeout: 3,
Servers: []string{
"time.google.com",
"time1.google.com",
"time2.google.com",
"time3.google.com",
"time4.google.com",
"time1.facebook.com",
"time2.facebook.com",
"time3.facebook.com",
"time4.facebook.com",
"time5.facebook.com",
"time.cloudflare.com",
"time.apple.com",
"time.asia.apple.com",
"time.euro.apple.com",
"time.windows.com",
"pool.ntp.org",
"0.pool.ntp.org",
"1.pool.ntp.org",
"2.pool.ntp.org",
"3.pool.ntp.org",
},
},
},
NextHopTable: mtypes.NextHopTable{
mtypes.Vertex(1): {
mtypes.Vertex(2): &v2,
},
mtypes.Vertex(2): {
mtypes.Vertex(1): &v1,
},
},
ResetConnInterval: 86400,
Peers: []mtypes.PeerInfo{
{
NodeID: 2,
PubKey: "dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=",
PSKey: "juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=",
EndPoint: "127.0.0.1:3002",
Static: true,
},
},
}
g := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting, tconfig.DynamicRoute.NTPConfig, mtypes.LoggerInfo{})
g.UpdateLatency(1, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 1, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(5, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 5, 0.5, 99999, 0, false, false)
g.UpdateLatency(6, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 6, 0.5, 99999, 0, false, false)
_, next, _ := g.FloydWarshall(false)
tconfig.NextHopTable = next
return tconfig
}
func GetExampleSuperConf(templatePath string) mtypes.SuperConfig {
sconfig := mtypes.SuperConfig{}
if templatePath != "" {
err := mtypes.ReadYaml(templatePath, &sconfig)
if err == nil {
return sconfig
}
}
v1 := mtypes.Vertex(1)
v2 := mtypes.Vertex(2)
random_passwd := mtypes.RandomStr(8, "passwd")
sconfig = mtypes.SuperConfig{
NodeName: "NodeSuper",
PostScript: "",
PrivKeyV4: "mL5IW0GuqbjgDeOJuPHBU2iJzBPNKhaNEXbIGwwYWWk=",
PrivKeyV6: "+EdOKIoBp/EvIusHDsvXhV1RJYbyN3Qr8nxlz35wl3I=",
ListenPort: 3000,
ListenPort_EdgeAPI: "3000",
ListenPort_ManageAPI: "3000",
API_Prefix: "/eg_api",
LogLevel: mtypes.LoggerInfo{
LogLevel: "normal",
LogTransit: false,
LogControl: true,
LogNormal: false,
LogInternal: true,
LogNTP: true,
},
RePushConfigInterval: 30,
PeerAliveTimeout: 70,
HttpPostInterval: 50,
SendPingInterval: 15,
Passwords: mtypes.Passwords{
ShowState: random_passwd + "_showstate",
AddPeer: random_passwd + "_addpeer",
DelPeer: random_passwd + "_delpeer",
UpdatePeer: random_passwd + "_updatepeer",
UpdateSuper: random_passwd + "_updatesuper",
},
GraphRecalculateSetting: mtypes.GraphRecalculateSetting{
StaticMode: false,
JitterTolerance: 50,
JitterToleranceMultiplier: 1.01,
DampingResistance: 0.8,
TimeoutCheckInterval: 5,
RecalculateCoolDown: 5,
},
NextHopTable: mtypes.NextHopTable{
mtypes.Vertex(1): {
mtypes.Vertex(2): &v2,
},
mtypes.Vertex(2): {
mtypes.Vertex(1): &v1,
},
},
EdgeTemplate: "example_config/super_mode/n1.yaml",
UsePSKForInterEdge: true,
Peers: []mtypes.SuperPeerInfo{
{
NodeID: 1,
Name: "Node_01",
PubKey: "ZqzLVSbXzjppERslwbf2QziWruW3V/UIx9oqwU8Fn3I=",
PSKey: "iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=",
AdditionalCost: 10,
},
{
NodeID: 2,
Name: "Node_02",
PubKey: "dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=",
PSKey: "juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=",
AdditionalCost: 10,
},
},
}
return sconfig
}

8
gencfg/gencfgPM.go Normal file
View File

@ -0,0 +1,8 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package gencfg

318
gencfg/gencfgSM.go Normal file
View File

@ -0,0 +1,318 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package gencfg
import (
"bufio"
"fmt"
"io/ioutil"
"math"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/KusakabeSi/EtherGuard-VPN/conn"
"github.com/KusakabeSi/EtherGuard-VPN/device"
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/tap"
yaml "gopkg.in/yaml.v2"
)
var gencfg_reader *bufio.Reader
func readFLn(promptF string, checkFn func(string) error, defaultAns func() string, args ...interface{}) string {
defaultans := defaultAns()
if defaultans != "" {
fmt.Printf(promptF+" ("+defaultans+") :", args...)
} else {
fmt.Printf(promptF+" :", args...)
}
text, err := gencfg_reader.ReadString('\n')
if err != nil {
panic(err)
}
text = strings.Replace(text, "\n", "", -1)
if text == "" {
text = defaultans
}
if err := checkFn(text); err != nil {
fmt.Println(err)
return readFLn(promptF, checkFn, defaultAns, args...)
}
return text
}
func ParseIDs(s string) ([]int, int, int, error) {
ret := make([]int, 0)
if len(s) <= 3 {
return ret, 0, 0, fmt.Errorf("Parse Error: %v", s)
}
if s[0] != '[' {
return ret, 0, 0, fmt.Errorf("Parse Error: %v", s)
}
if s[len(s)-1] != ']' {
return ret, 0, 0, fmt.Errorf("Parse Error: %v", s)
}
s = s[1 : len(s)-1]
as := strings.Split(s, ",")
min := math.MaxUint16
max := 0
for i, es := range as {
if strings.Contains(es, "~") {
esl := strings.SplitN(es, "~", 2)
si, err := strconv.ParseInt(esl[0], 10, 16)
if err != nil {
return ret, min, max, err
}
ei, err := strconv.ParseInt(esl[1], 10, 16)
if err != nil {
return ret, min, max, err
}
if si >= ei {
return ret, min, max, fmt.Errorf("end %v must > start %v", ei, si)
}
if int(si) < 0 {
return ret, min, max, fmt.Errorf("node ID < 0 at element %v", i)
}
if min > int(si) {
min = int(si)
}
if int(si) < max {
return ret, min, max, fmt.Errorf("list out of order at the %vth element: %v", i, es)
} else if int(si) == max {
return ret, min, max, fmt.Errorf("duplicate id in the %vth element: %v", i, es)
}
max = int(ei)
for ; si <= ei; si++ {
ret = append(ret, int(si))
}
} else {
si, err := strconv.ParseInt(es, 10, 16)
if err != nil {
return ret, min, max, err
}
if int(si) < max {
return ret, min, max, fmt.Errorf("List out of order at the %vth element!", i)
} else if int(si) == max {
return ret, min, max, fmt.Errorf("duplicate id in the %vth element", i)
}
if min > int(si) {
min = int(si)
}
max = int(si)
ret = append(ret, int(si))
}
}
return ret, min, max, nil
}
func printExampleSMCfg() {
tconfig := SMCfg{}
toprint, _ := yaml.Marshal(tconfig)
fmt.Print(string(toprint))
}
func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
SMCfg := SMCfg{}
if printExample {
printExampleSMCfg()
return
}
err = mtypes.ReadYaml(SMCinfigPath, &SMCfg)
if err != nil {
return err
}
s := SMCfg.ConfigOutputDir
err = os.MkdirAll(s, 0o700)
if err != nil {
return err
}
files, err := os.ReadDir(s)
if err != nil {
return err
}
if len(files) > 0 {
return fmt.Errorf(s + " not empty")
}
CfgSavePath := s
s = SMCfg.SuperConfigTemplate
if s != "" {
var sconfig mtypes.SuperConfig
err = mtypes.ReadYaml(s, &sconfig)
if err != nil {
fmt.Printf("Error read config: %v\t%v\n", s, err)
return err
}
}
SuperTamplatePath := s
s = SMCfg.EdgeConfigTemplate
if s != "" {
var econfig mtypes.EdgeConfig
err = mtypes.ReadYaml(s, &econfig)
if err != nil {
fmt.Printf("Error read config: %v\t%v\n", s, err)
return err
}
}
EdgeTamplatePath := s
sconfig := GetExampleSuperConf(SuperTamplatePath)
s = SMCfg.NetworkName
if len(s) > 10 {
return fmt.Errorf("Name too long")
}
allowed := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
for _, c := range []byte(s) {
if strings.Contains(allowed, string(c)) == false {
return fmt.Errorf("Name can only contain %v", allowed)
}
}
NetworkName := s
ListenPort := fmt.Sprintf("%v", SMCfg.Supernode.ListenPort)
API_Prefix := SMCfg.Supernode.EdgeAPI_Prefix
s = SMCfg.Supernode.EndpointV4
if s != "" {
_, err = conn.LookupIP(s+":"+ListenPort, 4)
if err != nil {
return err
}
}
EndpointV4 := s
s = SMCfg.Supernode.EndpointV6
if s != "" {
if strings.Contains(s, ":") && (s[0] != '[' || s[len(s)-1] != ']') {
return fmt.Errorf("Invalid IPv6 format, please use [%v] instead", s)
}
_, err = conn.LookupIP(s+":"+ListenPort, 6)
if err != nil {
return
}
} else if EndpointV4 == "" {
return fmt.Errorf("Muse provide at lease v4 v6 address")
}
EndpointV6 := s
EndpointEdgeAPIUrl := SMCfg.Supernode.Endpoint_EdgeAPI
sconfig.NodeName = NetworkName + "SP"
sconfig.API_Prefix = API_Prefix
sconfig.ListenPort, _ = strconv.Atoi(ListenPort)
sconfig.ListenPort_EdgeAPI = ListenPort
sconfig.ListenPort_ManageAPI = ListenPort
sconfig.NextHopTable = make(mtypes.NextHopTable)
sconfig.EdgeTemplate = EdgeTamplatePath
NodeIDs, _, ModeIDmax, err := ParseIDs(SMCfg.EdgeNode.NodeIDs)
if err != nil {
return
}
s = SMCfg.EdgeNode.MacPrefix
if s != "" {
_, err = tap.GetMacAddr(s, uint32(ModeIDmax))
if err != nil {
return err
}
} else {
pbyte := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
pbyte[0] &^= 0b00000001
pbyte[0] |= 0b00000010
s = fmt.Sprintf("%X:%X:%X:%X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
}
MacPrefix := s
s = SMCfg.EdgeNode.IPv4Range
if s != "" {
_, _, err = tap.GetIP(4, s, uint32(ModeIDmax))
if err != nil {
return err
}
}
IPv4Block := s
s = SMCfg.EdgeNode.IPv6Range
if s != "" {
_, _, err = tap.GetIP(6, s, uint32(ModeIDmax))
if err != nil {
return err
}
}
IPv6Block := s
s = SMCfg.EdgeNode.IPv6LLRange
if s != "" {
_, _, err = tap.GetIP(6, s, uint32(ModeIDmax))
if err != nil {
return err
}
}
IPv6LLBlock := s
SuperPeerInfo := make([]mtypes.SuperPeerInfo, 0, ModeIDmax)
PrivKeyS4 := device.NoisePrivateKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{})))
PubKeyS4 := PrivKeyS4.PublicKey()
PrivKeyS6 := device.NoisePrivateKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{})))
PubKeyS6 := PrivKeyS6.PublicKey()
sconfig.PrivKeyV4 = PrivKeyS4.ToString()
sconfig.PrivKeyV6 = PrivKeyS6.ToString()
allec := make(map[mtypes.Vertex]mtypes.EdgeConfig)
peerceconf := GetExampleEdgeConf(EdgeTamplatePath)
peerceconf.Peers = []mtypes.PeerInfo{}
peerceconf.NextHopTable = make(mtypes.NextHopTable)
for _, ii := range NodeIDs {
i := mtypes.Vertex(ii)
PSKeyE := device.NoisePresharedKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{})))
PrivKeyE := device.NoisePrivateKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{})))
PubKeyE := PrivKeyE.PublicKey()
idstr := fmt.Sprintf("%0"+strconv.Itoa(len(strconv.Itoa(ModeIDmax)))+"d", i)
allec[i] = peerceconf
peerceconf.DynamicRoute.SuperNode.EndpointV4 = EndpointV4 + ":" + ListenPort
peerceconf.DynamicRoute.SuperNode.EndpointV6 = EndpointV6 + ":" + ListenPort
peerceconf.DynamicRoute.SuperNode.EndpointEdgeAPIUrl = EndpointEdgeAPIUrl
peerceconf.Interface.MacAddrPrefix = MacPrefix
peerceconf.Interface.IPv4CIDR = IPv4Block
peerceconf.Interface.IPv6CIDR = IPv6Block
peerceconf.Interface.IPv6LLPrefix = IPv6LLBlock
peerceconf.NodeID = i
peerceconf.NodeName = NetworkName + idstr
peerceconf.Interface.Name = NetworkName + idstr
peerceconf.DynamicRoute.SuperNode.PubKeyV4 = PubKeyS4.ToString()
peerceconf.DynamicRoute.SuperNode.PubKeyV6 = PubKeyS6.ToString()
peerceconf.DynamicRoute.SuperNode.PSKey = PSKeyE.ToString()
peerceconf.PrivKey = PrivKeyE.ToString()
SuperPeerInfo = append(SuperPeerInfo, mtypes.SuperPeerInfo{
NodeID: i,
Name: NetworkName + idstr,
PubKey: PubKeyE.ToString(),
PSKey: PSKeyE.ToString(),
AdditionalCost: peerceconf.DynamicRoute.AdditionalCost,
SkipLocalIP: peerceconf.DynamicRoute.SuperNode.SkipLocalIP,
})
mtypesBytes, _ := yaml.Marshal(peerceconf)
ioutil.WriteFile(filepath.Join(CfgSavePath, NetworkName+"_edge"+idstr+".yaml"), mtypesBytes, 0o600)
fmt.Println(filepath.Join(CfgSavePath, NetworkName+"_edge"+idstr+".yaml"))
}
sconfig.Peers = SuperPeerInfo
mtypesBytes, _ := yaml.Marshal(sconfig)
ioutil.WriteFile(filepath.Join(CfgSavePath, NetworkName+"_super.yaml"), mtypesBytes, 0o600)
fmt.Println(filepath.Join(CfgSavePath, NetworkName+"_super.yaml"))
return nil
}

38
gencfg/types.go Normal file
View File

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package gencfg
type SMCfg struct {
ConfigOutputDir string `yaml:"Config output dir"`
SuperConfigTemplate string `yaml:"ConfigTemplate for super node"`
EdgeConfigTemplate string `yaml:"ConfigTemplate for edge node"`
NetworkName string `yaml:"Network name"`
Supernode struct {
ListenPort int `yaml:"Listen port"`
EdgeAPI_Prefix string `yaml:"EdgeAPI prefix"`
EndpointV4 string `yaml:"Endpoint(IPv4)(optional)"`
EndpointV6 string `yaml:"Endpoint(IPv6)(optional)"`
Endpoint_EdgeAPI string `yaml:"Endpoint(EdgeAPI)"`
} `yaml:"Super Node"`
EdgeNode struct {
NodeIDs string `yaml:"Node IDs"`
MacPrefix string `yaml:"MacAddress prefix"`
IPv4Range string `yaml:"IPv4 range"`
IPv6Range string `yaml:"IPv6 range"`
IPv6LLRange string `yaml:"IPv6 LL range"`
} `yaml:"Edge Node"`
}
type PMG struct {
ConfigOutputDir string `yaml:"Config output dir"`
EdgeConfigTemplate string `yaml:"ConfigTemplate for edge node"`
NetworkName string `yaml:"Network name"`
EdgeNodes []struct {
NodeID string `yaml:"Node ID"`
Endpoint string `yaml:"Endpoint(optional)"`
} `yaml:"Edge Nodes"`
DistanceMatrix string `yaml:"Distance matrix for all nodes"`
}

86
go.sum Normal file
View File

@ -0,0 +1,86 @@
git.fd.io/govpp.git v0.3.6-0.20210927044411-385ccc0d8ba9 h1:QFHVGWCWf6e226vMy1zU614eC3glrfJO2CwREUk8D6s=
git.fd.io/govpp.git v0.3.6-0.20210927044411-385ccc0d8ba9/go.mod h1:OCVd4W8SH+666KRQoMj6PM+oipLDZAHhqMz9B1TGbgI=
git.fd.io/govpp.git/extras v0.0.0-20211129071605-0a0c03d45954 h1:F4tLgA7dY1lY1GQ6D7dMiLie39FV6QXinM7BU9cRENY=
git.fd.io/govpp.git/extras v0.0.0-20211129071605-0a0c03d45954/go.mod h1:GhryuN3x7qZ/wYLlEiPUVi6glJvh5S5V6E+XASV4774=
github.com/KusakabeSi/go-cache v0.0.0-20210823132304-22b5b1d22b41 h1:o6o1+n8vqD/Qsxw26x7aLH6QQzPGGmQdKQqQRpkA/ac=
github.com/KusakabeSi/go-cache v0.0.0-20210823132304-22b5b1d22b41/go.mod h1:u+fcGXuY9eUnv1Lw58RgBJcfNxv8rT2jHNI3tdDUHp0=
github.com/beevik/ntp v0.3.0 h1:xzVrPrE4ziasFXgBVBZJDP0Wg/KpMwk2KHJ4Ba8GrDw=
github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
github.com/bennyscetbun/jsongo v1.1.0/go.mod h1:suxbVmjBV8+A2BBAM5EYVh6Uj8j3rqJhzWf3hv7Ff8U=
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=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ftrvxmtrx/fd v0.0.0-20150925145434-c6d800382fff/go.mod h1:yUhRXHewUVJ1k89wHKP68xfzk7kwXUx/DV1nx4EBMbw=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lunixbochs/struc v0.0.0-20200521075829-a4cb8d33dbbe h1:ewr1srjRCmcQogPQ/NCx6XCk6LGVmsVCc9Y3vvPZj+Y=
github.com/lunixbochs/struc v0.0.0-20200521075829-a4cb8d33dbbe/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.1.0 h1:e3YP4dN/HYPpGh29X1ZkcxcEICsOls9huyVCRBaxjq8=
github.com/onsi/gomega v1.1.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
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/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/wk8/go-ordered-map v0.2.0 h1:KlvGyHstD1kkGZkPtHCyCfRYS0cz84uk6rrW/Dnhdtk=
github.com/wk8/go-ordered-map v0.2.0/go.mod h1:9ZIbRunKbuvfPKyBP1SIKLcXNlv74YCOZ3t3VTS6gRk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8=
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200610111108-226ff32320da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

16
main.go
View File

@ -8,7 +8,6 @@ package main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"runtime"
"syscall"
@ -16,10 +15,10 @@ import (
nonSecureRand "math/rand"
"github.com/KusakabeSi/EtherGuard-VPN/gencfg"
"github.com/KusakabeSi/EtherGuard-VPN/ipc"
"github.com/KusakabeSi/EtherGuard-VPN/path"
"github.com/KusakabeSi/EtherGuard-VPN/tap"
yaml "gopkg.in/yaml.v2"
)
const (
@ -36,15 +35,6 @@ func printUsage() {
fmt.Printf("Usage: %s -s/c CONFIG-PATH\n", os.Args[0])
}
func readYaml(filePath string, out interface{}) (err error) {
yamlFile, err := ioutil.ReadFile(filePath)
if err != nil {
return
}
err = yaml.Unmarshal(yamlFile, out)
return
}
var (
tconfig = flag.String("config", "", "Config path for the interface.")
mode = flag.String("mode", "", "Running mode. [super|edge|solve|gencfg]")
@ -84,9 +74,9 @@ func main() {
case "gencfg":
switch *cfgmode {
case "super":
err = genSuperCfg()
err = gencfg.GenSuperCfg(*tconfig, *printExample)
default:
err = fmt.Errorf("gencfg: generate config for %v mode are not implement.", *cfgmode)
err = fmt.Errorf("gencfg: generate config for %v mode are not implement", *cfgmode)
}
default:

View File

@ -19,6 +19,7 @@ import (
"github.com/KusakabeSi/EtherGuard-VPN/conn"
"github.com/KusakabeSi/EtherGuard-VPN/device"
"github.com/KusakabeSi/EtherGuard-VPN/gencfg"
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/path"
"github.com/KusakabeSi/EtherGuard-VPN/tap"
@ -26,145 +27,11 @@ import (
)
func printExampleEdgeConf() {
tconfig := getExampleEdgeConf("")
tconfig := gencfg.GetExampleEdgeConf("")
toprint, _ := yaml.Marshal(tconfig)
fmt.Print(string(toprint))
}
func getExampleEdgeConf(templatePath string) mtypes.EdgeConfig {
tconfig := mtypes.EdgeConfig{}
if templatePath != "" {
err := readYaml(templatePath, &tconfig)
if err == nil {
return tconfig
}
}
v1 := mtypes.Vertex(1)
v2 := mtypes.Vertex(2)
tconfig = mtypes.EdgeConfig{
Interface: mtypes.InterfaceConf{
IType: "tap",
Name: "tap1",
VPPIFaceID: 1,
VPPBridgeID: 4242,
MacAddrPrefix: "AA:BB:CC:DD",
MTU: 1416,
RecvAddr: "127.0.0.1:4001",
SendAddr: "127.0.0.1:5001",
L2HeaderMode: "nochg",
},
NodeID: 1,
NodeName: "Node01",
PostScript: "",
DefaultTTL: 200,
L2FIBTimeout: 3600,
PrivKey: "6GyDagZKhbm5WNqMiRHhkf43RlbMJ34IieTlIuvfJ1M=",
ListenPort: 0,
LogLevel: mtypes.LoggerInfo{
LogLevel: "error",
LogTransit: false,
LogControl: true,
LogNormal: false,
LogInternal: true,
LogNTP: true,
},
DynamicRoute: mtypes.DynamicRouteInfo{
SendPingInterval: 16,
PeerAliveTimeout: 70,
DupCheckTimeout: 40,
ConnTimeOut: 20,
ConnNextTry: 5,
AdditionalCost: 10,
SaveNewPeers: true,
SuperNode: mtypes.SuperInfo{
UseSuperNode: true,
PSKey: "iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=",
EndpointV4: "127.0.0.1:3000",
PubKeyV4: "LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=",
EndpointV6: "[::1]:3000",
PubKeyV6: "HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=",
EndpointEdgeAPIUrl: "http://127.0.0.1:3000/eg_api",
SuperNodeInfoTimeout: 50,
SkipLocalIP: false,
},
P2P: mtypes.P2PInfo{
UseP2P: false,
SendPeerInterval: 20,
GraphRecalculateSetting: mtypes.GraphRecalculateSetting{
StaticMode: false,
JitterTolerance: 20,
JitterToleranceMultiplier: 1.1,
TimeoutCheckInterval: 5,
RecalculateCoolDown: 5,
},
},
NTPConfig: mtypes.NTPInfo{
UseNTP: true,
MaxServerUse: 8,
SyncTimeInterval: 3600,
NTPTimeout: 3,
Servers: []string{
"time.google.com",
"time1.google.com",
"time2.google.com",
"time3.google.com",
"time4.google.com",
"time1.facebook.com",
"time2.facebook.com",
"time3.facebook.com",
"time4.facebook.com",
"time5.facebook.com",
"time.cloudflare.com",
"time.apple.com",
"time.asia.apple.com",
"time.euro.apple.com",
"time.windows.com",
"pool.ntp.org",
"0.pool.ntp.org",
"1.pool.ntp.org",
"2.pool.ntp.org",
"3.pool.ntp.org",
},
},
},
NextHopTable: mtypes.NextHopTable{
mtypes.Vertex(1): {
mtypes.Vertex(2): &v2,
},
mtypes.Vertex(2): {
mtypes.Vertex(1): &v1,
},
},
ResetConnInterval: 86400,
Peers: []mtypes.PeerInfo{
{
NodeID: 2,
PubKey: "dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=",
PSKey: "juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=",
EndPoint: "127.0.0.1:3002",
Static: true,
},
},
}
g := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting, tconfig.DynamicRoute.NTPConfig, mtypes.LoggerInfo{})
g.UpdateLatency(1, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 1, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(5, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 5, 0.5, 99999, 0, false, false)
g.UpdateLatency(6, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 6, 0.5, 99999, 0, false, false)
_, next, _ := g.FloydWarshall(false)
tconfig.NextHopTable = next
return tconfig
}
func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (err error) {
if printExample {
printExampleEdgeConf()
@ -174,7 +41,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
//printExampleConf()
//return
err = readYaml(configPath, &econfig)
err = mtypes.ReadYaml(configPath, &econfig)
if err != nil {
fmt.Printf("Error read config: %v\t%v\n", configPath, err)
return err

View File

@ -1,229 +0,0 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/KusakabeSi/EtherGuard-VPN/conn"
"github.com/KusakabeSi/EtherGuard-VPN/device"
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/tap"
yaml "gopkg.in/yaml.v2"
)
var gencfg_reader *bufio.Reader
func readFLn(promptF string, checkFn func(string) error, defaultAns func() string, args ...interface{}) string {
defaultans := defaultAns()
if defaultans != "" {
fmt.Printf(promptF+" ("+defaultans+") :", args...)
} else {
fmt.Printf(promptF+" :", args...)
}
text, err := gencfg_reader.ReadString('\n')
if err != nil {
panic(err)
}
text = strings.Replace(text, "\n", "", -1)
if text == "" {
text = defaultans
}
if err := checkFn(text); err != nil {
fmt.Println(err)
return readFLn(promptF, checkFn, defaultAns, args...)
}
return text
}
func genSuperCfg() error {
gencfg_reader = bufio.NewReader(os.Stdin)
noCheck := func(string) error {
return nil
}
noDefault := func() string {
return ""
}
CfgSavePath := readFLn("Config save path", func(s string) (err error) {
err = os.MkdirAll(s, 0o700)
if err != nil {
return
}
files, err := os.ReadDir(s)
if err != nil {
return
}
if len(files) > 0 {
return fmt.Errorf(s + " not empty")
}
return
}, func() string { return filepath.Join(".", "eg_generated_configs") })
SuperTamplatePath := readFLn("SuperConfig template path(optional)", func(s string) (err error) {
if s != "" {
var sconfig mtypes.SuperConfig
err = readYaml(s, &sconfig)
if err != nil {
fmt.Printf("Error read config: %v\t%v\n", s, err)
return err
}
}
return
}, noDefault)
EdgeTamplatePath := readFLn("EdgeTamplatePath template path(optional)", func(s string) (err error) {
if s != "" {
var econfig mtypes.EdgeConfig
err = readYaml(s, &econfig)
if err != nil {
fmt.Printf("Error read config: %v\t%v\n", s, err)
return err
}
}
return
}, noDefault)
sconfig := getExampleSuperConf(SuperTamplatePath)
NetworkName := readFLn("Network name", func(s string) (err error) {
if len(s) > 10 {
return fmt.Errorf("Name too long")
}
allowed := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
for _, c := range []byte(s) {
if strings.Contains(allowed, string(c)) == false {
return fmt.Errorf("Name can only contain %v", allowed)
}
}
return
}, func() string { return "eg_net" })
ListenPort := readFLn("SuperNode ListenPort", func(s string) (err error) {
_, err = strconv.ParseUint(s, 10, 16)
return
}, func() string { return "12369" })
API_Prefix := readFLn("EdgeAPI prefix", noCheck, func() string { return "/" + NetworkName + "/eg_api" })
EndpointV4 := readFLn("IPv4/domain of your supernode (optional)", func(s string) (err error) {
if s != "" {
_, err = conn.LookupIP(s+":"+ListenPort, 4)
}
return
}, noDefault)
EndpointV6 := readFLn("IPv6/domain of your supernode (optional)", func(s string) (err error) {
if s != "" {
if strings.Contains(s, ":") && (s[0] != '[' || s[len(s)-1] != ']') {
return fmt.Errorf("Invalid IPv6 format, please use [%v] instead", s)
}
_, err = conn.LookupIP(s+":"+ListenPort, 6)
} else if EndpointV4 == "" {
return fmt.Errorf("Muse provide at lease v4 v6 address")
}
return
}, noDefault)
EndpointEdgeAPIUrl := readFLn("URL(use domain would be better) of the EdgeAPI provided by supernode", noCheck, func() string { return fmt.Sprintf("http://%v:%v%v", EndpointV4, ListenPort, API_Prefix) })
sconfig.NodeName = NetworkName + "SP"
sconfig.API_Prefix = API_Prefix
sconfig.ListenPort, _ = strconv.Atoi(ListenPort)
sconfig.ListenPort_EdgeAPI = ListenPort
sconfig.ListenPort_ManageAPI = ListenPort
sconfig.NextHopTable = make(mtypes.NextHopTable)
sconfig.EdgeTemplate = EdgeTamplatePath
NodeNum := readFLn("Number of your nodes", func(s string) (err error) {
_, err = strconv.ParseInt(s, 10, 16)
return
}, noDefault)
MaxNode, _ := strconv.ParseInt(NodeNum, 10, 16)
MacPrefix := readFLn("MacAddress Prefix", func(s string) (err error) {
_, err = tap.GetMacAddr(s, uint32(MaxNode))
return
}, func() string {
pbyte := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
pbyte[0] &^= 0b00000001
pbyte[0] |= 0b00000010
return fmt.Sprintf("%X:%X:%X:%X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
})
IPv4Block := readFLn("IPv4 block(optional)", func(s string) (err error) {
if s != "" {
_, _, err = tap.GetIP(4, s, uint32(MaxNode))
}
return err
}, noDefault)
IPv6Block := readFLn("IPv6 block(optional)", func(s string) (err error) {
if s != "" {
_, _, err = tap.GetIP(6, s, uint32(MaxNode))
}
return err
}, noDefault)
IPv6LLBlock := readFLn("IPv6LL block(optional)", func(s string) (err error) {
if s != "" {
_, _, err = tap.GetIP(6, s, uint32(MaxNode))
}
return err
}, noDefault)
SuperPeerInfo := make([]mtypes.SuperPeerInfo, 0, MaxNode)
PrivKeyS4 := device.NoisePrivateKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{})))
PubKeyS4 := PrivKeyS4.PublicKey()
PrivKeyS6 := device.NoisePrivateKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{})))
PubKeyS6 := PrivKeyS6.PublicKey()
sconfig.PrivKeyV4 = PrivKeyS4.ToString()
sconfig.PrivKeyV6 = PrivKeyS6.ToString()
allec := make(map[mtypes.Vertex]mtypes.EdgeConfig)
peerceconf := getExampleEdgeConf(EdgeTamplatePath)
peerceconf.Peers = []mtypes.PeerInfo{}
peerceconf.NextHopTable = make(mtypes.NextHopTable)
for i := mtypes.Vertex(1); i <= mtypes.Vertex(MaxNode); i++ {
PSKeyE := device.NoisePresharedKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{})))
PrivKeyE := device.NoisePrivateKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{})))
PubKeyE := PrivKeyE.PublicKey()
idstr := fmt.Sprintf("%0"+strconv.Itoa(len(NodeNum))+"d", i)
allec[i] = peerceconf
peerceconf.DynamicRoute.SuperNode.EndpointV4 = EndpointV4 + ":" + ListenPort
peerceconf.DynamicRoute.SuperNode.EndpointV6 = EndpointV6 + ":" + ListenPort
peerceconf.DynamicRoute.SuperNode.EndpointEdgeAPIUrl = EndpointEdgeAPIUrl
peerceconf.Interface.MacAddrPrefix = MacPrefix
peerceconf.Interface.IPv4CIDR = IPv4Block
peerceconf.Interface.IPv6CIDR = IPv6Block
peerceconf.Interface.IPv6LLPrefix = IPv6LLBlock
peerceconf.NodeID = i
peerceconf.NodeName = NetworkName + idstr
peerceconf.Interface.Name = NetworkName + idstr
peerceconf.DynamicRoute.SuperNode.PubKeyV4 = PubKeyS4.ToString()
peerceconf.DynamicRoute.SuperNode.PubKeyV6 = PubKeyS6.ToString()
peerceconf.DynamicRoute.SuperNode.PSKey = PSKeyE.ToString()
peerceconf.PrivKey = PrivKeyE.ToString()
SuperPeerInfo = append(SuperPeerInfo, mtypes.SuperPeerInfo{
NodeID: i,
Name: NetworkName + idstr,
PubKey: PubKeyE.ToString(),
PSKey: PSKeyE.ToString(),
AdditionalCost: peerceconf.DynamicRoute.AdditionalCost,
SkipLocalIP: peerceconf.DynamicRoute.SuperNode.SkipLocalIP,
})
mtypesBytes, _ := yaml.Marshal(peerceconf)
ioutil.WriteFile(filepath.Join(CfgSavePath, NetworkName+"_edge"+idstr+".yaml"), mtypesBytes, 0o600)
fmt.Println(filepath.Join(CfgSavePath, NetworkName+"_edge"+idstr+".yaml"))
}
sconfig.Peers = SuperPeerInfo
mtypesBytes, _ := yaml.Marshal(sconfig)
ioutil.WriteFile(filepath.Join(CfgSavePath, NetworkName+"_super.yaml"), mtypesBytes, 0o600)
fmt.Println(filepath.Join(CfgSavePath, NetworkName+"_super.yaml"))
return nil
}

View File

@ -499,9 +499,12 @@ func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) {
pong_msg.AdditionalCost = AdditionalCost_use
}
applied_pones = append(applied_pones, pong_msg)
if httpobj.http_sconfig.LogLevel.LogControl {
fmt.Println("Control: Unpack from : Post body " + pong_msg.ToString())
}
}
}
changed := httpobj.http_graph.UpdateLatencyMulti(client_report.Pongs, true, true)
changed := httpobj.http_graph.UpdateLatencyMulti(applied_pones, true, true)
if changed {
NhTable := httpobj.http_graph.GetNHTable(true)
NhTablestr, _ := json.Marshal(NhTable)

View File

@ -23,6 +23,7 @@ import (
"github.com/KusakabeSi/EtherGuard-VPN/conn"
"github.com/KusakabeSi/EtherGuard-VPN/device"
"github.com/KusakabeSi/EtherGuard-VPN/gencfg"
"github.com/KusakabeSi/EtherGuard-VPN/ipc"
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/path"
@ -61,90 +62,11 @@ func checkNhTable(NhTable mtypes.NextHopTable, peers []mtypes.SuperPeerInfo) err
}
func printExampleSuperConf() {
sconfig := getExampleSuperConf("")
sconfig := gencfg.GetExampleSuperConf("")
scprint, _ := yaml.Marshal(sconfig)
fmt.Print(string(scprint))
}
func getExampleSuperConf(templatePath string) mtypes.SuperConfig {
sconfig := mtypes.SuperConfig{}
if templatePath != "" {
err := readYaml(templatePath, &sconfig)
if err == nil {
return sconfig
}
}
v1 := mtypes.Vertex(1)
v2 := mtypes.Vertex(2)
random_passwd := mtypes.RandomStr(8, "passwd")
sconfig = mtypes.SuperConfig{
NodeName: "NodeSuper",
PostScript: "",
PrivKeyV4: "mL5IW0GuqbjgDeOJuPHBU2iJzBPNKhaNEXbIGwwYWWk=",
PrivKeyV6: "+EdOKIoBp/EvIusHDsvXhV1RJYbyN3Qr8nxlz35wl3I=",
ListenPort: 3000,
ListenPort_EdgeAPI: "3000",
ListenPort_ManageAPI: "3000",
API_Prefix: "/eg_api",
LogLevel: mtypes.LoggerInfo{
LogLevel: "normal",
LogTransit: false,
LogControl: true,
LogNormal: false,
LogInternal: true,
LogNTP: true,
},
RePushConfigInterval: 30,
PeerAliveTimeout: 70,
HttpPostInterval: 50,
SendPingInterval: 15,
Passwords: mtypes.Passwords{
ShowState: random_passwd + "_showstate",
AddPeer: random_passwd + "_addpeer",
DelPeer: random_passwd + "_delpeer",
UpdatePeer: random_passwd + "_updatepeer",
UpdateSuper: random_passwd + "_updatesuper",
},
GraphRecalculateSetting: mtypes.GraphRecalculateSetting{
StaticMode: false,
JitterTolerance: 5,
JitterToleranceMultiplier: 1.01,
TimeoutCheckInterval: 5,
RecalculateCoolDown: 5,
},
NextHopTable: mtypes.NextHopTable{
mtypes.Vertex(1): {
mtypes.Vertex(2): &v2,
},
mtypes.Vertex(2): {
mtypes.Vertex(1): &v1,
},
},
EdgeTemplate: "example_config/super_mode/n1.yaml",
UsePSKForInterEdge: true,
Peers: []mtypes.SuperPeerInfo{
{
NodeID: 1,
Name: "Node_01",
PubKey: "ZqzLVSbXzjppERslwbf2QziWruW3V/UIx9oqwU8Fn3I=",
PSKey: "iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=",
AdditionalCost: 10,
},
{
NodeID: 2,
Name: "Node_02",
PubKey: "dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=",
PSKey: "juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=",
AdditionalCost: 10,
},
},
}
return sconfig
}
func Super(configPath string, useUAPI bool, printExample bool, bindmode string) (err error) {
if printExample {
printExampleSuperConf()
@ -152,13 +74,13 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
}
var sconfig mtypes.SuperConfig
err = readYaml(configPath, &sconfig)
err = mtypes.ReadYaml(configPath, &sconfig)
if err != nil {
fmt.Printf("Error read config: %v\t%v\n", configPath, err)
return err
}
httpobj.http_sconfig = &sconfig
http_econfig_tmp := getExampleEdgeConf(sconfig.EdgeTemplate)
http_econfig_tmp := gencfg.GetExampleEdgeConf(sconfig.EdgeTemplate)
httpobj.http_econfig_tmp = &http_econfig_tmp
NodeName := sconfig.NodeName
if len(NodeName) > 32 {

View File

@ -160,6 +160,7 @@ type GraphRecalculateSetting struct {
StaticMode bool `yaml:"StaticMode"`
JitterTolerance float64 `yaml:"JitterTolerance"`
JitterToleranceMultiplier float64 `yaml:"JitterToleranceMultiplier"`
DampingResistance float64 `yaml:"DampingResistance"`
TimeoutCheckInterval float64 `yaml:"TimeoutCheckInterval"`
RecalculateCoolDown float64 `yaml:"RecalculateCoolDown"`
}

View File

@ -8,6 +8,8 @@ import (
"io/ioutil"
nonSecureRand "math/rand"
"time"
"gopkg.in/yaml.v2"
)
func S2TD(secs float64) time.Duration {
@ -69,3 +71,12 @@ func GUzip(bytesIn []byte) (ret []byte, err error) {
}
return ioutil.ReadAll(r)
}
func ReadYaml(filePath string, out interface{}) (err error) {
yamlFile, err := ioutil.ReadFile(filePath)
if err != nil {
return
}
err = yaml.Unmarshal(yamlFile, out)
return
}

View File

@ -41,6 +41,7 @@ type IG struct {
StaticMode bool
JitterTolerance float64
JitterToleranceMultiplier float64
DampingResistance float64
SuperNodeInfoTimeout time.Duration
RecalculateCoolDown time.Duration
TimeoutCheckInterval time.Duration
@ -64,6 +65,7 @@ func NewGraph(num_node int, IsSuperMode bool, theconfig mtypes.GraphRecalculateS
StaticMode: theconfig.StaticMode,
JitterTolerance: theconfig.JitterTolerance,
JitterToleranceMultiplier: theconfig.JitterToleranceMultiplier,
DampingResistance: theconfig.DampingResistance,
RecalculateCoolDown: mtypes.S2TD(theconfig.RecalculateCoolDown),
TimeoutCheckInterval: mtypes.S2TD(theconfig.TimeoutCheckInterval),
ntp_info: ntpinfo,
@ -87,8 +89,8 @@ func (g *IG) GetWeightType(x float64) (y float64) {
return y
}
func (g *IG) ShouldUpdate(u mtypes.Vertex, v mtypes.Vertex, newval float64) bool {
oldval := math.Abs(g.OldWeight(u, v, false) * 1000)
func (g *IG) ShouldUpdate(oldval float64, newval float64) bool {
oldval = math.Abs(oldval * 1000)
newval = math.Abs(newval * 1000)
if g.IsSuperMode {
if g.JitterTolerance > 0.001 && g.JitterToleranceMultiplier >= 1 {
@ -110,7 +112,8 @@ func (g *IG) CheckAnyShouldUpdate() bool {
for v, _ := range vert {
if u != v {
newVal := g.Weight(u, v, false)
if g.ShouldUpdate(u, v, newVal) {
oldVal := g.OldWeight(u, v, false)
if g.ShouldUpdate(oldVal, newVal) {
return true
}
}
@ -176,13 +179,13 @@ func (g *IG) UpdateLatency(src mtypes.Vertex, dst mtypes.Vertex, val float64, Ti
}
func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, checkchange bool) (changed bool) {
g.edgelock.Lock()
should_update := false
for _, pong_msg := range pong_info {
u := pong_msg.Src_nodeID
v := pong_msg.Dst_nodeID
w := pong_msg.Timediff
w_in := pong_msg.Timediff
w := w_in
additionalCost := pong_msg.AdditionalCost
if additionalCost < 0 {
additionalCost = 0
@ -194,9 +197,12 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
g.edges[u] = make(map[mtypes.Vertex]*Latency)
}
g.edgelock.Unlock()
should_update = should_update || g.ShouldUpdate(u, v, w)
oldval := g.OldWeight(u, v, false)
g.edgelock.Lock()
if oldval != Infinity {
w = oldval*g.DampingResistance + w_in*(1-g.DampingResistance)
}
should_update = should_update || g.ShouldUpdate(oldval, w)
if _, ok := g.edges[u][v]; ok {
g.edges[u][v].ping = w
g.edges[u][v].validUntil = time.Now().Add(mtypes.S2TD(pong_msg.TimeToAlive))
@ -409,9 +415,11 @@ func Path(u, v mtypes.Vertex, next mtypes.NextHopTable) (path []mtypes.Vertex) {
}
func (g *IG) SetNHTable(nh mtypes.NextHopTable) { // set nhTable from supernode
g.edgelock.Lock()
g.nhTable = nh
g.changed = true
g.NhTableExpire = time.Now().Add(g.SuperNodeInfoTimeout)
g.edgelock.Unlock()
}
func (g *IG) GetNHTable(recalculate bool) mtypes.NextHopTable {
@ -499,7 +507,7 @@ func Solve(filePath string, pe bool) error {
return nil
}
g := NewGraph(3, false, mtypes.GraphRecalculateSetting{ }, mtypes.NTPInfo{}, mtypes.LoggerInfo{LogInternal: true})
g := NewGraph(3, false, mtypes.GraphRecalculateSetting{}, mtypes.NTPInfo{}, mtypes.LoggerInfo{LogInternal: true})
inputb, err := ioutil.ReadFile(filePath)
if err != nil {
return err