Set IP to interface via ioctl

This commit is contained in:
Kusakabe Si 2021-12-04 14:46:36 +00:00
parent 61e6489a70
commit e3113149aa
13 changed files with 725 additions and 475 deletions

View File

@ -1,3 +1,8 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package device
import (
@ -372,7 +377,7 @@ func (device *Device) process_UpdatePeerMsg(peer *Peer, State_hash string) error
client := http.Client{
Timeout: 8 * time.Second,
}
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.APIUrl + "/peerinfo" ////////////////////////////////////////////////////////////////////////////////////////////////
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/peerinfo" ////////////////////////////////////////////////////////////////////////////////////////////////
req, err := http.NewRequest("GET", downloadurl, nil)
q := req.URL.Query()
q.Add("NodeID", device.ID.ToString())
@ -485,7 +490,7 @@ func (device *Device) process_UpdateNhTableMsg(peer *Peer, State_hash string) er
client := &http.Client{
Timeout: 8 * time.Second,
}
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.APIUrl + "/nhtable" ////////////////////////////////////////////////////////////////////////////////////////////////
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/nhtable" ////////////////////////////////////////////////////////////////////////////////////////////////
req, err := http.NewRequest("GET", downloadurl, nil)
q := req.URL.Query()
q.Add("NodeID", device.ID.ToString())
@ -536,7 +541,7 @@ func (device *Device) process_UpdateSuperParamsMsg(peer *Peer, State_hash string
client := &http.Client{
Timeout: 8 * time.Second,
}
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.APIUrl + "/superparams" ////////////////////////////////////////////////////////////////////////////////////////////////
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/superparams" ////////////////////////////////////////////////////////////////////////////////////////////////
req, err := http.NewRequest("GET", downloadurl, nil)
q := req.URL.Query()
q.Add("NodeID", device.ID.ToString())
@ -902,7 +907,7 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
client := &http.Client{
Timeout: 8 * time.Second,
}
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.APIUrl + "/post/nodeinfo"
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/post/nodeinfo"
req, err := http.NewRequest("POST", downloadurl, bytes.NewReader(body))
q := req.URL.Query()
q.Add("NodeID", device.ID.ToString())

View File

@ -1,60 +1,63 @@
interface:
itype: stdio
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: kbdbg
nodeid: 1
nodename: Node01
postscript: example_config/echo.sh test
defaultttl: 200
l2fibtimeout: 3600
privkey: 6GyDagZKhbm5WNqMiRHhkf43RlbMJ34IieTlIuvfJ1M=
listenport: 0
loglevel:
loglevel: error
logtransit: true
logcontrol: true
lognormal: true
loginternal: true
logntp: true
dynamicroute:
sendpinginterval: 16
peeralivetimeout: 70
dupchecktimeout: 40
conntimeout: 20
connnexttry: 5
additionalcost: 10
savenewpeers: true
supernode:
usesupernode: true
pskey: iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=
connurlv4: 127.0.0.1:3000
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
connurlv6: ''
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
apiurl: http://127.0.0.1:3000/api
skiplocalip: false
supernodeinfotimeout: 50
p2p:
usep2p: false
sendpeerinterval: 20
graphrecalculatesetting:
staticmode: false
jittertolerance: 20
jittertolerancemultiplier: 1.1
timeoutcheckinterval: 5
recalculatecooldown: 5
ntpconfig:
usentp: true
maxserveruse: 8
synctimeinterval: 3600
ntptimeout: 3
servers:
Interface:
IType: stdio
Name: tap1
VPPIFaceID: 1
VPPBridgeID: 4242
MacAddrPrefix: AA:BB:CC:DD
IPv4CIDR: ""
IPv6CIDR: ""
IPv6LLPrefix: ""
MTU: 1416
RecvAddr: 127.0.0.1:4001
SendAddr: 127.0.0.1:5001
L2HeaderMode: kbdbg
NodeID: 1
NodeName: Node01
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
PrivKey: 6GyDagZKhbm5WNqMiRHhkf43RlbMJ34IieTlIuvfJ1M=
ListenPort: 0
LogLevel:
LogLevel: error
LogTransit: true
LogControl: true
LogNormal: true
LogInternal: true
LogNTP: true
DynamicRoute:
SendPingInterval: 16
PeerAliveTimeout: 70
DupCheckTimeout: 40
ConnTimeOut: 20
ConnNextTry: 5
AdditionalCost: 10
SaveNewPeers: true
SuperNode:
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
SkipLocalIP: false
SuperNodeInfoTimeout: 50
P2P:
UseP2P: false
SendPeerInterval: 20
GraphRecalculateSetting:
StaticMode: false
JitterTolerance: 20
JitterToleranceMultiplier: 1.1
TimeoutCheckInterval: 5
RecalculateCoolDown: 5
NTPConfig:
UseNTP: true
MaxServerUse: 8
SyncTimeInterval: 3600
NTPTimeout: 3
Servers:
- time.google.com
- time1.google.com
- time2.google.com
@ -70,6 +73,11 @@ dynamicroute:
- time.asia.apple.com
- time.euro.apple.com
- time.windows.com
nexthoptable: {}
resetconninterval: 86400
peers: []
- pool.ntp.org
- 0.pool.ntp.org
- 1.pool.ntp.org
- 2.pool.ntp.org
- 3.pool.ntp.org
NextHopTable: {}
ResetConnInterval: 86400
Peers: []

View File

@ -1,60 +1,63 @@
interface:
itype: stdio
name: tap2
vppifaceid: 2
vppbridgeid: 4242
macaddrprefix: AA:BB:CC:DD
mtu: 1416
recvaddr: 127.0.0.1:4002
sendaddr: 127.0.0.1:5002
l2headermode: kbdbg
nodeid: 2
nodename: Node02
postscript: example_config/echo.sh test
defaultttl: 200
l2fibtimeout: 3600
privkey: OH8BsVUU2Rqzeu9B2J5GPG8PUmxWfX8uVvNFZKhVF3o=
listenport: 0
loglevel:
loglevel: error
logtransit: true
logcontrol: true
lognormal: true
loginternal: true
logntp: true
dynamicroute:
sendpinginterval: 16
peeralivetimeout: 70
dupchecktimeout: 40
conntimeout: 20
connnexttry: 5
additionalcost: 10
savenewpeers: true
supernode:
usesupernode: true
pskey: juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=
connurlv4: 127.0.0.1:3000
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
connurlv6: ''
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
apiurl: http://127.0.0.1:3000/api
skiplocalip: false
supernodeinfotimeout: 50
p2p:
usep2p: false
sendpeerinterval: 20
graphrecalculatesetting:
staticmode: false
jittertolerance: 20
jittertolerancemultiplier: 1.1
timeoutcheckinterval: 5
recalculatecooldown: 5
ntpconfig:
usentp: true
maxserveruse: 8
synctimeinterval: 3600
ntptimeout: 3
servers:
Interface:
IType: stdio
Name: tap1
VPPIFaceID: 2
VPPBridgeID: 4242
MacAddrPrefix: AA:BB:CC:DD
IPv4CIDR: ""
IPv6CIDR: ""
IPv6LLPrefix: ""
MTU: 1416
RecvAddr: 127.0.0.1:4002
SendAddr: 127.0.0.1:5002
L2HeaderMode: kbdbg
NodeID: 2
NodeName: Node02
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
PrivKey: OH8BsVUU2Rqzeu9B2J5GPG8PUmxWfX8uVvNFZKhVF3o=
ListenPort: 0
LogLevel:
LogLevel: error
LogTransit: true
LogControl: true
LogNormal: true
LogInternal: true
LogNTP: true
DynamicRoute:
SendPingInterval: 16
PeerAliveTimeout: 70
DupCheckTimeout: 40
ConnTimeOut: 20
ConnNextTry: 5
AdditionalCost: 10
SaveNewPeers: true
SuperNode:
UseSuperNode: true
PSKey: juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=
EndpointV4: 127.0.0.1:3000
PubKeyV4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
EndpointV6: '[::1]:3000'
PubKeyV6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
EndpointEdgeAPIUrl: http://127.0.0.1:3000/eg_api
SkipLocalIP: false
SuperNodeInfoTimeout: 50
P2P:
UseP2P: false
SendPeerInterval: 20
GraphRecalculateSetting:
StaticMode: false
JitterTolerance: 20
JitterToleranceMultiplier: 1.1
TimeoutCheckInterval: 5
RecalculateCoolDown: 5
NTPConfig:
UseNTP: true
MaxServerUse: 8
SyncTimeInterval: 3600
NTPTimeout: 3
Servers:
- time.google.com
- time1.google.com
- time2.google.com
@ -70,6 +73,11 @@ dynamicroute:
- time.asia.apple.com
- time.euro.apple.com
- time.windows.com
nexthoptable: {}
resetconninterval: 86400
peers: []
- pool.ntp.org
- 0.pool.ntp.org
- 1.pool.ntp.org
- 2.pool.ntp.org
- 3.pool.ntp.org
NextHopTable: {}
ResetConnInterval: 86400
Peers: []

View File

@ -1,46 +1,45 @@
nodename: NodeSuper
postscript: example_config/echo.sh test
privkeyv4: mL5IW0GuqbjgDeOJuPHBU2iJzBPNKhaNEXbIGwwYWWk=
privkeyv6: +EdOKIoBp/EvIusHDsvXhV1RJYbyN3Qr8nxlz35wl3I=
listenport: 3000
repushconfiginterval: 30
httppostinterval: 50
peeralivetimeout: 70
sendpinginterval: 15
loglevel:
loglevel: normal
logtransit: true
logcontrol: true
lognormal: false
loginternal: true
logntp: false
passwords:
showstate: passwd
addpeer: passwd_addpeer
delpeer: passwd_delpeer
graphrecalculatesetting:
staticmode: false
jittertolerance: 5
jittertolerancemultiplier: 1.01
timeoutcheckinterval: 5
recalculatecooldown: 5
nexthoptable:
1:
2: 2
2:
1: 1
edgetemplate: example_config/super_mode/n1.yaml
usepskforinteredge: true
peers:
- nodeid: 1
name: Node_01
pubkey: ZqzLVSbXzjppERslwbf2QziWruW3V/UIx9oqwU8Fn3I=
pskey: iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=
additionalcost: 10
skiplocalip: false
- nodeid: 2
name: Node_02
pubkey: dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=
pskey: juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=
additionalcost: 10
skiplocalip: false
NodeName: NodeSuper
PostScript: ""
PrivKeyV4: mL5IW0GuqbjgDeOJuPHBU2iJzBPNKhaNEXbIGwwYWWk=
PrivKeyV6: +EdOKIoBp/EvIusHDsvXhV1RJYbyN3Qr8nxlz35wl3I=
ListenPort: 3000
ListenPort_EdgeAPI: "3000"
ListenPort_ManageAPI: "3000"
API_Prefix: /eg_api
RePushConfigInterval: 30
HttpPostInterval: 50
PeerAliveTimeout: 70
SendPingInterval: 15
LogLevel:
LogLevel: normal
LogTransit: true
LogControl: true
LogNormal: false
LogInternal: true
LogNTP: false
Passwords:
ShowState: passwd
AddPeer: passwd_addpeer
DelPeer: passwd_delpeer
GraphRecalculateSetting:
StaticMode: false
JitterTolerance: 5
JitterToleranceMultiplier: 1.01
TimeoutCheckInterval: 5
RecalculateCoolDown: 5
NextHopTable: {}
EdgeTemplate: example_config/super_mode/n1.yaml
UsePSKForInterEdge: true
Peers:
- NodeID: 1
Name: Node_01
PubKey: ZqzLVSbXzjppERslwbf2QziWruW3V/UIx9oqwU8Fn3I=
PSKey: iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=
AdditionalCost: 10
SkipLocalIP: false
- NodeID: 2
Name: Node_02
PubKey: dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=
PSKey: juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=
AdditionalCost: 10
SkipLocalIP: false

16
main.go
View File

@ -1,9 +1,6 @@
//go:build !windows
// +build !windows
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved.
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package main
@ -47,8 +44,9 @@ func readYaml(filePath string, out interface{}) (err error) {
var (
tconfig = flag.String("config", "", "Config path for the interface.")
mode = flag.String("mode", "", "Running mode. [super|edge|solve]")
mode = flag.String("mode", "", "Running mode. [super|edge|solve|gencfg]")
printExample = flag.Bool("example", false, "Print example config")
cfgmode = flag.String("cfgmode", "", "Running mode for generated config. [none|super|p2p]")
bind = flag.String("bind", "linux", "UDP socket bind mode. [linux|std]\nYou may need std mode if you want to run Etherguard under WSL.")
nouapi = flag.Bool("no-uapi", false, "Disable UAPI\nWith UAPI, you can check etherguard status by \"wg\" command")
version = flag.Bool("version", false, "Show version")
@ -79,6 +77,14 @@ func main() {
err = Super(*tconfig, !*nouapi, *printExample, *bind)
case "solve":
err = path.Solve(*tconfig, *printExample)
case "gencfg":
switch *cfgmode {
case "super":
err = genSuperCfg()
default:
err = fmt.Errorf("gencfg: generate config for %v mode are not implement.", *cfgmode)
}
default:
flag.Usage()
}

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved.
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package main
@ -30,9 +30,9 @@ func printExampleEdgeConf() {
v2 := mtypes.Vertex(2)
tconfig := mtypes.EdgeConfig{
Interface: mtypes.InterfaceConf{
Itype: "stdio",
IType: "stdio",
Name: "tap1",
VPPIfaceID: 1,
VPPIFaceID: 1,
VPPBridgeID: 4242,
MacAddrPrefix: "AA:BB:CC:DD",
MTU: 1416,
@ -53,7 +53,7 @@ func printExampleEdgeConf() {
LogControl: true,
LogNormal: true,
LogInternal: true,
LogNTP: false,
LogNTP: true,
},
DynamicRoute: mtypes.DynamicRouteInfo{
SendPingInterval: 16,
@ -61,19 +61,20 @@ func printExampleEdgeConf() {
DupCheckTimeout: 40,
ConnTimeOut: 20,
ConnNextTry: 5,
AdditionalCost: 10,
SaveNewPeers: true,
SuperNode: mtypes.SuperInfo{
UseSuperNode: true,
PSKey: "iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=",
ConnURLV4: "127.0.0.1:3000",
EndpointV4: "127.0.0.1:3000",
PubKeyV4: "LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=",
ConnURLV6: "[::1]:3000",
EndpointV6: "[::1]:3000",
PubKeyV6: "HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=",
APIUrl: "http://127.0.0.1:3000/api",
EndpointEdgeAPIUrl: "http://127.0.0.1:3000/eg_api",
SuperNodeInfoTimeout: 50,
SkipLocalIP: false,
},
P2P: mtypes.P2Pinfo{
P2P: mtypes.P2PInfo{
UseP2P: false,
SendPeerInterval: 20,
GraphRecalculateSetting: mtypes.GraphRecalculateSetting{
@ -84,12 +85,13 @@ func printExampleEdgeConf() {
RecalculateCoolDown: 5,
},
},
NTPconfig: mtypes.NTPinfo{
NTPConfig: mtypes.NTPInfo{
UseNTP: true,
MaxServerUse: 8,
SyncTimeInterval: 3600,
NTPTimeout: 3,
Servers: []string{"time.google.com",
Servers: []string{
"time.google.com",
"time1.google.com",
"time2.google.com",
"time3.google.com",
@ -103,7 +105,13 @@ func printExampleEdgeConf() {
"time.apple.com",
"time.asia.apple.com",
"time.euro.apple.com",
"time.windows.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{
@ -125,7 +133,7 @@ func printExampleEdgeConf() {
},
},
}
g := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting, tconfig.DynamicRoute.NTPconfig, tconfig.LogLevel)
g := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting, tconfig.DynamicRoute.NTPConfig, tconfig.LogLevel)
g.UpdateLatency(1, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 1, 0.5, 99999, 0, false, false)
@ -189,7 +197,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
var thetap tap.Device
// open TUN device (or use supplied fd)
switch econfig.Interface.Itype {
switch econfig.Interface.IType {
case "dummy":
thetap, err = tap.CreateDummyTAP()
case "stdio":
@ -211,7 +219,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
case "tap":
thetap, err = tap.CreateTAP(econfig.Interface, econfig.NodeID)
default:
return errors.New("Unknow interface type:" + econfig.Interface.Itype)
return errors.New("Unknow interface type:" + econfig.Interface.IType)
}
if err != nil {
logger.Errorf("Failed to create TAP device: %v", err)
@ -227,7 +235,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
if econfig.DynamicRoute.P2P.UseP2P == false && econfig.DynamicRoute.SuperNode.UseSuperNode == false {
econfig.LogLevel.LogNTP = false // NTP in static mode is useless
}
graph := path.NewGraph(3, false, econfig.DynamicRoute.P2P.GraphRecalculateSetting, econfig.DynamicRoute.NTPconfig, econfig.LogLevel)
graph := path.NewGraph(3, false, econfig.DynamicRoute.P2P.GraphRecalculateSetting, econfig.DynamicRoute.NTPConfig, econfig.LogLevel)
graph.SetNHTable(econfig.NextHopTable)
the_device := device.NewDevice(thetap, econfig.NodeID, conn.NewDefaultBind(true, true, bindmode), logger, graph, false, configPath, &econfig, nil, nil, Version)
@ -261,7 +269,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
if econfig.DynamicRoute.SuperNode.UseSuperNode {
S4 := true
S6 := true
if econfig.DynamicRoute.SuperNode.ConnURLV4 != "" {
if econfig.DynamicRoute.SuperNode.EndpointV4 != "" {
pk, err := device.Str2PubKey(econfig.DynamicRoute.SuperNode.PubKeyV4)
if err != nil {
fmt.Println("Error decode base64 ", err)
@ -277,13 +285,13 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
return err
}
peer.SetPSK(psk)
err = peer.SetEndpointFromConnURL(econfig.DynamicRoute.SuperNode.ConnURLV4, 4, false)
err = peer.SetEndpointFromConnURL(econfig.DynamicRoute.SuperNode.EndpointV4, 4, false)
if err != nil {
logger.Errorf("Failed to set endpoint for supernode v4 %v: %v", econfig.DynamicRoute.SuperNode.ConnURLV4, err)
logger.Errorf("Failed to set endpoint for supernode v4 %v: %v", econfig.DynamicRoute.SuperNode.EndpointV4, err)
S4 = false
}
}
if econfig.DynamicRoute.SuperNode.ConnURLV6 != "" {
if econfig.DynamicRoute.SuperNode.EndpointV6 != "" {
pk, err := device.Str2PubKey(econfig.DynamicRoute.SuperNode.PubKeyV6)
if err != nil {
fmt.Println("Error decode base64 ", err)
@ -299,10 +307,10 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
}
peer.SetPSK(psk)
peer.StaticConn = false
peer.ConnURL = econfig.DynamicRoute.SuperNode.ConnURLV6
err = peer.SetEndpointFromConnURL(econfig.DynamicRoute.SuperNode.ConnURLV6, 6, false)
peer.ConnURL = econfig.DynamicRoute.SuperNode.EndpointV6
err = peer.SetEndpointFromConnURL(econfig.DynamicRoute.SuperNode.EndpointV6, 6, false)
if err != nil {
logger.Errorf("Failed to set endpoint for supernode v6 %v: %v", econfig.DynamicRoute.SuperNode.ConnURLV6, err)
logger.Errorf("Failed to set endpoint for supernode v6 %v: %v", econfig.DynamicRoute.SuperNode.EndpointV6, err)
S6 = false
}
if !(S4 || S6) {
@ -325,6 +333,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
envs := make(map[string]string)
nid := econfig.NodeID
nid_bytearr := []byte{0, 0}
MacAddr, _ := tap.GetMacAddr(econfig.Interface.MacAddrPrefix, uint32(nid))
binary.LittleEndian.PutUint16(nid_bytearr, uint16(nid))
envs["EG_MODE"] = "edge"
@ -336,7 +345,9 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
envs["EG_NODE_ID_BYTE0_HEX"] = fmt.Sprintf("%X", nid_bytearr[0])
envs["EG_NODE_ID_BYTE1_HEX"] = fmt.Sprintf("%X", nid_bytearr[1])
envs["EG_INTERFACE_NAME"] = econfig.Interface.Name
envs["EG_INTERFACE_TYPE"] = econfig.Interface.Itype
envs["EG_INTERFACE_TYPE"] = econfig.Interface.IType
envs["EG_INTERFACE_MAC_PREFIX"] = econfig.Interface.MacAddrPrefix
envs["EG_INTERFACE_MAC_ADDR"] = MacAddr.String()
cmdarg, err := shlex.Split(econfig.PostScript)
if err != nil {

78
main_gencfg.go Normal file
View File

@ -0,0 +1,78 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
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...)
}
fmt.Printf(promptF+" :", args...)
text, err := gencfg_reader.ReadString('\n')
if err != nil {
panic(err)
}
text = strings.Replace(text, "\n", "", -1)
if err := checkFn(text); err != nil {
fmt.Println(err)
return readFLn(promptF, checkFn, defaultAns, args...)
}
if text == "" {
text = defaultans
}
return text
}
func noCheck(string) error {
return nil
}
func genSuperCfg() error {
gencfg_reader = bufio.NewReader(os.Stdin)
/*
noCheck := func(string) error {
return nil
}
noDefault := func() string {
return ""
}
NetworkName := readFLn("Network name", func(s string) (err error) {
if len(s) > 12 {
return fmt.Errorf("Name too long")
}
return
}, func() string { return "MyEgNet" })
MacPrefix := readFLn("MacAddress Prefix", func(s string) (err error) {
_, err = tap.GetMacAddr(s, 0)
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("MacAddress Prefix", func(s string) error {
_, _, err := tap.GetIP(4, s, 0)
return err
}, noDefault)
IPv6Block := readFLn("MacAddress Prefix", func(s string) error {
_, _, err := tap.GetIP(6, s, 0)
return err
}, noDefault)
*/
return nil
}

View File

@ -1,3 +1,8 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package main
import (
@ -28,17 +33,15 @@ import (
)
type http_shared_objects struct {
http_graph *path.IG
http_device4 *device.Device
http_device6 *device.Device
http_HashSalt []byte
http_NhTable_Hash string
http_PeerInfo_hash string
http_SuperParams_Hash string
http_SuperParamsStr []byte
http_NhTableStr []byte
http_PeerInfo mtypes.API_Peers
http_super_chains *mtypes.SUPER_Events
http_graph *path.IG
http_device4 *device.Device
http_device6 *device.Device
http_HashSalt []byte
http_NhTable_Hash string
http_PeerInfo_hash string
http_NhTableStr []byte
http_PeerInfo mtypes.API_Peers
http_super_chains *mtypes.SUPER_Events
http_passwords mtypes.Passwords
http_StateExpire time.Time
@ -80,12 +83,13 @@ type HttpPeerInfo struct {
}
type PeerState struct {
NhTableState atomic.Value // string
PeerInfoState atomic.Value // string
SuperParamState atomic.Value // string
JETSecret atomic.Value // mtypes.JWTSecret
httpPostCount atomic.Value // uint64
LastSeen atomic.Value // time.Time
NhTableState atomic.Value // string
PeerInfoState atomic.Value // string
SuperParamState atomic.Value // string
SuperParamStateClient atomic.Value // string
JETSecret atomic.Value // mtypes.JWTSecret
httpPostCount atomic.Value // uint64
LastSeen atomic.Value // time.Time
}
type client struct {
@ -221,17 +225,17 @@ func get_superparams(w http.ResponseWriter, r *http.Request) {
return
}
if httpobj.http_SuperParams_Hash != State {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("Paramater State: State not correct"))
return
}
if _, has := httpobj.http_PeerState[PubKey]; has == false {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author."))
return
}
if httpobj.http_PeerState[PubKey].SuperParamState.Load().(string) != State {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("Paramater State: State not correct"))
return
}
// Do something
SuperParams := mtypes.API_SuperParams{
SendPingInterval: httpobj.http_sconfig.SendPingInterval,
@ -240,7 +244,7 @@ func get_superparams(w http.ResponseWriter, r *http.Request) {
AdditionalCost: httpobj.http_PeerID2Info[NodeID].AdditionalCost,
}
SuperParamStr, _ := json.Marshal(SuperParams)
httpobj.http_PeerState[PubKey].SuperParamState.Store(State)
httpobj.http_PeerState[PubKey].SuperParamStateClient.Store(State)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(SuperParamStr))
@ -743,17 +747,45 @@ func peerdel(w http.ResponseWriter, r *http.Request) { //Waiting for test
return
}
func HttpServer(http_port int, apiprefix string) {
mux := http.NewServeMux()
if apiprefix[0] != '/' {
func HttpServer(edgeListen string, manageListen string, apiprefix string) (err error) {
if len(apiprefix) > 0 && apiprefix[0] != '/' {
apiprefix = "/" + apiprefix
}
mux.HandleFunc(apiprefix+"/superparams", get_superparams)
mux.HandleFunc(apiprefix+"/peerinfo", get_peerinfo)
mux.HandleFunc(apiprefix+"/nhtable", get_nhtable)
mux.HandleFunc(apiprefix+"/peerstate", get_peerstate)
mux.HandleFunc(apiprefix+"/post/nodeinfo", post_nodeinfo)
mux.HandleFunc(apiprefix+"/peer/add", peeradd) //Waiting for test
mux.HandleFunc(apiprefix+"/peer/del", peerdel) //Waiting for test
http.ListenAndServe(":"+strconv.Itoa(http_port), mux)
if len(edgeListen) > 0 && edgeListen[0] != ':' {
edgeListen = ":" + edgeListen
}
if len(manageListen) > 0 && manageListen[0] != ':' {
manageListen = ":" + manageListen
}
if edgeListen == manageListen {
mux := http.NewServeMux()
mux.HandleFunc(apiprefix+"/edge/superparams", get_superparams)
mux.HandleFunc(apiprefix+"/edge/peerinfo", get_peerinfo)
mux.HandleFunc(apiprefix+"/edge/nhtable", get_nhtable)
mux.HandleFunc(apiprefix+"/edge/post/nodeinfo", post_nodeinfo)
mux.HandleFunc(apiprefix+"/manage/peerstate", get_peerstate)
mux.HandleFunc(apiprefix+"/manage/peer/add", peeradd)
mux.HandleFunc(apiprefix+"/manage/peer/del", peerdel)
err = http.ListenAndServe(edgeListen, mux)
return
} else {
edgemux := http.NewServeMux()
managemux := http.NewServeMux()
edgemux.HandleFunc(apiprefix+"/edge/superparams", get_superparams)
edgemux.HandleFunc(apiprefix+"/edge/peerinfo", get_peerinfo)
edgemux.HandleFunc(apiprefix+"/edge/nhtable", get_nhtable)
edgemux.HandleFunc(apiprefix+"/edge/post/nodeinfo", post_nodeinfo)
managemux.HandleFunc(apiprefix+"/manage/peerstate", get_peerstate)
managemux.HandleFunc(apiprefix+"/manage/peer/add", peeradd)
managemux.HandleFunc(apiprefix+"/manage/peer/del", peerdel)
err = http.ListenAndServe(edgeListen, edgemux)
if err != nil {
return
}
if manageListen != "" {
err = http.ListenAndServe(manageListen, managemux)
}
return
}
}

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 WireGuard LLC. All Rights Reserved.
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package main
@ -65,11 +65,14 @@ func printExampleSuperConf() {
v2 := mtypes.Vertex(2)
sconfig := mtypes.SuperConfig{
NodeName: "NodeSuper",
PostScript: "",
PrivKeyV4: "mL5IW0GuqbjgDeOJuPHBU2iJzBPNKhaNEXbIGwwYWWk=",
PrivKeyV6: "+EdOKIoBp/EvIusHDsvXhV1RJYbyN3Qr8nxlz35wl3I=",
ListenPort: 3000,
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: true,
@ -196,7 +199,7 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
Event_server_pong: make(chan mtypes.PongMsg, 1<<5),
Event_server_register: make(chan mtypes.RegisterMsg, 1<<5),
}
httpobj.http_graph = path.NewGraph(3, true, sconfig.GraphRecalculateSetting, mtypes.NTPinfo{}, sconfig.LogLevel)
httpobj.http_graph = path.NewGraph(3, true, sconfig.GraphRecalculateSetting, mtypes.NTPInfo{}, sconfig.LogLevel)
httpobj.http_graph.SetNHTable(httpobj.http_sconfig.NextHopTable)
if sconfig.GraphRecalculateSetting.StaticMode {
err = checkNhTable(httpobj.http_sconfig.NextHopTable, sconfig.Peers)
@ -257,13 +260,16 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
}
defer uapi6.Close()
}
prepare_superparams(*httpobj.http_sconfig)
go Event_server_event_hendler(httpobj.http_graph, httpobj.http_super_chains)
go RoutinePushSettings(mtypes.S2TD(sconfig.RePushConfigInterval))
go RoutineTimeoutCheck()
go HttpServer(sconfig.ListenPort, "/api")
go HttpServer(sconfig.ListenPort_EdgeAPI, sconfig.ListenPort_ManageAPI, sconfig.API_Prefix)
if sconfig.PostScript != "" {
envs := make(map[string]string)
envs["EG_MODE"] = "super"
envs["EG_NODE_NAME"] = sconfig.NodeName
cmdarg, err := shlex.Split(sconfig.PostScript)
if err != nil {
return fmt.Errorf("Error parse PostScript %v\n", err)
@ -294,21 +300,6 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
return
}
func prepare_superparams(sconfig mtypes.SuperConfig) {
SuperParams := mtypes.API_SuperParams{
SendPingInterval: sconfig.SendPingInterval,
HttpPostInterval: sconfig.HttpPostInterval,
PeerAliveTimeout: sconfig.PeerAliveTimeout,
AdditionalCost: -1,
}
SuperParamStr, _ := json.Marshal(SuperParams)
httpobj.http_SuperParamsStr = SuperParamStr
md5_hash_raw := md5.Sum(append(httpobj.http_SuperParamsStr, httpobj.http_HashSalt...))
new_hash_str := hex.EncodeToString(md5_hash_raw[:])
httpobj.http_SuperParams_Hash = new_hash_str
}
func super_peeradd(peerconf mtypes.SuperPeerInfo) error {
// No lock, lock before call me
pk, err := device.Str2PubKey(peerconf.PubKey)
@ -351,10 +342,22 @@ func super_peeradd(peerconf mtypes.SuperPeerInfo) error {
}
httpobj.http_PeerID2Info[peerconf.NodeID] = peerconf
SuperParams := mtypes.API_SuperParams{
SendPingInterval: httpobj.http_sconfig.SendPingInterval,
HttpPostInterval: httpobj.http_sconfig.HttpPostInterval,
PeerAliveTimeout: httpobj.http_sconfig.PeerAliveTimeout,
AdditionalCost: peerconf.AdditionalCost,
}
SuperParamStr, _ := json.Marshal(SuperParams)
md5_hash_raw := md5.Sum(append(SuperParamStr, httpobj.http_HashSalt...))
new_hash_str := hex.EncodeToString(md5_hash_raw[:])
PS := PeerState{}
PS.NhTableState.Store("") // string
PS.PeerInfoState.Store("") // string
PS.SuperParamState.Store("") // string
PS.SuperParamState.Store(new_hash_str) // string
PS.SuperParamStateClient.Store("") // string
PS.JETSecret.Store(mtypes.JWTSecret{}) // mtypes.JWTSecret
PS.httpPostCount.Store(uint64(0)) // uint64
PS.LastSeen.Store(time.Time{}) // time.Time
@ -569,29 +572,31 @@ func PushPeerinfo(force bool) {
func PushServerParams(force bool) {
//No lock
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
Node_id: mtypes.SuperNodeMessage,
Action: mtypes.UpdateSuperParams,
Code: 0,
Params: string(httpobj.http_SuperParams_Hash[:]),
})
if err != nil {
fmt.Println("Error get byte")
return
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage)
header.SetPacketLength(uint16(len(body)))
header.SetSrc(mtypes.SuperNodeMessage)
header.SetTTL(0)
copy(buf[path.EgHeaderLen:], body)
for pkstr, peerstate := range httpobj.http_PeerState {
isAlive := peerstate.LastSeen.Load().(time.Time).Add(mtypes.S2TD(httpobj.http_sconfig.PeerAliveTimeout)).After(time.Now())
if !isAlive {
continue
}
if force || peerstate.SuperParamState.Load().(string) != httpobj.http_SuperParams_Hash {
if force || peerstate.SuperParamState.Load().(string) != peerstate.SuperParamStateClient.Load().(string) {
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
Node_id: mtypes.SuperNodeMessage,
Action: mtypes.UpdateSuperParams,
Code: 0,
Params: peerstate.SuperParamState.Load().(string),
})
if err != nil {
fmt.Println("Error get byte")
return
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage)
header.SetPacketLength(uint16(len(body)))
header.SetSrc(mtypes.SuperNodeMessage)
header.SetTTL(0)
copy(buf[path.EgHeaderLen:], body)
if peer := httpobj.http_device4.LookupPeerByStr(pkstr); peer != nil {
httpobj.http_device4.SendPacket(peer, path.ServerUpdate, buf, device.MessageTransportOffsetContent)
}

View File

@ -18,82 +18,88 @@ const (
)
type EdgeConfig struct {
Interface InterfaceConf
NodeID Vertex
NodeName string
PostScript string
DefaultTTL uint8
L2FIBTimeout float64
PrivKey string
ListenPort int
LogLevel LoggerInfo
DynamicRoute DynamicRouteInfo
NextHopTable NextHopTable
ResetConnInterval float64
Peers []PeerInfo
Interface InterfaceConf `yaml:"Interface"`
NodeID Vertex `yaml:"NodeID"`
NodeName string `yaml:"NodeName"`
PostScript string `yaml:"PostScript"`
DefaultTTL uint8 `yaml:"DefaultTTL"`
L2FIBTimeout float64 `yaml:"L2FIBTimeout"`
PrivKey string `yaml:"PrivKey"`
ListenPort int `yaml:"ListenPort"`
LogLevel LoggerInfo `yaml:"LogLevel"`
DynamicRoute DynamicRouteInfo `yaml:"DynamicRoute"`
NextHopTable NextHopTable `yaml:"NextHopTable"`
ResetConnInterval float64 `yaml:"ResetConnInterval"`
Peers []PeerInfo `yaml:"Peers"`
}
type SuperConfig struct {
NodeName string
PostScript string
PrivKeyV4 string
PrivKeyV6 string
ListenPort int
RePushConfigInterval float64
HttpPostInterval float64
PeerAliveTimeout float64
SendPingInterval float64
LogLevel LoggerInfo
Passwords Passwords
GraphRecalculateSetting GraphRecalculateSetting
NextHopTable NextHopTable
EdgeTemplate string
UsePSKForInterEdge bool
Peers []SuperPeerInfo
NodeName string `yaml:"NodeName"`
PostScript string `yaml:"PostScript"`
PrivKeyV4 string `yaml:"PrivKeyV4"`
PrivKeyV6 string `yaml:"PrivKeyV6"`
ListenPort int `yaml:"ListenPort"`
ListenPort_EdgeAPI string `yaml:"ListenPort_EdgeAPI"`
ListenPort_ManageAPI string `yaml:"ListenPort_ManageAPI"`
API_Prefix string `yaml:"API_Prefix"`
RePushConfigInterval float64 `yaml:"RePushConfigInterval"`
HttpPostInterval float64 `yaml:"HttpPostInterval"`
PeerAliveTimeout float64 `yaml:"PeerAliveTimeout"`
SendPingInterval float64 `yaml:"SendPingInterval"`
LogLevel LoggerInfo `yaml:"LogLevel"`
Passwords Passwords `yaml:"Passwords"`
GraphRecalculateSetting GraphRecalculateSetting `yaml:"GraphRecalculateSetting"`
NextHopTable NextHopTable `yaml:"NextHopTable"`
EdgeTemplate string `yaml:"EdgeTemplate"`
UsePSKForInterEdge bool `yaml:"UsePSKForInterEdge"`
Peers []SuperPeerInfo `yaml:"Peers"`
}
type Passwords struct {
ShowState string
AddPeer string
DelPeer string
ShowState string `yaml:"ShowState"`
AddPeer string `yaml:"AddPeer"`
DelPeer string `yaml:"DelPeer"`
}
type InterfaceConf struct {
Itype string
Name string
VPPIfaceID uint32
VPPBridgeID uint32
MacAddrPrefix string
MTU int
RecvAddr string
SendAddr string
L2HeaderMode string
IType string `yaml:"IType"`
Name string `yaml:"Name"`
VPPIFaceID uint32 `yaml:"VPPIFaceID"`
VPPBridgeID uint32 `yaml:"VPPBridgeID"`
MacAddrPrefix string `yaml:"MacAddrPrefix"`
IPv4CIDR string `yaml:"IPv4CIDR"`
IPv6CIDR string `yaml:"IPv6CIDR"`
IPv6LLPrefix string `yaml:"IPv6LLPrefix"`
MTU int `yaml:"MTU"`
RecvAddr string `yaml:"RecvAddr"`
SendAddr string `yaml:"SendAddr"`
L2HeaderMode string `yaml:"L2HeaderMode"`
}
type PeerInfo struct {
NodeID Vertex
PubKey string
PSKey string
EndPoint string
Static bool
NodeID Vertex `yaml:"NodeID"`
PubKey string `yaml:"PubKey"`
PSKey string `yaml:"PSKey"`
EndPoint string `yaml:"EndPoint"`
Static bool `yaml:"Static"`
}
type SuperPeerInfo struct {
NodeID Vertex
Name string
PubKey string
PSKey string
AdditionalCost float64
SkipLocalIP bool
NodeID Vertex `yaml:"NodeID"`
Name string `yaml:"Name"`
PubKey string `yaml:"PubKey"`
PSKey string `yaml:"PSKey"`
AdditionalCost float64 `yaml:"AdditionalCost"`
SkipLocalIP bool `yaml:"SkipLocalIP"`
}
type LoggerInfo struct {
LogLevel string
LogTransit bool
LogControl bool
LogNormal bool
LogInternal bool
LogNTP bool
LogLevel string `yaml:"LogLevel"`
LogTransit bool `yaml:"LogTransit"`
LogControl bool `yaml:"LogControl"`
LogNormal bool `yaml:"LogNormal"`
LogInternal bool `yaml:"LogInternal"`
LogNTP bool `yaml:"LogNTP"`
}
func (v *Vertex) ToString() string {
@ -110,50 +116,50 @@ func (v *Vertex) ToString() string {
}
type DynamicRouteInfo struct {
SendPingInterval float64
PeerAliveTimeout float64
DupCheckTimeout float64
ConnTimeOut float64
ConnNextTry float64
AdditionalCost float64
SaveNewPeers bool
SuperNode SuperInfo
P2P P2Pinfo
NTPconfig NTPinfo
SendPingInterval float64 `yaml:"SendPingInterval"`
PeerAliveTimeout float64 `yaml:"PeerAliveTimeout"`
DupCheckTimeout float64 `yaml:"DupCheckTimeout"`
ConnTimeOut float64 `yaml:"ConnTimeOut"`
ConnNextTry float64 `yaml:"ConnNextTry"`
AdditionalCost float64 `yaml:"AdditionalCost"`
SaveNewPeers bool `yaml:"SaveNewPeers"`
SuperNode SuperInfo `yaml:"SuperNode"`
P2P P2PInfo `yaml:"P2P"`
NTPConfig NTPInfo `yaml:"NTPConfig"`
}
type NTPinfo struct {
UseNTP bool
MaxServerUse int
SyncTimeInterval float64
NTPTimeout float64
Servers []string
type NTPInfo struct {
UseNTP bool `yaml:"UseNTP"`
MaxServerUse int `yaml:"MaxServerUse"`
SyncTimeInterval float64 `yaml:"SyncTimeInterval"`
NTPTimeout float64 `yaml:"NTPTimeout"`
Servers []string `yaml:"Servers"`
}
type SuperInfo struct {
UseSuperNode bool
PSKey string
ConnURLV4 string
PubKeyV4 string
ConnURLV6 string
PubKeyV6 string
APIUrl string
SkipLocalIP bool
SuperNodeInfoTimeout float64
UseSuperNode bool `yaml:"UseSuperNode"`
PSKey string `yaml:"PSKey"`
EndpointV4 string `yaml:"EndpointV4"`
PubKeyV4 string `yaml:"PubKeyV4"`
EndpointV6 string `yaml:"EndpointV6"`
PubKeyV6 string `yaml:"PubKeyV6"`
EndpointEdgeAPIUrl string `yaml:"EndpointEdgeAPIUrl"`
SkipLocalIP bool `yaml:"SkipLocalIP"`
SuperNodeInfoTimeout float64 `yaml:"SuperNodeInfoTimeout"`
}
type P2Pinfo struct {
UseP2P bool
SendPeerInterval float64
GraphRecalculateSetting GraphRecalculateSetting
type P2PInfo struct {
UseP2P bool `yaml:"UseP2P"`
SendPeerInterval float64 `yaml:"SendPeerInterval"`
GraphRecalculateSetting GraphRecalculateSetting `yaml:"GraphRecalculateSetting"`
}
type GraphRecalculateSetting struct {
StaticMode bool
JitterTolerance float64
JitterToleranceMultiplier float64
TimeoutCheckInterval float64
RecalculateCoolDown float64
StaticMode bool `yaml:"StaticMode"`
JitterTolerance float64 `yaml:"JitterTolerance"`
JitterToleranceMultiplier float64 `yaml:"JitterToleranceMultiplier"`
TimeoutCheckInterval float64 `yaml:"TimeoutCheckInterval"`
RecalculateCoolDown float64 `yaml:"RecalculateCoolDown"`
}
type DistTable map[Vertex]map[Vertex]float64

View File

@ -53,12 +53,12 @@ type IG struct {
loglevel mtypes.LoggerInfo
ntp_wg sync.WaitGroup
ntp_info mtypes.NTPinfo
ntp_info mtypes.NTPInfo
ntp_offset time.Duration
ntp_servers orderedmap.OrderedMap // serverurl:lentancy
}
func NewGraph(num_node int, IsSuperMode bool, theconfig mtypes.GraphRecalculateSetting, ntpinfo mtypes.NTPinfo, loglevel mtypes.LoggerInfo) *IG {
func NewGraph(num_node int, IsSuperMode bool, theconfig mtypes.GraphRecalculateSetting, ntpinfo mtypes.NTPInfo, loglevel mtypes.LoggerInfo) *IG {
g := IG{
edgelock: &sync.RWMutex{},
StaticMode: theconfig.StaticMode,
@ -499,7 +499,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

View File

@ -8,6 +8,8 @@ package tap
import (
"encoding/binary"
"errors"
"fmt"
"math/big"
"net"
"strconv"
"strings"
@ -30,6 +32,56 @@ func GetSrcMacAddr(packet []byte) (srcMacAddr MacAddress) {
return
}
func GetIP(version int, netcidr string, uid uint32) (net.IP, net.IPMask, error) {
_, the_net, err := net.ParseCIDR(netcidr)
if err != nil {
return nil, nil, fmt.Errorf("Not a valid IPv%v CIDR: %v", version, netcidr)
}
the_ip := the_net.IP
if version == 4 {
if strings.Contains(netcidr, ":") {
return nil, nil, errors.New("Not a valid IPv4 CIDR: " + netcidr)
}
if the_ip.To4() == nil {
return nil, nil, errors.New("Not a valid IPv4 CIDR: " + netcidr)
}
}
if version == 6 {
if strings.Contains(netcidr, ".") {
return nil, nil, errors.New("Not a valid IPv4 CIDR: " + netcidr)
}
if the_ip.To4() != nil {
return nil, nil, errors.New("Not a valid IPv6 CIDR: " + netcidr)
}
}
ones, bits := the_net.Mask.Size()
maxuid := big.NewInt(1)
maxuid.Lsh(maxuid, uint((bits - ones)))
ip_use := big.NewInt(int64(uid))
if maxuid.Cmp(big.NewInt(2)) > 0 {
maxuid.Sub(maxuid, big.NewInt(2))
if uid == 0 {
ip_use.Set(maxuid)
ip_use.Sub(ip_use, big.NewInt(1))
}
}
if ip_use.Cmp(maxuid) > 0 {
return nil, nil, fmt.Errorf("The CIDR %v can only contain %v IPs. But your NodeID %v exceed it.", netcidr, maxuid, uid)
}
IP_Int := big.NewInt(0)
IP_Int.SetBytes(the_ip)
IP_Int.Add(IP_Int, ip_use)
ip_arr := IP_Int.Bytes()
if len(ip_arr) < 16 {
ip_arr = append(make([]byte, 16-len(ip_arr)), ip_arr...)
}
if len(ip_arr) > 16 {
ip_arr = ip_arr[len(ip_arr)-16:]
}
result_ip := net.IP(ip_arr)
return result_ip, the_net.Mask, nil
}
func GetMacAddr(prefix string, uid uint32) (mac MacAddress, err error) {
macprefix, _, err := prefixStr2prefix(prefix)
if err != nil {

View File

@ -16,7 +16,10 @@ import (
"encoding/binary"
"errors"
"fmt"
"net"
"os"
"os/exec"
"strconv"
"sync"
"syscall"
"time"
@ -196,7 +199,7 @@ func (tap *NativeTap) routineNetlinkListener() {
}
}
func (tap *NativeTap) setMacAddr(mac MacAddress) (err error) {
func ioctlRequest(cmd uintptr, arg uintptr) (err error) {
fd, err := unix.Socket(
unix.AF_INET,
unix.SOCK_DGRAM,
@ -206,6 +209,20 @@ func (tap *NativeTap) setMacAddr(mac MacAddress) (err error) {
return err
}
defer unix.Close(fd)
_, _, err = unix.Syscall(
unix.SYS_IOCTL,
uintptr(fd),
cmd,
arg,
)
if err.(syscall.Errno) == syscall.Errno(0) {
err = nil
}
return
}
func (tap *NativeTap) setMacAddr(mac MacAddress) (err error) {
var ifr [ifReqSize]byte
name, err := tap.Name()
if err != nil {
@ -218,28 +235,82 @@ func (tap *NativeTap) setMacAddr(mac MacAddress) (err error) {
copy(ifr[:unix.IFNAMSIZ], name)
binary.LittleEndian.PutUint16(ifr[unix.IFNAMSIZ:unix.IFNAMSIZ+2], unix.AF_UNIX)
copy(ifr[unix.IFNAMSIZ+2:unix.IFNAMSIZ+8], mac[:])
_, _, err = unix.Syscall(
unix.SYS_IOCTL,
uintptr(fd),
uintptr(unix.SIOCSIFHWADDR),
uintptr(unsafe.Pointer(&ifr[0])),
)
if err.(syscall.Errno) == syscall.Errno(0) {
err = nil
err = ioctlRequest(unix.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr[0])))
return
}
func (tap *NativeTap) addIPAddr(version string, ip net.IP, mask net.IPMask) (err error) {
var ifr [ifReqSize]byte
name, err := tap.Name()
if err != nil {
return err
}
/*
bin_ip = socket.inet_aton(ip)
ifreq = struct.pack('16sH2s4s8s', iface, socket.AF_INET, '\x00' * 2, bin_ip, '\x00' * 8)
fcntl.ioctl(sock, SIOCSIFADDR, ifreq)
*/
if version == "4" {
{
iparr := [4]byte{}
copy(iparr[:], ip[len(ip)-4:])
sockaddr := unix.RawSockaddrInet4{
Family: unix.AF_INET,
Port: 0,
Addr: iparr,
}
sockaddr_arr := (*[unsafe.Sizeof(sockaddr)]byte)(unsafe.Pointer(&sockaddr))[:]
copy(ifr[:unix.IFNAMSIZ], name) // 0-16
copy(ifr[unix.IFNAMSIZ:], sockaddr_arr) // 20-
err = ioctlRequest(unix.SIOCSIFADDR, uintptr(unsafe.Pointer(&ifr[0])))
if err != nil {
return
}
}
{
iparr := [4]byte{}
copy(iparr[:], mask[len(mask)-4:])
sockaddr := unix.RawSockaddrInet4{
Family: unix.AF_INET,
Port: 0,
Addr: iparr,
}
sockaddr_arr := (*[unsafe.Sizeof(sockaddr)]byte)(unsafe.Pointer(&sockaddr))[:]
copy(ifr[:unix.IFNAMSIZ], name) // 0-16
copy(ifr[unix.IFNAMSIZ:], sockaddr_arr) // 20-
err = ioctlRequest(unix.SIOCSIFNETMASK, uintptr(unsafe.Pointer(&ifr[0])))
if err != nil {
return
}
}
} else if version == "6" {
o, _ := mask.Size()
masklen := strconv.Itoa(o)
e := exec.Command("ip", "addr", "add", ip.String()+"/"+masklen, "dev", name)
ret, err := e.CombinedOutput()
if err != nil {
fmt.Println("Please make sure `ip` tool installed")
return fmt.Errorf(string(ret))
}
} else if version == "6ll" {
_, llnet, _ := net.ParseCIDR("fe80::/64")
if llnet.Contains(ip) == false {
return fmt.Errorf("%v is not a link-local address", ip)
}
e := exec.Command("ip", "addr", "add", ip.String()+"/64", "dev", name)
ret, err := e.CombinedOutput()
if err != nil {
fmt.Println("Please make sure `ip` tool installed")
return fmt.Errorf(string(ret))
}
}
return
}
func (tap *NativeTap) setUp() (err error) {
fd, err := unix.Socket(
unix.AF_INET,
unix.SOCK_DGRAM,
0,
)
if err != nil {
return err
}
defer unix.Close(fd)
var ifr [ifReqSize]byte
name, err := tap.Name()
if err != nil {
@ -253,81 +324,29 @@ func (tap *NativeTap) setUp() (err error) {
copy(ifr[:unix.IFNAMSIZ], name)
binary.LittleEndian.PutUint16(ifr[unix.IFNAMSIZ:unix.IFNAMSIZ+2], unix.AF_UNIX)
binary.LittleEndian.PutUint16(ifr[unix.IFNAMSIZ+2:unix.IFNAMSIZ+4], flags)
_, _, err = unix.Syscall(
unix.SYS_IOCTL,
uintptr(fd),
uintptr(unix.SIOCSIFFLAGS),
uintptr(unsafe.Pointer(&ifr[0])),
)
if err.(syscall.Errno) == syscall.Errno(0) {
err = nil
}
err = ioctlRequest(unix.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifr[0])))
return
}
func getIFIndex(name string) (int32, error) {
fd, err := unix.Socket(
unix.AF_INET,
unix.SOCK_DGRAM,
0,
)
if err != nil {
return 0, err
}
defer unix.Close(fd)
func getIFIndex(name string) (ret int32, err error) {
var ifr [ifReqSize]byte
copy(ifr[:], name)
_, _, errno := unix.Syscall(
unix.SYS_IOCTL,
uintptr(fd),
uintptr(unix.SIOCGIFINDEX),
uintptr(unsafe.Pointer(&ifr[0])),
)
if errno != 0 {
return 0, errno
}
err = ioctlRequest(unix.SIOCGIFINDEX, uintptr(unsafe.Pointer(&ifr[0])))
return *(*int32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])), nil
}
func (tap *NativeTap) setMTU(n int) error {
func (tap *NativeTap) setMTU(n int) (err error) {
name, err := tap.Name()
if err != nil {
return err
}
// open datagram socket
fd, err := unix.Socket(
unix.AF_INET,
unix.SOCK_DGRAM,
0,
)
if err != nil {
return err
}
defer unix.Close(fd)
// do ioctl call
var ifr [ifReqSize]byte
copy(ifr[:], name)
*(*uint32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ])) = uint32(n)
_, _, errno := unix.Syscall(
unix.SYS_IOCTL,
uintptr(fd),
uintptr(unix.SIOCSIFMTU),
uintptr(unsafe.Pointer(&ifr[0])),
)
if errno != 0 {
return fmt.Errorf("failed to set MTU of TUN device: %w", errno)
}
err = ioctlRequest(unix.SIOCSIFMTU, uintptr(unsafe.Pointer(&ifr[0])))
return nil
return
}
func (tap *NativeTap) MTU() (int, error) {
@ -335,33 +354,10 @@ func (tap *NativeTap) MTU() (int, error) {
if err != nil {
return 0, err
}
// open datagram socket
fd, err := unix.Socket(
unix.AF_INET,
unix.SOCK_DGRAM,
0,
)
if err != nil {
return 0, err
}
defer unix.Close(fd)
// do ioctl call
var ifr [ifReqSize]byte
copy(ifr[:], name)
_, _, errno := unix.Syscall(
unix.SYS_IOCTL,
uintptr(fd),
uintptr(unix.SIOCGIFMTU),
uintptr(unsafe.Pointer(&ifr[0])),
)
if errno != 0 {
return 0, fmt.Errorf("failed to get MTU of TUN device: %w", errno)
}
err = ioctlRequest(unix.SIOCGIFMTU, uintptr(unsafe.Pointer(&ifr[0])))
return int(*(*int32)(unsafe.Pointer(&ifr[unix.IFNAMSIZ]))), nil
}
@ -521,9 +517,13 @@ func CreateTAPFromFile(file *os.File, iconfig mtypes.InterfaceConf, NodeID mtype
if err != nil {
return nil, err
}
defer func() {
if err != nil {
unix.Close(tap.netlinkSock)
}
}()
tap.netlinkCancel, err = rwcancel.NewRWCancel(tap.netlinkSock)
if err != nil {
unix.Close(tap.netlinkSock)
return nil, err
}
@ -533,7 +533,6 @@ func CreateTAPFromFile(file *os.File, iconfig mtypes.InterfaceConf, NodeID mtype
err = tap.setMTU(iconfig.MTU)
if err != nil {
unix.Close(tap.netlinkSock)
return nil, err
}
IfMacAddr, err := GetMacAddr(iconfig.MacAddrPrefix, uint32(NodeID))
@ -543,14 +542,55 @@ func CreateTAPFromFile(file *os.File, iconfig mtypes.InterfaceConf, NodeID mtype
}
err = tap.setMacAddr(IfMacAddr)
if err != nil {
unix.Close(tap.netlinkSock)
return nil, err
}
tapname, err := tap.Name()
if err != nil {
return nil, err
}
err = tap.setUp()
if err != nil {
unix.Close(tap.netlinkSock)
return nil, err
}
if iconfig.IPv6LLPrefix != "" {
e := exec.Command("ip", "addr", "flush", "dev", tapname)
_, err := e.CombinedOutput()
if err != nil {
fmt.Println("Please make sure `ip` tool installed")
return nil, err
}
cidrstr := iconfig.IPv6LLPrefix
ip, mask, err := GetIP(6, cidrstr, uint32(NodeID))
if err != nil {
return nil, err
}
err = tap.addIPAddr("6ll", ip, mask)
if err != nil {
return nil, err
}
}
if iconfig.IPv6CIDR != "" {
cidrstr := iconfig.IPv6CIDR
ip, mask, err := GetIP(6, cidrstr, uint32(NodeID))
if err != nil {
return nil, err
}
err = tap.addIPAddr("6", ip, mask)
if err != nil {
return nil, err
}
}
if iconfig.IPv4CIDR != "" {
cidrstr := iconfig.IPv4CIDR
ip, mask, err := GetIP(4, cidrstr, uint32(NodeID))
if err != nil {
return nil, err
}
err = tap.addIPAddr("4", ip, mask)
}
return tap, nil
}