diff --git a/README_zh.md b/README_zh.md
index 2620478..8efc3d6 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -82,8 +82,6 @@ VPN起來以後,自己手動加ip也行
$ ./etherguard-go -mode gencfg -cfgmode super -config example_config/super_mode/gensuper.yaml
```
-
-
把一個super,2個edge分別搬去三台機器
或是2台機器,super和edge可以是同一台
diff --git a/device/peer.go b/device/peer.go
index 88e6624..4e87250 100644
--- a/device/peer.go
+++ b/device/peer.go
@@ -154,7 +154,7 @@ type Peer struct {
LastPacketReceivedAdd1Sec atomic.Value // *time.Time
- SingleWayLatency float64
+ SingleWayLatency atomic.Value
stopping sync.WaitGroup // routines pending stop
ID mtypes.Vertex
@@ -245,7 +245,7 @@ func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool,
peer.cookieGenerator.Init(pk)
peer.device = device
peer.endpoint_trylist = NewEndpoint_trylist(peer, mtypes.S2TD(device.EdgeConfig.DynamicRoute.PeerAliveTimeout))
- peer.SingleWayLatency = mtypes.Infinity
+ peer.SingleWayLatency.Store(mtypes.Infinity)
peer.queue.outbound = newAutodrainingOutboundQueue(device)
peer.queue.inbound = newAutodrainingInboundQueue(device)
peer.queue.staged = make(chan *QueueOutboundElement, QueueStagedSize)
diff --git a/device/receive.go b/device/receive.go
index 3e7b584..52584b2 100644
--- a/device/receive.go
+++ b/device/receive.go
@@ -470,39 +470,76 @@ func (peer *Peer) RoutineSequentialReceiver() {
packet_type = elem.Type
if device.IsSuperNode {
- switch dst_nodeID {
- case mtypes.NodeID_AllPeer:
+ if packet_type.IsControl_Edge2Super() {
should_process = true
+ } else {
+ device.log.Errorf("received unsupported packet_type %v from %v %v", packet_type, src_nodeID, peer.endpoint.DstToString())
+ goto skip
+ }
+ switch dst_nodeID {
case mtypes.NodeID_SuperNode:
should_process = true
default:
- device.log.Errorf("Invalid dst_nodeID received. Check your code for bug")
+ device.log.Errorf("received invalid dst_nodeID %v from %v %v", dst_nodeID, src_nodeID, peer.endpoint.DstToString())
+ goto skip
}
} else {
- switch dst_nodeID {
- case mtypes.NodeID_Boardcast:
- should_receive = true
- should_transfer = true
- case mtypes.NodeID_SuperNode:
- should_process = true
- case mtypes.NodeID_AllPeer:
- packet := elem.packet[path.EgHeaderLen:] //true packet
- if device.CheckNoDup(packet) {
+ // Set should_receive and should_process
+ if packet_type.IsNormal() {
+ switch dst_nodeID {
+ case device.ID:
+ should_receive = true
+ case mtypes.NodeID_Broadcast:
+ should_receive = true
+ case mtypes.NodeID_AllPeer:
+ should_receive = true
+ }
+ }
+ if packet_type.IsControl_Edge2Edge() {
+ switch dst_nodeID {
+ case device.ID:
should_process = true
+ case mtypes.NodeID_Broadcast:
+ should_process = true
+ case mtypes.NodeID_AllPeer:
+ should_process = true
+ }
+ }
+ if packet_type.IsControl_Super2Edge() {
+ if peer.ID == mtypes.NodeID_SuperNode {
+ switch dst_nodeID {
+ case device.ID:
+ should_process = true
+ case mtypes.NodeID_SuperNode:
+ should_process = true
+ }
+
+ } else {
+ device.log.Errorf("received ServerUpdate packet from non supernode %v %v", src_nodeID, peer.endpoint.DstToString())
+ goto skip
+ }
+ }
+
+ // Set should_transfer
+ switch dst_nodeID {
+ case mtypes.NodeID_Broadcast:
+ should_transfer = true
+ case mtypes.NodeID_AllPeer:
+ packet := elem.packet[path.EgHeaderLen:] //packet body
+ if device.CheckNoDup(packet) {
should_transfer = true
} else {
- should_process = false
- should_transfer = false
if device.LogLevel.LogTransit {
- fmt.Printf("Transit: Duplicate packet received from %d through %d , src_nodeID = %d . Dropeed.\n", peer.ID, device.ID, src_nodeID)
+ fmt.Printf("Transit: Duplicate packet received from %d through %d , src_nodeID = %d . Dropped.\n", peer.ID, device.ID, src_nodeID)
}
+ goto skip
}
case device.ID:
- if packet_type == path.NormalPacket {
- should_receive = true
- } else {
- should_process = true
- }
+ should_transfer = false
+ case mtypes.NodeID_SuperNode:
+ should_transfer = false
+ case mtypes.NodeID_Invalid:
+ should_transfer = false
default:
if device.graph.Next(device.ID, dst_nodeID) != mtypes.NodeID_Invalid {
should_transfer = true
@@ -517,7 +554,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
device.log.Verbosef("TTL is 0 %v", dst_nodeID)
} else {
EgHeader.SetTTL(l2ttl - 1)
- if dst_nodeID == mtypes.NodeID_Boardcast { //Regular transfer algorithm
+ if dst_nodeID == mtypes.NodeID_Broadcast { //Regular transfer algorithm
device.TransitBoardcastPacket(src_nodeID, peer.ID, elem.Type, elem.packet, MessageTransportOffsetContent)
} else if dst_nodeID == mtypes.NodeID_AllPeer { // Control Message will try send to every know node regardless the connectivity
skip_list := make(map[mtypes.Vertex]bool)
@@ -534,7 +571,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
if device.LogLevel.LogTransit {
fmt.Printf("Transit: Transfer packet from %d through %d to %d\n", peer.ID, device.ID, peer_out.ID)
}
- device.SendPacket(peer_out, elem.Type, elem.packet, MessageTransportOffsetContent)
+ go device.SendPacket(peer_out, elem.Type, elem.packet, MessageTransportOffsetContent)
}
}
}
diff --git a/device/receivesendproc.go b/device/receivesendproc.go
index 3f6fe2e..7de3eed 100644
--- a/device/receivesendproc.go
+++ b/device/receivesendproc.go
@@ -309,17 +309,20 @@ func (device *Device) server_process_Pong(peer *Peer, content mtypes.PongMsg) er
func (device *Device) process_ping(peer *Peer, content mtypes.PingMsg) error {
Timediff := device.graph.GetCurrentTime().Sub(content.Time).Seconds()
- peer.SingleWayLatency = Timediff
+ NewTimediff := peer.SingleWayLatency.Load().(float64)
+ DR := NewTimediff * device.EdgeConfig.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance
+ NewTimediff = NewTimediff*DR + Timediff*(1-DR)
+ peer.SingleWayLatency.Store(NewTimediff)
PongMSG := mtypes.PongMsg{
Src_nodeID: content.Src_nodeID,
Dst_nodeID: device.ID,
- Timediff: Timediff,
+ Timediff: NewTimediff,
TimeToAlive: device.EdgeConfig.DynamicRoute.PeerAliveTimeout,
AdditionalCost: device.EdgeConfig.DynamicRoute.AdditionalCost,
}
if device.EdgeConfig.DynamicRoute.P2P.UseP2P && time.Now().After(device.graph.NhTableExpire) {
- device.graph.UpdateLatency(content.Src_nodeID, device.ID, PongMSG.Timediff, device.EdgeConfig.DynamicRoute.PeerAliveTimeout, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
+ device.graph.UpdateLatencyMulti([]mtypes.PongMsg{PongMSG}, true, false)
}
body, err := mtypes.GetByte(&PongMSG)
if err != nil {
@@ -887,7 +890,7 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
RequestID: 0,
Src_nodeID: device.ID,
Dst_nodeID: id,
- Timediff: peer.SingleWayLatency,
+ Timediff: peer.SingleWayLatency.Load().(float64),
TimeToAlive: time.Since(*peer.LastPacketReceivedAdd1Sec.Load().(*time.Time)).Seconds() + device.EdgeConfig.DynamicRoute.PeerAliveTimeout,
}
pongs = append(pongs, pong)
@@ -989,7 +992,7 @@ func (device *Device) RoutineSpreadAllMyNeighbor() {
timeout := mtypes.S2TD(device.EdgeConfig.DynamicRoute.P2P.SendPeerInterval)
for {
device.process_RequestPeerMsg(mtypes.QueryPeerMsg{
- Request_ID: uint32(mtypes.NodeID_Boardcast),
+ Request_ID: uint32(mtypes.NodeID_Broadcast),
})
time.Sleep(timeout)
}
diff --git a/device/send.go b/device/send.go
index 5a51f00..0705036 100644
--- a/device/send.go
+++ b/device/send.go
@@ -256,9 +256,9 @@ func (device *Device) RoutineReadFromTUN() {
dstMacAddr := tap.GetDstMacAddr(elem.packet[path.EgHeaderLen:])
// lookup peer
if tap.IsNotUnicast(dstMacAddr) {
- dst_nodeID = mtypes.NodeID_Boardcast
+ dst_nodeID = mtypes.NodeID_Broadcast
} else if val, ok := device.l2fib.Load(dstMacAddr); !ok { //Lookup failed
- dst_nodeID = mtypes.NodeID_Boardcast
+ dst_nodeID = mtypes.NodeID_Broadcast
} else {
dst_nodeID = val.(*IdAndTime).ID
}
@@ -275,7 +275,7 @@ func (device *Device) RoutineReadFromTUN() {
continue
}
- if dst_nodeID != mtypes.NodeID_Boardcast {
+ if dst_nodeID != mtypes.NodeID_Broadcast {
var peer *Peer
next_id := device.graph.Next(device.ID, dst_nodeID)
if next_id != mtypes.NodeID_Invalid {
diff --git a/example_config/static_mode/n1.yaml b/example_config/static_mode/EgNet_edge1.yaml
similarity index 87%
rename from example_config/static_mode/n1.yaml
rename to example_config/static_mode/EgNet_edge1.yaml
index 5236178..bde9a9a 100644
--- a/example_config/static_mode/n1.yaml
+++ b/example_config/static_mode/EgNet_edge1.yaml
@@ -3,7 +3,7 @@ Interface:
Name: tap1
VPPIFaceID: 1
VPPBridgeID: 4242
- MacAddrPrefix: 8E:AA:C8:4B
+ MacAddrPrefix: DA:21:10:81
IPv4CIDR: 192.168.76.0/24
IPv6CIDR: fd95:71cb:a3df:e586::/64
IPv6LLPrefix: fe80::a3df:0/112
@@ -12,17 +12,17 @@ Interface:
SendAddr: 127.0.0.1:5001
L2HeaderMode: kbdbg
NodeID: 1
-NodeName: Node1
+NodeName: EgNet1
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
-PrivKey: Fe9Q6K5L6xTVbx/zFc07tnQuo+pkeyrhfoTQ3BF5GRM=
+PrivKey: LFFQqPBQ84x2AQ9BCI+0wG8nr+Y6yXHqhXkMCb4HCmg=
ListenPort: 3001
LogLevel:
LogLevel: error
LogTransit: true
- LogControl: true
LogNormal: true
+ LogControl: true
LogInternal: true
LogNTP: true
DynamicRoute:
@@ -100,8 +100,8 @@ NextHopTable:
ResetConnInterval: 86400
Peers:
- NodeID: 2
- PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
- PSKey: kWDwCaC11UvYjfiXBMwYpR6Pujo1vaVW8JTusp1Kkrw=
+ PubKey: 0r2o9Hb36gYVgD3VSKCH18MVOZw0BvzcJ6TOTo6Cc1g=
+ PSKey: lFq67qp9LXL3PtlEJ3SGg3c/6++Ljy2I8i/k0Xcibvk=
EndPoint: 127.0.0.1:3002
- PersistentKeepalive: 30
+ PersistentKeepalive: 0
Static: true
diff --git a/example_config/static_mode/n2.yaml b/example_config/static_mode/EgNet_edge2.yaml
similarity index 79%
rename from example_config/static_mode/n2.yaml
rename to example_config/static_mode/EgNet_edge2.yaml
index 85fa7bf..7293c34 100644
--- a/example_config/static_mode/n2.yaml
+++ b/example_config/static_mode/EgNet_edge2.yaml
@@ -3,7 +3,7 @@ Interface:
Name: tap1
VPPIFaceID: 1
VPPBridgeID: 4242
- MacAddrPrefix: 8E:AA:C8:4B
+ MacAddrPrefix: DA:21:10:81
IPv4CIDR: 192.168.76.0/24
IPv6CIDR: fd95:71cb:a3df:e586::/64
IPv6LLPrefix: fe80::a3df:0/112
@@ -12,17 +12,17 @@ Interface:
SendAddr: 127.0.0.1:5001
L2HeaderMode: kbdbg
NodeID: 2
-NodeName: Node2
+NodeName: EgNet2
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
-PrivKey: WaeR98bFhy0rxw7unsaTo7aR2RmySo9l185IZqPWl1c=
+PrivKey: M8SxYCTHCPES/yPqcKP4mr+AoMAx9sgUmk64FCJIv6k=
ListenPort: 3002
LogLevel:
LogLevel: error
LogTransit: true
- LogControl: true
LogNormal: true
+ LogControl: true
LogInternal: true
LogNTP: true
DynamicRoute:
@@ -100,20 +100,20 @@ NextHopTable:
ResetConnInterval: 86400
Peers:
- NodeID: 1
- PubKey: iDhQA9pgL01Gb0MrPzbiV80P4Uv3+uY/s+wNTQye0Qo=
- PSKey: kWDwCaC11UvYjfiXBMwYpR6Pujo1vaVW8JTusp1Kkrw=
+ PubKey: fnc7bfFTf7B23hwtARPpX14tCeZwNfDhGCJctBpMfA8=
+ PSKey: lFq67qp9LXL3PtlEJ3SGg3c/6++Ljy2I8i/k0Xcibvk=
EndPoint: 127.0.0.1:3001
PersistentKeepalive: 0
Static: true
- NodeID: 3
- PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
- PSKey: f2/34zUTLx8RP9cYisESoQlxz55oGZlTemqxv25VVa8=
+ PubKey: ymNpm430tiph3rMSVnQzDAxmK9+3jdcRFi6e96xmQUI=
+ PSKey: Y86PZY1ldgoyzPJxEqei5Vg5zlzkJkoO77LJfxV8alE=
EndPoint: 127.0.0.1:3003
PersistentKeepalive: 0
Static: true
- NodeID: 4
- PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
- PSKey: zkG1ywPqS4MiGofuWmxHHBs8YBlnYd04B4T9IhkbXYM=
+ PubKey: 9YSIkihv/+aeukOaWwsR9EKvO1DM9+5kN53a/osTpmA=
+ PSKey: QHyrrls0KT2dvBKtoWkZvq5NQ+Xyjm0YgbMUzCCRw34=
EndPoint: 127.0.0.1:3004
- PersistentKeepalive: 30
+ PersistentKeepalive: 0
Static: true
diff --git a/example_config/static_mode/n3.yaml b/example_config/static_mode/EgNet_edge3.yaml
similarity index 79%
rename from example_config/static_mode/n3.yaml
rename to example_config/static_mode/EgNet_edge3.yaml
index 0ff078e..dbca261 100644
--- a/example_config/static_mode/n3.yaml
+++ b/example_config/static_mode/EgNet_edge3.yaml
@@ -3,7 +3,7 @@ Interface:
Name: tap1
VPPIFaceID: 1
VPPBridgeID: 4242
- MacAddrPrefix: 8E:AA:C8:4B
+ MacAddrPrefix: DA:21:10:81
IPv4CIDR: 192.168.76.0/24
IPv6CIDR: fd95:71cb:a3df:e586::/64
IPv6LLPrefix: fe80::a3df:0/112
@@ -12,17 +12,17 @@ Interface:
SendAddr: 127.0.0.1:5001
L2HeaderMode: kbdbg
NodeID: 3
-NodeName: Node3
+NodeName: EgNet3
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
-PrivKey: vNUFWbZXySk2dTl5R9UEG73p+4IQmywvC1uQStf0vao=
+PrivKey: cTO/GUSYHoj5mKczCyQu/ckPiDMEygkUbXcY3RafGEE=
ListenPort: 3003
LogLevel:
LogLevel: error
LogTransit: true
- LogControl: true
LogNormal: true
+ LogControl: true
LogInternal: true
LogNTP: true
DynamicRoute:
@@ -99,21 +99,21 @@ NextHopTable:
5: 4
ResetConnInterval: 86400
Peers:
-- NodeID: 5
- PubKey: AarP7cL6TVmFyHRZLXuxFGr5uQghsp57ydsJdj+lGzs=
- PSKey: +TU8Zi8dr/UBqNyW/MYMgJiqkLnRbHW4ExQYQ2eNEag=
- EndPoint: 127.0.0.1:3005
- PersistentKeepalive: 0
- Static: true
- NodeID: 2
- PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
- PSKey: f2/34zUTLx8RP9cYisESoQlxz55oGZlTemqxv25VVa8=
+ PubKey: 0r2o9Hb36gYVgD3VSKCH18MVOZw0BvzcJ6TOTo6Cc1g=
+ PSKey: Y86PZY1ldgoyzPJxEqei5Vg5zlzkJkoO77LJfxV8alE=
EndPoint: 127.0.0.1:3002
PersistentKeepalive: 0
Static: true
- NodeID: 4
- PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
- PSKey: 8HN+PBGDKmBFCDlWIyNUFFYS4X6ONGXI32AIKXSnUqU=
+ PubKey: 9YSIkihv/+aeukOaWwsR9EKvO1DM9+5kN53a/osTpmA=
+ PSKey: SQyLomXDeknBIFezUKardOviAmNS+YZ1XTvZtYVlOtE=
EndPoint: 127.0.0.1:3004
- PersistentKeepalive: 30
+ PersistentKeepalive: 0
+ Static: true
+- NodeID: 5
+ PubKey: x66hOjYXoZjL1FI3OVtf/CWittsnvmezKV6sW0v5FXQ=
+ PSKey: ChWBQurfGNZE5xIlhi9EUvZrQPBvkFsfrPaD6tyqSYg=
+ EndPoint: 127.0.0.1:3005
+ PersistentKeepalive: 0
Static: true
diff --git a/example_config/static_mode/n4.yaml b/example_config/static_mode/EgNet_edge4.yaml
similarity index 79%
rename from example_config/static_mode/n4.yaml
rename to example_config/static_mode/EgNet_edge4.yaml
index 13c7c14..4ff6ae7 100644
--- a/example_config/static_mode/n4.yaml
+++ b/example_config/static_mode/EgNet_edge4.yaml
@@ -3,7 +3,7 @@ Interface:
Name: tap1
VPPIFaceID: 1
VPPBridgeID: 4242
- MacAddrPrefix: 8E:AA:C8:4B
+ MacAddrPrefix: DA:21:10:81
IPv4CIDR: 192.168.76.0/24
IPv6CIDR: fd95:71cb:a3df:e586::/64
IPv6LLPrefix: fe80::a3df:0/112
@@ -12,17 +12,17 @@ Interface:
SendAddr: 127.0.0.1:5001
L2HeaderMode: kbdbg
NodeID: 4
-NodeName: Node4
+NodeName: EgNet4
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
-PrivKey: sn0BUwyNxfmgePYi6O6a8pFDKiLaCz6jk3ws+covRTA=
+PrivKey: ai9XXdezwamYHf7EvzmLGlMp7mUg+hZwoqLefzwHWVM=
ListenPort: 3004
LogLevel:
LogLevel: error
LogTransit: true
- LogControl: true
LogNormal: true
+ LogControl: true
LogInternal: true
LogNTP: true
DynamicRoute:
@@ -100,20 +100,20 @@ NextHopTable:
ResetConnInterval: 86400
Peers:
- NodeID: 2
- PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
- PSKey: zkG1ywPqS4MiGofuWmxHHBs8YBlnYd04B4T9IhkbXYM=
+ PubKey: 0r2o9Hb36gYVgD3VSKCH18MVOZw0BvzcJ6TOTo6Cc1g=
+ PSKey: QHyrrls0KT2dvBKtoWkZvq5NQ+Xyjm0YgbMUzCCRw34=
EndPoint: 127.0.0.1:3002
PersistentKeepalive: 0
Static: true
- NodeID: 3
- PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
- PSKey: 8HN+PBGDKmBFCDlWIyNUFFYS4X6ONGXI32AIKXSnUqU=
+ PubKey: ymNpm430tiph3rMSVnQzDAxmK9+3jdcRFi6e96xmQUI=
+ PSKey: SQyLomXDeknBIFezUKardOviAmNS+YZ1XTvZtYVlOtE=
EndPoint: 127.0.0.1:3003
PersistentKeepalive: 0
Static: true
- NodeID: 6
- PubKey: GH6ra6xhDezskkJrr/DXPi93vtmhi96DFBJ3s8U20EA=
- PSKey: f50pI53AQ6RoTGEnTSjl5YJhuMS/xiJjwtPuiP0xMUM=
+ PubKey: f6kHXq3qPLocdM0CZEkoumOHevrabzqOBFG5vg9cjDc=
+ PSKey: crsb9pbTY/Bei7TugjPNtg4dVKVzjwC/A6AjlSVoqbQ=
EndPoint: 127.0.0.1:3006
- PersistentKeepalive: 30
+ PersistentKeepalive: 0
Static: true
diff --git a/example_config/static_mode/n5.yaml b/example_config/static_mode/EgNet_edge5.yaml
similarity index 87%
rename from example_config/static_mode/n5.yaml
rename to example_config/static_mode/EgNet_edge5.yaml
index 55fa33f..4dfd665 100644
--- a/example_config/static_mode/n5.yaml
+++ b/example_config/static_mode/EgNet_edge5.yaml
@@ -3,7 +3,7 @@ Interface:
Name: tap1
VPPIFaceID: 1
VPPBridgeID: 4242
- MacAddrPrefix: 8E:AA:C8:4B
+ MacAddrPrefix: DA:21:10:81
IPv4CIDR: 192.168.76.0/24
IPv6CIDR: fd95:71cb:a3df:e586::/64
IPv6LLPrefix: fe80::a3df:0/112
@@ -12,17 +12,17 @@ Interface:
SendAddr: 127.0.0.1:5001
L2HeaderMode: kbdbg
NodeID: 5
-NodeName: Node5
+NodeName: EgNet5
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
-PrivKey: Blk9f1+NiC2fVCZpUBG34G9hrcLThemk/1Zd/dET6AA=
+PrivKey: hBNK6Wu/Cl2MOXVA/F8yZsqIQ5eeIYCKPJeLu7i/190=
ListenPort: 3005
LogLevel:
LogLevel: error
LogTransit: true
- LogControl: true
LogNormal: true
+ LogControl: true
LogInternal: true
LogNTP: true
DynamicRoute:
@@ -100,8 +100,8 @@ NextHopTable:
ResetConnInterval: 86400
Peers:
- NodeID: 3
- PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
- PSKey: +TU8Zi8dr/UBqNyW/MYMgJiqkLnRbHW4ExQYQ2eNEag=
+ PubKey: ymNpm430tiph3rMSVnQzDAxmK9+3jdcRFi6e96xmQUI=
+ PSKey: ChWBQurfGNZE5xIlhi9EUvZrQPBvkFsfrPaD6tyqSYg=
EndPoint: 127.0.0.1:3003
- PersistentKeepalive: 30
+ PersistentKeepalive: 0
Static: true
diff --git a/example_config/static_mode/n6.yaml b/example_config/static_mode/EgNet_edge6.yaml
similarity index 87%
rename from example_config/static_mode/n6.yaml
rename to example_config/static_mode/EgNet_edge6.yaml
index 46c8184..794cf15 100644
--- a/example_config/static_mode/n6.yaml
+++ b/example_config/static_mode/EgNet_edge6.yaml
@@ -3,7 +3,7 @@ Interface:
Name: tap1
VPPIFaceID: 1
VPPBridgeID: 4242
- MacAddrPrefix: 8E:AA:C8:4B
+ MacAddrPrefix: DA:21:10:81
IPv4CIDR: 192.168.76.0/24
IPv6CIDR: fd95:71cb:a3df:e586::/64
IPv6LLPrefix: fe80::a3df:0/112
@@ -12,17 +12,17 @@ Interface:
SendAddr: 127.0.0.1:5001
L2HeaderMode: kbdbg
NodeID: 6
-NodeName: Node6
+NodeName: EgNet6
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
-PrivKey: h03OJ1d8cVGF8TemiWWTla7RCIMtInhUnjs2CBb8AT8=
+PrivKey: ao6wfUYOG3FBYYPlb+VtXk2ZiK6j/6ac75Y9VuKd2Vs=
ListenPort: 3006
LogLevel:
LogLevel: error
LogTransit: true
- LogControl: true
LogNormal: true
+ LogControl: true
LogInternal: true
LogNTP: true
DynamicRoute:
@@ -100,8 +100,8 @@ NextHopTable:
ResetConnInterval: 86400
Peers:
- NodeID: 4
- PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
- PSKey: f50pI53AQ6RoTGEnTSjl5YJhuMS/xiJjwtPuiP0xMUM=
+ PubKey: 9YSIkihv/+aeukOaWwsR9EKvO1DM9+5kN53a/osTpmA=
+ PSKey: crsb9pbTY/Bei7TugjPNtg4dVKVzjwC/A6AjlSVoqbQ=
EndPoint: 127.0.0.1:3004
- PersistentKeepalive: 30
+ PersistentKeepalive: 0
Static: true
diff --git a/example_config/static_mode/README_zh.md b/example_config/static_mode/README_zh.md
index ac56c26..647be8f 100644
--- a/example_config/static_mode/README_zh.md
+++ b/example_config/static_mode/README_zh.md
@@ -1,84 +1,105 @@
# Etherguard
-[English](README.md)
-
-Static Mode的[範例配置檔](./)的說明文件
+[English](README.md) | [中文](#)
## Static Mode
沒有自動選路,沒有握手伺服器
+類似原本的wireguard,一切都要提前配置好
+設定檔裡面的`NextHopTable`部分,只有此模式會生效
-十分類似原本的wireguard,一切都要提前配置好
-
-但是除了peer以外,還要額外配置轉發表,所有人共用一份轉發表
-
-設定檔裡面的`nexthoptable`部分,只有此模式會生效
-
-這個模式下,不存在任何的Control Message,斷線偵測甚麼的也不會有
+這個模式下,不存在任何的Control Message,斷線偵測什麼的也不會有
請務必保持提前定義好的拓樸。不然如果存在中轉,中轉節點斷了,部分連線就會中斷
+## Quick Start
+首先,按照需求修改`genstatic.yaml`
+
+```yaml
+Config output dir: /tmp/eg_gen_static # 設定檔輸出位置
+ConfigTemplate for edge node: "" # 設定檔Template
+Network name: "EgNet"
+Edge Node:
+ MacAddress prefix: "" # 留空隨機產生
+ IPv4 range: 192.168.76.0/24 # 順帶一提,IP的部分可以直接省略沒關係
+ IPv6 range: fd95:71cb:a3df:e586::/64 # 這個欄位唯一的目的只是在啟動以後,調用ip命令,幫tap接口加個ip
+ IPv6 LL range: fe80::a3df:0/112 # 和VPN本身運作完全無關
+Edge Nodes: # 所有的節點相關設定
+ 1:
+ Endpoint(optional): 127.0.0.1:3001
+ 2:
+ Endpoint(optional): 127.0.0.1:3002
+ 3:
+ Endpoint(optional): 127.0.0.1:3003
+ 4:
+ Endpoint(optional): 127.0.0.1:3004
+ 5:
+ Endpoint(optional): 127.0.0.1:3005
+ 6:
+ Endpoint(optional): 127.0.0.1:3006
+Distance matrix for all nodes: |- # 左邊是起點,上面是終點,Inf代表此二節點不相連 ,數值代表相連。數值大小代表通過成本(通常是延遲)
+ X 1 2 3 4 5 6
+ 1 0 1.0 Inf Inf Inf Inf
+ 2 1.0 0 1.0 1.0 Inf Inf
+ 3 Inf 1.0 0 1 1.0 Inf
+ 4 Inf 1.0 1.0 0 Inf 1.0
+ 5 Inf Inf 1.0 Inf 1.0 Inf
+ 6 Inf Inf Inf 1.0 Inf 1.0
+```
+接著執行這個,就會生成所需設定檔了。
+```
+./etherguard-go -mode gencfg -cfgmode static -config example_config/static_mode/genstatic.yaml
+```
+
+把這些設定檔不捨去對應節點,然後再執行
+```
+./etherguard-go -config [設定檔位置] -mode edge
+```
+就可以了
+
+確認運作以後,可以關閉不必要的log增加性能
+
+## Documentation
+
+Static Mode的說明文件
+
這份[範例配置檔](./)的網路拓樸如圖所示
!["Topology"](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/static_mode/Example_static.png)
發出封包時,會設定起始ID=自己的Node ID,終點ID則是看Dst Mac Address。
-如果Dst MacAddr是廣播地址,或是不在自己的對應表裡面,就會設定終點=Boardcast
+如果Dst MacAddr是廣播地址,或是不在自己的對應表裡面,就會設定終點=Broadcast
收到封包的時候,如果`dst==自己ID`,就會收下,不轉給任何人。
同時還會看它的 Src Mac Address 和 Src NodeID ,並加入對應表
這樣下次傳給他就可以直接傳給目標,而不用廣播給全節點了
所以設定檔中的轉發表如下表。格式是yaml的巢狀dictionary
-轉發/發送封包時,直接查詢 `NhTable[起點][終點]=下一跳`
+轉發/發送封包時,直接查詢`NhTable`
就知道下面一個封包要轉給誰了
+NextHopTable 是長這樣的資料結構,`NhTable[起點][終點]=下一跳`
+
```yaml
-nexthoptable:
+NextHopTable:
1:
2: 2
3: 2
- 4: 2
- 5: 2
- 6: 2
2:
1: 1
3: 3
- 4: 4
- 5: 3
- 6: 4
+
3:
1: 2
2: 2
- 4: 4
- 5: 5
- 6: 4
- 4:
- 1: 2
- 2: 2
- 3: 3
- 5: 3
- 6: 6
- 5:
- 1: 3
- 2: 3
- 3: 3
- 4: 3
- 6: 3
- 6:
- 1: 4
- 2: 4
- 3: 4
- 4: 4
- 5: 4
```
-### Boardcast
-比較特別的是`終點ID=Boardcast`的情況。
+### Broadcast
+比較特別的是`終點ID=Broadcast`的情況。
-假設今天的狀況:我是4號,我收到`起點ID = 1,終點ID=boardcast`的封包
+假設今天的狀況:我是4號,我收到`起點ID = 1,終點ID=Broadcast`的封包
我應該只轉給6號就好,而不會轉給3號。
因為3號會收到來自2號的封包,自己就不用重複遞送了
-因此我有設計,如果`終點ID = Boardcast`,就會檢查Src到自己的所有鄰居,會不會經過自己
+因此我有設計,如果`終點ID = Broadcast`,就會檢查Src到自己的所有鄰居,會不會經過自己
**1 -> 6** 會經過自己: [1 2 4 6]
**1 -> 3** 不會: [1 2 3]
2號是封包來源跳過檢查
@@ -94,189 +115,97 @@ nexthoptable:
```
X 1 2 3 4 5 6
-1 0 0.5 Inf Inf Inf Inf
-2 0.5 0 0.5 0.5 Inf Inf
-3 Inf 0.5 0 0.5 0.5 Inf
-4 Inf 0.5 0.5 0 Inf 0.5
-5 Inf Inf 0.5 Inf 0 Inf
-6 Inf Inf Inf 0.5 Inf 0
+1 0 1.0 Inf Inf Inf Inf
+2 1.0 0 1.0 1.0 Inf Inf
+3 Inf 1.0 0 1 1.0 Inf
+4 Inf 1.0 1.0 0 Inf 1.0
+5 Inf Inf 1.0 Inf 1.0 Inf
+6 Inf Inf Inf 1.0 Inf 1.0
```
之後用這個指令就能輸出用Floyd Warshall算好的轉發表了,填入設定檔即可
-```
-./etherguard-go -config example_config/static_mode/path.txt -mode slove
-NextHopTable:
- 1:
- 2: 2
- 3: 2
- 4: 2
- 5: 2
- 6: 2
- 2:
- 1: 1
- 3: 3
- 4: 4
- 5: 3
- 6: 4
- 3:
- 1: 2
- 2: 2
- 4: 4
- 5: 5
- 6: 4
- 4:
- 1: 2
- 2: 2
- 3: 3
- 5: 3
- 6: 6
- 5:
- 1: 3
- 2: 3
- 3: 3
- 4: 3
- 6: 3
- 6:
- 1: 4
- 2: 4
- 3: 4
- 4: 4
- 5: 4
-```
+### EdgeNode Config Parameter
-程式還會額外輸出一些資訊,像是路徑表。
-會標示所有的起點終點組合的封包路徑,還有行經距離
-```
-Human readable:
-src dist path
-1 -> 2 0.500000 [1 2]
-1 -> 3 1.000000 [1 2 3]
-1 -> 4 1.000000 [1 2 4]
-1 -> 5 1.500000 [1 2 3 5]
-1 -> 6 1.500000 [1 2 4 6]
-2 -> 1 0.500000 [2 1]
-2 -> 3 0.500000 [2 3]
-2 -> 4 0.500000 [2 4]
-2 -> 5 1.000000 [2 3 5]
-2 -> 6 1.000000 [2 4 6]
-3 -> 1 1.000000 [3 2 1]
-3 -> 2 0.500000 [3 2]
-3 -> 4 0.500000 [3 4]
-3 -> 5 0.500000 [3 5]
-3 -> 6 1.000000 [3 4 6]
-4 -> 1 1.000000 [4 2 1]
-4 -> 2 0.500000 [4 2]
-4 -> 3 0.500000 [4 3]
-4 -> 5 1.000000 [4 3 5]
-4 -> 6 0.500000 [4 6]
-5 -> 1 1.500000 [5 3 2 1]
-5 -> 2 1.000000 [5 3 2]
-5 -> 3 0.500000 [5 3]
-5 -> 4 1.000000 [5 3 4]
-5 -> 6 1.500000 [5 3 4 6]
-6 -> 1 1.500000 [6 4 2 1]
-6 -> 2 1.000000 [6 4 2]
-6 -> 3 1.000000 [6 4 3]
-6 -> 4 0.500000 [6 4]
-6 -> 5 1.500000 [6 4 3 5]
-```
+Key | Description
+-------------- |:-----
+[Interface](#Interface)| 接口相關設定。VPN有兩端,一端是VPN網路,另一端則是本地接口
+NodeID | 節點ID。節點之間辨識身分用的,同一網路內節點ID不能重複
+NodeName | 節點名稱
+PostScript | 初始化完畢之後要跑的腳本
+DefaultTTL | TTL,etherguard層使用,和乙太層不共通
+L2FIBTimeout | MacAddr-> NodeID 查找表的 timeout(秒) ,類似ARP table
+PrivKey | 私鑰,和wireguard規格一樣
+ListenPort | 監聽的udp埠
+[LogLevel](#LogLevel)| 紀錄log
+[DynamicRoute](../super_mode/README_zh.md#DynamicRoute) | 動態路由相關設定,Static模式用不到
+NextHopTable | 轉發表, 下一跳 = `NhTable[起點][終點]`
+ResetConnInterval | 如果對方是動態ip就要用這個。每隔一段時間就會重置連線,重新解析域名
+[Peers](#Peers) | 鄰居節點,和wireguard相同
-有些設定檔對應某些運作模式,這邊針對共同部分的設定做說明
+Interface | Description
+---------------|:-----
+[IType](#IType)| 接口類型,意味著從VPN網路收到的封包要丟去哪邊
+Name | 裝置名稱
+VPPIFaceID | VPP 的 interface ID。同一個VPP runtime內不能重複
+VPPBridgeID | VPP 的網橋ID。不使用VPP網橋功能的話填0
+MacAddrPrefix | MAC地址前綴。真正的 MAC 地址=[前綴]:[NodeID]
+IPv4CIDR | 啟動以後,調用ip命令,幫tap接口加個ip。僅限tap有效
+IPv4CIDR | 啟動以後,調用ip命令,幫tap接口加個ip。僅限tap有效
+IPv6LLPrefix | 啟動以後,調用ip命令,幫tap接口加個ip。僅限tap有效
+MTU | 裝置MTU,僅限`tap` , `vpp` 模式有效
+RecvAddr | listen地址,收到的東西丟去 VPN 網路。僅限`*sock`生效
+SendAddr | 連線地址,VPN網路收到的東西丟去這個地址。僅限`*sock`生效
+[L2HeaderMode](#L2HeaderMode) | 僅限 `stdio` 生效。debug用途,有三種模式
-### Edge config
+IType | Description
+-----------|:-----
+dummy | 收到的封包直接丟棄,但幫忙轉發。作為中繼節點,本身不加入網路使用
+stdio | 收到的封包丟stdout,stdin進來的資料丟入vpn網路,debug用途
需要參數: `MacAddrPrefix` && `L2HeaderMode`
+udpsock | 收到的封包丟去一個udp socket
需要參數: `RecvAddr` && `SendAddr`
+tcpsock | 收到的封包丟去一個tcp socket
需要參數: `RecvAddr` \|\| `SendAddr`
+unixsock | 收到的封包丟去一個unix socket(SOCK_STREAM 模式)
需要參數: `RecvAddr` \|\| `SendAddr`
+udpsock | 收到的封包丟去一個unix socket(SOCK_DGRAM 模式)
需要參數: `RecvAddr` \|\| `SendAddr`
+udpsock | 收到的封包丟去一個unix socket(SOCK_SEQPACKET 模式)
需要參數: `RecvAddr` \|\| `SendAddr`
+fd | 收到的封包丟去一個特定的file descriptor
需要參數: 無. 但是使用環境變數 `EG_FD_RX` && `EG_FD_TX` 來指定
+vpp | 使用libmemif使vpp加入VPN網路
需要參數: `Name` && `VPPIFaceID` && `VPPBridgeID` && `MacAddrPrefix` && `MTU`
+tap | Linux的tap設備。讓linux加入VPN網路
需要參數: `Name` && `MacAddrPrefix` && `MTU`
可選參數:`IPv4CIDR` , `IPv6CIDR` , `IPv6LLPrefix`
-1. `interface`
- 1. `itype`: 裝置類型,意味著從VPN網路收到的封包要丟去哪個硬體
- 1. `dummy`: 收到的封包直接丟棄,也不發出任何封包。作為中繼節點使用
- 2. `stdio`: 收到的封包丟stdout,stdin進來的資料丟入vpn網路
- 需要參數: `macaddrprefix`,`l2headermode`
- 3. `udpsock`: 把VPN網路收到的layer2封包讀寫去一個udp socket.
- Paramaters: `recvaddr`,`sendaddr`
- 3. `tcpsock`: 把VPN網路收到的layer2封包讀寫去一個tcp socket.
- Paramaters: `recvaddr`,`sendaddr`
- 3. `unixsock`: 把VPN網路收到的layer2封包讀寫去一個unix socket(SOCK_STREAM 模式).
- Paramaters: `recvaddr`,`sendaddr`
- 3. `unixgramsock`: 把VPN網路收到的layer2封包讀寫去一個unix socket(SOCK_DGRAM 模式).
- Paramaters: `recvaddr`,`sendaddr`
- 3. `unixpacketsock`: 把VPN網路收到的layer2封包讀寫去一個unix socket(SOCK_SEQPACKET 模式).
- Paramaters: `recvaddr`,`sendaddr`
- 3. `fd`: 把VPN網路收到的layer2封包讀寫去一個特定的file descriptor.
- Paramaters: 無. 但是使用環境變數 `EG_FD_RX` 和 `EG_FD_TX` 來指定
- 4. `vpp`: 使用libmemif使vpp加入VPN網路
- 需要參數: `name`,`vppifaceid`,`vppbridgeid`,`macaddrprefix`,`mtu`
- 5. `tap`: Linux的tap設備。讓linux加入VPN網路
- 需要參數: `name`,`macaddrprefix`,`mtu`
- 2. `name` : 裝置名稱
- 3. `vppifaceid`: VPP 的 interface ID。一個VPP runtime內不能重複
- 4. `vppbridgeid`: VPP 的網橋ID。不使用VPP網橋功能的話填0
- 5. `macaddrprefix`: MAC地址前綴。真正的 MAC 地址=[前綴]:[NodeID]。
- 如果這邊填了完整6格長度,就忽略`NodeID`
- 6. `recvaddr`: 僅限`XXXsock`生效。listen地址,收到的東西丟去 VPN 網路
- 7. `sendaddr`: 僅限`XXXsock`生效。連線地址,VPN網路收到的東西丟去這個地址
- 8. `l2headermode`: 僅限 `stdio` 生效。debug用途,有三種模式:
- 1. `nochg`: 從 VPN 網路收到什麼,就往tap裝置發送什麼。不對封包作任何更動
- 2. `kbdbg`: 鍵盤bebug模式。搭配 `stdio` 模式,讓我 debug 用
- 因為前 12 byte 會用來做選路判斷,但是只是要debug,構造完整的封包就不是很方便
- 這個模式下,如果輸入b2content,就會幫你把b轉換成`FF:FF:FF:FF:FF:FF`, `2` 轉換成 `AA:BB:CC:DD:EE:02` 。封包內容變成 `b"0xffffffffffffaabbccddee02content"`。
- 用鍵盤就能輕鬆產生L2 header,查看選路的行為
- 3. `noL2`: 拔掉L2 Header的模式。
- 但是本VPN會查詢L2用作選路,所以會變成一律廣播
-2. `nodeid`: 節點ID。節點之間辨識身分用的,同一網路內節點ID不能重複
-3. `postscript`: etherguard初始化完畢之後要跑的腳本.
-3. `nodename`: 節點名稱
-4. `defaultttl`: 預設ttl(etherguard層使用,和乙太層不共通)
-5. `l2fibtimeout`: MacAddr-> NodeID 查找表的 timeout(秒)
-5. `privkey`: 私鑰,和wireguard規格一樣
-5. `listenport`: 監聽的udp埠
-6. `loglevel`: 紀錄log
- 1. `loglevel`: wireguard原本的log紀錄器的loglevel。
- 有`debug`,`error`,`slient`三種程度
- 2. `logtransit`: 轉送封包,也就是起點/終點都不是自己的封包的log
- 3. `logcontrol`: Control Message的log
- 4. `lognormal`: 收發普通封包,起點是自己or終點是自己的log
- 5. `logntp`: NTP 同步時鐘相關的log
-7. `dynamicroute`: 動態路由相關的設定。時間類設定單位都是秒
- 1. `sendpinginterval`: 發送Ping訊息的間隔
- 2. `dupchecktimeout`: 重複封包檢查的timeout。完全相同的封包收第二次會被丟棄
- 1. `peeralivetimeout`: 每次收到封包就重置,超過時間沒收到就標記該peer離線
- 3. `conntimeout`: 檢查peer離線的間格,如果標記離線,就切換下一個endpoint(supernode可能傳了多個endpoint過來)
- 4. `savenewpeers`: 是否把下載來的鄰居資訊存到本地設定檔裡面
- 5. `supernode`: 參見[Super模式](example_config/super_mode/README_zh.md)
- 6. `p2p` 參見 [P2P模式](example_config/p2p_mode/README_zh.md)
- 7. `ntpconfig`: NTP 相關的設定
- 1. `usentp`: 是否使用ntp同步時鐘
- 2. `maxserveruse`: 一次對多連線幾個NTP伺服器
- 第一次會全部連一遍測延遲,之後每次都取延遲前n低的來用
- 3. `synctimeinterval`: 多久同步一次
- 4. `ntptimeout`: 多久算是超時
- 5. `servers`: NTP伺服器列表
-8. `nexthoptable`: 轉發表。只有Static模式會用到,參見 [Static模式](example_config/super_mode/README_zh.md)
-9. `resetconninterval`: 如果對方是動態ip就要用這個。每隔一段時間就會重新解析domain。
-10. `peers`: 和wireguard一樣的peer資訊
- 1. `nodeid`: 對方的節點ID
- 2. `pubkey`: 對方的公鑰
- 3. `pskey`: 對方的預共享金鑰。但是目前沒用(因為不能設定自己的),之後會加
- 4. `endpoint`: 對方的連線地址。如果roaming會覆寫設定檔
- 5. `static`: 設定成true的話,每隔`resetconninterval`秒就會重新解析一次domain,與此同時也不會被roaming覆寫
+L2HeaderMode | Description
+---------------|:-----
+nochg | 收到的封包丟stdout,stdin進來的資料丟入vpn網路,不對封包作任何更動
+kbdbg | 前 12byte 會用來做選路判斷
但是stdio模式下,使用鍵盤輸入一個Ethernet frame不太方便
此模式讓我快速產生Ethernet frame,debug更方便
`b`轉換成`FF:FF:FF:FF:FF:FF`
`2`轉換成 `AA:BB:CC:DD:EE:02`
輸入`b2aaaaa`就會變成`b"0xffffffffffffaabbccddee02aaaaa"`
+noL2 | 讀取時拔掉L2 Header的模式
寫入時時一律使用廣播MacAddress
-### Super config
+LogLevel | Description
+------------|:-----
+LogLevel | wireguard原本的log紀錄器的loglevel
接受參數: `debug`,`error`,`slient`
+LogTransit | 轉送封包,也就是起點/終點都不是自己的封包的log
+LogNormal | 收發普通封包,起點是自己or終點是自己的log
+LogControl | Control Message的log
+LogInternal | 一些內部事件的log
+LogNTP | NTP 同步時鐘相關的log
- 參見 [example_config/super_mode/README_zh.md](example_config/super_mode/README_zh.md)
-
-### Quick start
+Peers | Description
+--------------------|:-----
+NodeID | 對方的節點ID
+PubKey | 對方的公鑰
+PSKey | 對方的預共享金鑰
+EndPoint | 對方的連線地址。如果漫遊,而且`Static=false`會覆寫設定檔
+PersistentKeepalive | wireguard的PersistentKeepalive參數
+Static | 關閉漫遊功能,每隔`ResetConnInterval`秒,重置回初始ip
#### Run example config
在**不同terminal**分別執行以下命令
```
-./etherguard-go -config example_config/super_mode/n1.yaml -mode edge
-./etherguard-go -config example_config/super_mode/n2.yaml -mode edge
-./etherguard-go -config example_config/super_mode/n3.yaml -mode edge
-./etherguard-go -config example_config/super_mode/n4.yaml -mode edge
-./etherguard-go -config example_config/super_mode/n5.yaml -mode edge
-./etherguard-go -config example_config/super_mode/n6.yaml -mode edge
+./etherguard-go -config example_config/super_mode/EgNet_edge1.yaml -mode edge
+./etherguard-go -config example_config/super_mode/EgNet_edge2.yaml -mode edge
+./etherguard-go -config example_config/super_mode/EgNet_edge3.yaml -mode edge
+./etherguard-go -config example_config/super_mode/EgNet_edge4.yaml -mode edge
+./etherguard-go -config example_config/super_mode/EgNet_edge5.yaml -mode edge
+./etherguard-go -config example_config/super_mode/EgNet_edge6.yaml -mode edge
```
因為本範例配置是stdio的kbdbg模式,stdin會讀入VPN網路
@@ -284,12 +213,7 @@ src dist path
```
b1message
```
-因為`l2headermode`是`kbdbg`,所以b1會被轉換成 12byte 的layer 2 header,b是廣播地址`FF:FF:FF:FF:FF:FF`,1是普通地址`AA:BB:CC:DD:EE:01`,message是後面的payload,然後再丟入VPN
+因為`L2HeaderMode`是`kbdbg`,所以b1會被轉換成 12byte 的layer 2 header,b是廣播地址`FF:FF:FF:FF:FF:FF`,1是普通地址`AA:BB:CC:DD:EE:01`,message是後面的payload,然後再丟入VPN
此時應該要能夠在另一個視窗上看見字串b1message。前12byte被轉換回來了
-#### Run your own etherguard
-
-要正式使用,請將itype改成`tap`,並且修改各節點的公鑰私鑰和連線地址
-再關閉不必要的log增加性能,最後部屬到不同節點即可
-
## 下一篇: [Super Mode的運作](../super_mode/README_zh.md)
\ No newline at end of file
diff --git a/example_config/static_mode/genstatic.yaml b/example_config/static_mode/genstatic.yaml
index 8aca6ed..fe78c05 100644
--- a/example_config/static_mode/genstatic.yaml
+++ b/example_config/static_mode/genstatic.yaml
@@ -1,6 +1,6 @@
Config output dir: /tmp/eg_gen_static
-ConfigTemplate for edge node: "n1.yaml"
-Network name: "Node"
+ConfigTemplate for edge node: "" # "EgNet_edge1.yaml"
+Network name: "EgNet"
Edge Node:
MacAddress prefix: ""
IPv4 range: 192.168.76.0/24
@@ -9,27 +9,21 @@ Edge Node:
Edge Nodes:
1:
Endpoint(optional): 127.0.0.1:3001
- PersistentKeepalive: 30
2:
Endpoint(optional): 127.0.0.1:3002
- PersistentKeepalive: 30
3:
Endpoint(optional): 127.0.0.1:3003
- PersistentKeepalive: 30
4:
Endpoint(optional): 127.0.0.1:3004
- PersistentKeepalive: 30
5:
Endpoint(optional): 127.0.0.1:3005
- PersistentKeepalive: 30
6:
Endpoint(optional): 127.0.0.1:3006
- PersistentKeepalive: 30
Distance matrix for all nodes: |-
X 1 2 3 4 5 6
- 1 0 1 Inf Inf Inf Inf
- 2 1 0 1 1 Inf Inf
- 3 Inf 1 0 1 1 Inf
- 4 Inf 1 1 0 Inf 1
- 5 Inf Inf 1 Inf 0 Inf
- 6 Inf Inf Inf 1 Inf 0
\ No newline at end of file
+ 1 0 1.0 Inf Inf Inf Inf
+ 2 1.0 0 1.0 1.0 Inf Inf
+ 3 Inf 1.0 0 1 1.0 Inf
+ 4 Inf 1.0 1.0 0 Inf 1.0
+ 5 Inf Inf 1.0 Inf 1.0 Inf
+ 6 Inf Inf Inf 1.0 Inf 1.0
\ No newline at end of file
diff --git a/example_config/super_mode/EGS03.png b/example_config/super_mode/EGS03.png
index 63e742b..00b7c56 100644
Binary files a/example_config/super_mode/EGS03.png and b/example_config/super_mode/EGS03.png differ
diff --git a/example_config/super_mode/EGS08.png b/example_config/super_mode/EGS08.png
new file mode 100644
index 0000000..6b363eb
Binary files /dev/null and b/example_config/super_mode/EGS08.png differ
diff --git a/example_config/super_mode/n1.yaml b/example_config/super_mode/Node_edge001.yaml
similarity index 67%
rename from example_config/super_mode/n1.yaml
rename to example_config/super_mode/Node_edge001.yaml
index 7c9d9f7..c956eba 100644
--- a/example_config/super_mode/n1.yaml
+++ b/example_config/super_mode/Node_edge001.yaml
@@ -1,28 +1,28 @@
Interface:
IType: stdio
- Name: tap1
+ Name: Node001
VPPIFaceID: 1
VPPBridgeID: 4242
- MacAddrPrefix: AA:BB:CC:DD
- IPv4CIDR: ""
- IPv6CIDR: ""
- IPv6LLPrefix: ""
+ MacAddrPrefix: CE:51:BA:B4
+ IPv4CIDR: 192.168.76.0/24
+ IPv6CIDR: fd95:71cb:a3df:e586::/64
+ IPv6LLPrefix: fe80::a3df:0/112
MTU: 1416
RecvAddr: 127.0.0.1:4001
SendAddr: 127.0.0.1:5001
L2HeaderMode: kbdbg
NodeID: 1
-NodeName: Node01
+NodeName: Node001
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
-PrivKey: 6GyDagZKhbm5WNqMiRHhkf43RlbMJ34IieTlIuvfJ1M=
-ListenPort: 0
+PrivKey: C0SXvffZh8nDqXYNzG4UqUJtSCiRMEj3ehX5o7QiJz0=
+ListenPort: 3001
LogLevel:
LogLevel: error
- LogTransit: true
+ LogTransit: false
LogControl: true
- LogNormal: true
+ LogNormal: false
LogInternal: true
LogNTP: true
DynamicRoute:
@@ -35,12 +35,12 @@ DynamicRoute:
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
+ PSKey: j2f9Fhdhw2O2zLqUqfL5nTFStjVWPnEXpw7Iqz6VX9M=
+ EndpointV4: 127.0.0.1:3456
+ PubKeyV4: Id/VoZ6HmTU3FSqhxBUswfuHHB0mQxfzcbdoJNGBRzQ=
+ EndpointV6: :3456
+ PubKeyV6: 40tADRhJTvaortwE5Ur4qNXhP+SOMX7ZuSvl251Yxnc=
+ EndpointEdgeAPIUrl: http://127.0.0.1:3456/eg_net/eg_api
SkipLocalIP: false
SuperNodeInfoTimeout: 50
P2P:
@@ -48,8 +48,10 @@ DynamicRoute:
SendPeerInterval: 20
GraphRecalculateSetting:
StaticMode: false
- JitterTolerance: 20
+ ManualLatency: {}
+ JitterTolerance: 50
JitterToleranceMultiplier: 1.1
+ DampingResistance: 0
TimeoutCheckInterval: 5
RecalculateCoolDown: 5
NTPConfig:
@@ -80,4 +82,4 @@ DynamicRoute:
- 3.pool.ntp.org
NextHopTable: {}
ResetConnInterval: 86400
-Peers: []
\ No newline at end of file
+Peers: []
diff --git a/example_config/super_mode/n2.yaml b/example_config/super_mode/Node_edge002.yaml
similarity index 66%
rename from example_config/super_mode/n2.yaml
rename to example_config/super_mode/Node_edge002.yaml
index d713b2a..98d34e7 100644
--- a/example_config/super_mode/n2.yaml
+++ b/example_config/super_mode/Node_edge002.yaml
@@ -1,28 +1,28 @@
Interface:
IType: stdio
- Name: tap1
- VPPIFaceID: 2
+ Name: Node002
+ VPPIFaceID: 1
VPPBridgeID: 4242
- MacAddrPrefix: AA:BB:CC:DD
- IPv4CIDR: ""
- IPv6CIDR: ""
- IPv6LLPrefix: ""
+ MacAddrPrefix: CE:51:BA:B4
+ IPv4CIDR: 192.168.76.0/24
+ IPv6CIDR: fd95:71cb:a3df:e586::/64
+ IPv6LLPrefix: fe80::a3df:0/112
MTU: 1416
RecvAddr: 127.0.0.1:4002
SendAddr: 127.0.0.1:5002
L2HeaderMode: kbdbg
NodeID: 2
-NodeName: Node02
+NodeName: Node002
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
-PrivKey: OH8BsVUU2Rqzeu9B2J5GPG8PUmxWfX8uVvNFZKhVF3o=
-ListenPort: 0
+PrivKey: AErxhLXdZvidPZVXRYgD+84fa2qYWG9ft4MRuCbAtt8=
+ListenPort: 3002
LogLevel:
LogLevel: error
- LogTransit: true
+ LogTransit: false
LogControl: true
- LogNormal: true
+ LogNormal: false
LogInternal: true
LogNTP: true
DynamicRoute:
@@ -35,12 +35,12 @@ DynamicRoute:
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
+ PSKey: iCw096jsW2aWyMwPyzVEvL8C3XXqMpB+jOeWqDC34uU=
+ EndpointV4: 127.0.0.1:3456
+ PubKeyV4: Id/VoZ6HmTU3FSqhxBUswfuHHB0mQxfzcbdoJNGBRzQ=
+ EndpointV6: :3456
+ PubKeyV6: 40tADRhJTvaortwE5Ur4qNXhP+SOMX7ZuSvl251Yxnc=
+ EndpointEdgeAPIUrl: http://127.0.0.1:3456/eg_net/eg_api
SkipLocalIP: false
SuperNodeInfoTimeout: 50
P2P:
@@ -48,8 +48,10 @@ DynamicRoute:
SendPeerInterval: 20
GraphRecalculateSetting:
StaticMode: false
- JitterTolerance: 20
+ ManualLatency: {}
+ JitterTolerance: 50
JitterToleranceMultiplier: 1.1
+ DampingResistance: 0
TimeoutCheckInterval: 5
RecalculateCoolDown: 5
NTPConfig:
@@ -80,4 +82,4 @@ DynamicRoute:
- 3.pool.ntp.org
NextHopTable: {}
ResetConnInterval: 86400
-Peers: []
\ No newline at end of file
+Peers: []
diff --git a/example_config/super_mode/n100.yaml b/example_config/super_mode/Node_edge100.yaml
similarity index 67%
rename from example_config/super_mode/n100.yaml
rename to example_config/super_mode/Node_edge100.yaml
index 3e2f94e..6faa2e5 100644
--- a/example_config/super_mode/n100.yaml
+++ b/example_config/super_mode/Node_edge100.yaml
@@ -1,12 +1,12 @@
Interface:
IType: stdio
- Name: tap1
- VPPIFaceID: 100
+ Name: Node100
+ VPPIFaceID: 1
VPPBridgeID: 4242
- MacAddrPrefix: AA:BB:CC:DD
- IPv4CIDR: ""
- IPv6CIDR: ""
- IPv6LLPrefix: ""
+ MacAddrPrefix: CE:51:BA:B4
+ IPv4CIDR: 192.168.76.0/24
+ IPv6CIDR: fd95:71cb:a3df:e586::/64
+ IPv6LLPrefix: fe80::a3df:0/112
MTU: 1416
RecvAddr: 127.0.0.1:4100
SendAddr: 127.0.0.1:5100
@@ -16,13 +16,13 @@ NodeName: Node100
PostScript: ""
DefaultTTL: 200
L2FIBTimeout: 3600
-PrivKey: IJtpnkm9ytbuCukx4VBMENJKuLngo9KSsS1D60BqonQ=
-ListenPort: 0
+PrivKey: a04BVvT+YbrX1ejjvMQVI6k5VRFlBkEX8tuLGWNyNrY=
+ListenPort: 3100
LogLevel:
LogLevel: error
- LogTransit: true
+ LogTransit: false
LogControl: true
- LogNormal: true
+ LogNormal: false
LogInternal: true
LogNTP: true
DynamicRoute:
@@ -35,12 +35,12 @@ DynamicRoute:
SaveNewPeers: true
SuperNode:
UseSuperNode: true
- PSKey: j9dS/lYvL16svSeC5lh+ldlq2iZX2MWwZfM3NNWpULI=
- EndpointV4: 127.0.0.1:3000
- PubKeyV4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
- EndpointV6: '[::1]:3000'
- PubKeyV6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
- EndpointEdgeAPIUrl: http://127.0.0.1:3000/eg_api
+ PSKey: Gfp2RkPNrKTeGKrCJNEvSyiBqYYRmzVnVG6CBuUKUNc=
+ EndpointV4: 127.0.0.1:3456
+ PubKeyV4: Id/VoZ6HmTU3FSqhxBUswfuHHB0mQxfzcbdoJNGBRzQ=
+ EndpointV6: :3456
+ PubKeyV6: 40tADRhJTvaortwE5Ur4qNXhP+SOMX7ZuSvl251Yxnc=
+ EndpointEdgeAPIUrl: http://127.0.0.1:3456/eg_net/eg_api
SkipLocalIP: false
SuperNodeInfoTimeout: 50
P2P:
@@ -48,8 +48,10 @@ DynamicRoute:
SendPeerInterval: 20
GraphRecalculateSetting:
StaticMode: false
- JitterTolerance: 20
+ ManualLatency: {}
+ JitterTolerance: 50
JitterToleranceMultiplier: 1.1
+ DampingResistance: 0
TimeoutCheckInterval: 5
RecalculateCoolDown: 5
NTPConfig:
@@ -80,4 +82,4 @@ DynamicRoute:
- 3.pool.ntp.org
NextHopTable: {}
ResetConnInterval: 86400
-Peers: []
\ No newline at end of file
+Peers: []
diff --git a/example_config/super_mode/Node_super.yaml b/example_config/super_mode/Node_super.yaml
new file mode 100644
index 0000000..607488f
--- /dev/null
+++ b/example_config/super_mode/Node_super.yaml
@@ -0,0 +1,55 @@
+NodeName: NodeSP
+PostScript: ""
+PrivKeyV4: 2P0mV5RkpFFyg+aLPK841sml5RobQGrxAV5ld4En9Kk=
+PrivKeyV6: 9JrdnAk1ljXUTn9VFb1uFyey20tQEQuzJJtVueM4vsw=
+ListenPort: 3456
+ListenPort_EdgeAPI: "3456"
+ListenPort_ManageAPI: "3456"
+API_Prefix: /eg_net/eg_api
+RePushConfigInterval: 30
+HttpPostInterval: 50
+PeerAliveTimeout: 70
+SendPingInterval: 15
+LogLevel:
+ LogLevel: normal
+ LogTransit: false
+ LogNormal: false
+ LogControl: true
+ LogInternal: true
+ LogNTP: true
+Passwords:
+ ShowState: passwd_showstate
+ AddPeer: passwd_addpeer
+ DelPeer: passwd_delpeer
+ UpdatePeer: passwd_updatepeer
+ UpdateSuper: passwd_updatesuper
+GraphRecalculateSetting:
+ StaticMode: false
+ ManualLatency: {}
+ JitterTolerance: 30
+ JitterToleranceMultiplier: 1.01
+ DampingResistance: 0.9
+ TimeoutCheckInterval: 5
+ RecalculateCoolDown: 5
+NextHopTable: {}
+EdgeTemplate: ""
+UsePSKForInterEdge: true
+Peers:
+- NodeID: 1
+ Name: Node001
+ PubKey: awnuKYQOgCywkJbHAynqMzKi5QEGsG0w4iBy2Ja1MDQ=
+ PSKey: j2f9Fhdhw2O2zLqUqfL5nTFStjVWPnEXpw7Iqz6VX9M=
+ AdditionalCost: 10
+ SkipLocalIP: false
+- NodeID: 2
+ Name: Node002
+ PubKey: WUyblc/DZzPNU5sOQQS2lS0aP53zFEVNjqCHjkhkdzE=
+ PSKey: iCw096jsW2aWyMwPyzVEvL8C3XXqMpB+jOeWqDC34uU=
+ AdditionalCost: 10
+ SkipLocalIP: false
+- NodeID: 100
+ Name: Node_100
+ PubKey: Bax6wOJpisSVJtrU92ujn8D/2oGUyhyPrKTXkHbGamM=
+ PSKey: Gfp2RkPNrKTeGKrCJNEvSyiBqYYRmzVnVG6CBuUKUNc=
+ AdditionalCost: 1000
+ SkipLocalIP: false
diff --git a/example_config/super_mode/README_zh.md b/example_config/super_mode/README_zh.md
index e813824..41225b2 100644
--- a/example_config/super_mode/README_zh.md
+++ b/example_config/super_mode/README_zh.md
@@ -1,42 +1,81 @@
# Etherguard
-[English](README.md)
-
-Super Mode的[範例配置檔](./)的說明文件
-在了解Super Mode的運作之前,建議您先閱讀[Static Mode的運作](../static_mode/README_zh.md)方法,再閱讀本篇會比較好
+[English](README.md) | [中文](#)
## Super Mode
Super Mode是受到[n2n](https://github.com/ntop/n2n)的啟發
-分為super node和edge node兩種節點
+分為SuperNode和EdgeNode兩種節點
-全部節點都會和supernode建立連線
-藉由supernode交換其他節點的資訊,以及udp打洞
-由supernode執行[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法),並把計算結果分發給全部edge node
+全部節點都會和SuperNode建立連線
+藉由SuperNode交換其他節點的資訊,以及udp打洞
+由SuperNode執行[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法),並把計算結果分發給全部edge node
-在edge node的super模式下,設定檔裡面的`nexthoptable`以及`peers`是無效的。
-這些資訊都是從super node上面下載
-同時,supernode會幫每個連線生成Preshared Key,分發給edge使用(如果`usepskforinteredge`有啟用的話)。
-```golang
-psk = shs256("PubkeyPeerA" + "PubkeyPeerB" + "主廚特調當季精選海鹽")[:32]
+
+## Quick start
+
+首先按需求修改`gensuper.yaml`
+
+```yaml
+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~10,11,19,23,29,31,55~66,88~99]"
+ MacAddress prefix: "" # 留空隨機產生
+ IPv4 range: 192.168.76.0/24 # IP的部分可以直接省略沒關係
+ IPv6 range: fd95:71cb:a3df:e586::/64 # 這個欄位唯一的目的只是在啟動以後,調用ip命令,幫tap接口加個ip
+ IPv6 LL range: fe80::a3df:0/112 # 和VPN本身運作完全無關
+```
+接著執行這個,就會生成所需設定檔了。
+```
+$ ./etherguard-go -mode gencfg -cfgmode super -config example_config/super_mode/gensuper.yaml
```
+把一個super,2個edge分別搬去三台機器
+或是2台機器,super和edge可以是同一台
+
+在Supernode執行
+```
+./etherguard-go -config [設定檔位置] -mode super
+```
+在EdgeNode執行
+```
+./etherguard-go -config [設定檔位置] -mode edge
+```
+
+## Documentation
+
+在了解Super Mode的運作之前,建議您先閱讀[Static Mode的運作](../static_mode/README_zh.md)方法,再閱讀本篇會比較好
+
+
+在EdgeNode的SuperMode下,設定檔裡面的`NextHopTable`以及`Peers`是無效的。
+這些資訊都是從SuperNode上面下載
+同時,SuperNode會幫每個連線生成pre-shared key,分發給edge使用(如果啟用`UsePSKForInterEdge`的話)。
+
### SuperMsg
-但是比起Static mode,Super mode引入了一種新的 `終點ID` 叫做 `SuperMsg`。
-所有送往Super node的封包都會是這種類型。
-這種封包不會在edge node之間傳播,收到也會不會轉給任何人,如同`終點ID == 自己`一般
+但是比起StaticMode,SuperMode引入了一種新的 `終點ID` 叫做 `NodeID_SuperNode`。
+所有送往SuperNode的封包都會是這種類型。
+這種封包不會在EdgeNode之間傳播,收到也會不會轉給任何人,如同`終點ID == 自己`一般
## Control Message
-從Super mode開始,我們有了Static mode不存在的Control Message。他會控制EtherGuard一些行為
-在Super mode下,我們不會轉發任何控制消息。 我們只會直接接收或發送給目標。
+從SuperMode開始,我們有了StaticMode不存在的Control Message。他會控制EtherGuard一些行為
+在SuperMode下,我們不會轉發任何控制消息。 我們只會直接接收或發送給目標。
下面列出Super Mode會出現的Control message
### Register
具體運作方式類似這張圖
![Register運作流程](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS01.png)
-1. edge node發送`Register`給super node
-2. super node收到以後就知道這個edge的endpoint IP和埠號。
+1. EdgeNode發送`Register`給sSuperNode
+2. SuperNode收到以後就知道這個EdgeNode的Endpoint IP和Port number。
3. 更新進資料庫以後發布`UpdatePeerMsg`。
-4. 其他edge node收到以後就用HTTP API去下載完整的peer list。並且把自己沒有的peer通通加到本地
+4. 其他edge node收到以後就用HTTP EdgeAPI去下載完整的peer list。並且把自己沒有的peer通通加到本地
### Ping/Pong
有了peer list以後,接下來的運作方式類似這張圖
@@ -46,18 +85,58 @@ Edge node 會嘗試向其他所有peer發送`Ping`,裡面會攜帶節點自己
收到`Ping`,就會產生一個`Pong`,並攜帶時間差。這個時間就是單向延遲
但是他不會把`Pong`送回給原節點,而是送給Super node
+### AdditionalCost
+有了各個節點的延遲以後,還不會立刻計算`Floyd-Warshall`,而是要先加上`AdditionalCost`
+
+以這張圖片的情境為例:
+![EGS08](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS08.png)
+Path | Latency |Cost|Win
+--------|:--------|:---|:--
+A->B->C | 3ms | 3 |
+A->C | 4ms | 4 | O
+
+但是這個情境,3ms 4ms 只相差1ms
+為了這1ms而多繞一趟實在浪費,而且轉發本身也要時間
+
+每個節點有了`AdditionalCost`參數,就能設定經過這個節點轉發,所需額外增加的成本
+
+假如ABC全部設定了`AdditionalCost=10`
+Path | Latency |AdditionalCost|Cost|Win
+--------|:--------|:-------------|:---|:--
+A->B->C | 3ms | 20 | 23 |
+A->C | 4ms | 10 | 14 | O
+
+A->C 就換選擇直連,不會為了省下1ms而繞路
+這邊`AdditionalCost=10`可以解釋為: 必須能省下10ms,才會繞這條路
+
+這個參數也有別的用途
+針對流量比較貴的節點,可以設定`AdditionalCost=10000`
+別人就不會走他中轉了,而是盡量繞別的路,或是直連
+除非別條路線全掛,只剩這挑Cost 10000的路線
+
+還有一個用法,全部節點都設定`AdditionalCost=10000`
+無視延遲,全節點都盡量直連,打動失敗才繞路
+
### UpdateNhTable
Super node收到節點們傳來的Pong以後,就知道他們的單向延遲了。接下來的運作方式類似這張圖
![image](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS03.png)
Super node收到Pong以後,就會更新它裡面的`Distance matrix`,並且重新計算轉發表
如果有變動,就發布`UpdateNhTableMsg`
-其他edge node收到以後就用HTTP API去下載完整的轉發表
+其他edge node收到以後就用HTTP EdgeAPI去下載完整的轉發表
-### UpdateError
-通知edges有錯誤發生,關閉egde端程式
-發生在版本號不匹被,該edge的NodeID配置錯誤,還有該Edge被刪除時觸發
+### ServerUpdate
+通知EdgeNode有事情發生
+1. 關閉EdgeNode程式
+ * 版本號不匹配
+ * 該edge的NodeID配置錯誤
+ * 該Edge被刪除
+2. 通知EdgeNode有更新
+ * UpdateNhTable
+ * UpdatePeer
+ * UpdateSuperParams
-### HTTP API
+
+## HTTP EdgeAPI
為什麼要用HTTP額外下載呢?直接`UpdateXXX`夾帶資訊不好嗎?
因為udp是不可靠協議,能攜帶的內容量也有上限。
但是peer list包含了全部的peer資訊,長度不是固定的,可能超過
@@ -68,12 +147,15 @@ Super node收到Pong以後,就會更新它裡面的`Distance matrix`,並且
這樣super node收到HTTP API看到`state hash`就知道這個edge node確實有收到`UpdateXXX`了。
不然每隔一段時間就會重新發送`UpdateXXX`給該節點
+預設配置是走HTTP。但為**了你的安全著想,建議使用nginx反代理成https**
+有想過SuperNode開發成直接支援https,但是證書動態更新太麻煩就沒有做了
+
## HTTP Manage API
-HTTP還有一些個API,給前端使用,幫助管理整個網路
+HTTP還有5個Manage API,給前端使用,幫助管理整個網路
### super/state
```bash
-curl "http://127.0.0.1:3000/eg_api/manage/super/state?Password=passwd_showstate"
+curl "http://127.0.0.1:3456/eg_net/eg_api/manage/super/state?Password=passwd_showstate"
```
可以給前端看的,用來顯示現在各節點之間的單向延遲狀況
之後可以用來畫力導向圖。
@@ -145,10 +227,10 @@ curl "http://127.0.0.1:3000/eg_api/manage/super/state?Password=passwd_showstate"
再來是新增peer,可以不用重啟Supernode就新增Peer
範例:
-```
-curl -X POST "http://127.0.0.1:3000/eg_api/manage/peer/add?Password=passwd_addpeer" \
+```bash
+curl -X POST "http://127.0.0.1:3456/eg_net/eg_api/manage/peer/add?Password=passwd_addpeer" \
-H "Content-Type: application/x-www-form-urlencoded" \
- -d "NodeID=100&Name=Node_100&PubKey=6SuqwPH9pxGigtZDNp3PABZYfSEzDaBSwuThsUUAcyM=&AdditionalCost=1000&PSKey=j9dS%2FlYvL16svSeC5lh%2Bldlq2iZX2MWwZfM3NNWpULI%3D&SkipLocalIP=false"
+ -d "NodeID=100&Name=Node_100&PubKey=Bax6wOJpisSVJtrU92ujn8D%2F2oGUyhyPrKTXkHbGamM%3D&AdditionalCost=1000&PSKey=Gfp2RkPNrKTeGKrCJNEvSyiBqYYRmzVnVG6CBuUKUNc%3D&SkipLocalIP=false"
```
參數:
1. URL query: Password: 新增peer用的密碼,在設定檔配置
@@ -172,13 +254,13 @@ curl -X POST "http://127.0.0.1:3000/eg_api/manage/peer/add?Password=passwd_addpe
設計上分別是給管理員使用,或是給加入網路的人,想離開網路使用
使用Password刪除可以刪除任意節點,以上面新增的節點為例,使用這個API即可刪除剛剛新增的節點
-```
-curl "http://127.0.0.1:3000/eg_api/manage/peer/del?Password=passwd_delpeer&NodeID=100"
+```bash
+curl "http://127.0.0.1:3456/eg_net/eg_api/manage/peer/del?Password=passwd_delpeer&NodeID=100"
```
也可以使用privkey刪除,同上,但是只要附上privkey參數就好
-```
-curl "http://127.0.0.1:3000/eg_api/manage/peer/del?PrivKey=IJtpnkm9ytbuCukx4VBMENJKuLngo9KSsS1D60BqonQ="
+```bash
+curl "http://127.0.0.1:3456/eg_net/eg_api/manage/peer/del?PrivKey=a04BVvT%2BYbrX1ejjvMQVI6k5VRFlBkEX8tuLGWNyNrY%3D"
```
參數:
@@ -193,65 +275,121 @@ curl "http://127.0.0.1:3000/eg_api/manage/peer/del?PrivKey=IJtpnkm9ytbuCukx4VBME
### peer/update
更新節點的一些參數
-```
-curl -X POST "http://127.0.0.1:12369/eg_net/eg_api/manage/peer/update?Password=e05znou1_updatepeer&NodeID=1" \
+```bash
+curl -X POST "http://127.0.0.1:3456/eg_net/eg_api/eg_api/manage/peer/update?Password=e05znou1_updatepeer&NodeID=1" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "AdditionalCost=10&SkipLocalIP=false"
```
### super/update
更新SuperNode的一些參數
-```
-curl -X POST "http://127.0.0.1:12369/eg_net/eg_api/manage/super/update?Password=e05znou1_updatesuper" \
+```bash
+curl -X POST "http://127.0.0.1:3456/eg_net/eg_api/eg_api/manage/super/update?Password=e05znou1_updatesuper" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "SendPingInterval=15&HttpPostInterval=60&PeerAliveTimeout=70"
```
+### SuperNode Config Parameter
-## Config Parameters
+Key | Description
+-------------- |:-----
+NodeName| 節點名稱
+PostScript | 初始化完畢之後要跑的腳本
+PrivKeyV4 | IPv4通訊使用的私鑰
+PrivKeyV6 | IPv6通訊使用的私鑰
+ListenPort | udp監聽埠
+ListenPort_EdgeAPI | HTTP EdgeAPI 的監聽埠
+ListenPort_ManageAPI| HTTP ManageAPI 的監聽埠
+API_Prefix | HTTP API prefix
+RePushConfigInterval| 重新push`UpdateXXX`的間格
+HttpPostInterval | EdgeNode 使用EdgeAPI回報狀態的頻率
+PeerAliveTimeout | 判定斷線Timeout
+SendPingInterval | EdgeNode 之間使用Ping/Pong測量延遲的間格
+[LogLevel](../static_mode/README_zh.md#LogLevel)| 紀錄log
+[Passwords](#Passwords) | HTTP ManageAPI 的密碼,5個API密碼是獨立的
+[GraphRecalculateSetting](#GraphRecalculateSetting) | 一些和[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法)相關的參數
+[NextHopTable](../static_mode/README_zh.md#NextHopTable) | StaticMode 模式下使用的轉發表
+EdgeTemplate | HTTP ManageAPI `peer/add` 返回的edge的參考設定檔
+UsePSKForInterEdge | 幫Edge生成PreSharedKey,供edge之間直接連線使用
+[Peers](#EdgeNodes) | EdgeNode資訊
-### Super mode的edge node有幾個參數
-1. `usesupernode`: 是否啟用Super mode
-1. `pskey`: 和supernode建立連線用的Pre shared Key
-1. `connurlv4`: Super node的IPv4連線地址
-1. `pubkeyv4`: Super node的IPv4工鑰
-1. `connurlv6`: Super node的IPv6連線地址
-1. `pubkeyv6`: Super node的IPv6工鑰
-1. `apiurl`: Super node的HTTP(S) API連線地址
-1. `supernodeinfotimeout`: Supernode Timeout
-1. `httppostinterval`: 15
-1. `skiplocalip`: 打洞時,一律使用supernode蒐集到的外部ip,不使用edge自行回報的local ip
+Passwords | Description
+--------------------|:-----
+ShowState | HTTP ManageAPI `super/state` 的密碼
+AddPeer | HTTP ManageAPI `peer/add` 的密碼
+DelPeer | HTTP ManageAPI `peer/del` 的密碼
+UpdatePeer | HTTP ManageAPI `peer/update` 的密碼
+UpdateSuper | HTTP ManageAPI `super/update` 的密碼
-### Super node本身的設定檔
+GraphRecalculateSetting | Description
+--------------------|:-----
+StaticMode | 關閉`Floyd-Warshall`演算法,只使用設定檔提供的NextHopTable`。SuperNode單純用來輔助打洞
+ManualLatency | 手動設定延遲,不採用EdgeNode回報的延遲(單位: 毫秒)
+JitterTolerance | 抖動容許誤差,收到Pong以後,一個37ms,一個39ms,不會觸發重新計算
比較對象是上次更新使用的值。如果37 37 41 43 .. 100 ,每次變動一點點,總變動量超過域值還是會更新
+JitterToleranceMultiplier | 抖動容許誤差的放大係數,高ping的話允許更多誤差
https://www.desmos.com/calculator/raoti16r5n
+DampingResistance | 防抖阻尼系數,`latency = latency_old * resistance + latency_in * (1-resistance)`
+TimeoutCheckInterval | 週期性檢查節點的連線狀況,是否斷線需要重新規劃線路
+RecalculateCoolDown | Floyd-Warshal是O(n^3)時間複雜度,不能太常算。
設個冷卻時間
有節點加入/斷線觸發的重新計算,無視這個CoolDown
-1. nodename: 節點名稱
-1. privkeyv4: ipv4用的私鑰
-1. privkeyv6: ipv6用的私鑰
-1. listenport: 監聽udp埠號
-1. loglevel: 參考 [README_zh.md](../README_zh.md)
-1. repushconfiginterval: 重新push`UpdateXXX`的間格
-1. passwords: HTTP API 密碼
- 1. showstate: 節點資訊
- 1. addpeer: 新增peer
- 1. delpeer: 刪除peer
-1. graphrecalculatesetting: 一些和[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法)相關的參數
- 1. staticmode: 關閉Floyd-Warshall演算法,只使用一開始載入的nexthoptable。Supernode單純用來輔助打洞
- 1. recalculatecooldown: Floyd-Warshal是O(n^3)時間複雜度,不能太常算。設個冷卻時間
- 1. jittertolerance: 抖動容許誤差,收到Pong以後,一個37ms,一個39ms,不會觸發重新計算
- 1. jittertolerancemultiplier: 一樣是抖動容許誤差,但是高ping的話允許更多誤差
- https://www.desmos.com/calculator/raoti16r5n
- 1. nodereporttimeout: 收到的`Pong`封包的有效期限。太久沒收到就變回Infinity
- 1. timeoutcheckinterval: 固定間格檢查,有沒有人的Pong封包超過有效期限,要重算轉發表
-1. nexthoptable: 僅在`staticmode==true` 有效,手動設定的nexthoptable
-1. edgetemplate: 給`addpeer`API用的。參考這個設定檔,顯示一個範例設定檔給edge
-1. usepskforinteredge: 是否啟用edge間pre shares key通信。若啟用則幫edge們自動生成PSK
-1. peers: Peer列表,參考 [README_zh.md](../README_zh.md)
- 1. nodeid: Peer的節點ID
- 1. name: Peer名稱(顯示在前端)
- 1. pubkey: peer 公鑰
- 1. pskey: preshared key 該peer和本Supernode連線的PSK
- 1. additionalcost: 此節點進行封包轉發的額外成本。單位: 毫秒
+Peers | Description
+--------------------|:-----
+NodeID | 節點ID
+PubKey | 公鑰
+PSKey | 預共享金鑰
+[AdditionalCost](#AdditionalCost) | 繞路成本(單位: 毫秒)
設定-1代表使用EdgeNode自身設定
+SkipLocalIP | 打洞時,不使用EdgeNode回報的本地IP,僅使用SuperNode蒐集到的外部IP
+### EdgeNode Config Parameter
+
+Key | Description
+-------------- |:-----
+[Interface](../static_mode/README_zh.md#Interface)| 接口相關設定。VPN有兩端,一端是VPN網路,另一端則是本地接口
+NodeID | 節點ID。節點之間辨識身分用的,同一網路內節點ID不能重複
+NodeName | 節點名稱
+PostScript | 初始化完畢之後要跑的腳本
+DefaultTTL | TTL,etherguard層使用,和乙太層不共通
+L2FIBTimeout | MacAddr-> NodeID 查找表的 timeout(秒) ,類似ARP table
+PrivKey | 私鑰,和wireguard規格一樣
+ListenPort | 監聽的udp埠
+[LogLevel](../static_mode/README_zh.md#LogLevel)| 紀錄log
+[DynamicRoute](#DynamicRoute) | 動態路由相關設定
+NextHopTable | 轉發表, SuperMode由SuperNode計算,EdgeNode用不到
+ResetConnInterval | 如果對方是動態ip就要用這個。每隔一段時間就會重置連線,重新解析域名
+[Peers](#Peers) | 鄰居節點,SuperMode從SuperNode計算,EdgeNode用不到
+
+DynamicRoute | Description
+--------------------|:-----
+SendPingInterval | 發送Ping訊息的間隔(秒)
+PeerAliveTimeout | 每次收到封包就重置,超過時間(秒)沒收到就標記該peer離線
+DupCheckTimeout | 重複封包檢查的timeout(秒)
完全相同的封包收第二次會被丟棄
+ConnTimeOut | 檢查peer離線的時間間格
如果標記離線,就切換下一個endpoint
SuperNode可能傳了多個endpoint過來
+ConnNextTry | 切換下一個endpoint的間隔
+[AdditionalCost](#AdditionalCost) | 繞路成本(毫秒)。僅限SuperNode設定-1時生效
+SaveNewPeers | 是否把下載來的鄰居資訊存到本地設定檔裡面
+[SuperNode](#SuperNode) | SuperNode相關設定
+P2P | P2P相關設定,SuperMode用不到
+[NTPConfig](#NTPConfig) | NTP時間同步相關設定
+
+SuperNode | Description
+---------------------|:-----
+UseSuperNode | 是否啟用SuperNode
+PSKey | 和SuperNode通訊用的PreShared Key
+EndpointV4 | SuperNode的IPv4 Endpoint
+PubKeyV4 | SuperNode的IPv4公鑰
+EndpointV6 | SuperNode的IPv6 Endpoint
+PubKeyV6 | SuperNode的IPv6公鑰
+EndpointEdgeAPIUrl | SuperNode的EdgeAPI存取路徑
+SkipLocalIP | 不回報本地IP,避免和其他Edge內網直連
+SuperNodeInfoTimeout | 實驗性選項,SuperNode離線超時,切換成P2P模式
需先打開P2P模式
`UseP2P=false`本選項無效
P2P模式尚未測試,穩定性未知,不推薦使用
+
+
+NTPConfig | Description
+--------------------|:-----
+UseNTP | 是否使用NTP同步時間
+MaxServerUse | 向多少NTP伺服器發送請求
+SyncTimeInterval | 多久同步一次時間
+NTPTimeout | NTP伺服器連線Timeout
+Servers | NTP伺服器列表
## V4 V6 兩個公鑰
為什麼要分開IPv4和IPv6呢?
@@ -284,12 +422,14 @@ Relay node其實也是一個edge node,只不過被設定成為interface=dummy
因為如果用127.0.0.1連接supernode,supernode看到封包的src IP就是127.0.0.1,就會把127.0.0.1分發給`Node_1`和`Node_2`
`Node_1`和`Node_2`看到`Node_R`的連線地址是`127.0.0.1`,就連不上了
-## Quick start
-執行此範例設定檔(請開三個terminal):
+#### Run example config
+
+在**不同terminal**分別執行以下命令
+
```bash
-./etherguard-go -config example_config/super_mode/s1.yaml -mode super
-./etherguard-go -config example_config/super_mode/n1.yaml -mode edge
-./etherguard-go -config example_config/super_mode/n2.yaml -mode edge
+./etherguard-go -config example_config/super_mode/Node_super.yaml -mode super
+./etherguard-go -config example_config/super_mode/Node_edge001.yaml -mode edge
+./etherguard-go -config example_config/super_mode/Node_edge002.yaml -mode edge
```
因為是stdio模式,stdin會讀入VPN網路
請在其中一個edge視窗中鍵入
diff --git a/example_config/super_mode/gensuper.yaml b/example_config/super_mode/gensuper.yaml
index 54489f8..e3e0793 100644
--- a/example_config/super_mode/gensuper.yaml
+++ b/example_config/super_mode/gensuper.yaml
@@ -1,15 +1,15 @@
-Config output dir: /tmp/eg_gen
+Config output dir: /tmp/eg_gen_super
ConfigTemplate for super node: ""
ConfigTemplate for edge node: ""
-Network name: eg_net
+Network name: EgNet
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
+ Endpoint(IPv4)(optional): 127.0.0.1
+ Endpoint(IPv6)(optional):
+ Endpoint(EdgeAPI): http://127.0.0.1:3456/eg_net/eg_api
Edge Node:
- Node IDs: "[1~10,11,19,23,29,31,55~66,88~99]"
+ Node IDs: "[1~2,100]"
MacAddress prefix: ""
IPv4 range: 192.168.76.0/24
IPv6 range: fd95:71cb:a3df:e586::/64
diff --git a/example_config/super_mode/s1.yaml b/example_config/super_mode/s1.yaml
deleted file mode 100644
index 2ee7e03..0000000
--- a/example_config/super_mode/s1.yaml
+++ /dev/null
@@ -1,47 +0,0 @@
-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_showstate
- AddPeer: passwd_addpeer
- DelPeer: passwd_delpeer
- UpdatePeer: passwd_updatepeer
- UpdateSuper: passwd_updatesuper
-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
diff --git a/example_config/super_mode/n1_fd.yaml b/example_config/super_mode/testfd/n1_fd.yaml
similarity index 100%
rename from example_config/super_mode/n1_fd.yaml
rename to example_config/super_mode/testfd/n1_fd.yaml
diff --git a/example_config/super_mode/n1_test_fd_mode.py b/example_config/super_mode/testfd/n1_test_fd_mode.py
similarity index 100%
rename from example_config/super_mode/n1_test_fd_mode.py
rename to example_config/super_mode/testfd/n1_test_fd_mode.py
diff --git a/example_config/super_mode/n1_test_fd_mode2.go b/example_config/super_mode/testfd/n1_test_fd_mode2.go
similarity index 100%
rename from example_config/super_mode/n1_test_fd_mode2.go
rename to example_config/super_mode/testfd/n1_test_fd_mode2.go
diff --git a/example_config/super_mode/n1_test_fd_mode2.py b/example_config/super_mode/testfd/n1_test_fd_mode2.py
similarity index 100%
rename from example_config/super_mode/n1_test_fd_mode2.py
rename to example_config/super_mode/testfd/n1_test_fd_mode2.py
diff --git a/gencfg/gencfgNM.go b/gencfg/gencfgNM.go
index 111a81f..763d184 100644
--- a/gencfg/gencfgNM.go
+++ b/gencfg/gencfgNM.go
@@ -92,17 +92,18 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
if !all_verts[NodeID] {
return fmt.Errorf("duplicate definition: NodeID %v ", NodeID)
}
- _, err = conn.LookupIP(endpoint, 0)
- if err != nil {
- return err
+ if endpoint != "" {
+ _, err = conn.LookupIP(endpoint, 0)
+ if err != nil {
+ return err
+ }
}
pri, pub := device.RandomKeyPair()
edge_infos[NodeID] = edge_info{
- Endpoint: endpoint,
- PrivKey: pri.ToString(),
- PubKey: pub.ToString(),
- PersistentKeepalive: edgeinfo.PersistentKeepalive,
- ConnectedEdge: make(map[mtypes.Vertex]bool),
+ Endpoint: endpoint,
+ PrivKey: pri.ToString(),
+ PubKey: pub.ToString(),
+ ConnectedEdge: make(map[mtypes.Vertex]bool),
}
all_verts[NodeID] = false
if NodeID > MaxNodeID {
@@ -118,7 +119,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
s := edge.Src_nodeID
d := edge.Dst_nodeID
if len(edge_infos[s].Endpoint)+len(edge_infos[d].Endpoint) == 0 {
- return fmt.Errorf("there are an edge between node %v and %v, but non of them have endpoint", s, d)
+ return fmt.Errorf("there are an edge between node [%v , %v], but non of them have endpoint", s, d)
}
edge_infos[s].ConnectedEdge[d] = true
edge_infos[d].ConnectedEdge[s] = true
@@ -132,7 +133,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
pbyte := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
pbyte[0] &^= 0b00000001
pbyte[0] |= 0b00000010
- NMCfg.EdgeNode.MacPrefix = fmt.Sprintf("%X:%X:%X:%X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
+ NMCfg.EdgeNode.MacPrefix = fmt.Sprintf("%02X:%02X:%02X:%02X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
}
dist, next, err := g.FloydWarshall(false)
@@ -177,6 +178,8 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
econfig.NodeID = NodeID
idstr := fmt.Sprintf("%0"+strconv.Itoa(len(MaxNodeID.ToString()))+"d", NodeID)
econfig.NodeName = NMCfg.NetworkName + idstr
+ PersistentKeepalive := uint32(30)
+ econfig.ListenPort = 0
if Edge.Endpoint != "" {
ps := strings.Split(Edge.Endpoint, ":")
pss := ps[len(ps)-1]
@@ -185,6 +188,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
return err
}
econfig.ListenPort = int(port)
+ PersistentKeepalive = 0
}
econfig.Peers = make([]mtypes.PeerInfo, 0)
for CNodeID, _ := range Edge.ConnectedEdge {
@@ -193,7 +197,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
PubKey: edge_infos[CNodeID].PubKey,
PSKey: pskdb.GetPSK(NodeID, CNodeID).ToString(),
EndPoint: edge_infos[CNodeID].Endpoint,
- PersistentKeepalive: Edge.PersistentKeepalive,
+ PersistentKeepalive: PersistentKeepalive,
Static: true,
})
}
diff --git a/gencfg/gencfgSM.go b/gencfg/gencfgSM.go
index f90ef39..7a19753 100644
--- a/gencfg/gencfgSM.go
+++ b/gencfg/gencfgSM.go
@@ -220,7 +220,7 @@ func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
pbyte := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
pbyte[0] &^= 0b00000001
pbyte[0] |= 0b00000010
- MacPrefix = fmt.Sprintf("%X:%X:%X:%X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
+ MacPrefix = fmt.Sprintf("%02X:%02X:%02X:%02X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
}
IPv4Block := SMCfg.EdgeNode.IPv4Range
@@ -264,6 +264,7 @@ func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
peerceconf.DynamicRoute.SuperNode.EndpointV4 = EndpointV4 + ":" + ListenPort
peerceconf.DynamicRoute.SuperNode.EndpointV6 = EndpointV6 + ":" + ListenPort
peerceconf.DynamicRoute.SuperNode.EndpointEdgeAPIUrl = EndpointEdgeAPIUrl
+ peerceconf.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance = 0
peerceconf.Interface.MacAddrPrefix = MacPrefix
peerceconf.Interface.IPv4CIDR = IPv4Block
peerceconf.Interface.IPv6CIDR = IPv6Block
diff --git a/gencfg/types.go b/gencfg/types.go
index 46dd708..f315d56 100644
--- a/gencfg/types.go
+++ b/gencfg/types.go
@@ -68,5 +68,4 @@ type edge_info struct {
ConnectedEdge map[mtypes.Vertex]bool
PrivKey string
PubKey string
- PersistentKeepalive uint32
}
diff --git a/main_edge.go b/main_edge.go
index 011bbd9..1ece5de 100644
--- a/main_edge.go
+++ b/main_edge.go
@@ -51,6 +51,9 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
if len(NodeName) > 32 {
return errors.New("Node name can't longer than 32 :" + NodeName)
}
+ if econfig.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance < 0 || econfig.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance >= 1 {
+ return fmt.Errorf("DampingResistance must in range [0,1) : %v", econfig.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance)
+ }
var logLevel int
switch econfig.LogLevel.LogLevel {
case "verbose", "debug":
diff --git a/main_httpserver.go b/main_httpserver.go
index 1e7c38a..9e8303e 100644
--- a/main_httpserver.go
+++ b/main_httpserver.go
@@ -684,7 +684,7 @@ func manage_peeradd(w http.ResponseWriter, r *http.Request) {
func manage_peerupdate(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
- toUpdate := mtypes.NodeID_Boardcast
+ toUpdate := mtypes.NodeID_Broadcast
var err error
var NodeID mtypes.Vertex
@@ -856,7 +856,7 @@ func manage_superupdate(w http.ResponseWriter, r *http.Request) {
func manage_peerdel(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
- toDelete := mtypes.NodeID_Boardcast
+ toDelete := mtypes.NodeID_Broadcast
var err error
var NodeID mtypes.Vertex
@@ -900,7 +900,7 @@ func manage_peerdel(w http.ResponseWriter, r *http.Request) {
toDelete = peerinfo.NodeID
}
}
- if toDelete == mtypes.NodeID_Boardcast {
+ if toDelete == mtypes.NodeID_Broadcast {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(fmt.Sprintf("Paramater PrivKey: \"%v\" not found", PubKey)))
return
diff --git a/main_super.go b/main_super.go
index 8294f99..95214cb 100644
--- a/main_super.go
+++ b/main_super.go
@@ -100,6 +100,9 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
if sconfig.RePushConfigInterval <= 0 {
return fmt.Errorf("RePushConfigInterval must > 0 : %v", sconfig.RePushConfigInterval)
}
+ if sconfig.GraphRecalculateSetting.DampingResistance < 0 || sconfig.GraphRecalculateSetting.DampingResistance >= 1 {
+ return fmt.Errorf("DampingResistance must in range [0,1) : %v", sconfig.GraphRecalculateSetting.DampingResistance)
+ }
var logLevel int
switch sconfig.LogLevel.LogLevel {
diff --git a/mtypes/config.go b/mtypes/config.go
index 4fea539..d70092f 100644
--- a/mtypes/config.go
+++ b/mtypes/config.go
@@ -10,11 +10,11 @@ import (
type Vertex uint16
const (
- NodeID_Boardcast Vertex = math.MaxUint16 - iota // Normal boardcast, boardcast with route table
+ NodeID_Broadcast Vertex = math.MaxUint16 - iota // Normal boardcast, boardcast with route table
NodeID_AllPeer Vertex = math.MaxUint16 - iota // p2p mode: boardcast to every know peer and prevent dup. super mode: send to supernode
NodeID_SuperNode Vertex = math.MaxUint16 - iota
- NodeID_Invalid Vertex = math.MaxUint16 - iota
- NodeID_Special Vertex = NodeID_Invalid
+ NodeID_Invalid Vertex = math.MaxUint16 - iota
+ NodeID_Special Vertex = NodeID_Invalid
)
type EdgeConfig struct {
@@ -99,15 +99,15 @@ type SuperPeerInfo struct {
type LoggerInfo struct {
LogLevel string `yaml:"LogLevel"`
LogTransit bool `yaml:"LogTransit"`
- LogControl bool `yaml:"LogControl"`
LogNormal bool `yaml:"LogNormal"`
+ LogControl bool `yaml:"LogControl"`
LogInternal bool `yaml:"LogInternal"`
LogNTP bool `yaml:"LogNTP"`
}
func (v *Vertex) ToString() string {
switch *v {
- case NodeID_Boardcast:
+ case NodeID_Broadcast:
return "Boardcast"
case NodeID_AllPeer:
return "Control"
diff --git a/path/header.go b/path/header.go
index 63e50dc..926a54a 100644
--- a/path/header.go
+++ b/path/header.go
@@ -32,6 +32,64 @@ const (
BroadcastPeer
)
+func (v Usage) IsNormal() bool {
+ return v == NormalPacket
+}
+
+func (v Usage) IsControl() bool {
+ switch v {
+ case Register:
+ return true
+ case ServerUpdate:
+ return true
+ case PingPacket:
+ return true
+ case PongPacket:
+ return true
+ case QueryPeer:
+ return true
+ case BroadcastPeer:
+ return true
+ default:
+ return false
+ }
+}
+
+func (v Usage) IsControl_Super2Edge() bool {
+ switch v {
+ case ServerUpdate:
+ return true
+ default:
+ return false
+ }
+}
+
+func (v Usage) IsControl_Edge2Super() bool {
+ switch v {
+ case Register:
+ return true
+ case PongPacket:
+ return true
+ default:
+ return false
+ }
+}
+
+func (v Usage) IsControl_Edge2Edge() bool {
+ switch v {
+ case PingPacket:
+ return true
+ case PongPacket:
+ return true
+ case QueryPeer:
+ return true
+ case BroadcastPeer:
+ return true
+ default:
+ return false
+ }
+}
+
func NewEgHeader(pac []byte) (e EgHeader, err error) {
if len(pac) != EgHeaderLen {
err = errors.New("invalid packet size")
diff --git a/path/path.go b/path/path.go
index 19da8c0..c97d189 100644
--- a/path/path.go
+++ b/path/path.go
@@ -189,7 +189,7 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
newval := pong_msg.Timediff
if _, ok := g.gsetting.ManualLatency[u]; ok {
if _, ok := g.gsetting.ManualLatency[u][v]; ok {
- newval = g.gsetting.ManualLatency[u][v]
+ newval = g.gsetting.ManualLatency[u][v] / 1000 // s to ms
}
}
w := newval
@@ -206,7 +206,7 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
g.edgelock.Unlock()
oldval := g.OldWeight(u, v, false)
g.edgelock.Lock()
- if oldval != mtypes.Infinity {
+ if oldval != mtypes.Infinity && g.IsSuperMode && g.gsetting.DampingResistance > 0 {
w = oldval*g.gsetting.DampingResistance + newval*(1-g.gsetting.DampingResistance)
}
should_update = should_update || g.ShouldUpdate(oldval, w, false)
diff --git a/tap/tap_stdio.go b/tap/tap_stdio.go
index 37fc722..02d35bd 100644
--- a/tap/tap_stdio.go
+++ b/tap/tap_stdio.go
@@ -100,10 +100,11 @@ func (tap *StdIOTap) Read(buf []byte, offset int) (int, error) {
}
} // read a packet from the device (without any additional headers)
func (tap *StdIOTap) Write(buf []byte, offset int) (size int, err error) {
- packet := make([]byte, len(buf[offset:]))
- copy(packet, buf[offset:])
+ packet := buf[offset:]
switch tap.L2mode {
case KeyboardDebug:
+ packet = make([]byte, len(buf[offset:]))
+ copy(packet, buf[offset:])
src := Mac2charForm(packet[6:12])
dst := Mac2charForm(packet[0:6])
packet[10] = dst