mirror of
https://github.com/KusakabeShi/EtherGuard-VPN.git
synced 2024-12-26 07:38:48 +01:00
fastgen static config, update readme
This commit is contained in:
parent
d555963227
commit
17fe0cdae3
@ -82,8 +82,6 @@ VPN起來以後,自己手動加ip也行
|
|||||||
$ ./etherguard-go -mode gencfg -cfgmode super -config example_config/super_mode/gensuper.yaml
|
$ ./etherguard-go -mode gencfg -cfgmode super -config example_config/super_mode/gensuper.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
把一個super,2個edge分別搬去三台機器
|
把一個super,2個edge分別搬去三台機器
|
||||||
或是2台機器,super和edge可以是同一台
|
或是2台機器,super和edge可以是同一台
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ type Peer struct {
|
|||||||
|
|
||||||
LastPacketReceivedAdd1Sec atomic.Value // *time.Time
|
LastPacketReceivedAdd1Sec atomic.Value // *time.Time
|
||||||
|
|
||||||
SingleWayLatency float64
|
SingleWayLatency atomic.Value
|
||||||
stopping sync.WaitGroup // routines pending stop
|
stopping sync.WaitGroup // routines pending stop
|
||||||
|
|
||||||
ID mtypes.Vertex
|
ID mtypes.Vertex
|
||||||
@ -245,7 +245,7 @@ func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool,
|
|||||||
peer.cookieGenerator.Init(pk)
|
peer.cookieGenerator.Init(pk)
|
||||||
peer.device = device
|
peer.device = device
|
||||||
peer.endpoint_trylist = NewEndpoint_trylist(peer, mtypes.S2TD(device.EdgeConfig.DynamicRoute.PeerAliveTimeout))
|
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.outbound = newAutodrainingOutboundQueue(device)
|
||||||
peer.queue.inbound = newAutodrainingInboundQueue(device)
|
peer.queue.inbound = newAutodrainingInboundQueue(device)
|
||||||
peer.queue.staged = make(chan *QueueOutboundElement, QueueStagedSize)
|
peer.queue.staged = make(chan *QueueOutboundElement, QueueStagedSize)
|
||||||
|
@ -470,39 +470,76 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
|||||||
packet_type = elem.Type
|
packet_type = elem.Type
|
||||||
|
|
||||||
if device.IsSuperNode {
|
if device.IsSuperNode {
|
||||||
switch dst_nodeID {
|
if packet_type.IsControl_Edge2Super() {
|
||||||
case mtypes.NodeID_AllPeer:
|
|
||||||
should_process = true
|
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:
|
case mtypes.NodeID_SuperNode:
|
||||||
should_process = true
|
should_process = true
|
||||||
default:
|
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 {
|
} else {
|
||||||
|
// Set should_receive and should_process
|
||||||
|
if packet_type.IsNormal() {
|
||||||
switch dst_nodeID {
|
switch dst_nodeID {
|
||||||
case mtypes.NodeID_Boardcast:
|
case device.ID:
|
||||||
should_receive = true
|
should_receive = true
|
||||||
should_transfer = true
|
case mtypes.NodeID_Broadcast:
|
||||||
case mtypes.NodeID_SuperNode:
|
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
|
should_process = true
|
||||||
case mtypes.NodeID_AllPeer:
|
case mtypes.NodeID_AllPeer:
|
||||||
packet := elem.packet[path.EgHeaderLen:] //true packet
|
|
||||||
if device.CheckNoDup(packet) {
|
|
||||||
should_process = true
|
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
|
should_transfer = true
|
||||||
} else {
|
} else {
|
||||||
should_process = false
|
|
||||||
should_transfer = false
|
|
||||||
if device.LogLevel.LogTransit {
|
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:
|
case device.ID:
|
||||||
if packet_type == path.NormalPacket {
|
should_transfer = false
|
||||||
should_receive = true
|
case mtypes.NodeID_SuperNode:
|
||||||
} else {
|
should_transfer = false
|
||||||
should_process = true
|
case mtypes.NodeID_Invalid:
|
||||||
}
|
should_transfer = false
|
||||||
default:
|
default:
|
||||||
if device.graph.Next(device.ID, dst_nodeID) != mtypes.NodeID_Invalid {
|
if device.graph.Next(device.ID, dst_nodeID) != mtypes.NodeID_Invalid {
|
||||||
should_transfer = true
|
should_transfer = true
|
||||||
@ -517,7 +554,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
|||||||
device.log.Verbosef("TTL is 0 %v", dst_nodeID)
|
device.log.Verbosef("TTL is 0 %v", dst_nodeID)
|
||||||
} else {
|
} else {
|
||||||
EgHeader.SetTTL(l2ttl - 1)
|
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)
|
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
|
} 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)
|
skip_list := make(map[mtypes.Vertex]bool)
|
||||||
@ -534,7 +571,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
|||||||
if device.LogLevel.LogTransit {
|
if device.LogLevel.LogTransit {
|
||||||
fmt.Printf("Transit: Transfer packet from %d through %d to %d\n", peer.ID, device.ID, peer_out.ID)
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
func (device *Device) process_ping(peer *Peer, content mtypes.PingMsg) error {
|
||||||
Timediff := device.graph.GetCurrentTime().Sub(content.Time).Seconds()
|
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{
|
PongMSG := mtypes.PongMsg{
|
||||||
Src_nodeID: content.Src_nodeID,
|
Src_nodeID: content.Src_nodeID,
|
||||||
Dst_nodeID: device.ID,
|
Dst_nodeID: device.ID,
|
||||||
Timediff: Timediff,
|
Timediff: NewTimediff,
|
||||||
TimeToAlive: device.EdgeConfig.DynamicRoute.PeerAliveTimeout,
|
TimeToAlive: device.EdgeConfig.DynamicRoute.PeerAliveTimeout,
|
||||||
AdditionalCost: device.EdgeConfig.DynamicRoute.AdditionalCost,
|
AdditionalCost: device.EdgeConfig.DynamicRoute.AdditionalCost,
|
||||||
}
|
}
|
||||||
if device.EdgeConfig.DynamicRoute.P2P.UseP2P && time.Now().After(device.graph.NhTableExpire) {
|
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)
|
body, err := mtypes.GetByte(&PongMSG)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -887,7 +890,7 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
|
|||||||
RequestID: 0,
|
RequestID: 0,
|
||||||
Src_nodeID: device.ID,
|
Src_nodeID: device.ID,
|
||||||
Dst_nodeID: 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,
|
TimeToAlive: time.Since(*peer.LastPacketReceivedAdd1Sec.Load().(*time.Time)).Seconds() + device.EdgeConfig.DynamicRoute.PeerAliveTimeout,
|
||||||
}
|
}
|
||||||
pongs = append(pongs, pong)
|
pongs = append(pongs, pong)
|
||||||
@ -989,7 +992,7 @@ func (device *Device) RoutineSpreadAllMyNeighbor() {
|
|||||||
timeout := mtypes.S2TD(device.EdgeConfig.DynamicRoute.P2P.SendPeerInterval)
|
timeout := mtypes.S2TD(device.EdgeConfig.DynamicRoute.P2P.SendPeerInterval)
|
||||||
for {
|
for {
|
||||||
device.process_RequestPeerMsg(mtypes.QueryPeerMsg{
|
device.process_RequestPeerMsg(mtypes.QueryPeerMsg{
|
||||||
Request_ID: uint32(mtypes.NodeID_Boardcast),
|
Request_ID: uint32(mtypes.NodeID_Broadcast),
|
||||||
})
|
})
|
||||||
time.Sleep(timeout)
|
time.Sleep(timeout)
|
||||||
}
|
}
|
||||||
|
@ -256,9 +256,9 @@ func (device *Device) RoutineReadFromTUN() {
|
|||||||
dstMacAddr := tap.GetDstMacAddr(elem.packet[path.EgHeaderLen:])
|
dstMacAddr := tap.GetDstMacAddr(elem.packet[path.EgHeaderLen:])
|
||||||
// lookup peer
|
// lookup peer
|
||||||
if tap.IsNotUnicast(dstMacAddr) {
|
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
|
} else if val, ok := device.l2fib.Load(dstMacAddr); !ok { //Lookup failed
|
||||||
dst_nodeID = mtypes.NodeID_Boardcast
|
dst_nodeID = mtypes.NodeID_Broadcast
|
||||||
} else {
|
} else {
|
||||||
dst_nodeID = val.(*IdAndTime).ID
|
dst_nodeID = val.(*IdAndTime).ID
|
||||||
}
|
}
|
||||||
@ -275,7 +275,7 @@ func (device *Device) RoutineReadFromTUN() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if dst_nodeID != mtypes.NodeID_Boardcast {
|
if dst_nodeID != mtypes.NodeID_Broadcast {
|
||||||
var peer *Peer
|
var peer *Peer
|
||||||
next_id := device.graph.Next(device.ID, dst_nodeID)
|
next_id := device.graph.Next(device.ID, dst_nodeID)
|
||||||
if next_id != mtypes.NodeID_Invalid {
|
if next_id != mtypes.NodeID_Invalid {
|
||||||
|
@ -3,7 +3,7 @@ Interface:
|
|||||||
Name: tap1
|
Name: tap1
|
||||||
VPPIFaceID: 1
|
VPPIFaceID: 1
|
||||||
VPPBridgeID: 4242
|
VPPBridgeID: 4242
|
||||||
MacAddrPrefix: 8E:AA:C8:4B
|
MacAddrPrefix: DA:21:10:81
|
||||||
IPv4CIDR: 192.168.76.0/24
|
IPv4CIDR: 192.168.76.0/24
|
||||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||||
IPv6LLPrefix: fe80::a3df:0/112
|
IPv6LLPrefix: fe80::a3df:0/112
|
||||||
@ -12,17 +12,17 @@ Interface:
|
|||||||
SendAddr: 127.0.0.1:5001
|
SendAddr: 127.0.0.1:5001
|
||||||
L2HeaderMode: kbdbg
|
L2HeaderMode: kbdbg
|
||||||
NodeID: 1
|
NodeID: 1
|
||||||
NodeName: Node1
|
NodeName: EgNet1
|
||||||
PostScript: ""
|
PostScript: ""
|
||||||
DefaultTTL: 200
|
DefaultTTL: 200
|
||||||
L2FIBTimeout: 3600
|
L2FIBTimeout: 3600
|
||||||
PrivKey: Fe9Q6K5L6xTVbx/zFc07tnQuo+pkeyrhfoTQ3BF5GRM=
|
PrivKey: LFFQqPBQ84x2AQ9BCI+0wG8nr+Y6yXHqhXkMCb4HCmg=
|
||||||
ListenPort: 3001
|
ListenPort: 3001
|
||||||
LogLevel:
|
LogLevel:
|
||||||
LogLevel: error
|
LogLevel: error
|
||||||
LogTransit: true
|
LogTransit: true
|
||||||
LogControl: true
|
|
||||||
LogNormal: true
|
LogNormal: true
|
||||||
|
LogControl: true
|
||||||
LogInternal: true
|
LogInternal: true
|
||||||
LogNTP: true
|
LogNTP: true
|
||||||
DynamicRoute:
|
DynamicRoute:
|
||||||
@ -100,8 +100,8 @@ NextHopTable:
|
|||||||
ResetConnInterval: 86400
|
ResetConnInterval: 86400
|
||||||
Peers:
|
Peers:
|
||||||
- NodeID: 2
|
- NodeID: 2
|
||||||
PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
|
PubKey: 0r2o9Hb36gYVgD3VSKCH18MVOZw0BvzcJ6TOTo6Cc1g=
|
||||||
PSKey: kWDwCaC11UvYjfiXBMwYpR6Pujo1vaVW8JTusp1Kkrw=
|
PSKey: lFq67qp9LXL3PtlEJ3SGg3c/6++Ljy2I8i/k0Xcibvk=
|
||||||
EndPoint: 127.0.0.1:3002
|
EndPoint: 127.0.0.1:3002
|
||||||
PersistentKeepalive: 30
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
|||||||
Name: tap1
|
Name: tap1
|
||||||
VPPIFaceID: 1
|
VPPIFaceID: 1
|
||||||
VPPBridgeID: 4242
|
VPPBridgeID: 4242
|
||||||
MacAddrPrefix: 8E:AA:C8:4B
|
MacAddrPrefix: DA:21:10:81
|
||||||
IPv4CIDR: 192.168.76.0/24
|
IPv4CIDR: 192.168.76.0/24
|
||||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||||
IPv6LLPrefix: fe80::a3df:0/112
|
IPv6LLPrefix: fe80::a3df:0/112
|
||||||
@ -12,17 +12,17 @@ Interface:
|
|||||||
SendAddr: 127.0.0.1:5001
|
SendAddr: 127.0.0.1:5001
|
||||||
L2HeaderMode: kbdbg
|
L2HeaderMode: kbdbg
|
||||||
NodeID: 2
|
NodeID: 2
|
||||||
NodeName: Node2
|
NodeName: EgNet2
|
||||||
PostScript: ""
|
PostScript: ""
|
||||||
DefaultTTL: 200
|
DefaultTTL: 200
|
||||||
L2FIBTimeout: 3600
|
L2FIBTimeout: 3600
|
||||||
PrivKey: WaeR98bFhy0rxw7unsaTo7aR2RmySo9l185IZqPWl1c=
|
PrivKey: M8SxYCTHCPES/yPqcKP4mr+AoMAx9sgUmk64FCJIv6k=
|
||||||
ListenPort: 3002
|
ListenPort: 3002
|
||||||
LogLevel:
|
LogLevel:
|
||||||
LogLevel: error
|
LogLevel: error
|
||||||
LogTransit: true
|
LogTransit: true
|
||||||
LogControl: true
|
|
||||||
LogNormal: true
|
LogNormal: true
|
||||||
|
LogControl: true
|
||||||
LogInternal: true
|
LogInternal: true
|
||||||
LogNTP: true
|
LogNTP: true
|
||||||
DynamicRoute:
|
DynamicRoute:
|
||||||
@ -100,20 +100,20 @@ NextHopTable:
|
|||||||
ResetConnInterval: 86400
|
ResetConnInterval: 86400
|
||||||
Peers:
|
Peers:
|
||||||
- NodeID: 1
|
- NodeID: 1
|
||||||
PubKey: iDhQA9pgL01Gb0MrPzbiV80P4Uv3+uY/s+wNTQye0Qo=
|
PubKey: fnc7bfFTf7B23hwtARPpX14tCeZwNfDhGCJctBpMfA8=
|
||||||
PSKey: kWDwCaC11UvYjfiXBMwYpR6Pujo1vaVW8JTusp1Kkrw=
|
PSKey: lFq67qp9LXL3PtlEJ3SGg3c/6++Ljy2I8i/k0Xcibvk=
|
||||||
EndPoint: 127.0.0.1:3001
|
EndPoint: 127.0.0.1:3001
|
||||||
PersistentKeepalive: 0
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
||||||
- NodeID: 3
|
- NodeID: 3
|
||||||
PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
|
PubKey: ymNpm430tiph3rMSVnQzDAxmK9+3jdcRFi6e96xmQUI=
|
||||||
PSKey: f2/34zUTLx8RP9cYisESoQlxz55oGZlTemqxv25VVa8=
|
PSKey: Y86PZY1ldgoyzPJxEqei5Vg5zlzkJkoO77LJfxV8alE=
|
||||||
EndPoint: 127.0.0.1:3003
|
EndPoint: 127.0.0.1:3003
|
||||||
PersistentKeepalive: 0
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
||||||
- NodeID: 4
|
- NodeID: 4
|
||||||
PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
|
PubKey: 9YSIkihv/+aeukOaWwsR9EKvO1DM9+5kN53a/osTpmA=
|
||||||
PSKey: zkG1ywPqS4MiGofuWmxHHBs8YBlnYd04B4T9IhkbXYM=
|
PSKey: QHyrrls0KT2dvBKtoWkZvq5NQ+Xyjm0YgbMUzCCRw34=
|
||||||
EndPoint: 127.0.0.1:3004
|
EndPoint: 127.0.0.1:3004
|
||||||
PersistentKeepalive: 30
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
|||||||
Name: tap1
|
Name: tap1
|
||||||
VPPIFaceID: 1
|
VPPIFaceID: 1
|
||||||
VPPBridgeID: 4242
|
VPPBridgeID: 4242
|
||||||
MacAddrPrefix: 8E:AA:C8:4B
|
MacAddrPrefix: DA:21:10:81
|
||||||
IPv4CIDR: 192.168.76.0/24
|
IPv4CIDR: 192.168.76.0/24
|
||||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||||
IPv6LLPrefix: fe80::a3df:0/112
|
IPv6LLPrefix: fe80::a3df:0/112
|
||||||
@ -12,17 +12,17 @@ Interface:
|
|||||||
SendAddr: 127.0.0.1:5001
|
SendAddr: 127.0.0.1:5001
|
||||||
L2HeaderMode: kbdbg
|
L2HeaderMode: kbdbg
|
||||||
NodeID: 3
|
NodeID: 3
|
||||||
NodeName: Node3
|
NodeName: EgNet3
|
||||||
PostScript: ""
|
PostScript: ""
|
||||||
DefaultTTL: 200
|
DefaultTTL: 200
|
||||||
L2FIBTimeout: 3600
|
L2FIBTimeout: 3600
|
||||||
PrivKey: vNUFWbZXySk2dTl5R9UEG73p+4IQmywvC1uQStf0vao=
|
PrivKey: cTO/GUSYHoj5mKczCyQu/ckPiDMEygkUbXcY3RafGEE=
|
||||||
ListenPort: 3003
|
ListenPort: 3003
|
||||||
LogLevel:
|
LogLevel:
|
||||||
LogLevel: error
|
LogLevel: error
|
||||||
LogTransit: true
|
LogTransit: true
|
||||||
LogControl: true
|
|
||||||
LogNormal: true
|
LogNormal: true
|
||||||
|
LogControl: true
|
||||||
LogInternal: true
|
LogInternal: true
|
||||||
LogNTP: true
|
LogNTP: true
|
||||||
DynamicRoute:
|
DynamicRoute:
|
||||||
@ -99,21 +99,21 @@ NextHopTable:
|
|||||||
5: 4
|
5: 4
|
||||||
ResetConnInterval: 86400
|
ResetConnInterval: 86400
|
||||||
Peers:
|
Peers:
|
||||||
- NodeID: 5
|
|
||||||
PubKey: AarP7cL6TVmFyHRZLXuxFGr5uQghsp57ydsJdj+lGzs=
|
|
||||||
PSKey: +TU8Zi8dr/UBqNyW/MYMgJiqkLnRbHW4ExQYQ2eNEag=
|
|
||||||
EndPoint: 127.0.0.1:3005
|
|
||||||
PersistentKeepalive: 0
|
|
||||||
Static: true
|
|
||||||
- NodeID: 2
|
- NodeID: 2
|
||||||
PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
|
PubKey: 0r2o9Hb36gYVgD3VSKCH18MVOZw0BvzcJ6TOTo6Cc1g=
|
||||||
PSKey: f2/34zUTLx8RP9cYisESoQlxz55oGZlTemqxv25VVa8=
|
PSKey: Y86PZY1ldgoyzPJxEqei5Vg5zlzkJkoO77LJfxV8alE=
|
||||||
EndPoint: 127.0.0.1:3002
|
EndPoint: 127.0.0.1:3002
|
||||||
PersistentKeepalive: 0
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
||||||
- NodeID: 4
|
- NodeID: 4
|
||||||
PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
|
PubKey: 9YSIkihv/+aeukOaWwsR9EKvO1DM9+5kN53a/osTpmA=
|
||||||
PSKey: 8HN+PBGDKmBFCDlWIyNUFFYS4X6ONGXI32AIKXSnUqU=
|
PSKey: SQyLomXDeknBIFezUKardOviAmNS+YZ1XTvZtYVlOtE=
|
||||||
EndPoint: 127.0.0.1:3004
|
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
|
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
|||||||
Name: tap1
|
Name: tap1
|
||||||
VPPIFaceID: 1
|
VPPIFaceID: 1
|
||||||
VPPBridgeID: 4242
|
VPPBridgeID: 4242
|
||||||
MacAddrPrefix: 8E:AA:C8:4B
|
MacAddrPrefix: DA:21:10:81
|
||||||
IPv4CIDR: 192.168.76.0/24
|
IPv4CIDR: 192.168.76.0/24
|
||||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||||
IPv6LLPrefix: fe80::a3df:0/112
|
IPv6LLPrefix: fe80::a3df:0/112
|
||||||
@ -12,17 +12,17 @@ Interface:
|
|||||||
SendAddr: 127.0.0.1:5001
|
SendAddr: 127.0.0.1:5001
|
||||||
L2HeaderMode: kbdbg
|
L2HeaderMode: kbdbg
|
||||||
NodeID: 4
|
NodeID: 4
|
||||||
NodeName: Node4
|
NodeName: EgNet4
|
||||||
PostScript: ""
|
PostScript: ""
|
||||||
DefaultTTL: 200
|
DefaultTTL: 200
|
||||||
L2FIBTimeout: 3600
|
L2FIBTimeout: 3600
|
||||||
PrivKey: sn0BUwyNxfmgePYi6O6a8pFDKiLaCz6jk3ws+covRTA=
|
PrivKey: ai9XXdezwamYHf7EvzmLGlMp7mUg+hZwoqLefzwHWVM=
|
||||||
ListenPort: 3004
|
ListenPort: 3004
|
||||||
LogLevel:
|
LogLevel:
|
||||||
LogLevel: error
|
LogLevel: error
|
||||||
LogTransit: true
|
LogTransit: true
|
||||||
LogControl: true
|
|
||||||
LogNormal: true
|
LogNormal: true
|
||||||
|
LogControl: true
|
||||||
LogInternal: true
|
LogInternal: true
|
||||||
LogNTP: true
|
LogNTP: true
|
||||||
DynamicRoute:
|
DynamicRoute:
|
||||||
@ -100,20 +100,20 @@ NextHopTable:
|
|||||||
ResetConnInterval: 86400
|
ResetConnInterval: 86400
|
||||||
Peers:
|
Peers:
|
||||||
- NodeID: 2
|
- NodeID: 2
|
||||||
PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
|
PubKey: 0r2o9Hb36gYVgD3VSKCH18MVOZw0BvzcJ6TOTo6Cc1g=
|
||||||
PSKey: zkG1ywPqS4MiGofuWmxHHBs8YBlnYd04B4T9IhkbXYM=
|
PSKey: QHyrrls0KT2dvBKtoWkZvq5NQ+Xyjm0YgbMUzCCRw34=
|
||||||
EndPoint: 127.0.0.1:3002
|
EndPoint: 127.0.0.1:3002
|
||||||
PersistentKeepalive: 0
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
||||||
- NodeID: 3
|
- NodeID: 3
|
||||||
PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
|
PubKey: ymNpm430tiph3rMSVnQzDAxmK9+3jdcRFi6e96xmQUI=
|
||||||
PSKey: 8HN+PBGDKmBFCDlWIyNUFFYS4X6ONGXI32AIKXSnUqU=
|
PSKey: SQyLomXDeknBIFezUKardOviAmNS+YZ1XTvZtYVlOtE=
|
||||||
EndPoint: 127.0.0.1:3003
|
EndPoint: 127.0.0.1:3003
|
||||||
PersistentKeepalive: 0
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
||||||
- NodeID: 6
|
- NodeID: 6
|
||||||
PubKey: GH6ra6xhDezskkJrr/DXPi93vtmhi96DFBJ3s8U20EA=
|
PubKey: f6kHXq3qPLocdM0CZEkoumOHevrabzqOBFG5vg9cjDc=
|
||||||
PSKey: f50pI53AQ6RoTGEnTSjl5YJhuMS/xiJjwtPuiP0xMUM=
|
PSKey: crsb9pbTY/Bei7TugjPNtg4dVKVzjwC/A6AjlSVoqbQ=
|
||||||
EndPoint: 127.0.0.1:3006
|
EndPoint: 127.0.0.1:3006
|
||||||
PersistentKeepalive: 30
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
|||||||
Name: tap1
|
Name: tap1
|
||||||
VPPIFaceID: 1
|
VPPIFaceID: 1
|
||||||
VPPBridgeID: 4242
|
VPPBridgeID: 4242
|
||||||
MacAddrPrefix: 8E:AA:C8:4B
|
MacAddrPrefix: DA:21:10:81
|
||||||
IPv4CIDR: 192.168.76.0/24
|
IPv4CIDR: 192.168.76.0/24
|
||||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||||
IPv6LLPrefix: fe80::a3df:0/112
|
IPv6LLPrefix: fe80::a3df:0/112
|
||||||
@ -12,17 +12,17 @@ Interface:
|
|||||||
SendAddr: 127.0.0.1:5001
|
SendAddr: 127.0.0.1:5001
|
||||||
L2HeaderMode: kbdbg
|
L2HeaderMode: kbdbg
|
||||||
NodeID: 5
|
NodeID: 5
|
||||||
NodeName: Node5
|
NodeName: EgNet5
|
||||||
PostScript: ""
|
PostScript: ""
|
||||||
DefaultTTL: 200
|
DefaultTTL: 200
|
||||||
L2FIBTimeout: 3600
|
L2FIBTimeout: 3600
|
||||||
PrivKey: Blk9f1+NiC2fVCZpUBG34G9hrcLThemk/1Zd/dET6AA=
|
PrivKey: hBNK6Wu/Cl2MOXVA/F8yZsqIQ5eeIYCKPJeLu7i/190=
|
||||||
ListenPort: 3005
|
ListenPort: 3005
|
||||||
LogLevel:
|
LogLevel:
|
||||||
LogLevel: error
|
LogLevel: error
|
||||||
LogTransit: true
|
LogTransit: true
|
||||||
LogControl: true
|
|
||||||
LogNormal: true
|
LogNormal: true
|
||||||
|
LogControl: true
|
||||||
LogInternal: true
|
LogInternal: true
|
||||||
LogNTP: true
|
LogNTP: true
|
||||||
DynamicRoute:
|
DynamicRoute:
|
||||||
@ -100,8 +100,8 @@ NextHopTable:
|
|||||||
ResetConnInterval: 86400
|
ResetConnInterval: 86400
|
||||||
Peers:
|
Peers:
|
||||||
- NodeID: 3
|
- NodeID: 3
|
||||||
PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
|
PubKey: ymNpm430tiph3rMSVnQzDAxmK9+3jdcRFi6e96xmQUI=
|
||||||
PSKey: +TU8Zi8dr/UBqNyW/MYMgJiqkLnRbHW4ExQYQ2eNEag=
|
PSKey: ChWBQurfGNZE5xIlhi9EUvZrQPBvkFsfrPaD6tyqSYg=
|
||||||
EndPoint: 127.0.0.1:3003
|
EndPoint: 127.0.0.1:3003
|
||||||
PersistentKeepalive: 30
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
|||||||
Name: tap1
|
Name: tap1
|
||||||
VPPIFaceID: 1
|
VPPIFaceID: 1
|
||||||
VPPBridgeID: 4242
|
VPPBridgeID: 4242
|
||||||
MacAddrPrefix: 8E:AA:C8:4B
|
MacAddrPrefix: DA:21:10:81
|
||||||
IPv4CIDR: 192.168.76.0/24
|
IPv4CIDR: 192.168.76.0/24
|
||||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||||
IPv6LLPrefix: fe80::a3df:0/112
|
IPv6LLPrefix: fe80::a3df:0/112
|
||||||
@ -12,17 +12,17 @@ Interface:
|
|||||||
SendAddr: 127.0.0.1:5001
|
SendAddr: 127.0.0.1:5001
|
||||||
L2HeaderMode: kbdbg
|
L2HeaderMode: kbdbg
|
||||||
NodeID: 6
|
NodeID: 6
|
||||||
NodeName: Node6
|
NodeName: EgNet6
|
||||||
PostScript: ""
|
PostScript: ""
|
||||||
DefaultTTL: 200
|
DefaultTTL: 200
|
||||||
L2FIBTimeout: 3600
|
L2FIBTimeout: 3600
|
||||||
PrivKey: h03OJ1d8cVGF8TemiWWTla7RCIMtInhUnjs2CBb8AT8=
|
PrivKey: ao6wfUYOG3FBYYPlb+VtXk2ZiK6j/6ac75Y9VuKd2Vs=
|
||||||
ListenPort: 3006
|
ListenPort: 3006
|
||||||
LogLevel:
|
LogLevel:
|
||||||
LogLevel: error
|
LogLevel: error
|
||||||
LogTransit: true
|
LogTransit: true
|
||||||
LogControl: true
|
|
||||||
LogNormal: true
|
LogNormal: true
|
||||||
|
LogControl: true
|
||||||
LogInternal: true
|
LogInternal: true
|
||||||
LogNTP: true
|
LogNTP: true
|
||||||
DynamicRoute:
|
DynamicRoute:
|
||||||
@ -100,8 +100,8 @@ NextHopTable:
|
|||||||
ResetConnInterval: 86400
|
ResetConnInterval: 86400
|
||||||
Peers:
|
Peers:
|
||||||
- NodeID: 4
|
- NodeID: 4
|
||||||
PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
|
PubKey: 9YSIkihv/+aeukOaWwsR9EKvO1DM9+5kN53a/osTpmA=
|
||||||
PSKey: f50pI53AQ6RoTGEnTSjl5YJhuMS/xiJjwtPuiP0xMUM=
|
PSKey: crsb9pbTY/Bei7TugjPNtg4dVKVzjwC/A6AjlSVoqbQ=
|
||||||
EndPoint: 127.0.0.1:3004
|
EndPoint: 127.0.0.1:3004
|
||||||
PersistentKeepalive: 30
|
PersistentKeepalive: 0
|
||||||
Static: true
|
Static: true
|
@ -1,84 +1,105 @@
|
|||||||
# Etherguard
|
# Etherguard
|
||||||
[English](README.md)
|
[English](README.md) | [中文](#)
|
||||||
|
|
||||||
Static Mode的[範例配置檔](./)的說明文件
|
|
||||||
|
|
||||||
## Static Mode
|
## Static Mode
|
||||||
|
|
||||||
沒有自動選路,沒有握手伺服器
|
沒有自動選路,沒有握手伺服器
|
||||||
|
類似原本的wireguard,一切都要提前配置好
|
||||||
|
設定檔裡面的`NextHopTable`部分,只有此模式會生效
|
||||||
|
|
||||||
十分類似原本的wireguard,一切都要提前配置好
|
這個模式下,不存在任何的Control Message,斷線偵測什麼的也不會有
|
||||||
|
|
||||||
但是除了peer以外,還要額外配置轉發表,所有人共用一份轉發表
|
|
||||||
|
|
||||||
設定檔裡面的`nexthoptable`部分,只有此模式會生效
|
|
||||||
|
|
||||||
這個模式下,不存在任何的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)
|
!["Topology"](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/static_mode/Example_static.png)
|
||||||
|
|
||||||
發出封包時,會設定起始ID=自己的Node ID,終點ID則是看Dst Mac Address。
|
發出封包時,會設定起始ID=自己的Node ID,終點ID則是看Dst Mac Address。
|
||||||
如果Dst MacAddr是廣播地址,或是不在自己的對應表裡面,就會設定終點=Boardcast
|
如果Dst MacAddr是廣播地址,或是不在自己的對應表裡面,就會設定終點=Broadcast
|
||||||
|
|
||||||
收到封包的時候,如果`dst==自己ID`,就會收下,不轉給任何人。
|
收到封包的時候,如果`dst==自己ID`,就會收下,不轉給任何人。
|
||||||
同時還會看它的 Src Mac Address 和 Src NodeID ,並加入對應表
|
同時還會看它的 Src Mac Address 和 Src NodeID ,並加入對應表
|
||||||
這樣下次傳給他就可以直接傳給目標,而不用廣播給全節點了
|
這樣下次傳給他就可以直接傳給目標,而不用廣播給全節點了
|
||||||
|
|
||||||
所以設定檔中的轉發表如下表。格式是yaml的巢狀dictionary
|
所以設定檔中的轉發表如下表。格式是yaml的巢狀dictionary
|
||||||
轉發/發送封包時,直接查詢 `NhTable[起點][終點]=下一跳`
|
轉發/發送封包時,直接查詢`NhTable`
|
||||||
就知道下面一個封包要轉給誰了
|
就知道下面一個封包要轉給誰了
|
||||||
|
|
||||||
|
NextHopTable 是長這樣的資料結構,`NhTable[起點][終點]=下一跳`
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
nexthoptable:
|
NextHopTable:
|
||||||
1:
|
1:
|
||||||
2: 2
|
2: 2
|
||||||
3: 2
|
3: 2
|
||||||
4: 2
|
|
||||||
5: 2
|
|
||||||
6: 2
|
|
||||||
2:
|
2:
|
||||||
1: 1
|
1: 1
|
||||||
3: 3
|
3: 3
|
||||||
4: 4
|
|
||||||
5: 3
|
|
||||||
6: 4
|
|
||||||
3:
|
3:
|
||||||
1: 2
|
1: 2
|
||||||
2: 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
|
### Broadcast
|
||||||
比較特別的是`終點ID=Boardcast`的情況。
|
比較特別的是`終點ID=Broadcast`的情況。
|
||||||
|
|
||||||
假設今天的狀況:我是4號,我收到`起點ID = 1,終點ID=boardcast`的封包
|
假設今天的狀況:我是4號,我收到`起點ID = 1,終點ID=Broadcast`的封包
|
||||||
我應該只轉給6號就好,而不會轉給3號。
|
我應該只轉給6號就好,而不會轉給3號。
|
||||||
因為3號會收到來自2號的封包,自己就不用重複遞送了
|
因為3號會收到來自2號的封包,自己就不用重複遞送了
|
||||||
|
|
||||||
因此我有設計,如果`終點ID = Boardcast`,就會檢查Src到自己的所有鄰居,會不會經過自己
|
因此我有設計,如果`終點ID = Broadcast`,就會檢查Src到自己的所有鄰居,會不會經過自己
|
||||||
**1 -> 6** 會經過自己: [1 2 4 6]
|
**1 -> 6** 會經過自己: [1 2 4 6]
|
||||||
**1 -> 3** 不會: [1 2 3]
|
**1 -> 3** 不會: [1 2 3]
|
||||||
2號是封包來源跳過檢查
|
2號是封包來源跳過檢查
|
||||||
@ -94,189 +115,97 @@ nexthoptable:
|
|||||||
|
|
||||||
```
|
```
|
||||||
X 1 2 3 4 5 6
|
X 1 2 3 4 5 6
|
||||||
1 0 0.5 Inf Inf Inf Inf
|
1 0 1.0 Inf Inf Inf Inf
|
||||||
2 0.5 0 0.5 0.5 Inf Inf
|
2 1.0 0 1.0 1.0 Inf Inf
|
||||||
3 Inf 0.5 0 0.5 0.5 Inf
|
3 Inf 1.0 0 1 1.0 Inf
|
||||||
4 Inf 0.5 0.5 0 Inf 0.5
|
4 Inf 1.0 1.0 0 Inf 1.0
|
||||||
5 Inf Inf 0.5 Inf 0 Inf
|
5 Inf Inf 1.0 Inf 1.0 Inf
|
||||||
6 Inf Inf Inf 0.5 Inf 0
|
6 Inf Inf Inf 1.0 Inf 1.0
|
||||||
```
|
```
|
||||||
|
|
||||||
之後用這個指令就能輸出用Floyd Warshall算好的轉發表了,填入設定檔即可
|
之後用這個指令就能輸出用Floyd Warshall算好的轉發表了,填入設定檔即可
|
||||||
```
|
|
||||||
./etherguard-go -config example_config/static_mode/path.txt -mode slove
|
|
||||||
|
|
||||||
NextHopTable:
|
### EdgeNode Config Parameter
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
程式還會額外輸出一些資訊,像是路徑表。
|
Key | Description
|
||||||
會標示所有的起點終點組合的封包路徑,還有行經距離
|
-------------- |:-----
|
||||||
```
|
[Interface](#Interface)| 接口相關設定。VPN有兩端,一端是VPN網路,另一端則是本地接口
|
||||||
Human readable:
|
NodeID | 節點ID。節點之間辨識身分用的,同一網路內節點ID不能重複
|
||||||
src dist path
|
NodeName | 節點名稱
|
||||||
1 -> 2 0.500000 [1 2]
|
PostScript | 初始化完畢之後要跑的腳本
|
||||||
1 -> 3 1.000000 [1 2 3]
|
DefaultTTL | TTL,etherguard層使用,和乙太層不共通
|
||||||
1 -> 4 1.000000 [1 2 4]
|
L2FIBTimeout | MacAddr-> NodeID 查找表的 timeout(秒) ,類似ARP table
|
||||||
1 -> 5 1.500000 [1 2 3 5]
|
PrivKey | 私鑰,和wireguard規格一樣
|
||||||
1 -> 6 1.500000 [1 2 4 6]
|
ListenPort | 監聽的udp埠
|
||||||
2 -> 1 0.500000 [2 1]
|
[LogLevel](#LogLevel)| 紀錄log
|
||||||
2 -> 3 0.500000 [2 3]
|
[DynamicRoute](../super_mode/README_zh.md#DynamicRoute) | 動態路由相關設定,Static模式用不到
|
||||||
2 -> 4 0.500000 [2 4]
|
NextHopTable | 轉發表, 下一跳 = `NhTable[起點][終點]`
|
||||||
2 -> 5 1.000000 [2 3 5]
|
ResetConnInterval | 如果對方是動態ip就要用這個。每隔一段時間就會重置連線,重新解析域名
|
||||||
2 -> 6 1.000000 [2 4 6]
|
[Peers](#Peers) | 鄰居節點,和wireguard相同
|
||||||
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]
|
|
||||||
```
|
|
||||||
|
|
||||||
有些設定檔對應某些運作模式,這邊針對共同部分的設定做說明
|
<a name="Interface"></a>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
|
<a name="IType"></a>IType | Description
|
||||||
|
-----------|:-----
|
||||||
|
dummy | 收到的封包直接丟棄,但幫忙轉發。作為中繼節點,本身不加入網路使用
|
||||||
|
stdio | 收到的封包丟stdout,stdin進來的資料丟入vpn網路,debug用途<br>需要參數: `MacAddrPrefix` && `L2HeaderMode`
|
||||||
|
udpsock | 收到的封包丟去一個udp socket<br>需要參數: `RecvAddr` && `SendAddr`
|
||||||
|
tcpsock | 收到的封包丟去一個tcp socket<br>需要參數: `RecvAddr` \|\| `SendAddr`
|
||||||
|
unixsock | 收到的封包丟去一個unix socket(SOCK_STREAM 模式)<br>需要參數: `RecvAddr` \|\| `SendAddr`
|
||||||
|
udpsock | 收到的封包丟去一個unix socket(SOCK_DGRAM 模式)<br>需要參數: `RecvAddr` \|\| `SendAddr`
|
||||||
|
udpsock | 收到的封包丟去一個unix socket(SOCK_SEQPACKET 模式)<br>需要參數: `RecvAddr` \|\| `SendAddr`
|
||||||
|
fd | 收到的封包丟去一個特定的file descriptor<br>需要參數: 無. 但是使用環境變數 `EG_FD_RX` && `EG_FD_TX` 來指定
|
||||||
|
vpp | 使用libmemif使vpp加入VPN網路<br>需要參數: `Name` && `VPPIFaceID` && `VPPBridgeID` && `MacAddrPrefix` && `MTU`
|
||||||
|
tap | Linux的tap設備。讓linux加入VPN網路<br>需要參數: `Name` && `MacAddrPrefix` && `MTU`<br>可選參數:`IPv4CIDR` , `IPv6CIDR` , `IPv6LLPrefix`
|
||||||
|
|
||||||
1. `interface`
|
<a name="L2HeaderMode"></a>L2HeaderMode | Description
|
||||||
1. `itype`: 裝置類型,意味著從VPN網路收到的封包要丟去哪個硬體
|
---------------|:-----
|
||||||
1. `dummy`: 收到的封包直接丟棄,也不發出任何封包。作為中繼節點使用
|
nochg | 收到的封包丟stdout,stdin進來的資料丟入vpn網路,不對封包作任何更動
|
||||||
2. `stdio`: 收到的封包丟stdout,stdin進來的資料丟入vpn網路
|
kbdbg | 前 12byte 會用來做選路判斷<br>但是stdio模式下,使用鍵盤輸入一個Ethernet frame不太方便<br>此模式讓我快速產生Ethernet frame,debug更方便<br>`b`轉換成`FF:FF:FF:FF:FF:FF`<br>`2`轉換成 `AA:BB:CC:DD:EE:02`<br>輸入`b2aaaaa`就會變成`b"0xffffffffffffaabbccddee02aaaaa"`
|
||||||
需要參數: `macaddrprefix`,`l2headermode`
|
noL2 | 讀取時拔掉L2 Header的模式<br>寫入時時一律使用廣播MacAddress
|
||||||
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覆寫
|
|
||||||
|
|
||||||
### Super config
|
<a name="LogLevel"></a>LogLevel | Description
|
||||||
|
------------|:-----
|
||||||
|
LogLevel | wireguard原本的log紀錄器的loglevel<br>接受參數: `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)
|
<a name="Peers"></a>Peers | Description
|
||||||
|
--------------------|:-----
|
||||||
### Quick start
|
NodeID | 對方的節點ID
|
||||||
|
PubKey | 對方的公鑰
|
||||||
|
PSKey | 對方的預共享金鑰
|
||||||
|
EndPoint | 對方的連線地址。如果漫遊,而且`Static=false`會覆寫設定檔
|
||||||
|
PersistentKeepalive | wireguard的PersistentKeepalive參數
|
||||||
|
Static | 關閉漫遊功能,每隔`ResetConnInterval`秒,重置回初始ip
|
||||||
|
|
||||||
#### Run example config
|
#### Run example config
|
||||||
|
|
||||||
在**不同terminal**分別執行以下命令
|
在**不同terminal**分別執行以下命令
|
||||||
|
|
||||||
```
|
```
|
||||||
./etherguard-go -config example_config/super_mode/n1.yaml -mode edge
|
./etherguard-go -config example_config/super_mode/EgNet_edge1.yaml -mode edge
|
||||||
./etherguard-go -config example_config/super_mode/n2.yaml -mode edge
|
./etherguard-go -config example_config/super_mode/EgNet_edge2.yaml -mode edge
|
||||||
./etherguard-go -config example_config/super_mode/n3.yaml -mode edge
|
./etherguard-go -config example_config/super_mode/EgNet_edge3.yaml -mode edge
|
||||||
./etherguard-go -config example_config/super_mode/n4.yaml -mode edge
|
./etherguard-go -config example_config/super_mode/EgNet_edge4.yaml -mode edge
|
||||||
./etherguard-go -config example_config/super_mode/n5.yaml -mode edge
|
./etherguard-go -config example_config/super_mode/EgNet_edge5.yaml -mode edge
|
||||||
./etherguard-go -config example_config/super_mode/n6.yaml -mode edge
|
./etherguard-go -config example_config/super_mode/EgNet_edge6.yaml -mode edge
|
||||||
```
|
```
|
||||||
|
|
||||||
因為本範例配置是stdio的kbdbg模式,stdin會讀入VPN網路
|
因為本範例配置是stdio的kbdbg模式,stdin會讀入VPN網路
|
||||||
@ -284,12 +213,7 @@ src dist path
|
|||||||
```
|
```
|
||||||
b1message
|
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被轉換回來了
|
此時應該要能夠在另一個視窗上看見字串b1message。前12byte被轉換回來了
|
||||||
|
|
||||||
#### Run your own etherguard
|
|
||||||
|
|
||||||
要正式使用,請將itype改成`tap`,並且修改各節點的公鑰私鑰和連線地址
|
|
||||||
再關閉不必要的log增加性能,最後部屬到不同節點即可
|
|
||||||
|
|
||||||
## 下一篇: [Super Mode的運作](../super_mode/README_zh.md)
|
## 下一篇: [Super Mode的運作](../super_mode/README_zh.md)
|
@ -1,6 +1,6 @@
|
|||||||
Config output dir: /tmp/eg_gen_static
|
Config output dir: /tmp/eg_gen_static
|
||||||
ConfigTemplate for edge node: "n1.yaml"
|
ConfigTemplate for edge node: "" # "EgNet_edge1.yaml"
|
||||||
Network name: "Node"
|
Network name: "EgNet"
|
||||||
Edge Node:
|
Edge Node:
|
||||||
MacAddress prefix: ""
|
MacAddress prefix: ""
|
||||||
IPv4 range: 192.168.76.0/24
|
IPv4 range: 192.168.76.0/24
|
||||||
@ -9,27 +9,21 @@ Edge Node:
|
|||||||
Edge Nodes:
|
Edge Nodes:
|
||||||
1:
|
1:
|
||||||
Endpoint(optional): 127.0.0.1:3001
|
Endpoint(optional): 127.0.0.1:3001
|
||||||
PersistentKeepalive: 30
|
|
||||||
2:
|
2:
|
||||||
Endpoint(optional): 127.0.0.1:3002
|
Endpoint(optional): 127.0.0.1:3002
|
||||||
PersistentKeepalive: 30
|
|
||||||
3:
|
3:
|
||||||
Endpoint(optional): 127.0.0.1:3003
|
Endpoint(optional): 127.0.0.1:3003
|
||||||
PersistentKeepalive: 30
|
|
||||||
4:
|
4:
|
||||||
Endpoint(optional): 127.0.0.1:3004
|
Endpoint(optional): 127.0.0.1:3004
|
||||||
PersistentKeepalive: 30
|
|
||||||
5:
|
5:
|
||||||
Endpoint(optional): 127.0.0.1:3005
|
Endpoint(optional): 127.0.0.1:3005
|
||||||
PersistentKeepalive: 30
|
|
||||||
6:
|
6:
|
||||||
Endpoint(optional): 127.0.0.1:3006
|
Endpoint(optional): 127.0.0.1:3006
|
||||||
PersistentKeepalive: 30
|
|
||||||
Distance matrix for all nodes: |-
|
Distance matrix for all nodes: |-
|
||||||
X 1 2 3 4 5 6
|
X 1 2 3 4 5 6
|
||||||
1 0 1 Inf Inf Inf Inf
|
1 0 1.0 Inf Inf Inf Inf
|
||||||
2 1 0 1 1 Inf Inf
|
2 1.0 0 1.0 1.0 Inf Inf
|
||||||
3 Inf 1 0 1 1 Inf
|
3 Inf 1.0 0 1 1.0 Inf
|
||||||
4 Inf 1 1 0 Inf 1
|
4 Inf 1.0 1.0 0 Inf 1.0
|
||||||
5 Inf Inf 1 Inf 0 Inf
|
5 Inf Inf 1.0 Inf 1.0 Inf
|
||||||
6 Inf Inf Inf 1 Inf 0
|
6 Inf Inf Inf 1.0 Inf 1.0
|
Binary file not shown.
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 43 KiB |
BIN
example_config/super_mode/EGS08.png
Normal file
BIN
example_config/super_mode/EGS08.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
@ -1,28 +1,28 @@
|
|||||||
Interface:
|
Interface:
|
||||||
IType: stdio
|
IType: stdio
|
||||||
Name: tap1
|
Name: Node001
|
||||||
VPPIFaceID: 1
|
VPPIFaceID: 1
|
||||||
VPPBridgeID: 4242
|
VPPBridgeID: 4242
|
||||||
MacAddrPrefix: AA:BB:CC:DD
|
MacAddrPrefix: CE:51:BA:B4
|
||||||
IPv4CIDR: ""
|
IPv4CIDR: 192.168.76.0/24
|
||||||
IPv6CIDR: ""
|
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||||
IPv6LLPrefix: ""
|
IPv6LLPrefix: fe80::a3df:0/112
|
||||||
MTU: 1416
|
MTU: 1416
|
||||||
RecvAddr: 127.0.0.1:4001
|
RecvAddr: 127.0.0.1:4001
|
||||||
SendAddr: 127.0.0.1:5001
|
SendAddr: 127.0.0.1:5001
|
||||||
L2HeaderMode: kbdbg
|
L2HeaderMode: kbdbg
|
||||||
NodeID: 1
|
NodeID: 1
|
||||||
NodeName: Node01
|
NodeName: Node001
|
||||||
PostScript: ""
|
PostScript: ""
|
||||||
DefaultTTL: 200
|
DefaultTTL: 200
|
||||||
L2FIBTimeout: 3600
|
L2FIBTimeout: 3600
|
||||||
PrivKey: 6GyDagZKhbm5WNqMiRHhkf43RlbMJ34IieTlIuvfJ1M=
|
PrivKey: C0SXvffZh8nDqXYNzG4UqUJtSCiRMEj3ehX5o7QiJz0=
|
||||||
ListenPort: 0
|
ListenPort: 3001
|
||||||
LogLevel:
|
LogLevel:
|
||||||
LogLevel: error
|
LogLevel: error
|
||||||
LogTransit: true
|
LogTransit: false
|
||||||
LogControl: true
|
LogControl: true
|
||||||
LogNormal: true
|
LogNormal: false
|
||||||
LogInternal: true
|
LogInternal: true
|
||||||
LogNTP: true
|
LogNTP: true
|
||||||
DynamicRoute:
|
DynamicRoute:
|
||||||
@ -35,12 +35,12 @@ DynamicRoute:
|
|||||||
SaveNewPeers: true
|
SaveNewPeers: true
|
||||||
SuperNode:
|
SuperNode:
|
||||||
UseSuperNode: true
|
UseSuperNode: true
|
||||||
PSKey: iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=
|
PSKey: j2f9Fhdhw2O2zLqUqfL5nTFStjVWPnEXpw7Iqz6VX9M=
|
||||||
EndpointV4: 127.0.0.1:3000
|
EndpointV4: 127.0.0.1:3456
|
||||||
PubKeyV4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
PubKeyV4: Id/VoZ6HmTU3FSqhxBUswfuHHB0mQxfzcbdoJNGBRzQ=
|
||||||
EndpointV6: '[::1]:3000'
|
EndpointV6: :3456
|
||||||
PubKeyV6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
PubKeyV6: 40tADRhJTvaortwE5Ur4qNXhP+SOMX7ZuSvl251Yxnc=
|
||||||
EndpointEdgeAPIUrl: http://127.0.0.1:3000/eg_api
|
EndpointEdgeAPIUrl: http://127.0.0.1:3456/eg_net/eg_api
|
||||||
SkipLocalIP: false
|
SkipLocalIP: false
|
||||||
SuperNodeInfoTimeout: 50
|
SuperNodeInfoTimeout: 50
|
||||||
P2P:
|
P2P:
|
||||||
@ -48,8 +48,10 @@ DynamicRoute:
|
|||||||
SendPeerInterval: 20
|
SendPeerInterval: 20
|
||||||
GraphRecalculateSetting:
|
GraphRecalculateSetting:
|
||||||
StaticMode: false
|
StaticMode: false
|
||||||
JitterTolerance: 20
|
ManualLatency: {}
|
||||||
|
JitterTolerance: 50
|
||||||
JitterToleranceMultiplier: 1.1
|
JitterToleranceMultiplier: 1.1
|
||||||
|
DampingResistance: 0
|
||||||
TimeoutCheckInterval: 5
|
TimeoutCheckInterval: 5
|
||||||
RecalculateCoolDown: 5
|
RecalculateCoolDown: 5
|
||||||
NTPConfig:
|
NTPConfig:
|
@ -1,28 +1,28 @@
|
|||||||
Interface:
|
Interface:
|
||||||
IType: stdio
|
IType: stdio
|
||||||
Name: tap1
|
Name: Node002
|
||||||
VPPIFaceID: 2
|
VPPIFaceID: 1
|
||||||
VPPBridgeID: 4242
|
VPPBridgeID: 4242
|
||||||
MacAddrPrefix: AA:BB:CC:DD
|
MacAddrPrefix: CE:51:BA:B4
|
||||||
IPv4CIDR: ""
|
IPv4CIDR: 192.168.76.0/24
|
||||||
IPv6CIDR: ""
|
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||||
IPv6LLPrefix: ""
|
IPv6LLPrefix: fe80::a3df:0/112
|
||||||
MTU: 1416
|
MTU: 1416
|
||||||
RecvAddr: 127.0.0.1:4002
|
RecvAddr: 127.0.0.1:4002
|
||||||
SendAddr: 127.0.0.1:5002
|
SendAddr: 127.0.0.1:5002
|
||||||
L2HeaderMode: kbdbg
|
L2HeaderMode: kbdbg
|
||||||
NodeID: 2
|
NodeID: 2
|
||||||
NodeName: Node02
|
NodeName: Node002
|
||||||
PostScript: ""
|
PostScript: ""
|
||||||
DefaultTTL: 200
|
DefaultTTL: 200
|
||||||
L2FIBTimeout: 3600
|
L2FIBTimeout: 3600
|
||||||
PrivKey: OH8BsVUU2Rqzeu9B2J5GPG8PUmxWfX8uVvNFZKhVF3o=
|
PrivKey: AErxhLXdZvidPZVXRYgD+84fa2qYWG9ft4MRuCbAtt8=
|
||||||
ListenPort: 0
|
ListenPort: 3002
|
||||||
LogLevel:
|
LogLevel:
|
||||||
LogLevel: error
|
LogLevel: error
|
||||||
LogTransit: true
|
LogTransit: false
|
||||||
LogControl: true
|
LogControl: true
|
||||||
LogNormal: true
|
LogNormal: false
|
||||||
LogInternal: true
|
LogInternal: true
|
||||||
LogNTP: true
|
LogNTP: true
|
||||||
DynamicRoute:
|
DynamicRoute:
|
||||||
@ -35,12 +35,12 @@ DynamicRoute:
|
|||||||
SaveNewPeers: true
|
SaveNewPeers: true
|
||||||
SuperNode:
|
SuperNode:
|
||||||
UseSuperNode: true
|
UseSuperNode: true
|
||||||
PSKey: juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=
|
PSKey: iCw096jsW2aWyMwPyzVEvL8C3XXqMpB+jOeWqDC34uU=
|
||||||
EndpointV4: 127.0.0.1:3000
|
EndpointV4: 127.0.0.1:3456
|
||||||
PubKeyV4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
PubKeyV4: Id/VoZ6HmTU3FSqhxBUswfuHHB0mQxfzcbdoJNGBRzQ=
|
||||||
EndpointV6: '[::1]:3000'
|
EndpointV6: :3456
|
||||||
PubKeyV6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
PubKeyV6: 40tADRhJTvaortwE5Ur4qNXhP+SOMX7ZuSvl251Yxnc=
|
||||||
EndpointEdgeAPIUrl: http://127.0.0.1:3000/eg_api
|
EndpointEdgeAPIUrl: http://127.0.0.1:3456/eg_net/eg_api
|
||||||
SkipLocalIP: false
|
SkipLocalIP: false
|
||||||
SuperNodeInfoTimeout: 50
|
SuperNodeInfoTimeout: 50
|
||||||
P2P:
|
P2P:
|
||||||
@ -48,8 +48,10 @@ DynamicRoute:
|
|||||||
SendPeerInterval: 20
|
SendPeerInterval: 20
|
||||||
GraphRecalculateSetting:
|
GraphRecalculateSetting:
|
||||||
StaticMode: false
|
StaticMode: false
|
||||||
JitterTolerance: 20
|
ManualLatency: {}
|
||||||
|
JitterTolerance: 50
|
||||||
JitterToleranceMultiplier: 1.1
|
JitterToleranceMultiplier: 1.1
|
||||||
|
DampingResistance: 0
|
||||||
TimeoutCheckInterval: 5
|
TimeoutCheckInterval: 5
|
||||||
RecalculateCoolDown: 5
|
RecalculateCoolDown: 5
|
||||||
NTPConfig:
|
NTPConfig:
|
@ -1,12 +1,12 @@
|
|||||||
Interface:
|
Interface:
|
||||||
IType: stdio
|
IType: stdio
|
||||||
Name: tap1
|
Name: Node100
|
||||||
VPPIFaceID: 100
|
VPPIFaceID: 1
|
||||||
VPPBridgeID: 4242
|
VPPBridgeID: 4242
|
||||||
MacAddrPrefix: AA:BB:CC:DD
|
MacAddrPrefix: CE:51:BA:B4
|
||||||
IPv4CIDR: ""
|
IPv4CIDR: 192.168.76.0/24
|
||||||
IPv6CIDR: ""
|
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||||
IPv6LLPrefix: ""
|
IPv6LLPrefix: fe80::a3df:0/112
|
||||||
MTU: 1416
|
MTU: 1416
|
||||||
RecvAddr: 127.0.0.1:4100
|
RecvAddr: 127.0.0.1:4100
|
||||||
SendAddr: 127.0.0.1:5100
|
SendAddr: 127.0.0.1:5100
|
||||||
@ -16,13 +16,13 @@ NodeName: Node100
|
|||||||
PostScript: ""
|
PostScript: ""
|
||||||
DefaultTTL: 200
|
DefaultTTL: 200
|
||||||
L2FIBTimeout: 3600
|
L2FIBTimeout: 3600
|
||||||
PrivKey: IJtpnkm9ytbuCukx4VBMENJKuLngo9KSsS1D60BqonQ=
|
PrivKey: a04BVvT+YbrX1ejjvMQVI6k5VRFlBkEX8tuLGWNyNrY=
|
||||||
ListenPort: 0
|
ListenPort: 3100
|
||||||
LogLevel:
|
LogLevel:
|
||||||
LogLevel: error
|
LogLevel: error
|
||||||
LogTransit: true
|
LogTransit: false
|
||||||
LogControl: true
|
LogControl: true
|
||||||
LogNormal: true
|
LogNormal: false
|
||||||
LogInternal: true
|
LogInternal: true
|
||||||
LogNTP: true
|
LogNTP: true
|
||||||
DynamicRoute:
|
DynamicRoute:
|
||||||
@ -35,12 +35,12 @@ DynamicRoute:
|
|||||||
SaveNewPeers: true
|
SaveNewPeers: true
|
||||||
SuperNode:
|
SuperNode:
|
||||||
UseSuperNode: true
|
UseSuperNode: true
|
||||||
PSKey: j9dS/lYvL16svSeC5lh+ldlq2iZX2MWwZfM3NNWpULI=
|
PSKey: Gfp2RkPNrKTeGKrCJNEvSyiBqYYRmzVnVG6CBuUKUNc=
|
||||||
EndpointV4: 127.0.0.1:3000
|
EndpointV4: 127.0.0.1:3456
|
||||||
PubKeyV4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
PubKeyV4: Id/VoZ6HmTU3FSqhxBUswfuHHB0mQxfzcbdoJNGBRzQ=
|
||||||
EndpointV6: '[::1]:3000'
|
EndpointV6: :3456
|
||||||
PubKeyV6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
PubKeyV6: 40tADRhJTvaortwE5Ur4qNXhP+SOMX7ZuSvl251Yxnc=
|
||||||
EndpointEdgeAPIUrl: http://127.0.0.1:3000/eg_api
|
EndpointEdgeAPIUrl: http://127.0.0.1:3456/eg_net/eg_api
|
||||||
SkipLocalIP: false
|
SkipLocalIP: false
|
||||||
SuperNodeInfoTimeout: 50
|
SuperNodeInfoTimeout: 50
|
||||||
P2P:
|
P2P:
|
||||||
@ -48,8 +48,10 @@ DynamicRoute:
|
|||||||
SendPeerInterval: 20
|
SendPeerInterval: 20
|
||||||
GraphRecalculateSetting:
|
GraphRecalculateSetting:
|
||||||
StaticMode: false
|
StaticMode: false
|
||||||
JitterTolerance: 20
|
ManualLatency: {}
|
||||||
|
JitterTolerance: 50
|
||||||
JitterToleranceMultiplier: 1.1
|
JitterToleranceMultiplier: 1.1
|
||||||
|
DampingResistance: 0
|
||||||
TimeoutCheckInterval: 5
|
TimeoutCheckInterval: 5
|
||||||
RecalculateCoolDown: 5
|
RecalculateCoolDown: 5
|
||||||
NTPConfig:
|
NTPConfig:
|
55
example_config/super_mode/Node_super.yaml
Normal file
55
example_config/super_mode/Node_super.yaml
Normal file
@ -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
|
@ -1,42 +1,81 @@
|
|||||||
# Etherguard
|
# Etherguard
|
||||||
[English](README.md)
|
[English](README.md) | [中文](#)
|
||||||
|
|
||||||
Super Mode的[範例配置檔](./)的說明文件
|
|
||||||
在了解Super Mode的運作之前,建議您先閱讀[Static Mode的運作](../static_mode/README_zh.md)方法,再閱讀本篇會比較好
|
|
||||||
|
|
||||||
## Super Mode
|
## Super Mode
|
||||||
|
|
||||||
Super Mode是受到[n2n](https://github.com/ntop/n2n)的啟發
|
Super Mode是受到[n2n](https://github.com/ntop/n2n)的啟發
|
||||||
分為super node和edge node兩種節點
|
分為SuperNode和EdgeNode兩種節點
|
||||||
|
|
||||||
全部節點都會和supernode建立連線
|
全部節點都會和SuperNode建立連線
|
||||||
藉由supernode交換其他節點的資訊,以及udp打洞
|
藉由SuperNode交換其他節點的資訊,以及udp打洞
|
||||||
由supernode執行[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法),並把計算結果分發給全部edge node
|
由SuperNode執行[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法),並把計算結果分發給全部edge node
|
||||||
|
|
||||||
在edge node的super模式下,設定檔裡面的`nexthoptable`以及`peers`是無效的。
|
|
||||||
這些資訊都是從super node上面下載
|
## Quick start
|
||||||
同時,supernode會幫每個連線生成Preshared Key,分發給edge使用(如果`usepskforinteredge`有啟用的話)。
|
|
||||||
```golang
|
首先按需求修改`gensuper.yaml`
|
||||||
psk = shs256("PubkeyPeerA" + "PubkeyPeerB" + "主廚特調當季精選海鹽")[:32]
|
|
||||||
|
```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
|
### SuperMsg
|
||||||
但是比起Static mode,Super mode引入了一種新的 `終點ID` 叫做 `SuperMsg`。
|
但是比起StaticMode,SuperMode引入了一種新的 `終點ID` 叫做 `NodeID_SuperNode`。
|
||||||
所有送往Super node的封包都會是這種類型。
|
所有送往SuperNode的封包都會是這種類型。
|
||||||
這種封包不會在edge node之間傳播,收到也會不會轉給任何人,如同`終點ID == 自己`一般
|
這種封包不會在EdgeNode之間傳播,收到也會不會轉給任何人,如同`終點ID == 自己`一般
|
||||||
|
|
||||||
## Control Message
|
## Control Message
|
||||||
從Super mode開始,我們有了Static mode不存在的Control Message。他會控制EtherGuard一些行為
|
從SuperMode開始,我們有了StaticMode不存在的Control Message。他會控制EtherGuard一些行為
|
||||||
在Super mode下,我們不會轉發任何控制消息。 我們只會直接接收或發送給目標。
|
在SuperMode下,我們不會轉發任何控制消息。 我們只會直接接收或發送給目標。
|
||||||
下面列出Super Mode會出現的Control message
|
下面列出Super Mode會出現的Control message
|
||||||
|
|
||||||
### Register
|
### Register
|
||||||
具體運作方式類似這張圖
|
具體運作方式類似這張圖
|
||||||
![Register運作流程](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS01.png)
|
![Register運作流程](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS01.png)
|
||||||
1. edge node發送`Register`給super node
|
1. EdgeNode發送`Register`給sSuperNode
|
||||||
2. super node收到以後就知道這個edge的endpoint IP和埠號。
|
2. SuperNode收到以後就知道這個EdgeNode的Endpoint IP和Port number。
|
||||||
3. 更新進資料庫以後發布`UpdatePeerMsg`。
|
3. 更新進資料庫以後發布`UpdatePeerMsg`。
|
||||||
4. 其他edge node收到以後就用HTTP API去下載完整的peer list。並且把自己沒有的peer通通加到本地
|
4. 其他edge node收到以後就用HTTP EdgeAPI去下載完整的peer list。並且把自己沒有的peer通通加到本地
|
||||||
|
|
||||||
### Ping/Pong
|
### Ping/Pong
|
||||||
有了peer list以後,接下來的運作方式類似這張圖
|
有了peer list以後,接下來的運作方式類似這張圖
|
||||||
@ -46,18 +85,58 @@ Edge node 會嘗試向其他所有peer發送`Ping`,裡面會攜帶節點自己
|
|||||||
收到`Ping`,就會產生一個`Pong`,並攜帶時間差。這個時間就是單向延遲
|
收到`Ping`,就會產生一個`Pong`,並攜帶時間差。這個時間就是單向延遲
|
||||||
但是他不會把`Pong`送回給原節點,而是送給Super node
|
但是他不會把`Pong`送回給原節點,而是送給Super node
|
||||||
|
|
||||||
|
### <a name="AdditionalCost"></a>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
|
### UpdateNhTable
|
||||||
Super node收到節點們傳來的Pong以後,就知道他們的單向延遲了。接下來的運作方式類似這張圖
|
Super node收到節點們傳來的Pong以後,就知道他們的單向延遲了。接下來的運作方式類似這張圖
|
||||||
![image](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS03.png)
|
![image](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS03.png)
|
||||||
Super node收到Pong以後,就會更新它裡面的`Distance matrix`,並且重新計算轉發表
|
Super node收到Pong以後,就會更新它裡面的`Distance matrix`,並且重新計算轉發表
|
||||||
如果有變動,就發布`UpdateNhTableMsg`
|
如果有變動,就發布`UpdateNhTableMsg`
|
||||||
其他edge node收到以後就用HTTP API去下載完整的轉發表
|
其他edge node收到以後就用HTTP EdgeAPI去下載完整的轉發表
|
||||||
|
|
||||||
### UpdateError
|
### ServerUpdate
|
||||||
通知edges有錯誤發生,關閉egde端程式
|
通知EdgeNode有事情發生
|
||||||
發生在版本號不匹被,該edge的NodeID配置錯誤,還有該Edge被刪除時觸發
|
1. 關閉EdgeNode程式
|
||||||
|
* 版本號不匹配
|
||||||
|
* 該edge的NodeID配置錯誤
|
||||||
|
* 該Edge被刪除
|
||||||
|
2. 通知EdgeNode有更新
|
||||||
|
* UpdateNhTable
|
||||||
|
* UpdatePeer
|
||||||
|
* UpdateSuperParams
|
||||||
|
|
||||||
### HTTP API
|
|
||||||
|
## HTTP EdgeAPI
|
||||||
為什麼要用HTTP額外下載呢?直接`UpdateXXX`夾帶資訊不好嗎?
|
為什麼要用HTTP額外下載呢?直接`UpdateXXX`夾帶資訊不好嗎?
|
||||||
因為udp是不可靠協議,能攜帶的內容量也有上限。
|
因為udp是不可靠協議,能攜帶的內容量也有上限。
|
||||||
但是peer list包含了全部的peer資訊,長度不是固定的,可能超過
|
但是peer list包含了全部的peer資訊,長度不是固定的,可能超過
|
||||||
@ -68,12 +147,15 @@ Super node收到Pong以後,就會更新它裡面的`Distance matrix`,並且
|
|||||||
這樣super node收到HTTP API看到`state hash`就知道這個edge node確實有收到`UpdateXXX`了。
|
這樣super node收到HTTP API看到`state hash`就知道這個edge node確實有收到`UpdateXXX`了。
|
||||||
不然每隔一段時間就會重新發送`UpdateXXX`給該節點
|
不然每隔一段時間就會重新發送`UpdateXXX`給該節點
|
||||||
|
|
||||||
|
預設配置是走HTTP。但為**了你的安全著想,建議使用nginx反代理成https**
|
||||||
|
有想過SuperNode開發成直接支援https,但是證書動態更新太麻煩就沒有做了
|
||||||
|
|
||||||
## HTTP Manage API
|
## HTTP Manage API
|
||||||
HTTP還有一些個API,給前端使用,幫助管理整個網路
|
HTTP還有5個Manage API,給前端使用,幫助管理整個網路
|
||||||
|
|
||||||
### super/state
|
### super/state
|
||||||
```bash
|
```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
|
再來是新增peer,可以不用重啟Supernode就新增Peer
|
||||||
|
|
||||||
範例:
|
範例:
|
||||||
```
|
```bash
|
||||||
curl -X POST "http://127.0.0.1:3000/eg_api/manage/peer/add?Password=passwd_addpeer" \
|
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" \
|
-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用的密碼,在設定檔配置
|
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即可刪除剛剛新增的節點
|
使用Password刪除可以刪除任意節點,以上面新增的節點為例,使用這個API即可刪除剛剛新增的節點
|
||||||
```
|
```bash
|
||||||
curl "http://127.0.0.1:3000/eg_api/manage/peer/del?Password=passwd_delpeer&NodeID=100"
|
curl "http://127.0.0.1:3456/eg_net/eg_api/manage/peer/del?Password=passwd_delpeer&NodeID=100"
|
||||||
```
|
```
|
||||||
|
|
||||||
也可以使用privkey刪除,同上,但是只要附上privkey參數就好
|
也可以使用privkey刪除,同上,但是只要附上privkey參數就好
|
||||||
```
|
```bash
|
||||||
curl "http://127.0.0.1:3000/eg_api/manage/peer/del?PrivKey=IJtpnkm9ytbuCukx4VBMENJKuLngo9KSsS1D60BqonQ="
|
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
|
### peer/update
|
||||||
更新節點的一些參數
|
更新節點的一些參數
|
||||||
```
|
```bash
|
||||||
curl -X POST "http://127.0.0.1:12369/eg_net/eg_api/manage/peer/update?Password=e05znou1_updatepeer&NodeID=1" \
|
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" \
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
-d "AdditionalCost=10&SkipLocalIP=false"
|
-d "AdditionalCost=10&SkipLocalIP=false"
|
||||||
```
|
```
|
||||||
|
|
||||||
### super/update
|
### super/update
|
||||||
更新SuperNode的一些參數
|
更新SuperNode的一些參數
|
||||||
```
|
```bash
|
||||||
curl -X POST "http://127.0.0.1:12369/eg_net/eg_api/manage/super/update?Password=e05znou1_updatesuper" \
|
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" \
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
-d "SendPingInterval=15&HttpPostInterval=60&PeerAliveTimeout=70"
|
-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有幾個參數
|
<a name="Passwords"></a>Passwords | Description
|
||||||
1. `usesupernode`: 是否啟用Super mode
|
--------------------|:-----
|
||||||
1. `pskey`: 和supernode建立連線用的Pre shared Key
|
ShowState | HTTP ManageAPI `super/state` 的密碼
|
||||||
1. `connurlv4`: Super node的IPv4連線地址
|
AddPeer | HTTP ManageAPI `peer/add` 的密碼
|
||||||
1. `pubkeyv4`: Super node的IPv4工鑰
|
DelPeer | HTTP ManageAPI `peer/del` 的密碼
|
||||||
1. `connurlv6`: Super node的IPv6連線地址
|
UpdatePeer | HTTP ManageAPI `peer/update` 的密碼
|
||||||
1. `pubkeyv6`: Super node的IPv6工鑰
|
UpdateSuper | HTTP ManageAPI `super/update` 的密碼
|
||||||
1. `apiurl`: Super node的HTTP(S) API連線地址
|
|
||||||
1. `supernodeinfotimeout`: Supernode Timeout
|
|
||||||
1. `httppostinterval`: 15
|
|
||||||
1. `skiplocalip`: 打洞時,一律使用supernode蒐集到的外部ip,不使用edge自行回報的local ip
|
|
||||||
|
|
||||||
### Super node本身的設定檔
|
<a name="GraphRecalculateSetting"></a>GraphRecalculateSetting | Description
|
||||||
|
--------------------|:-----
|
||||||
|
StaticMode | 關閉`Floyd-Warshall`演算法,只使用設定檔提供的NextHopTable`。SuperNode單純用來輔助打洞
|
||||||
|
ManualLatency | 手動設定延遲,不採用EdgeNode回報的延遲(單位: 毫秒)
|
||||||
|
JitterTolerance | 抖動容許誤差,收到Pong以後,一個37ms,一個39ms,不會觸發重新計算<br>比較對象是上次更新使用的值。如果37 37 41 43 .. 100 ,每次變動一點點,總變動量超過域值還是會更新
|
||||||
|
JitterToleranceMultiplier | 抖動容許誤差的放大係數,高ping的話允許更多誤差<br>https://www.desmos.com/calculator/raoti16r5n
|
||||||
|
DampingResistance | 防抖阻尼系數,`latency = latency_old * resistance + latency_in * (1-resistance)`
|
||||||
|
TimeoutCheckInterval | 週期性檢查節點的連線狀況,是否斷線需要重新規劃線路
|
||||||
|
RecalculateCoolDown | Floyd-Warshal是O(n^3)時間複雜度,不能太常算。<br>設個冷卻時間<br>有節點加入/斷線觸發的重新計算,無視這個CoolDown
|
||||||
|
|
||||||
1. nodename: 節點名稱
|
<a name="EdgeNodes"></a>Peers | Description
|
||||||
1. privkeyv4: ipv4用的私鑰
|
--------------------|:-----
|
||||||
1. privkeyv6: ipv6用的私鑰
|
NodeID | 節點ID
|
||||||
1. listenport: 監聽udp埠號
|
PubKey | 公鑰
|
||||||
1. loglevel: 參考 [README_zh.md](../README_zh.md)
|
PSKey | 預共享金鑰
|
||||||
1. repushconfiginterval: 重新push`UpdateXXX`的間格
|
[AdditionalCost](#AdditionalCost) | 繞路成本(單位: 毫秒)<br>設定-1代表使用EdgeNode自身設定
|
||||||
1. passwords: HTTP API 密碼
|
SkipLocalIP | 打洞時,不使用EdgeNode回報的本地IP,僅使用SuperNode蒐集到的外部IP
|
||||||
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: 此節點進行封包轉發的額外成本。單位: 毫秒
|
|
||||||
|
|
||||||
|
### 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用不到
|
||||||
|
|
||||||
|
<a name="DynamicRoute"></a>DynamicRoute | Description
|
||||||
|
--------------------|:-----
|
||||||
|
SendPingInterval | 發送Ping訊息的間隔(秒)
|
||||||
|
PeerAliveTimeout | 每次收到封包就重置,超過時間(秒)沒收到就標記該peer離線
|
||||||
|
DupCheckTimeout | 重複封包檢查的timeout(秒)<br>完全相同的封包收第二次會被丟棄
|
||||||
|
ConnTimeOut | 檢查peer離線的時間間格<br>如果標記離線,就切換下一個endpoint<br>SuperNode可能傳了多個endpoint過來
|
||||||
|
ConnNextTry | 切換下一個endpoint的間隔
|
||||||
|
[AdditionalCost](#AdditionalCost) | 繞路成本(毫秒)。僅限SuperNode設定-1時生效
|
||||||
|
SaveNewPeers | 是否把下載來的鄰居資訊存到本地設定檔裡面
|
||||||
|
[SuperNode](#SuperNode) | SuperNode相關設定
|
||||||
|
P2P | P2P相關設定,SuperMode用不到
|
||||||
|
[NTPConfig](#NTPConfig) | NTP時間同步相關設定
|
||||||
|
|
||||||
|
<a name="SuperNode"></a>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模式<br>需先打開P2P模式<br>`UseP2P=false`本選項無效<br>P2P模式尚未測試,穩定性未知,不推薦使用
|
||||||
|
|
||||||
|
|
||||||
|
<a name="NTPConfig"></a>NTPConfig | Description
|
||||||
|
--------------------|:-----
|
||||||
|
UseNTP | 是否使用NTP同步時間
|
||||||
|
MaxServerUse | 向多少NTP伺服器發送請求
|
||||||
|
SyncTimeInterval | 多久同步一次時間
|
||||||
|
NTPTimeout | NTP伺服器連線Timeout
|
||||||
|
Servers | NTP伺服器列表
|
||||||
|
|
||||||
## V4 V6 兩個公鑰
|
## V4 V6 兩個公鑰
|
||||||
為什麼要分開IPv4和IPv6呢?
|
為什麼要分開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`
|
因為如果用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`,就連不上了
|
`Node_1`和`Node_2`看到`Node_R`的連線地址是`127.0.0.1`,就連不上了
|
||||||
|
|
||||||
## Quick start
|
#### Run example config
|
||||||
執行此範例設定檔(請開三個terminal):
|
|
||||||
|
在**不同terminal**分別執行以下命令
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./etherguard-go -config example_config/super_mode/s1.yaml -mode super
|
./etherguard-go -config example_config/super_mode/Node_super.yaml -mode super
|
||||||
./etherguard-go -config example_config/super_mode/n1.yaml -mode edge
|
./etherguard-go -config example_config/super_mode/Node_edge001.yaml -mode edge
|
||||||
./etherguard-go -config example_config/super_mode/n2.yaml -mode edge
|
./etherguard-go -config example_config/super_mode/Node_edge002.yaml -mode edge
|
||||||
```
|
```
|
||||||
因為是stdio模式,stdin會讀入VPN網路
|
因為是stdio模式,stdin會讀入VPN網路
|
||||||
請在其中一個edge視窗中鍵入
|
請在其中一個edge視窗中鍵入
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
Config output dir: /tmp/eg_gen
|
Config output dir: /tmp/eg_gen_super
|
||||||
ConfigTemplate for super node: ""
|
ConfigTemplate for super node: ""
|
||||||
ConfigTemplate for edge node: ""
|
ConfigTemplate for edge node: ""
|
||||||
Network name: eg_net
|
Network name: EgNet
|
||||||
Super Node:
|
Super Node:
|
||||||
Listen port: 3456
|
Listen port: 3456
|
||||||
EdgeAPI prefix: /eg_net/eg_api
|
EdgeAPI prefix: /eg_net/eg_api
|
||||||
Endpoint(IPv4)(optional): example.com
|
Endpoint(IPv4)(optional): 127.0.0.1
|
||||||
Endpoint(IPv6)(optional): example.com
|
Endpoint(IPv6)(optional):
|
||||||
Endpoint(EdgeAPI): http://example.com:3456/eg_net/eg_api
|
Endpoint(EdgeAPI): http://127.0.0.1:3456/eg_net/eg_api
|
||||||
Edge Node:
|
Edge Node:
|
||||||
Node IDs: "[1~10,11,19,23,29,31,55~66,88~99]"
|
Node IDs: "[1~2,100]"
|
||||||
MacAddress prefix: ""
|
MacAddress prefix: ""
|
||||||
IPv4 range: 192.168.76.0/24
|
IPv4 range: 192.168.76.0/24
|
||||||
IPv6 range: fd95:71cb:a3df:e586::/64
|
IPv6 range: fd95:71cb:a3df:e586::/64
|
||||||
|
@ -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
|
|
@ -92,16 +92,17 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
|||||||
if !all_verts[NodeID] {
|
if !all_verts[NodeID] {
|
||||||
return fmt.Errorf("duplicate definition: NodeID %v ", NodeID)
|
return fmt.Errorf("duplicate definition: NodeID %v ", NodeID)
|
||||||
}
|
}
|
||||||
|
if endpoint != "" {
|
||||||
_, err = conn.LookupIP(endpoint, 0)
|
_, err = conn.LookupIP(endpoint, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pri, pub := device.RandomKeyPair()
|
pri, pub := device.RandomKeyPair()
|
||||||
edge_infos[NodeID] = edge_info{
|
edge_infos[NodeID] = edge_info{
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
PrivKey: pri.ToString(),
|
PrivKey: pri.ToString(),
|
||||||
PubKey: pub.ToString(),
|
PubKey: pub.ToString(),
|
||||||
PersistentKeepalive: edgeinfo.PersistentKeepalive,
|
|
||||||
ConnectedEdge: make(map[mtypes.Vertex]bool),
|
ConnectedEdge: make(map[mtypes.Vertex]bool),
|
||||||
}
|
}
|
||||||
all_verts[NodeID] = false
|
all_verts[NodeID] = false
|
||||||
@ -118,7 +119,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
|||||||
s := edge.Src_nodeID
|
s := edge.Src_nodeID
|
||||||
d := edge.Dst_nodeID
|
d := edge.Dst_nodeID
|
||||||
if len(edge_infos[s].Endpoint)+len(edge_infos[d].Endpoint) == 0 {
|
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[s].ConnectedEdge[d] = true
|
||||||
edge_infos[d].ConnectedEdge[s] = 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 := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
|
||||||
pbyte[0] &^= 0b00000001
|
pbyte[0] &^= 0b00000001
|
||||||
pbyte[0] |= 0b00000010
|
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)
|
dist, next, err := g.FloydWarshall(false)
|
||||||
@ -177,6 +178,8 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
|||||||
econfig.NodeID = NodeID
|
econfig.NodeID = NodeID
|
||||||
idstr := fmt.Sprintf("%0"+strconv.Itoa(len(MaxNodeID.ToString()))+"d", NodeID)
|
idstr := fmt.Sprintf("%0"+strconv.Itoa(len(MaxNodeID.ToString()))+"d", NodeID)
|
||||||
econfig.NodeName = NMCfg.NetworkName + idstr
|
econfig.NodeName = NMCfg.NetworkName + idstr
|
||||||
|
PersistentKeepalive := uint32(30)
|
||||||
|
econfig.ListenPort = 0
|
||||||
if Edge.Endpoint != "" {
|
if Edge.Endpoint != "" {
|
||||||
ps := strings.Split(Edge.Endpoint, ":")
|
ps := strings.Split(Edge.Endpoint, ":")
|
||||||
pss := ps[len(ps)-1]
|
pss := ps[len(ps)-1]
|
||||||
@ -185,6 +188,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
econfig.ListenPort = int(port)
|
econfig.ListenPort = int(port)
|
||||||
|
PersistentKeepalive = 0
|
||||||
}
|
}
|
||||||
econfig.Peers = make([]mtypes.PeerInfo, 0)
|
econfig.Peers = make([]mtypes.PeerInfo, 0)
|
||||||
for CNodeID, _ := range Edge.ConnectedEdge {
|
for CNodeID, _ := range Edge.ConnectedEdge {
|
||||||
@ -193,7 +197,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
|||||||
PubKey: edge_infos[CNodeID].PubKey,
|
PubKey: edge_infos[CNodeID].PubKey,
|
||||||
PSKey: pskdb.GetPSK(NodeID, CNodeID).ToString(),
|
PSKey: pskdb.GetPSK(NodeID, CNodeID).ToString(),
|
||||||
EndPoint: edge_infos[CNodeID].Endpoint,
|
EndPoint: edge_infos[CNodeID].Endpoint,
|
||||||
PersistentKeepalive: Edge.PersistentKeepalive,
|
PersistentKeepalive: PersistentKeepalive,
|
||||||
Static: true,
|
Static: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
|
|||||||
pbyte := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
|
pbyte := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
|
||||||
pbyte[0] &^= 0b00000001
|
pbyte[0] &^= 0b00000001
|
||||||
pbyte[0] |= 0b00000010
|
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
|
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.EndpointV4 = EndpointV4 + ":" + ListenPort
|
||||||
peerceconf.DynamicRoute.SuperNode.EndpointV6 = EndpointV6 + ":" + ListenPort
|
peerceconf.DynamicRoute.SuperNode.EndpointV6 = EndpointV6 + ":" + ListenPort
|
||||||
peerceconf.DynamicRoute.SuperNode.EndpointEdgeAPIUrl = EndpointEdgeAPIUrl
|
peerceconf.DynamicRoute.SuperNode.EndpointEdgeAPIUrl = EndpointEdgeAPIUrl
|
||||||
|
peerceconf.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance = 0
|
||||||
peerceconf.Interface.MacAddrPrefix = MacPrefix
|
peerceconf.Interface.MacAddrPrefix = MacPrefix
|
||||||
peerceconf.Interface.IPv4CIDR = IPv4Block
|
peerceconf.Interface.IPv4CIDR = IPv4Block
|
||||||
peerceconf.Interface.IPv6CIDR = IPv6Block
|
peerceconf.Interface.IPv6CIDR = IPv6Block
|
||||||
|
@ -68,5 +68,4 @@ type edge_info struct {
|
|||||||
ConnectedEdge map[mtypes.Vertex]bool
|
ConnectedEdge map[mtypes.Vertex]bool
|
||||||
PrivKey string
|
PrivKey string
|
||||||
PubKey string
|
PubKey string
|
||||||
PersistentKeepalive uint32
|
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,9 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
|
|||||||
if len(NodeName) > 32 {
|
if len(NodeName) > 32 {
|
||||||
return errors.New("Node name can't longer than 32 :" + NodeName)
|
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
|
var logLevel int
|
||||||
switch econfig.LogLevel.LogLevel {
|
switch econfig.LogLevel.LogLevel {
|
||||||
case "verbose", "debug":
|
case "verbose", "debug":
|
||||||
|
@ -684,7 +684,7 @@ func manage_peeradd(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func manage_peerupdate(w http.ResponseWriter, r *http.Request) {
|
func manage_peerupdate(w http.ResponseWriter, r *http.Request) {
|
||||||
params := r.URL.Query()
|
params := r.URL.Query()
|
||||||
toUpdate := mtypes.NodeID_Boardcast
|
toUpdate := mtypes.NodeID_Broadcast
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var NodeID mtypes.Vertex
|
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) {
|
func manage_peerdel(w http.ResponseWriter, r *http.Request) {
|
||||||
params := r.URL.Query()
|
params := r.URL.Query()
|
||||||
toDelete := mtypes.NodeID_Boardcast
|
toDelete := mtypes.NodeID_Broadcast
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var NodeID mtypes.Vertex
|
var NodeID mtypes.Vertex
|
||||||
@ -900,7 +900,7 @@ func manage_peerdel(w http.ResponseWriter, r *http.Request) {
|
|||||||
toDelete = peerinfo.NodeID
|
toDelete = peerinfo.NodeID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if toDelete == mtypes.NodeID_Boardcast {
|
if toDelete == mtypes.NodeID_Broadcast {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
w.Write([]byte(fmt.Sprintf("Paramater PrivKey: \"%v\" not found", PubKey)))
|
w.Write([]byte(fmt.Sprintf("Paramater PrivKey: \"%v\" not found", PubKey)))
|
||||||
return
|
return
|
||||||
|
@ -100,6 +100,9 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
|
|||||||
if sconfig.RePushConfigInterval <= 0 {
|
if sconfig.RePushConfigInterval <= 0 {
|
||||||
return fmt.Errorf("RePushConfigInterval must > 0 : %v", sconfig.RePushConfigInterval)
|
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
|
var logLevel int
|
||||||
switch sconfig.LogLevel.LogLevel {
|
switch sconfig.LogLevel.LogLevel {
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
type Vertex uint16
|
type Vertex uint16
|
||||||
|
|
||||||
const (
|
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_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_SuperNode Vertex = math.MaxUint16 - iota
|
||||||
NodeID_Invalid Vertex = math.MaxUint16 - iota
|
NodeID_Invalid Vertex = math.MaxUint16 - iota
|
||||||
@ -99,15 +99,15 @@ type SuperPeerInfo struct {
|
|||||||
type LoggerInfo struct {
|
type LoggerInfo struct {
|
||||||
LogLevel string `yaml:"LogLevel"`
|
LogLevel string `yaml:"LogLevel"`
|
||||||
LogTransit bool `yaml:"LogTransit"`
|
LogTransit bool `yaml:"LogTransit"`
|
||||||
LogControl bool `yaml:"LogControl"`
|
|
||||||
LogNormal bool `yaml:"LogNormal"`
|
LogNormal bool `yaml:"LogNormal"`
|
||||||
|
LogControl bool `yaml:"LogControl"`
|
||||||
LogInternal bool `yaml:"LogInternal"`
|
LogInternal bool `yaml:"LogInternal"`
|
||||||
LogNTP bool `yaml:"LogNTP"`
|
LogNTP bool `yaml:"LogNTP"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vertex) ToString() string {
|
func (v *Vertex) ToString() string {
|
||||||
switch *v {
|
switch *v {
|
||||||
case NodeID_Boardcast:
|
case NodeID_Broadcast:
|
||||||
return "Boardcast"
|
return "Boardcast"
|
||||||
case NodeID_AllPeer:
|
case NodeID_AllPeer:
|
||||||
return "Control"
|
return "Control"
|
||||||
|
@ -32,6 +32,64 @@ const (
|
|||||||
BroadcastPeer
|
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) {
|
func NewEgHeader(pac []byte) (e EgHeader, err error) {
|
||||||
if len(pac) != EgHeaderLen {
|
if len(pac) != EgHeaderLen {
|
||||||
err = errors.New("invalid packet size")
|
err = errors.New("invalid packet size")
|
||||||
|
@ -189,7 +189,7 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
|
|||||||
newval := pong_msg.Timediff
|
newval := pong_msg.Timediff
|
||||||
if _, ok := g.gsetting.ManualLatency[u]; ok {
|
if _, ok := g.gsetting.ManualLatency[u]; ok {
|
||||||
if _, ok := g.gsetting.ManualLatency[u][v]; 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
|
w := newval
|
||||||
@ -206,7 +206,7 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
|
|||||||
g.edgelock.Unlock()
|
g.edgelock.Unlock()
|
||||||
oldval := g.OldWeight(u, v, false)
|
oldval := g.OldWeight(u, v, false)
|
||||||
g.edgelock.Lock()
|
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)
|
w = oldval*g.gsetting.DampingResistance + newval*(1-g.gsetting.DampingResistance)
|
||||||
}
|
}
|
||||||
should_update = should_update || g.ShouldUpdate(oldval, w, false)
|
should_update = should_update || g.ShouldUpdate(oldval, w, false)
|
||||||
|
@ -100,10 +100,11 @@ func (tap *StdIOTap) Read(buf []byte, offset int) (int, error) {
|
|||||||
}
|
}
|
||||||
} // read a packet from the device (without any additional headers)
|
} // read a packet from the device (without any additional headers)
|
||||||
func (tap *StdIOTap) Write(buf []byte, offset int) (size int, err error) {
|
func (tap *StdIOTap) Write(buf []byte, offset int) (size int, err error) {
|
||||||
packet := make([]byte, len(buf[offset:]))
|
packet := buf[offset:]
|
||||||
copy(packet, buf[offset:])
|
|
||||||
switch tap.L2mode {
|
switch tap.L2mode {
|
||||||
case KeyboardDebug:
|
case KeyboardDebug:
|
||||||
|
packet = make([]byte, len(buf[offset:]))
|
||||||
|
copy(packet, buf[offset:])
|
||||||
src := Mac2charForm(packet[6:12])
|
src := Mac2charForm(packet[6:12])
|
||||||
dst := Mac2charForm(packet[0:6])
|
dst := Mac2charForm(packet[0:6])
|
||||||
packet[10] = dst
|
packet[10] = dst
|
||||||
|
Loading…
Reference in New Issue
Block a user