fast spread, static gencfg

This commit is contained in:
Kusakabe Si 2021-12-09 07:46:15 +00:00
parent 1c50fe0c98
commit d555963227
30 changed files with 1312 additions and 987 deletions

View File

@ -175,7 +175,7 @@ func removePeerLocked(device *Device, peer *Peer, key NoisePublicKey) {
// remove from peer map // remove from peer map
id := peer.ID id := peer.ID
delete(device.peers.keyMap, key) delete(device.peers.keyMap, key)
if id == mtypes.SuperNodeMessage { if id == mtypes.NodeID_SuperNode {
delete(device.peers.SuperPeer, key) delete(device.peers.SuperPeer, key)
} else { } else {
delete(device.peers.IDMap, id) delete(device.peers.IDMap, id)
@ -412,7 +412,7 @@ func (device *Device) LookupPeerIDAtConfig(pk NoisePublicKey) (ID mtypes.Vertex,
if device.IsSuperNode { if device.IsSuperNode {
var peerlist []mtypes.SuperPeerInfo var peerlist []mtypes.SuperPeerInfo
if device.SuperConfig == nil { if device.SuperConfig == nil {
return 0, errors.New("Superconfig is nil") return 0, errors.New("superconfig is nil")
} }
peerlist = device.SuperConfig.Peers peerlist = device.SuperConfig.Peers
pkstr := pk.ToString() pkstr := pk.ToString()
@ -424,7 +424,7 @@ func (device *Device) LookupPeerIDAtConfig(pk NoisePublicKey) (ID mtypes.Vertex,
} else { } else {
var peerlist []mtypes.PeerInfo var peerlist []mtypes.PeerInfo
if device.EdgeConfig == nil { if device.EdgeConfig == nil {
return 0, errors.New("EdgeConfig is nil") return 0, errors.New("edgeconfig is nil")
} }
peerlist = device.EdgeConfig.Peers peerlist = device.EdgeConfig.Peers
pkstr := pk.ToString() pkstr := pk.ToString()
@ -435,7 +435,42 @@ func (device *Device) LookupPeerIDAtConfig(pk NoisePublicKey) (ID mtypes.Vertex,
} }
} }
return 0, errors.New("Peer not found in the config file.") return 0, errors.New("peer not found in the config file")
}
type VPair struct {
s mtypes.Vertex
d mtypes.Vertex
}
type PSKDB struct {
db sync.Map
}
func (D *PSKDB) GetPSK(s mtypes.Vertex, d mtypes.Vertex) (psk NoisePresharedKey) {
if s > d {
s, d = d, s
}
vp := VPair{
s: s,
d: d,
}
pski, ok := D.db.Load(vp)
if !ok {
psk = RandomPSK()
pski, _ = D.db.LoadOrStore(vp, psk)
return pski.(NoisePresharedKey)
}
return pski.(NoisePresharedKey)
}
func (D *PSKDB) DelNode(n mtypes.Vertex) {
D.db.Range(func(key, value interface{}) bool {
vp := key.(VPair)
if vp.s == n || vp.d == n {
D.db.Delete(vp)
}
return true
})
} }
func (device *Device) LookupPeer(pk NoisePublicKey) *Peer { func (device *Device) LookupPeer(pk NoisePublicKey) *Peer {
@ -452,20 +487,20 @@ func (device *Device) LookupPeerByStr(pks string) *Peer {
return device.LookupPeer(pk) return device.LookupPeer(pk)
} }
func (pk *NoisePublicKey) ToString() string { func (pk NoisePublicKey) ToString() string {
if bytes.Equal(pk[:], make([]byte, len(pk))) { if bytes.Equal(pk[:], make([]byte, len(pk))) {
return "" return ""
} }
return string(base64.StdEncoding.EncodeToString(pk[:])) return string(base64.StdEncoding.EncodeToString(pk[:]))
} }
func (pk *NoisePrivateKey) ToString() (result string) { func (pk NoisePrivateKey) ToString() (result string) {
if bytes.Equal(pk[:], make([]byte, len(pk))) { if bytes.Equal(pk[:], make([]byte, len(pk))) {
return "" return ""
} }
return string(base64.StdEncoding.EncodeToString(pk[:])) return string(base64.StdEncoding.EncodeToString(pk[:]))
} }
func (pk *NoisePresharedKey) ToString() (result string) { func (pk NoisePresharedKey) ToString() (result string) {
if bytes.Equal(pk[:], make([]byte, len(pk))) { if bytes.Equal(pk[:], make([]byte, len(pk))) {
return "" return ""
} }
@ -474,7 +509,7 @@ func (pk *NoisePresharedKey) ToString() (result string) {
func Str2PubKey(k string) (pk NoisePublicKey, err error) { func Str2PubKey(k string) (pk NoisePublicKey, err error) {
if k == "" { if k == "" {
err = errors.New("Empty public key string") err = errors.New("empty public key string")
return return
} }
sk_slice, err := base64.StdEncoding.DecodeString(k) sk_slice, err := base64.StdEncoding.DecodeString(k)
@ -484,7 +519,7 @@ func Str2PubKey(k string) (pk NoisePublicKey, err error) {
func Str2PriKey(k string) (pk NoisePrivateKey, err error) { func Str2PriKey(k string) (pk NoisePrivateKey, err error) {
if k == "" { if k == "" {
err = errors.New("Empty private key string") err = errors.New("empty private key string")
return return
} }
sk_slice, err := base64.StdEncoding.DecodeString(k) sk_slice, err := base64.StdEncoding.DecodeString(k)
@ -501,6 +536,16 @@ func Str2PSKey(k string) (pk NoisePresharedKey, err error) {
return return
} }
func RandomKeyPair() (pri NoisePrivateKey, pub NoisePublicKey) {
pri = mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, make([]byte, 32)))
pub = pri.PublicKey()
return
}
func RandomPSK() (pk NoisePresharedKey) {
return mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, make([]byte, 32)))
}
func (device *Device) GetConnurl(v mtypes.Vertex) string { func (device *Device) GetConnurl(v mtypes.Vertex) string {
if peer, has := device.peers.IDMap[v]; has { if peer, has := device.peers.IDMap[v]; has {
if peer.endpoint != nil { if peer.endpoint != nil {

View File

@ -18,7 +18,6 @@ import (
"github.com/KusakabeSi/EtherGuard-VPN/conn" "github.com/KusakabeSi/EtherGuard-VPN/conn"
"github.com/KusakabeSi/EtherGuard-VPN/mtypes" "github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/path"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
@ -51,7 +50,7 @@ func (et *endpoint_trylist) UpdateSuper(urls mtypes.API_connurl, UseLocalIP bool
newmap_super := make(map[string]*endpoint_tryitem) newmap_super := make(map[string]*endpoint_tryitem)
if urls.IsEmpty() { if urls.IsEmpty() {
if et.peer.device.LogLevel.LogInternal { if et.peer.device.LogLevel.LogInternal {
fmt.Println(fmt.Sprintf("Internal: Peer %v : Reset trylist(super) %v", et.peer.ID.ToString(), "nil")) fmt.Printf("Internal: Peer %v : Reset trylist(super) %v\n", et.peer.ID.ToString(), "nil")
} }
} }
for url, it := range urls.GetList(UseLocalIP) { for url, it := range urls.GetList(UseLocalIP) {
@ -61,18 +60,18 @@ func (et *endpoint_trylist) UpdateSuper(urls mtypes.API_connurl, UseLocalIP bool
_, err := conn.LookupIP(url, 0) _, err := conn.LookupIP(url, 0)
if err != nil { if err != nil {
if et.peer.device.LogLevel.LogInternal { if et.peer.device.LogLevel.LogInternal {
fmt.Println(fmt.Sprintf("Internal: Peer %v : Update trylist(super) %v error: %v", et.peer.ID.ToString(), url, err)) fmt.Printf("Internal: Peer %v : Update trylist(super) %v error: %v\n", et.peer.ID.ToString(), url, err)
} }
continue continue
} }
if val, ok := et.trymap_super[url]; ok { if val, ok := et.trymap_super[url]; ok {
if et.peer.device.LogLevel.LogInternal { if et.peer.device.LogLevel.LogInternal {
fmt.Println(fmt.Sprintf("Internal: Peer %v : Update trylist(super) %v", et.peer.ID.ToString(), url)) fmt.Printf("Internal: Peer %v : Update trylist(super) %v\n", et.peer.ID.ToString(), url)
} }
newmap_super[url] = val newmap_super[url] = val
} else { } else {
if et.peer.device.LogLevel.LogInternal { if et.peer.device.LogLevel.LogInternal {
fmt.Println(fmt.Sprintf("Internal: Peer %v : New trylist(super) %v", et.peer.ID.ToString(), url)) fmt.Printf("Internal: Peer %v : New trylist(super) %v\n", et.peer.ID.ToString(), url)
} }
newmap_super[url] = &endpoint_tryitem{ newmap_super[url] = &endpoint_tryitem{
URL: url, URL: url,
@ -93,7 +92,7 @@ func (et *endpoint_trylist) UpdateP2P(url string) {
defer et.Unlock() defer et.Unlock()
if _, ok := et.trymap_p2p[url]; !ok { if _, ok := et.trymap_p2p[url]; !ok {
if et.peer.device.LogLevel.LogInternal { if et.peer.device.LogLevel.LogInternal {
fmt.Println(fmt.Sprintf("Internal: Peer %v : Add trylist(p2p) %v", et.peer.ID.ToString(), url)) fmt.Printf("Internal: Peer %v : Add trylist(p2p) %v\n", et.peer.ID.ToString(), url)
} }
et.trymap_p2p[url] = &endpoint_tryitem{ et.trymap_p2p[url] = &endpoint_tryitem{
URL: url, URL: url,
@ -123,7 +122,7 @@ func (et *endpoint_trylist) GetNextTry() (bool, string) {
for url, v := range et.trymap_p2p { for url, v := range et.trymap_p2p {
if v.firstTry.After(time.Time{}) && v.firstTry.Add(et.timeout).Before(time.Now()) { if v.firstTry.After(time.Time{}) && v.firstTry.Add(et.timeout).Before(time.Now()) {
if et.peer.device.LogLevel.LogInternal { if et.peer.device.LogLevel.LogInternal {
fmt.Println(fmt.Sprintf("Internal: Peer %v : Delete trylist(p2p) %v", et.peer.ID.ToString(), url)) fmt.Printf("Internal: Peer %v : Delete trylist(p2p) %v\n", et.peer.ID.ToString(), url)
} }
delete(et.trymap_p2p, url) delete(et.trymap_p2p, url)
} }
@ -203,15 +202,15 @@ type Peer struct {
persistentKeepaliveInterval uint32 // accessed atomically persistentKeepaliveInterval uint32 // accessed atomically
} }
func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool) (*Peer, error) { func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool, PersistentKeepalive uint32) (*Peer, error) {
if isSuper == false { if !isSuper {
if id < mtypes.Special_NodeID { if id < mtypes.NodeID_Special {
//pass check //pass check
} else { } else {
return nil, errors.New(fmt.Sprint("ID ", uint32(id), " is a special NodeID")) return nil, errors.New(fmt.Sprint("ID ", uint32(id), " is a special NodeID"))
} }
} else { } else {
if id == mtypes.SuperNodeMessage { if id == mtypes.NodeID_SuperNode {
//pass check //pass check
} else { } else {
return nil, errors.New(fmt.Sprint("ID", uint32(id), "is not a supernode NodeID")) return nil, errors.New(fmt.Sprint("ID", uint32(id), "is not a supernode NodeID"))
@ -221,7 +220,6 @@ func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool)
if device.isClosed() { if device.isClosed() {
return nil, errors.New("device closed") return nil, errors.New("device closed")
} }
// lock resources // lock resources
device.staticIdentity.RLock() device.staticIdentity.RLock()
defer device.staticIdentity.RUnlock() defer device.staticIdentity.RUnlock()
@ -239,6 +237,7 @@ func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool)
fmt.Println("Internal: Create peer with ID : " + id.ToString() + " and PubKey:" + pk.ToString()) fmt.Println("Internal: Create peer with ID : " + id.ToString() + " and PubKey:" + pk.ToString())
} }
peer := new(Peer) peer := new(Peer)
atomic.SwapUint32(&peer.persistentKeepaliveInterval, PersistentKeepalive)
peer.LastPacketReceivedAdd1Sec.Store(&time.Time{}) peer.LastPacketReceivedAdd1Sec.Store(&time.Time{})
peer.Lock() peer.Lock()
defer peer.Unlock() defer peer.Unlock()
@ -246,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 = path.Infinity peer.SingleWayLatency = 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)
@ -272,7 +271,7 @@ func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool)
peer.endpoint = nil peer.endpoint = nil
// add // add
if id == mtypes.SuperNodeMessage { // To communicate with supernode if id == mtypes.NodeID_SuperNode { // To communicate with supernode
device.peers.SuperPeer[pk] = peer device.peers.SuperPeer[pk] = peer
device.peers.keyMap[pk] = peer device.peers.keyMap[pk] = peer
} else { // Regular peer, other edgenodes } else { // Regular peer, other edgenodes
@ -285,7 +284,6 @@ func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool)
if peer.device.isUp() { if peer.device.isUp() {
peer.Start() peer.Start()
} }
return peer, nil return peer, nil
} }
@ -452,7 +450,7 @@ func (peer *Peer) Stop() {
} }
func (peer *Peer) SetPSK(psk NoisePresharedKey) { func (peer *Peer) SetPSK(psk NoisePresharedKey) {
if peer.device.IsSuperNode == false && peer.ID < mtypes.Special_NodeID && peer.device.EdgeConfig.DynamicRoute.P2P.UseP2P == true { if !peer.device.IsSuperNode && peer.ID < mtypes.NodeID_Special && peer.device.EdgeConfig.DynamicRoute.P2P.UseP2P {
peer.device.log.Verbosef("Preshared keys disabled in P2P mode.") peer.device.log.Verbosef("Preshared keys disabled in P2P mode.")
return return
} }
@ -490,8 +488,15 @@ func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) {
return return
} }
peer.Lock() peer.Lock()
if peer.ID == mtypes.SuperNodeMessage { defer peer.Unlock()
if peer.ID == mtypes.NodeID_SuperNode {
conn, err := net.Dial("udp", endpoint.DstToString()) conn, err := net.Dial("udp", endpoint.DstToString())
if err != nil {
if peer.device.LogLevel.LogControl {
fmt.Printf("Control: Set endpoint to peer %v failed: %v", peer.ID, err)
}
return
}
defer conn.Close() defer conn.Close()
if err == nil { if err == nil {
IP := conn.LocalAddr().(*net.UDPAddr).IP IP := conn.LocalAddr().(*net.UDPAddr).IP
@ -504,7 +509,7 @@ func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) {
} }
peer.device.SaveToConfig(peer, endpoint) peer.device.SaveToConfig(peer, endpoint)
peer.endpoint = endpoint peer.endpoint = endpoint
peer.Unlock()
} }
func (peer *Peer) GetEndpointSrcStr() string { func (peer *Peer) GetEndpointSrcStr() string {
@ -525,7 +530,7 @@ func (device *Device) SaveToConfig(peer *Peer, endpoint conn.Endpoint) {
if device.IsSuperNode { //Can't use in super mode if device.IsSuperNode { //Can't use in super mode
return return
} }
if peer.StaticConn == true { //static conn do not write new endpoint to config if peer.StaticConn { //static conn do not write new endpoint to config
return return
} }
if !device.EdgeConfig.DynamicRoute.P2P.UseP2P { //Must in p2p mode if !device.EdgeConfig.DynamicRoute.P2P.UseP2P { //Must in p2p mode
@ -545,7 +550,7 @@ func (device *Device) SaveToConfig(peer *Peer, endpoint conn.Endpoint) {
for _, peerfile := range device.EdgeConfig.Peers { for _, peerfile := range device.EdgeConfig.Peers {
if peerfile.NodeID == peer.ID && peerfile.PubKey == pubkeystr { if peerfile.NodeID == peer.ID && peerfile.PubKey == pubkeystr {
foundInFile = true foundInFile = true
if peerfile.Static == false { if !peerfile.Static {
peerfile.EndPoint = url peerfile.EndPoint = url
} }
} else if peerfile.NodeID == peer.ID || peerfile.PubKey == pubkeystr { } else if peerfile.NodeID == peer.ID || peerfile.PubKey == pubkeystr {

View File

@ -463,7 +463,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
device.log.Errorf("Invalid EgHeader from peer %v", peer) device.log.Errorf("Invalid EgHeader from peer %v", peer)
goto skip goto skip
} }
EgHeader, err = path.NewEgHeader(elem.packet[0:path.EgHeaderLen]) // EG header EgHeader, _ = path.NewEgHeader(elem.packet[0:path.EgHeaderLen]) // EG header
src_nodeID = EgHeader.GetSrc() src_nodeID = EgHeader.GetSrc()
dst_nodeID = EgHeader.GetDst() dst_nodeID = EgHeader.GetDst()
elem.packet = elem.packet[:EgHeader.GetPacketLength()+path.EgHeaderLen] // EG header + true packet elem.packet = elem.packet[:EgHeader.GetPacketLength()+path.EgHeaderLen] // EG header + true packet
@ -471,21 +471,21 @@ func (peer *Peer) RoutineSequentialReceiver() {
if device.IsSuperNode { if device.IsSuperNode {
switch dst_nodeID { switch dst_nodeID {
case mtypes.ControlMessage: case mtypes.NodeID_AllPeer:
should_process = true should_process = true
case mtypes.SuperNodeMessage: 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("Invalid dst_nodeID received. Check your code for bug")
} }
} else { } else {
switch dst_nodeID { switch dst_nodeID {
case mtypes.Broadcast: case mtypes.NodeID_Boardcast:
should_receive = true should_receive = true
should_transfer = true should_transfer = true
case mtypes.SuperNodeMessage: case mtypes.NodeID_SuperNode:
should_process = true should_process = true
case mtypes.ControlMessage: case mtypes.NodeID_AllPeer:
packet := elem.packet[path.EgHeaderLen:] //true packet packet := elem.packet[path.EgHeaderLen:] //true packet
if device.CheckNoDup(packet) { if device.CheckNoDup(packet) {
should_process = true should_process = true
@ -504,7 +504,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
should_process = true should_process = true
} }
default: default:
if device.graph.Next(device.ID, dst_nodeID) != nil { if device.graph.Next(device.ID, dst_nodeID) != mtypes.NodeID_Invalid {
should_transfer = true should_transfer = true
} else { } else {
device.log.Verbosef("No route to peer ID %v", dst_nodeID) device.log.Verbosef("No route to peer ID %v", dst_nodeID)
@ -517,9 +517,9 @@ 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.Broadcast { //Regular transfer algorithm if dst_nodeID == mtypes.NodeID_Boardcast { //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.ControlMessage { // 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)
skip_list[src_nodeID] = true //Don't send to conimg peer and source peer skip_list[src_nodeID] = true //Don't send to conimg peer and source peer
skip_list[peer.ID] = true skip_list[peer.ID] = true
@ -527,9 +527,9 @@ func (peer *Peer) RoutineSequentialReceiver() {
} else { } else {
next_id := device.graph.Next(device.ID, dst_nodeID) next_id := device.graph.Next(device.ID, dst_nodeID)
if next_id != nil { if next_id != mtypes.NodeID_Invalid {
device.peers.RLock() device.peers.RLock()
peer_out = device.peers.IDMap[*next_id] peer_out = device.peers.IDMap[next_id]
device.peers.RUnlock() device.peers.RUnlock()
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)

View File

@ -73,14 +73,14 @@ func (device *Device) SendPacket(peer *Peer, usage path.Usage, packet []byte, of
func (device *Device) BoardcastPacket(skip_list map[mtypes.Vertex]bool, usage path.Usage, packet []byte, offset int) { // Send packet to all connected peers func (device *Device) BoardcastPacket(skip_list map[mtypes.Vertex]bool, usage path.Usage, packet []byte, offset int) { // Send packet to all connected peers
send_list := device.graph.GetBoardcastList(device.ID) send_list := device.graph.GetBoardcastList(device.ID)
for node_id, _ := range skip_list { for node_id := range skip_list {
send_list[node_id] = false send_list[node_id] = false
} }
device.peers.RLock() device.peers.RLock()
for node_id, should_send := range send_list { for node_id, should_send := range send_list {
if should_send { if should_send {
peer_out, _ := device.peers.IDMap[node_id] peer_out := device.peers.IDMap[node_id]
device.SendPacket(peer_out, usage, packet, offset) go device.SendPacket(peer_out, usage, packet, offset)
} }
} }
device.peers.RUnlock() device.peers.RUnlock()
@ -95,20 +95,25 @@ func (device *Device) SpreadPacket(skip_list map[mtypes.Vertex]bool, usage path.
} }
continue continue
} }
device.SendPacket(peer_out, usage, packet, MessageTransportOffsetContent) go device.SendPacket(peer_out, usage, packet, MessageTransportOffsetContent)
} }
device.peers.RUnlock() device.peers.RUnlock()
} }
func (device *Device) TransitBoardcastPacket(src_nodeID mtypes.Vertex, in_id mtypes.Vertex, usage path.Usage, packet []byte, offset int) { func (device *Device) TransitBoardcastPacket(src_nodeID mtypes.Vertex, in_id mtypes.Vertex, usage path.Usage, packet []byte, offset int) {
node_boardcast_list := device.graph.GetBoardcastThroughList(device.ID, in_id, src_nodeID) node_boardcast_list, errs := device.graph.GetBoardcastThroughList(device.ID, in_id, src_nodeID)
if device.LogLevel.LogControl {
for _, err := range errs {
fmt.Printf("Internal: Can't boardcast: %v", err)
}
}
device.peers.RLock() device.peers.RLock()
for peer_id := range node_boardcast_list { for peer_id := range node_boardcast_list {
peer_out := device.peers.IDMap[peer_id] peer_out := device.peers.IDMap[peer_id]
if device.LogLevel.LogTransit { if device.LogLevel.LogTransit {
fmt.Printf("Transit: Transfer packet from %d through %d to %d\n", in_id, device.ID, peer_out.ID) fmt.Printf("Transit: Transfer packet from %d through %d to %d\n", in_id, device.ID, peer_out.ID)
} }
device.SendPacket(peer_out, usage, packet, offset) go device.SendPacket(peer_out, usage, packet, offset)
} }
device.peers.RUnlock() device.peers.RUnlock()
} }
@ -120,7 +125,7 @@ func (device *Device) Send2Super(usage path.Usage, packet []byte, offset int) {
/*if device.LogTransit { /*if device.LogTransit {
fmt.Printf("Send to supernode %s\n", peer_out.endpoint.DstToString()) fmt.Printf("Send to supernode %s\n", peer_out.endpoint.DstToString())
}*/ }*/
device.SendPacket(peer_out, usage, packet, offset) go device.SendPacket(peer_out, usage, packet, offset)
} }
} }
device.peers.RUnlock() device.peers.RUnlock()
@ -147,7 +152,7 @@ func (device *Device) process_received(msg_type path.Usage, peer *Peer, body []b
return device.server_process_Pong(peer, content) return device.server_process_Pong(peer, content)
} }
default: default:
err = errors.New("Not a valid msg_type") err = errors.New("not a valid msg_type")
} }
} else { } else {
switch msg_type { switch msg_type {
@ -172,7 +177,7 @@ func (device *Device) process_received(msg_type path.Usage, peer *Peer, body []b
return device.process_BoardcastPeerMsg(peer, content) return device.process_BoardcastPeerMsg(peer, content)
} }
default: default:
err = errors.New("Not a valid msg_type") err = errors.New("not a valid msg_type")
} }
} }
return return
@ -229,7 +234,7 @@ func (device *Device) GeneratePingPacket(src_nodeID mtypes.Vertex, request_reply
if err != nil { if err != nil {
return nil, path.PingPacket, err return nil, path.PingPacket, err
} }
header.SetDst(mtypes.ControlMessage) header.SetDst(mtypes.NodeID_AllPeer)
header.SetTTL(0) header.SetTTL(0)
header.SetSrc(device.ID) header.SetSrc(device.ID)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
@ -270,7 +275,7 @@ func (device *Device) server_process_RegisterMsg(peer *Peer, content mtypes.Regi
Params: fmt.Sprintf("Your nodeID: %v is not match with registered nodeID: %v", content.Node_id, peer.ID), Params: fmt.Sprintf("Your nodeID: %v is not match with registered nodeID: %v", content.Node_id, peer.ID),
} }
} }
if compareVersion(content.Version, device.Version) == false { if !compareVersion(content.Version, device.Version) {
ServerUpdateMsg = mtypes.ServerUpdateMsg{ ServerUpdateMsg = mtypes.ServerUpdateMsg{
Node_id: peer.ID, Node_id: peer.ID,
Action: mtypes.ThrowError, Action: mtypes.ThrowError,
@ -284,12 +289,12 @@ func (device *Device) server_process_RegisterMsg(peer *Peer, content mtypes.Regi
return err return err
} }
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, err := path.NewEgHeader(buf[:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetSrc(device.ID) header.SetSrc(device.ID)
header.SetTTL(0) header.SetTTL(0)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
copy(buf[path.EgHeaderLen:], body) copy(buf[path.EgHeaderLen:], body)
header.SetDst(mtypes.SuperNodeMessage) header.SetDst(mtypes.NodeID_SuperNode)
device.SendPacket(peer, path.ServerUpdate, buf, MessageTransportOffsetContent) device.SendPacket(peer, path.ServerUpdate, buf, MessageTransportOffsetContent)
return nil return nil
} }
@ -321,17 +326,17 @@ func (device *Device) process_ping(peer *Peer, content mtypes.PingMsg) error {
return err return err
} }
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, err := path.NewEgHeader(buf[:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetSrc(device.ID) header.SetSrc(device.ID)
header.SetTTL(device.EdgeConfig.DefaultTTL) header.SetTTL(device.EdgeConfig.DefaultTTL)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
copy(buf[path.EgHeaderLen:], body) copy(buf[path.EgHeaderLen:], body)
if device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode { if device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode {
header.SetDst(mtypes.SuperNodeMessage) header.SetDst(mtypes.NodeID_SuperNode)
device.Send2Super(path.PongPacket, buf, MessageTransportOffsetContent) device.Send2Super(path.PongPacket, buf, MessageTransportOffsetContent)
} }
if device.EdgeConfig.DynamicRoute.P2P.UseP2P { if device.EdgeConfig.DynamicRoute.P2P.UseP2P {
header.SetDst(mtypes.ControlMessage) header.SetDst(mtypes.NodeID_AllPeer)
device.SpreadPacket(make(map[mtypes.Vertex]bool), path.PongPacket, buf, MessageTransportOffsetContent) device.SpreadPacket(make(map[mtypes.Vertex]bool), path.PongPacket, buf, MessageTransportOffsetContent)
} }
go device.SendPing(peer, content.RequestReply, 0, 3) go device.SendPing(peer, content.RequestReply, 0, 3)
@ -352,7 +357,7 @@ func (device *Device) process_pong(peer *Peer, content mtypes.PongMsg) error {
return err return err
} }
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, err := path.NewEgHeader(buf[:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetSrc(device.ID) header.SetSrc(device.ID)
header.SetTTL(device.EdgeConfig.DefaultTTL) header.SetTTL(device.EdgeConfig.DefaultTTL)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
@ -379,6 +384,10 @@ func (device *Device) process_UpdatePeerMsg(peer *Peer, State_hash string) error
} }
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/peerinfo" //////////////////////////////////////////////////////////////////////////////////////////////// downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/peerinfo" ////////////////////////////////////////////////////////////////////////////////////////////////
req, err := http.NewRequest("GET", downloadurl, nil) req, err := http.NewRequest("GET", downloadurl, nil)
if err != nil {
device.log.Errorf(err.Error())
return err
}
q := req.URL.Query() q := req.URL.Query()
q.Add("NodeID", device.ID.ToString()) q.Add("NodeID", device.ID.ToString())
q.Add("PubKey", device.staticIdentity.publicKey.ToString()) q.Add("PubKey", device.staticIdentity.publicKey.ToString())
@ -444,13 +453,13 @@ func (device *Device) process_UpdatePeerMsg(peer *Peer, State_hash string) error
if device.LogLevel.LogControl { if device.LogLevel.LogControl {
fmt.Println("Control: Add new peer to local ID:" + peerinfo.NodeID.ToString() + " PubKey:" + PubKey) fmt.Println("Control: Add new peer to local ID:" + peerinfo.NodeID.ToString() + " PubKey:" + PubKey)
} }
if device.graph.Weight(device.ID, peerinfo.NodeID, false) == path.Infinity { // add node to graph if device.graph.Weight(device.ID, peerinfo.NodeID, false) == mtypes.Infinity { // add node to graph
device.graph.UpdateLatency(device.ID, peerinfo.NodeID, path.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false) device.graph.UpdateLatency(device.ID, peerinfo.NodeID, mtypes.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
} }
if device.graph.Weight(peerinfo.NodeID, device.ID, false) == path.Infinity { // add node to graph if device.graph.Weight(peerinfo.NodeID, device.ID, false) == mtypes.Infinity { // add node to graph
device.graph.UpdateLatency(peerinfo.NodeID, device.ID, path.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false) device.graph.UpdateLatency(peerinfo.NodeID, device.ID, mtypes.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
} }
device.NewPeer(sk, peerinfo.NodeID, false) device.NewPeer(sk, peerinfo.NodeID, false, 0)
thepeer = device.LookupPeer(sk) thepeer = device.LookupPeer(sk)
} }
if peerinfo.PSKey != "" { if peerinfo.PSKey != "" {
@ -492,6 +501,10 @@ func (device *Device) process_UpdateNhTableMsg(peer *Peer, State_hash string) er
} }
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/nhtable" //////////////////////////////////////////////////////////////////////////////////////////////// downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/nhtable" ////////////////////////////////////////////////////////////////////////////////////////////////
req, err := http.NewRequest("GET", downloadurl, nil) req, err := http.NewRequest("GET", downloadurl, nil)
if err != nil {
device.log.Errorf(err.Error())
return err
}
q := req.URL.Query() q := req.URL.Query()
q.Add("NodeID", device.ID.ToString()) q.Add("NodeID", device.ID.ToString())
q.Add("PubKey", device.staticIdentity.publicKey.ToString()) q.Add("PubKey", device.staticIdentity.publicKey.ToString())
@ -543,6 +556,10 @@ func (device *Device) process_UpdateSuperParamsMsg(peer *Peer, State_hash string
} }
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/superparams" //////////////////////////////////////////////////////////////////////////////////////////////// downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/superparams" ////////////////////////////////////////////////////////////////////////////////////////////////
req, err := http.NewRequest("GET", downloadurl, nil) req, err := http.NewRequest("GET", downloadurl, nil)
if err != nil {
device.log.Errorf(err.Error())
return err
}
q := req.URL.Query() q := req.URL.Query()
q.Add("NodeID", device.ID.ToString()) q.Add("NodeID", device.ID.ToString())
q.Add("PubKey", device.staticIdentity.publicKey.ToString()) q.Add("PubKey", device.staticIdentity.publicKey.ToString())
@ -601,7 +618,7 @@ func (device *Device) process_UpdateSuperParamsMsg(peer *Peer, State_hash string
} }
func (device *Device) process_ServerUpdateMsg(peer *Peer, content mtypes.ServerUpdateMsg) error { func (device *Device) process_ServerUpdateMsg(peer *Peer, content mtypes.ServerUpdateMsg) error {
if peer.ID != mtypes.SuperNodeMessage { if peer.ID != mtypes.NodeID_SuperNode {
if device.LogLevel.LogControl { if device.LogLevel.LogControl {
fmt.Println("Control: Ignored UpdateErrorMsg. Not from supernode.") fmt.Println("Control: Ignored UpdateErrorMsg. Not from supernode.")
} }
@ -634,7 +651,7 @@ func (device *Device) process_RequestPeerMsg(content mtypes.QueryPeerMsg) error
if device.EdgeConfig.DynamicRoute.P2P.UseP2P { if device.EdgeConfig.DynamicRoute.P2P.UseP2P {
device.peers.RLock() device.peers.RLock()
for pubkey, peer := range device.peers.keyMap { for pubkey, peer := range device.peers.keyMap {
if peer.ID >= mtypes.Special_NodeID { if peer.ID >= mtypes.NodeID_Special {
continue continue
} }
if peer.endpoint == nil { if peer.endpoint == nil {
@ -661,7 +678,7 @@ func (device *Device) process_RequestPeerMsg(content mtypes.QueryPeerMsg) error
} }
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[0:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[0:path.EgHeaderLen])
header.SetDst(mtypes.ControlMessage) header.SetDst(mtypes.NodeID_AllPeer)
header.SetTTL(device.EdgeConfig.DefaultTTL) header.SetTTL(device.EdgeConfig.DefaultTTL)
header.SetSrc(device.ID) header.SetSrc(device.ID)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
@ -688,13 +705,13 @@ func (device *Device) process_BoardcastPeerMsg(peer *Peer, content mtypes.Boardc
if device.LogLevel.LogControl { if device.LogLevel.LogControl {
fmt.Println("Control: Add new peer to local ID:" + content.NodeID.ToString() + " PubKey:" + pk.ToString()) fmt.Println("Control: Add new peer to local ID:" + content.NodeID.ToString() + " PubKey:" + pk.ToString())
} }
if device.graph.Weight(device.ID, content.NodeID, false) == path.Infinity { // add node to graph if device.graph.Weight(device.ID, content.NodeID, false) == mtypes.Infinity { // add node to graph
device.graph.UpdateLatency(device.ID, content.NodeID, path.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false) device.graph.UpdateLatency(device.ID, content.NodeID, mtypes.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
} }
if device.graph.Weight(content.NodeID, device.ID, false) == path.Infinity { // add node to graph if device.graph.Weight(content.NodeID, device.ID, false) == mtypes.Infinity { // add node to graph
device.graph.UpdateLatency(content.NodeID, device.ID, path.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false) device.graph.UpdateLatency(content.NodeID, device.ID, mtypes.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
} }
device.NewPeer(pk, content.NodeID, false) device.NewPeer(pk, content.NodeID, false, 0)
} }
if !thepeer.IsPeerAlive() { if !thepeer.IsPeerAlive() {
//Peer died, try to switch to this new endpoint //Peer died, try to switch to this new endpoint
@ -772,7 +789,7 @@ func (device *Device) RoutineSendPing(startchan <-chan struct{}) {
if !(device.EdgeConfig.DynamicRoute.P2P.UseP2P || device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode) { if !(device.EdgeConfig.DynamicRoute.P2P.UseP2P || device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode) {
return return
} }
waitchan := make(<-chan time.Time) var waitchan <-chan time.Time
for { for {
if device.EdgeConfig.DynamicRoute.SendPingInterval > 0 { if device.EdgeConfig.DynamicRoute.SendPingInterval > 0 {
waitchan = time.After(mtypes.S2TD(device.EdgeConfig.DynamicRoute.SendPingInterval)) waitchan = time.After(mtypes.S2TD(device.EdgeConfig.DynamicRoute.SendPingInterval))
@ -798,7 +815,7 @@ func (device *Device) RoutineRegister(startchan chan struct{}) {
if !(device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode) { if !(device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode) {
return return
} }
waitchan := time.After(8 * time.Second) var waitchan <-chan time.Time
startchan <- struct{}{} startchan <- struct{}{}
for { for {
if device.EdgeConfig.DynamicRoute.SendPingInterval > 0 { if device.EdgeConfig.DynamicRoute.SendPingInterval > 0 {
@ -830,7 +847,7 @@ func (device *Device) RoutineRegister(startchan chan struct{}) {
}) })
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[0:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[0:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage) header.SetDst(mtypes.NodeID_SuperNode)
header.SetTTL(0) header.SetTTL(0)
header.SetSrc(device.ID) header.SetSrc(device.ID)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
@ -843,7 +860,7 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
if !(device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode) { if !(device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode) {
return return
} }
waitchan := make(<-chan time.Time) var waitchan <-chan time.Time
for { for {
if device.SuperConfig.HttpPostInterval > 0 { if device.SuperConfig.HttpPostInterval > 0 {
waitchan = time.After(mtypes.S2TD(device.SuperConfig.HttpPostInterval)) waitchan = time.After(mtypes.S2TD(device.SuperConfig.HttpPostInterval))
@ -852,7 +869,6 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
} }
select { select {
case <-waitchan: case <-waitchan:
break
case <-startchan: case <-startchan:
if device.LogLevel.LogControl { if device.LogLevel.LogControl {
fmt.Println("Control: Start RoutinePostPeerInfo()") fmt.Println("Control: Start RoutinePostPeerInfo()")
@ -872,7 +888,7 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
Src_nodeID: device.ID, Src_nodeID: device.ID,
Dst_nodeID: id, Dst_nodeID: id,
Timediff: peer.SingleWayLatency, Timediff: peer.SingleWayLatency,
TimeToAlive: time.Now().Sub(*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)
if device.LogLevel.LogControl { if device.LogLevel.LogControl {
@ -914,13 +930,17 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
PostCount: device.HttpPostCount, PostCount: device.HttpPostCount,
BodyHash: bodyhash, BodyHash: bodyhash,
}) })
tokenString, err := token.SignedString(device.JWTSecret[:]) tokenString, _ := token.SignedString(device.JWTSecret[:])
// Construct post request // Construct post request
client := &http.Client{ client := &http.Client{
Timeout: 8 * time.Second, Timeout: 8 * time.Second,
} }
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/post/nodeinfo" downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/post/nodeinfo"
req, err := http.NewRequest("POST", downloadurl, bytes.NewReader(body)) req, err := http.NewRequest("POST", downloadurl, bytes.NewReader(body))
if err != nil {
device.log.Errorf(err.Error())
continue
}
q := req.URL.Query() q := req.URL.Query()
q.Add("NodeID", device.ID.ToString()) q.Add("NodeID", device.ID.ToString())
q.Add("PubKey", device.staticIdentity.publicKey.ToString()) q.Add("PubKey", device.staticIdentity.publicKey.ToString())
@ -955,9 +975,7 @@ func (device *Device) RoutineRecalculateNhTable() {
} }
for { for {
if time.Now().After(device.graph.NhTableExpire) { if time.Now().After(device.graph.NhTableExpire) {
if device.graph.CheckAnyShouldUpdate() { device.graph.RecalculateNhTable(false)
device.graph.RecalculateNhTable(false)
}
} }
time.Sleep(device.graph.TimeoutCheckInterval) time.Sleep(device.graph.TimeoutCheckInterval)
} }
@ -971,7 +989,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.Broadcast), Request_ID: uint32(mtypes.NodeID_Boardcast),
}) })
time.Sleep(timeout) time.Sleep(timeout)
} }

View File

@ -251,14 +251,14 @@ func (device *Device) RoutineReadFromTUN() {
//add custom header dst_node, src_node, ttl //add custom header dst_node, src_node, ttl
size += path.EgHeaderLen size += path.EgHeaderLen
elem.packet = elem.buffer[offset : offset+size] elem.packet = elem.buffer[offset : offset+size]
EgBody, err := path.NewEgHeader(elem.packet[0:path.EgHeaderLen]) EgBody, _ := path.NewEgHeader(elem.packet[0:path.EgHeaderLen])
dst_nodeID := EgBody.GetDst() dst_nodeID := EgBody.GetDst()
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.Broadcast dst_nodeID = mtypes.NodeID_Boardcast
} 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.Broadcast dst_nodeID = mtypes.NodeID_Boardcast
} else { } else {
dst_nodeID = val.(*IdAndTime).ID dst_nodeID = val.(*IdAndTime).ID
} }
@ -275,12 +275,12 @@ func (device *Device) RoutineReadFromTUN() {
continue continue
} }
if dst_nodeID != mtypes.Broadcast { if dst_nodeID != mtypes.NodeID_Boardcast {
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 != nil { if next_id != mtypes.NodeID_Invalid {
device.peers.RLock() device.peers.RLock()
peer = device.peers.IDMap[*next_id] peer = device.peers.IDMap[next_id]
device.peers.RUnlock() device.peers.RUnlock()
if peer == nil { if peer == nil {
continue continue

View File

@ -282,9 +282,9 @@ func (device *Device) handlePublicKeyLine(peer *ipcSetPeer, value string) error
if peer.created { if peer.created {
id, err := device.LookupPeerIDAtConfig(publicKey) id, err := device.LookupPeerIDAtConfig(publicKey)
if err != nil { if err != nil {
return errors.New("Create new peer by UAPI is not implemented") return errors.New("create new peer by UAPI is not implemented")
} }
peer.Peer, err = device.NewPeer(publicKey, id, false) peer.Peer, err = device.NewPeer(publicKey, id, false, 0)
if err != nil { if err != nil {
return ipcErrorf(ipc.IpcErrorInvalid, "failed to create new peer: %w", err) return ipcErrorf(ipc.IpcErrorInvalid, "failed to create new peer: %w", err)
} }

View File

@ -0,0 +1,35 @@
Config output dir: /tmp/eg_gen_static
ConfigTemplate for edge node: "n1.yaml"
Network name: "Node"
Edge Node:
MacAddress prefix: ""
IPv4 range: 192.168.76.0/24
IPv6 range: fd95:71cb:a3df:e586::/64
IPv6 LL range: fe80::a3df:0/112
Edge Nodes:
1:
Endpoint(optional): 127.0.0.1:3001
PersistentKeepalive: 30
2:
Endpoint(optional): 127.0.0.1:3002
PersistentKeepalive: 30
3:
Endpoint(optional): 127.0.0.1:3003
PersistentKeepalive: 30
4:
Endpoint(optional): 127.0.0.1:3004
PersistentKeepalive: 30
5:
Endpoint(optional): 127.0.0.1:3005
PersistentKeepalive: 30
6:
Endpoint(optional): 127.0.0.1:3006
PersistentKeepalive: 30
Distance matrix for all nodes: |-
X 1 2 3 4 5 6
1 0 1 Inf Inf Inf Inf
2 1 0 1 1 Inf Inf
3 Inf 1 0 1 1 Inf
4 Inf 1 1 0 Inf 1
5 Inf Inf 1 Inf 0 Inf
6 Inf Inf Inf 1 Inf 0

View File

@ -1,72 +1,66 @@
interface: Interface:
itype: stdio IType: stdio
name: tap1 Name: tap1
vppifaceid: 1 VPPIFaceID: 1
vppbridgeid: 4242 VPPBridgeID: 4242
macaddrprefix: AA:BB:CC:DD MacAddrPrefix: 8E:AA:C8:4B
mtu: 1416 IPv4CIDR: 192.168.76.0/24
recvaddr: 127.0.0.1:4001 IPv6CIDR: fd95:71cb:a3df:e586::/64
sendaddr: 127.0.0.1:5001 IPv6LLPrefix: fe80::a3df:0/112
l2headermode: kbdbg MTU: 1416
nodeid: 1 RecvAddr: 127.0.0.1:4001
nodename: Node01 SendAddr: 127.0.0.1:5001
defaultttl: 200 L2HeaderMode: kbdbg
l2fibtimeout: 3600 NodeID: 1
privkey: aABzjKhWdkFfQ29ZuijtMp1h1TNJe66SDCwvfmvQznw= NodeName: Node1
listenport: 3001 PostScript: ""
loglevel: DefaultTTL: 200
loglevel: error L2FIBTimeout: 3600
logtransit: true PrivKey: Fe9Q6K5L6xTVbx/zFc07tnQuo+pkeyrhfoTQ3BF5GRM=
logcontrol: true ListenPort: 3001
lognormal: true LogLevel:
loginternal: true LogLevel: error
logntp: true LogTransit: true
dynamicroute: LogControl: true
sendpinginterval: 20 LogNormal: true
peeralivetimeout: 30 LogInternal: true
dupchecktimeout: 40 LogNTP: true
conntimeout: 30 DynamicRoute:
connnexttry: 5 SendPingInterval: 16
savenewpeers: false PeerAliveTimeout: 70
supernode: DupCheckTimeout: 40
usesupernode: false ConnTimeOut: 20
connurlv4: 127.0.0.1:3000 ConnNextTry: 5
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic= AdditionalCost: 10
connurlv6: '[::1]:3000' SaveNewPeers: true
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI= SuperNode:
apiurl: http://127.0.0.1:3000/api UseSuperNode: false
supernodeinfotimeout: 40 PSKey: ""
p2p: EndpointV4: ""
usep2p: false PubKeyV4: ""
sendpeerinterval: 20 EndpointV6: ""
graphrecalculatesetting: PubKeyV6: ""
staticmode: false EndpointEdgeAPIUrl: ""
jittertolerance: 20 SkipLocalIP: false
jittertolerancemultiplier: 1.1 SuperNodeInfoTimeout: 50
nodereporttimeout: 40 P2P:
recalculatecooldown: 5 UseP2P: false
ntpconfig: SendPeerInterval: 20
usentp: false GraphRecalculateSetting:
maxserveruse: 8 StaticMode: false
synctimeinterval: 3600 ManualLatency: {}
ntptimeout: 10 JitterTolerance: 50
servers: JitterToleranceMultiplier: 1.1
- time.google.com DampingResistance: 0.9
- time1.google.com TimeoutCheckInterval: 5
- time2.google.com RecalculateCoolDown: 5
- time3.google.com NTPConfig:
- time4.google.com UseNTP: true
- time1.facebook.com MaxServerUse: 8
- time2.facebook.com SyncTimeInterval: 3600
- time3.facebook.com NTPTimeout: 3
- time4.facebook.com Servers: []
- time5.facebook.com NextHopTable:
- time.cloudflare.com
- time.apple.com
- time.asia.apple.com
- time.euro.apple.com
- time.windows.com
nexthoptable:
1: 1:
2: 2 2: 2
3: 2 3: 2
@ -103,10 +97,11 @@ nexthoptable:
3: 4 3: 4
4: 4 4: 4
5: 4 5: 4
resetconninterval: 86400 ResetConnInterval: 86400
peers: Peers:
- nodeid: 2 - NodeID: 2
pubkey: csT+hco4Jpa7btMeC9subHk2ZqzxcljcBk/57V0cSEk= PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
pskey: "" PSKey: kWDwCaC11UvYjfiXBMwYpR6Pujo1vaVW8JTusp1Kkrw=
endpoint: 127.0.0.1:3002 EndPoint: 127.0.0.1:3002
static: true PersistentKeepalive: 30
Static: true

View File

@ -1,72 +1,66 @@
interface: Interface:
itype: stdio IType: stdio
name: tap2 Name: tap1
vppifaceid: 2 VPPIFaceID: 1
vppbridgeid: 4242 VPPBridgeID: 4242
macaddrprefix: AA:BB:CC:DD MacAddrPrefix: 8E:AA:C8:4B
mtu: 1416 IPv4CIDR: 192.168.76.0/24
recvaddr: 127.0.0.1:4002 IPv6CIDR: fd95:71cb:a3df:e586::/64
sendaddr: 127.0.0.1:5002 IPv6LLPrefix: fe80::a3df:0/112
l2headermode: kbdbg MTU: 1416
nodeid: 2 RecvAddr: 127.0.0.1:4001
nodename: Node02 SendAddr: 127.0.0.1:5001
defaultttl: 200 L2HeaderMode: kbdbg
l2fibtimeout: 3600 NodeID: 2
privkey: UNZMzPX5fG/8yGC8edVj/ksF9N6ARRqdq7fqE/PD7ls= NodeName: Node2
listenport: 3002 PostScript: ""
loglevel: DefaultTTL: 200
loglevel: error L2FIBTimeout: 3600
logtransit: true PrivKey: WaeR98bFhy0rxw7unsaTo7aR2RmySo9l185IZqPWl1c=
logcontrol: true ListenPort: 3002
lognormal: true LogLevel:
loginternal: true LogLevel: error
logntp: true LogTransit: true
dynamicroute: LogControl: true
sendpinginterval: 20 LogNormal: true
peeralivetimeout: 30 LogInternal: true
dupchecktimeout: 40 LogNTP: true
conntimeout: 30 DynamicRoute:
connnexttry: 5 SendPingInterval: 16
savenewpeers: false PeerAliveTimeout: 70
supernode: DupCheckTimeout: 40
usesupernode: false ConnTimeOut: 20
connurlv4: 127.0.0.1:3000 ConnNextTry: 5
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic= AdditionalCost: 10
connurlv6: '[::1]:3000' SaveNewPeers: true
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI= SuperNode:
apiurl: http://127.0.0.1:3000/api UseSuperNode: false
supernodeinfotimeout: 40 PSKey: ""
p2p: EndpointV4: ""
usep2p: false PubKeyV4: ""
sendpeerinterval: 20 EndpointV6: ""
graphrecalculatesetting: PubKeyV6: ""
staticmode: false EndpointEdgeAPIUrl: ""
jittertolerance: 20 SkipLocalIP: false
jittertolerancemultiplier: 1.1 SuperNodeInfoTimeout: 50
nodereporttimeout: 40 P2P:
recalculatecooldown: 5 UseP2P: false
ntpconfig: SendPeerInterval: 20
usentp: false GraphRecalculateSetting:
maxserveruse: 8 StaticMode: false
synctimeinterval: 3600 ManualLatency: {}
ntptimeout: 10 JitterTolerance: 50
servers: JitterToleranceMultiplier: 1.1
- time.google.com DampingResistance: 0.9
- time1.google.com TimeoutCheckInterval: 5
- time2.google.com RecalculateCoolDown: 5
- time3.google.com NTPConfig:
- time4.google.com UseNTP: true
- time1.facebook.com MaxServerUse: 8
- time2.facebook.com SyncTimeInterval: 3600
- time3.facebook.com NTPTimeout: 3
- time4.facebook.com Servers: []
- time5.facebook.com NextHopTable:
- time.cloudflare.com
- time.apple.com
- time.asia.apple.com
- time.euro.apple.com
- time.windows.com
nexthoptable:
1: 1:
2: 2 2: 2
3: 2 3: 2
@ -103,20 +97,23 @@ nexthoptable:
3: 4 3: 4
4: 4 4: 4
5: 4 5: 4
resetconninterval: 86400 ResetConnInterval: 86400
peers: Peers:
- nodeid: 1 - NodeID: 1
pubkey: CooSkIP7/wiC7Rh83UYnB2yPkJijkNFmhtorHtyYlzY= PubKey: iDhQA9pgL01Gb0MrPzbiV80P4Uv3+uY/s+wNTQye0Qo=
pskey: "" PSKey: kWDwCaC11UvYjfiXBMwYpR6Pujo1vaVW8JTusp1Kkrw=
endpoint: 127.0.0.1:3001 EndPoint: 127.0.0.1:3001
static: true PersistentKeepalive: 0
- nodeid: 3 Static: true
pubkey: 0meQ0pQCAkLZdpfyMqggpnk0k3UKG2M8jfIMlQjTRWs= - NodeID: 3
pskey: "" PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
endpoint: 127.0.0.1:3003 PSKey: f2/34zUTLx8RP9cYisESoQlxz55oGZlTemqxv25VVa8=
static: true EndPoint: 127.0.0.1:3003
- nodeid: 4 PersistentKeepalive: 0
pubkey: 2EfY85KF1S+3dZ3A55eZcyi0QU+sOzOyuADtJs2U2Ww= Static: true
pskey: "" - NodeID: 4
endpoint: 127.0.0.1:3004 PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
static: true PSKey: zkG1ywPqS4MiGofuWmxHHBs8YBlnYd04B4T9IhkbXYM=
EndPoint: 127.0.0.1:3004
PersistentKeepalive: 30
Static: true

View File

@ -1,72 +1,66 @@
interface: Interface:
itype: stdio IType: stdio
name: tap3 Name: tap1
vppifaceid: 3 VPPIFaceID: 1
vppbridgeid: 4242 VPPBridgeID: 4242
macaddrprefix: AA:BB:CC:DD MacAddrPrefix: 8E:AA:C8:4B
mtu: 1416 IPv4CIDR: 192.168.76.0/24
recvaddr: 127.0.0.1:4003 IPv6CIDR: fd95:71cb:a3df:e586::/64
sendaddr: 127.0.0.1:5003 IPv6LLPrefix: fe80::a3df:0/112
l2headermode: kbdbg MTU: 1416
nodeid: 3 RecvAddr: 127.0.0.1:4001
nodename: Node03 SendAddr: 127.0.0.1:5001
defaultttl: 200 L2HeaderMode: kbdbg
l2fibtimeout: 3600 NodeID: 3
privkey: gJy35nbsd8FuuxyWHjsefN+U+oM7RkuIB1EanNLSVHg= NodeName: Node3
listenport: 3003 PostScript: ""
loglevel: DefaultTTL: 200
loglevel: error L2FIBTimeout: 3600
logtransit: true PrivKey: vNUFWbZXySk2dTl5R9UEG73p+4IQmywvC1uQStf0vao=
logcontrol: true ListenPort: 3003
lognormal: true LogLevel:
loginternal: true LogLevel: error
logntp: true LogTransit: true
dynamicroute: LogControl: true
sendpinginterval: 20 LogNormal: true
peeralivetimeout: 30 LogInternal: true
dupchecktimeout: 40 LogNTP: true
conntimeout: 30 DynamicRoute:
connnexttry: 5 SendPingInterval: 16
savenewpeers: false PeerAliveTimeout: 70
supernode: DupCheckTimeout: 40
usesupernode: false ConnTimeOut: 20
connurlv4: 127.0.0.1:3000 ConnNextTry: 5
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic= AdditionalCost: 10
connurlv6: '[::1]:3000' SaveNewPeers: true
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI= SuperNode:
apiurl: http://127.0.0.1:3000/api UseSuperNode: false
supernodeinfotimeout: 40 PSKey: ""
p2p: EndpointV4: ""
usep2p: false PubKeyV4: ""
sendpeerinterval: 20 EndpointV6: ""
graphrecalculatesetting: PubKeyV6: ""
staticmode: false EndpointEdgeAPIUrl: ""
jittertolerance: 20 SkipLocalIP: false
jittertolerancemultiplier: 1.1 SuperNodeInfoTimeout: 50
nodereporttimeout: 40 P2P:
recalculatecooldown: 5 UseP2P: false
ntpconfig: SendPeerInterval: 20
usentp: false GraphRecalculateSetting:
maxserveruse: 8 StaticMode: false
synctimeinterval: 3600 ManualLatency: {}
ntptimeout: 10 JitterTolerance: 50
servers: JitterToleranceMultiplier: 1.1
- time.google.com DampingResistance: 0.9
- time1.google.com TimeoutCheckInterval: 5
- time2.google.com RecalculateCoolDown: 5
- time3.google.com NTPConfig:
- time4.google.com UseNTP: true
- time1.facebook.com MaxServerUse: 8
- time2.facebook.com SyncTimeInterval: 3600
- time3.facebook.com NTPTimeout: 3
- time4.facebook.com Servers: []
- time5.facebook.com NextHopTable:
- time.cloudflare.com
- time.apple.com
- time.asia.apple.com
- time.euro.apple.com
- time.windows.com
nexthoptable:
1: 1:
2: 2 2: 2
3: 2 3: 2
@ -103,20 +97,23 @@ nexthoptable:
3: 4 3: 4
4: 4 4: 4
5: 4 5: 4
resetconninterval: 86400 ResetConnInterval: 86400
peers: Peers:
- nodeid: 2 - NodeID: 5
pubkey: csT+hco4Jpa7btMeC9subHk2ZqzxcljcBk/57V0cSEk= PubKey: AarP7cL6TVmFyHRZLXuxFGr5uQghsp57ydsJdj+lGzs=
pskey: "" PSKey: +TU8Zi8dr/UBqNyW/MYMgJiqkLnRbHW4ExQYQ2eNEag=
endpoint: 127.0.0.1:3002 EndPoint: 127.0.0.1:3005
static: true PersistentKeepalive: 0
- nodeid: 4 Static: true
pubkey: 2EfY85KF1S+3dZ3A55eZcyi0QU+sOzOyuADtJs2U2Ww= - NodeID: 2
pskey: "" PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
endpoint: 127.0.0.1:3004 PSKey: f2/34zUTLx8RP9cYisESoQlxz55oGZlTemqxv25VVa8=
static: true EndPoint: 127.0.0.1:3002
- nodeid: 5 PersistentKeepalive: 0
pubkey: yS7a/e0l0qF7z9MO/P79yYVfLI6UAli2iKjEZa6XmgY= Static: true
pskey: "" - NodeID: 4
endpoint: 127.0.0.1:3005 PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
static: true PSKey: 8HN+PBGDKmBFCDlWIyNUFFYS4X6ONGXI32AIKXSnUqU=
EndPoint: 127.0.0.1:3004
PersistentKeepalive: 30
Static: true

View File

@ -1,72 +1,66 @@
interface: Interface:
itype: stdio IType: stdio
name: tap4 Name: tap1
vppifaceid: 4 VPPIFaceID: 1
vppbridgeid: 4242 VPPBridgeID: 4242
macaddrprefix: AA:BB:CC:DD MacAddrPrefix: 8E:AA:C8:4B
mtu: 1416 IPv4CIDR: 192.168.76.0/24
recvaddr: 127.0.0.1:4004 IPv6CIDR: fd95:71cb:a3df:e586::/64
sendaddr: 127.0.0.1:5004 IPv6LLPrefix: fe80::a3df:0/112
l2headermode: kbdbg MTU: 1416
nodeid: 4 RecvAddr: 127.0.0.1:4001
nodename: Node04 SendAddr: 127.0.0.1:5001
defaultttl: 200 L2HeaderMode: kbdbg
l2fibtimeout: 3600 NodeID: 4
privkey: wAdLgCk0SHiO11/aUf9944focD1BUCH5b6Pe+cRHHXQ= NodeName: Node4
listenport: 3004 PostScript: ""
loglevel: DefaultTTL: 200
loglevel: error L2FIBTimeout: 3600
logtransit: true PrivKey: sn0BUwyNxfmgePYi6O6a8pFDKiLaCz6jk3ws+covRTA=
logcontrol: true ListenPort: 3004
lognormal: true LogLevel:
loginternal: true LogLevel: error
logntp: true LogTransit: true
dynamicroute: LogControl: true
sendpinginterval: 20 LogNormal: true
peeralivetimeout: 30 LogInternal: true
dupchecktimeout: 40 LogNTP: true
conntimeout: 30 DynamicRoute:
connnexttry: 5 SendPingInterval: 16
savenewpeers: false PeerAliveTimeout: 70
supernode: DupCheckTimeout: 40
usesupernode: false ConnTimeOut: 20
connurlv4: 127.0.0.1:3000 ConnNextTry: 5
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic= AdditionalCost: 10
connurlv6: '[::1]:3000' SaveNewPeers: true
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI= SuperNode:
apiurl: http://127.0.0.1:3000/api UseSuperNode: false
supernodeinfotimeout: 40 PSKey: ""
p2p: EndpointV4: ""
usep2p: false PubKeyV4: ""
sendpeerinterval: 20 EndpointV6: ""
graphrecalculatesetting: PubKeyV6: ""
staticmode: false EndpointEdgeAPIUrl: ""
jittertolerance: 20 SkipLocalIP: false
jittertolerancemultiplier: 1.1 SuperNodeInfoTimeout: 50
nodereporttimeout: 40 P2P:
recalculatecooldown: 5 UseP2P: false
ntpconfig: SendPeerInterval: 20
usentp: false GraphRecalculateSetting:
maxserveruse: 8 StaticMode: false
synctimeinterval: 3600 ManualLatency: {}
ntptimeout: 10 JitterTolerance: 50
servers: JitterToleranceMultiplier: 1.1
- time.google.com DampingResistance: 0.9
- time1.google.com TimeoutCheckInterval: 5
- time2.google.com RecalculateCoolDown: 5
- time3.google.com NTPConfig:
- time4.google.com UseNTP: true
- time1.facebook.com MaxServerUse: 8
- time2.facebook.com SyncTimeInterval: 3600
- time3.facebook.com NTPTimeout: 3
- time4.facebook.com Servers: []
- time5.facebook.com NextHopTable:
- time.cloudflare.com
- time.apple.com
- time.asia.apple.com
- time.euro.apple.com
- time.windows.com
nexthoptable:
1: 1:
2: 2 2: 2
3: 2 3: 2
@ -103,20 +97,23 @@ nexthoptable:
3: 4 3: 4
4: 4 4: 4
5: 4 5: 4
resetconninterval: 86400 ResetConnInterval: 86400
peers: Peers:
- nodeid: 2 - NodeID: 2
pubkey: csT+hco4Jpa7btMeC9subHk2ZqzxcljcBk/57V0cSEk= PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
pskey: "" PSKey: zkG1ywPqS4MiGofuWmxHHBs8YBlnYd04B4T9IhkbXYM=
endpoint: 127.0.0.1:3002 EndPoint: 127.0.0.1:3002
static: true PersistentKeepalive: 0
- nodeid: 3 Static: true
pubkey: 0meQ0pQCAkLZdpfyMqggpnk0k3UKG2M8jfIMlQjTRWs= - NodeID: 3
pskey: "" PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
endpoint: 127.0.0.1:3003 PSKey: 8HN+PBGDKmBFCDlWIyNUFFYS4X6ONGXI32AIKXSnUqU=
static: true EndPoint: 127.0.0.1:3003
- nodeid: 6 PersistentKeepalive: 0
pubkey: EXLAGpDrkB5cjP7lr4dL0FGZG0rssmQNtWx9k/CGChk= Static: true
pskey: "" - NodeID: 6
endpoint: 127.0.0.1:3006 PubKey: GH6ra6xhDezskkJrr/DXPi93vtmhi96DFBJ3s8U20EA=
static: true PSKey: f50pI53AQ6RoTGEnTSjl5YJhuMS/xiJjwtPuiP0xMUM=
EndPoint: 127.0.0.1:3006
PersistentKeepalive: 30
Static: true

View File

@ -1,72 +1,66 @@
interface: Interface:
itype: stdio IType: stdio
name: tap5 Name: tap1
vppifaceid: 5 VPPIFaceID: 1
vppbridgeid: 4242 VPPBridgeID: 4242
macaddrprefix: AA:BB:CC:DD MacAddrPrefix: 8E:AA:C8:4B
mtu: 1416 IPv4CIDR: 192.168.76.0/24
recvaddr: 127.0.0.1:4005 IPv6CIDR: fd95:71cb:a3df:e586::/64
sendaddr: 127.0.0.1:5005 IPv6LLPrefix: fe80::a3df:0/112
l2headermode: kbdbg MTU: 1416
nodeid: 5 RecvAddr: 127.0.0.1:4001
nodename: Node05 SendAddr: 127.0.0.1:5001
defaultttl: 200 L2HeaderMode: kbdbg
l2fibtimeout: 3600 NodeID: 5
privkey: gLmzeCbmN/hjiE+ehNXL9IxuG9hhWIYv2s16/DOW6FE= NodeName: Node5
listenport: 3005 PostScript: ""
loglevel: DefaultTTL: 200
loglevel: error L2FIBTimeout: 3600
logtransit: true PrivKey: Blk9f1+NiC2fVCZpUBG34G9hrcLThemk/1Zd/dET6AA=
logcontrol: true ListenPort: 3005
lognormal: true LogLevel:
loginternal: true LogLevel: error
logntp: true LogTransit: true
dynamicroute: LogControl: true
sendpinginterval: 20 LogNormal: true
peeralivetimeout: 30 LogInternal: true
dupchecktimeout: 40 LogNTP: true
conntimeout: 30 DynamicRoute:
connnexttry: 5 SendPingInterval: 16
savenewpeers: false PeerAliveTimeout: 70
supernode: DupCheckTimeout: 40
usesupernode: false ConnTimeOut: 20
connurlv4: 127.0.0.1:3000 ConnNextTry: 5
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic= AdditionalCost: 10
connurlv6: '[::1]:3000' SaveNewPeers: true
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI= SuperNode:
apiurl: http://127.0.0.1:3000/api UseSuperNode: false
supernodeinfotimeout: 40 PSKey: ""
p2p: EndpointV4: ""
usep2p: false PubKeyV4: ""
sendpeerinterval: 20 EndpointV6: ""
graphrecalculatesetting: PubKeyV6: ""
staticmode: false EndpointEdgeAPIUrl: ""
jittertolerance: 20 SkipLocalIP: false
jittertolerancemultiplier: 1.1 SuperNodeInfoTimeout: 50
nodereporttimeout: 40 P2P:
recalculatecooldown: 5 UseP2P: false
ntpconfig: SendPeerInterval: 20
usentp: false GraphRecalculateSetting:
maxserveruse: 8 StaticMode: false
synctimeinterval: 3600 ManualLatency: {}
ntptimeout: 10 JitterTolerance: 50
servers: JitterToleranceMultiplier: 1.1
- time.google.com DampingResistance: 0.9
- time1.google.com TimeoutCheckInterval: 5
- time2.google.com RecalculateCoolDown: 5
- time3.google.com NTPConfig:
- time4.google.com UseNTP: true
- time1.facebook.com MaxServerUse: 8
- time2.facebook.com SyncTimeInterval: 3600
- time3.facebook.com NTPTimeout: 3
- time4.facebook.com Servers: []
- time5.facebook.com NextHopTable:
- time.cloudflare.com
- time.apple.com
- time.asia.apple.com
- time.euro.apple.com
- time.windows.com
nexthoptable:
1: 1:
2: 2 2: 2
3: 2 3: 2
@ -103,10 +97,11 @@ nexthoptable:
3: 4 3: 4
4: 4 4: 4
5: 4 5: 4
resetconninterval: 86400 ResetConnInterval: 86400
peers: Peers:
- nodeid: 3 - NodeID: 3
pubkey: 0meQ0pQCAkLZdpfyMqggpnk0k3UKG2M8jfIMlQjTRWs= PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
pskey: "" PSKey: +TU8Zi8dr/UBqNyW/MYMgJiqkLnRbHW4ExQYQ2eNEag=
endpoint: 127.0.0.1:3003 EndPoint: 127.0.0.1:3003
static: true PersistentKeepalive: 30
Static: true

View File

@ -1,72 +1,66 @@
interface: Interface:
itype: stdio IType: stdio
name: tap6 Name: tap1
vppifaceid: 6 VPPIFaceID: 1
vppbridgeid: 4242 VPPBridgeID: 4242
macaddrprefix: AA:BB:CC:DD MacAddrPrefix: 8E:AA:C8:4B
mtu: 1416 IPv4CIDR: 192.168.76.0/24
recvaddr: 127.0.0.1:4006 IPv6CIDR: fd95:71cb:a3df:e586::/64
sendaddr: 127.0.0.1:5006 IPv6LLPrefix: fe80::a3df:0/112
l2headermode: kbdbg MTU: 1416
nodeid: 6 RecvAddr: 127.0.0.1:4001
nodename: Node06 SendAddr: 127.0.0.1:5001
defaultttl: 200 L2HeaderMode: kbdbg
l2fibtimeout: 3600 NodeID: 6
privkey: IIX5F6oWZUS2dlhxWFJ7TxdJtDCr5jzeuhxUB6YM7Us= NodeName: Node6
listenport: 3006 PostScript: ""
loglevel: DefaultTTL: 200
loglevel: error L2FIBTimeout: 3600
logtransit: true PrivKey: h03OJ1d8cVGF8TemiWWTla7RCIMtInhUnjs2CBb8AT8=
logcontrol: true ListenPort: 3006
lognormal: true LogLevel:
loginternal: true LogLevel: error
logntp: true LogTransit: true
dynamicroute: LogControl: true
sendpinginterval: 20 LogNormal: true
peeralivetimeout: 30 LogInternal: true
dupchecktimeout: 40 LogNTP: true
conntimeout: 30 DynamicRoute:
connnexttry: 5 SendPingInterval: 16
savenewpeers: false PeerAliveTimeout: 70
supernode: DupCheckTimeout: 40
usesupernode: false ConnTimeOut: 20
connurlv4: 127.0.0.1:3000 ConnNextTry: 5
pubkeyv4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic= AdditionalCost: 10
connurlv6: '[::1]:3000' SaveNewPeers: true
pubkeyv6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI= SuperNode:
apiurl: http://127.0.0.1:3000/api UseSuperNode: false
supernodeinfotimeout: 40 PSKey: ""
p2p: EndpointV4: ""
usep2p: false PubKeyV4: ""
sendpeerinterval: 20 EndpointV6: ""
graphrecalculatesetting: PubKeyV6: ""
staticmode: false EndpointEdgeAPIUrl: ""
jittertolerance: 20 SkipLocalIP: false
jittertolerancemultiplier: 1.1 SuperNodeInfoTimeout: 50
nodereporttimeout: 40 P2P:
recalculatecooldown: 5 UseP2P: false
ntpconfig: SendPeerInterval: 20
usentp: false GraphRecalculateSetting:
maxserveruse: 8 StaticMode: false
synctimeinterval: 3600 ManualLatency: {}
ntptimeout: 10 JitterTolerance: 50
servers: JitterToleranceMultiplier: 1.1
- time.google.com DampingResistance: 0.9
- time1.google.com TimeoutCheckInterval: 5
- time2.google.com RecalculateCoolDown: 5
- time3.google.com NTPConfig:
- time4.google.com UseNTP: true
- time1.facebook.com MaxServerUse: 8
- time2.facebook.com SyncTimeInterval: 3600
- time3.facebook.com NTPTimeout: 3
- time4.facebook.com Servers: []
- time5.facebook.com NextHopTable:
- time.cloudflare.com
- time.apple.com
- time.asia.apple.com
- time.euro.apple.com
- time.windows.com
nexthoptable:
1: 1:
2: 2 2: 2
3: 2 3: 2
@ -103,10 +97,11 @@ nexthoptable:
3: 4 3: 4
4: 4 4: 4
5: 4 5: 4
resetconninterval: 86400 ResetConnInterval: 86400
peers: Peers:
- nodeid: 4 - NodeID: 4
pubkey: 2EfY85KF1S+3dZ3A55eZcyi0QU+sOzOyuADtJs2U2Ww= PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
pskey: "" PSKey: f50pI53AQ6RoTGEnTSjl5YJhuMS/xiJjwtPuiP0xMUM=
endpoint: 127.0.0.1:3004 EndPoint: 127.0.0.1:3004
static: true PersistentKeepalive: 30
Static: true

View File

@ -10,17 +10,17 @@ import (
"github.com/KusakabeSi/EtherGuard-VPN/path" "github.com/KusakabeSi/EtherGuard-VPN/path"
) )
func GetExampleEdgeConf(templatePath string) mtypes.EdgeConfig { func GetExampleEdgeConf(templatePath string, getDemo bool) mtypes.EdgeConfig {
tconfig := mtypes.EdgeConfig{} econfig := mtypes.EdgeConfig{}
if templatePath != "" { if templatePath != "" {
err := mtypes.ReadYaml(templatePath, &tconfig) err := mtypes.ReadYaml(templatePath, &econfig)
if err == nil { if err == nil {
return tconfig return econfig
} }
} }
v1 := mtypes.Vertex(1) v1 := mtypes.Vertex(1)
v2 := mtypes.Vertex(2) v2 := mtypes.Vertex(2)
tconfig = mtypes.EdgeConfig{ econfig = mtypes.EdgeConfig{
Interface: mtypes.InterfaceConf{ Interface: mtypes.InterfaceConf{
IType: "tap", IType: "tap",
Name: "tap1", Name: "tap1",
@ -73,9 +73,17 @@ func GetExampleEdgeConf(templatePath string) mtypes.EdgeConfig {
StaticMode: false, StaticMode: false,
JitterTolerance: 50, JitterTolerance: 50,
JitterToleranceMultiplier: 1.1, JitterToleranceMultiplier: 1.1,
DampingResistance: 0.8, DampingResistance: 0.9,
TimeoutCheckInterval: 5, TimeoutCheckInterval: 5,
RecalculateCoolDown: 5, RecalculateCoolDown: 5,
ManualLatency: mtypes.DistTable{
mtypes.Vertex(1): {
mtypes.Vertex(2): 2,
},
mtypes.Vertex(2): {
mtypes.Vertex(1): 2,
},
},
}, },
}, },
NTPConfig: mtypes.NTPInfo{ NTPConfig: mtypes.NTPInfo{
@ -109,43 +117,50 @@ func GetExampleEdgeConf(templatePath string) mtypes.EdgeConfig {
}, },
NextHopTable: mtypes.NextHopTable{ NextHopTable: mtypes.NextHopTable{
mtypes.Vertex(1): { mtypes.Vertex(1): {
mtypes.Vertex(2): &v2, mtypes.Vertex(2): v2,
}, },
mtypes.Vertex(2): { mtypes.Vertex(2): {
mtypes.Vertex(1): &v1, mtypes.Vertex(1): v1,
}, },
}, },
ResetConnInterval: 86400, ResetConnInterval: 86400,
Peers: []mtypes.PeerInfo{ Peers: []mtypes.PeerInfo{
{ {
NodeID: 2, NodeID: 2,
PubKey: "dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=", PubKey: "dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=",
PSKey: "juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=", PSKey: "juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=",
EndPoint: "127.0.0.1:3002", EndPoint: "127.0.0.1:3002",
Static: true, PersistentKeepalive: 30,
Static: true,
}, },
}, },
} }
g := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting, tconfig.DynamicRoute.NTPConfig, mtypes.LoggerInfo{}) if getDemo {
g, _ := path.NewGraph(3, false, econfig.DynamicRoute.P2P.GraphRecalculateSetting, econfig.DynamicRoute.NTPConfig, mtypes.LoggerInfo{})
g.UpdateLatency(1, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 1, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(2, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 2, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(5, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 5, 0.5, 99999, 0, false, false)
g.UpdateLatency(6, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 6, 0.5, 99999, 0, false, false)
_, next, _ := g.FloydWarshall(false)
econfig.NextHopTable = next
g.UpdateLatency(1, 2, 0.5, 99999, 0, false, false) } else {
g.UpdateLatency(2, 1, 0.5, 99999, 0, false, false) econfig.Peers = []mtypes.PeerInfo{}
g.UpdateLatency(2, 3, 0.5, 99999, 0, false, false) econfig.NextHopTable = make(mtypes.NextHopTable)
g.UpdateLatency(3, 2, 0.5, 99999, 0, false, false) econfig.DynamicRoute.P2P.GraphRecalculateSetting.ManualLatency = make(mtypes.DistTable)
g.UpdateLatency(2, 4, 0.5, 99999, 0, false, false) }
g.UpdateLatency(4, 2, 0.5, 99999, 0, false, false) return econfig
g.UpdateLatency(3, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(5, 3, 0.5, 99999, 0, false, false)
g.UpdateLatency(3, 5, 0.5, 99999, 0, false, false)
g.UpdateLatency(6, 4, 0.5, 99999, 0, false, false)
g.UpdateLatency(4, 6, 0.5, 99999, 0, false, false)
_, next, _ := g.FloydWarshall(false)
tconfig.NextHopTable = next
return tconfig
} }
func GetExampleSuperConf(templatePath string) mtypes.SuperConfig { func GetExampleSuperConf(templatePath string, getDemo bool) mtypes.SuperConfig {
sconfig := mtypes.SuperConfig{} sconfig := mtypes.SuperConfig{}
if templatePath != "" { if templatePath != "" {
err := mtypes.ReadYaml(templatePath, &sconfig) err := mtypes.ReadYaml(templatePath, &sconfig)
@ -189,18 +204,18 @@ func GetExampleSuperConf(templatePath string) mtypes.SuperConfig {
}, },
GraphRecalculateSetting: mtypes.GraphRecalculateSetting{ GraphRecalculateSetting: mtypes.GraphRecalculateSetting{
StaticMode: false, StaticMode: false,
JitterTolerance: 50, JitterTolerance: 30,
JitterToleranceMultiplier: 1.01, JitterToleranceMultiplier: 1.01,
DampingResistance: 0.8, DampingResistance: 0.9,
TimeoutCheckInterval: 5, TimeoutCheckInterval: 5,
RecalculateCoolDown: 5, RecalculateCoolDown: 5,
}, },
NextHopTable: mtypes.NextHopTable{ NextHopTable: mtypes.NextHopTable{
mtypes.Vertex(1): { mtypes.Vertex(1): {
mtypes.Vertex(2): &v2, mtypes.Vertex(2): v2,
}, },
mtypes.Vertex(2): { mtypes.Vertex(2): {
mtypes.Vertex(1): &v1, mtypes.Vertex(1): v1,
}, },
}, },
EdgeTemplate: "example_config/super_mode/n1.yaml", EdgeTemplate: "example_config/super_mode/n1.yaml",
@ -222,5 +237,10 @@ func GetExampleSuperConf(templatePath string) mtypes.SuperConfig {
}, },
}, },
} }
if !getDemo {
sconfig.Peers = []mtypes.SuperPeerInfo{}
sconfig.NextHopTable = make(mtypes.NextHopTable)
sconfig.GraphRecalculateSetting.ManualLatency = make(mtypes.DistTable)
}
return sconfig return sconfig
} }

206
gencfg/gencfgNM.go Normal file
View File

@ -0,0 +1,206 @@
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2017-2021 Kusakabe Si. All Rights Reserved.
*/
package gencfg
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/KusakabeSi/EtherGuard-VPN/conn"
"github.com/KusakabeSi/EtherGuard-VPN/device"
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/path"
"github.com/KusakabeSi/EtherGuard-VPN/tap"
yaml "gopkg.in/yaml.v2"
)
func printNMCinfig() {
tconfig := NMCfg{}
tconfig.EdgeNodes = make(map[mtypes.Vertex]edge_raw_info)
tconfig.EdgeNodes[mtypes.Vertex(1)] = edge_raw_info{Endpoint: "1.example.com:3456"}
tconfig.EdgeNodes[mtypes.Vertex(2)] = edge_raw_info{Endpoint: "2.example.com:4567"}
tconfig.DistanceMatrix = `X 1 2
1 0 1
2 1 0`
toprint, _ := yaml.Marshal(tconfig)
fmt.Print(string(toprint))
}
func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
NMCfg := NMCfg{}
if printExample {
printNMCinfig()
return
}
err = mtypes.ReadYaml(NMCinfigPath, &NMCfg)
if err != nil {
return err
}
os.Chdir(filepath.Dir(NMCinfigPath))
err = os.MkdirAll(NMCfg.ConfigOutputDir, 0o700)
if err != nil {
return err
}
files, err := os.ReadDir(NMCfg.ConfigOutputDir)
if err != nil {
return err
}
if len(files) > 0 {
return fmt.Errorf(NMCfg.ConfigOutputDir + " not empty")
}
if NMCfg.EdgeConfigTemplate != "" {
var econfig mtypes.EdgeConfig
err = mtypes.ReadYaml(NMCfg.EdgeConfigTemplate, &econfig)
if err != nil {
fmt.Printf("Error read config: %v\t%v\n", NMCfg.EdgeConfigTemplate, err)
return err
}
}
if len(NMCfg.NetworkName) > 10 {
return fmt.Errorf("name too long")
}
allowed := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
for _, c := range []byte(NMCfg.NetworkName) {
if !strings.Contains(allowed, string(c)) {
return fmt.Errorf("name can only contain %v", allowed)
}
}
g, _ := path.NewGraph(0, false, mtypes.GraphRecalculateSetting{}, mtypes.NTPInfo{}, mtypes.LoggerInfo{LogInternal: false})
edges, err := path.ParseDistanceMatrix(NMCfg.DistanceMatrix)
if err != nil {
return err
}
g.UpdateLatencyMulti(edges, false, false)
all_verts := g.Vertices()
MaxNodeID := mtypes.Vertex(0)
edge_infos := make(map[mtypes.Vertex]edge_info)
for NodeID, edgeinfo := range NMCfg.EdgeNodes {
endpoint := edgeinfo.Endpoint
if _, has := all_verts[NodeID]; !has {
return fmt.Errorf("not found in DistanceMatrix: NodeID %v", NodeID)
}
if !all_verts[NodeID] {
return fmt.Errorf("duplicate definition: NodeID %v ", NodeID)
}
_, err = conn.LookupIP(endpoint, 0)
if err != nil {
return err
}
pri, pub := device.RandomKeyPair()
edge_infos[NodeID] = edge_info{
Endpoint: endpoint,
PrivKey: pri.ToString(),
PubKey: pub.ToString(),
PersistentKeepalive: edgeinfo.PersistentKeepalive,
ConnectedEdge: make(map[mtypes.Vertex]bool),
}
all_verts[NodeID] = false
if NodeID > MaxNodeID {
MaxNodeID = NodeID
}
}
for nid, notinconf := range all_verts {
if notinconf {
return fmt.Errorf("NodeID %v exists in DistanceMatrix but not in config", nid)
}
}
for _, edge := range edges {
s := edge.Src_nodeID
d := edge.Dst_nodeID
if len(edge_infos[s].Endpoint)+len(edge_infos[d].Endpoint) == 0 {
return fmt.Errorf("there are an edge between node %v and %v, but non of them have endpoint", s, d)
}
edge_infos[s].ConnectedEdge[d] = true
edge_infos[d].ConnectedEdge[s] = true
}
if NMCfg.EdgeNode.MacPrefix != "" {
_, err = tap.GetMacAddr(NMCfg.EdgeNode.MacPrefix, uint32(MaxNodeID))
if err != nil {
return err
}
} else {
pbyte := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
pbyte[0] &^= 0b00000001
pbyte[0] |= 0b00000010
NMCfg.EdgeNode.MacPrefix = fmt.Sprintf("%X:%X:%X:%X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
}
dist, next, err := g.FloydWarshall(false)
g.SetNHTable(next)
if err != nil {
fmt.Println("Error:", err)
}
nhTableStr, _ := yaml.Marshal(next)
fmt.Println(string(nhTableStr))
all_vert := g.Vertices()
for u := range all_vert {
for v := range all_vert {
if u != v {
path, err := g.Path(u, v)
if err != nil {
return fmt.Errorf("couldn't find path from %v to %v: %v", u, v, err)
}
fmt.Printf("%d -> %d\t%3f\t%v\n", u, v, dist[u][v], path)
}
}
}
econfig := GetExampleEdgeConf(NMCfg.EdgeConfigTemplate, false)
econfig.DynamicRoute.P2P.UseP2P = false
econfig.DynamicRoute.SuperNode.UseSuperNode = false
econfig.NextHopTable = next
econfig.DynamicRoute.NTPConfig.Servers = make([]string, 0)
econfig.DynamicRoute.SuperNode.PSKey = ""
econfig.DynamicRoute.SuperNode.EndpointV4 = ""
econfig.DynamicRoute.SuperNode.EndpointV6 = ""
econfig.DynamicRoute.SuperNode.PubKeyV4 = ""
econfig.DynamicRoute.SuperNode.PubKeyV6 = ""
econfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl = ""
var pskdb device.PSKDB
for NodeID, Edge := range edge_infos {
econfig.Interface.MacAddrPrefix = NMCfg.EdgeNode.MacPrefix
econfig.Interface.IPv4CIDR = NMCfg.EdgeNode.IPv4Range
econfig.Interface.IPv6CIDR = NMCfg.EdgeNode.IPv6Range
econfig.Interface.IPv6LLPrefix = NMCfg.EdgeNode.IPv6LLRange
econfig.PrivKey = Edge.PrivKey
econfig.NodeID = NodeID
idstr := fmt.Sprintf("%0"+strconv.Itoa(len(MaxNodeID.ToString()))+"d", NodeID)
econfig.NodeName = NMCfg.NetworkName + idstr
if Edge.Endpoint != "" {
ps := strings.Split(Edge.Endpoint, ":")
pss := ps[len(ps)-1]
port, err := strconv.ParseUint(pss, 10, 16)
if err != nil {
return err
}
econfig.ListenPort = int(port)
}
econfig.Peers = make([]mtypes.PeerInfo, 0)
for CNodeID, _ := range Edge.ConnectedEdge {
econfig.Peers = append(econfig.Peers, mtypes.PeerInfo{
NodeID: CNodeID,
PubKey: edge_infos[CNodeID].PubKey,
PSKey: pskdb.GetPSK(NodeID, CNodeID).ToString(),
EndPoint: edge_infos[CNodeID].Endpoint,
PersistentKeepalive: Edge.PersistentKeepalive,
Static: true,
})
}
mtypesBytes, _ := yaml.Marshal(econfig)
ioutil.WriteFile(filepath.Join(NMCfg.ConfigOutputDir, NMCfg.NetworkName+"_edge"+idstr+".yaml"), mtypesBytes, 0o600)
fmt.Println(filepath.Join(NMCfg.ConfigOutputDir, NMCfg.NetworkName+"_edge"+idstr+".yaml"))
}
return nil
}

View File

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

View File

@ -127,78 +127,68 @@ func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
return err return err
} }
s := SMCfg.ConfigOutputDir os.Chdir(filepath.Dir(SMCinfigPath))
err = os.MkdirAll(s, 0o700)
err = os.MkdirAll(SMCfg.ConfigOutputDir, 0o700)
if err != nil { if err != nil {
return err return err
} }
files, err := os.ReadDir(s) files, err := os.ReadDir(SMCfg.ConfigOutputDir)
if err != nil { if err != nil {
return err return err
} }
if len(files) > 0 { if len(files) > 0 {
return fmt.Errorf(s + " not empty") return fmt.Errorf(SMCfg.ConfigOutputDir + " not empty")
} }
CfgSavePath := s if SMCfg.SuperConfigTemplate != "" {
s = SMCfg.SuperConfigTemplate
if s != "" {
var sconfig mtypes.SuperConfig var sconfig mtypes.SuperConfig
err = mtypes.ReadYaml(s, &sconfig) err = mtypes.ReadYaml(SMCfg.SuperConfigTemplate, &sconfig)
if err != nil { if err != nil {
fmt.Printf("Error read config: %v\t%v\n", s, err) fmt.Printf("Error read config: %v\t%v\n", SMCfg.SuperConfigTemplate, err)
return err return err
} }
} }
SuperTamplatePath := s if SMCfg.EdgeConfigTemplate != "" {
s = SMCfg.EdgeConfigTemplate
if s != "" {
var econfig mtypes.EdgeConfig var econfig mtypes.EdgeConfig
err = mtypes.ReadYaml(s, &econfig) err = mtypes.ReadYaml(SMCfg.EdgeConfigTemplate, &econfig)
if err != nil { if err != nil {
fmt.Printf("Error read config: %v\t%v\n", s, err) fmt.Printf("Error read config: %v\t%v\n", SMCfg.EdgeConfigTemplate, err)
return err return err
} }
} }
EdgeTamplatePath := s
sconfig := GetExampleSuperConf(SuperTamplatePath) sconfig := GetExampleSuperConf(SMCfg.SuperConfigTemplate, false)
s = SMCfg.NetworkName if len(SMCfg.NetworkName) > 10 {
if len(s) > 10 {
return fmt.Errorf("Name too long") return fmt.Errorf("Name too long")
} }
allowed := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_" allowed := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
for _, c := range []byte(s) { for _, c := range []byte(SMCfg.NetworkName) {
if strings.Contains(allowed, string(c)) == false { if strings.Contains(allowed, string(c)) == false {
return fmt.Errorf("Name can only contain %v", allowed) return fmt.Errorf("Name can only contain %v", allowed)
} }
} }
NetworkName := s
ListenPort := fmt.Sprintf("%v", SMCfg.Supernode.ListenPort) ListenPort := fmt.Sprintf("%v", SMCfg.Supernode.ListenPort)
API_Prefix := SMCfg.Supernode.EdgeAPI_Prefix API_Prefix := SMCfg.Supernode.EdgeAPI_Prefix
s = SMCfg.Supernode.EndpointV4 EndpointV4 := SMCfg.Supernode.EndpointV4
if s != "" { if EndpointV4 != "" {
_, err = conn.LookupIP(s+":"+ListenPort, 4) _, err = conn.LookupIP(EndpointV4+":"+ListenPort, 4)
if err != nil { if err != nil {
return err return err
} }
} }
EndpointV4 := s
s = SMCfg.Supernode.EndpointV6 EndpointV6 := SMCfg.Supernode.EndpointV6
if s != "" { if EndpointV6 != "" {
if strings.Contains(s, ":") && (s[0] != '[' || s[len(s)-1] != ']') { if strings.Contains(EndpointV6, ":") && (EndpointV6[0] != '[' || EndpointV6[len(EndpointV6)-1] != ']') {
return fmt.Errorf("Invalid IPv6 format, please use [%v] instead", s) return fmt.Errorf("Invalid IPv6 format, please use [%v] instead", EndpointV6)
} }
_, err = conn.LookupIP(s+":"+ListenPort, 6) _, err = conn.LookupIP(EndpointV6+":"+ListenPort, 6)
if err != nil { if err != nil {
return return
} }
@ -206,26 +196,23 @@ func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
return fmt.Errorf("Muse provide at lease v4 v6 address") return fmt.Errorf("Muse provide at lease v4 v6 address")
} }
EndpointV6 := s
EndpointEdgeAPIUrl := SMCfg.Supernode.Endpoint_EdgeAPI EndpointEdgeAPIUrl := SMCfg.Supernode.Endpoint_EdgeAPI
sconfig.NodeName = NetworkName + "SP" sconfig.NodeName = SMCfg.NetworkName + "SP"
sconfig.API_Prefix = API_Prefix sconfig.API_Prefix = API_Prefix
sconfig.ListenPort, _ = strconv.Atoi(ListenPort) sconfig.ListenPort, _ = strconv.Atoi(ListenPort)
sconfig.ListenPort_EdgeAPI = ListenPort sconfig.ListenPort_EdgeAPI = ListenPort
sconfig.ListenPort_ManageAPI = ListenPort sconfig.ListenPort_ManageAPI = ListenPort
sconfig.NextHopTable = make(mtypes.NextHopTable) sconfig.EdgeTemplate = SMCfg.EdgeConfigTemplate
sconfig.EdgeTemplate = EdgeTamplatePath
NodeIDs, _, ModeIDmax, err := ParseIDs(SMCfg.EdgeNode.NodeIDs) NodeIDs, _, ModeIDmax, err := ParseIDs(SMCfg.EdgeNode.NodeIDs)
if err != nil { if err != nil {
return return
} }
s = SMCfg.EdgeNode.MacPrefix MacPrefix := SMCfg.EdgeNode.MacPrefix
if s != "" { if MacPrefix != "" {
_, err = tap.GetMacAddr(s, uint32(ModeIDmax)) _, err = tap.GetMacAddr(MacPrefix, uint32(ModeIDmax))
if err != nil { if err != nil {
return err return err
} }
@ -233,52 +220,44 @@ 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
s = fmt.Sprintf("%X:%X:%X:%X", pbyte[0], pbyte[1], pbyte[2], pbyte[3]) MacPrefix = fmt.Sprintf("%X:%X:%X:%X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
} }
MacPrefix := s
s = SMCfg.EdgeNode.IPv4Range
if s != "" {
_, _, err = tap.GetIP(4, s, uint32(ModeIDmax))
if err != nil {
return err
}
}
IPv4Block := s
s = SMCfg.EdgeNode.IPv6Range IPv4Block := SMCfg.EdgeNode.IPv4Range
if s != "" { if IPv4Block != "" {
_, _, err = tap.GetIP(6, s, uint32(ModeIDmax)) _, _, err = tap.GetIP(4, IPv4Block, uint32(ModeIDmax))
if err != nil { if err != nil {
return err return err
} }
} }
IPv6Block := s
s = SMCfg.EdgeNode.IPv6LLRange IPv6Block := SMCfg.EdgeNode.IPv6Range
if s != "" { if IPv6Block != "" {
_, _, err = tap.GetIP(6, s, uint32(ModeIDmax)) _, _, err = tap.GetIP(6, IPv6Block, uint32(ModeIDmax))
if err != nil {
return err
}
}
IPv6LLBlock := SMCfg.EdgeNode.IPv6LLRange
if IPv6LLBlock != "" {
_, _, err = tap.GetIP(6, IPv6LLBlock, uint32(ModeIDmax))
if err != nil { if err != nil {
return err return err
} }
} }
IPv6LLBlock := s
SuperPeerInfo := make([]mtypes.SuperPeerInfo, 0, ModeIDmax) SuperPeerInfo := make([]mtypes.SuperPeerInfo, 0, ModeIDmax)
PrivKeyS4 := device.NoisePrivateKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{}))) PrivKeyS4, PubKeyS4 := device.RandomKeyPair()
PubKeyS4 := PrivKeyS4.PublicKey() PrivKeyS6, PubKeyS6 := device.RandomKeyPair()
PrivKeyS6 := device.NoisePrivateKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{})))
PubKeyS6 := PrivKeyS6.PublicKey()
sconfig.PrivKeyV4 = PrivKeyS4.ToString() sconfig.PrivKeyV4 = PrivKeyS4.ToString()
sconfig.PrivKeyV6 = PrivKeyS6.ToString() sconfig.PrivKeyV6 = PrivKeyS6.ToString()
allec := make(map[mtypes.Vertex]mtypes.EdgeConfig) allec := make(map[mtypes.Vertex]mtypes.EdgeConfig)
peerceconf := GetExampleEdgeConf(EdgeTamplatePath) peerceconf := GetExampleEdgeConf(sconfig.EdgeTemplate, false)
peerceconf.Peers = []mtypes.PeerInfo{}
peerceconf.NextHopTable = make(mtypes.NextHopTable)
for _, ii := range NodeIDs { for _, ii := range NodeIDs {
i := mtypes.Vertex(ii) i := mtypes.Vertex(ii)
PSKeyE := device.NoisePresharedKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{}))) PSKeyE := device.RandomPSK()
PrivKeyE := device.NoisePrivateKey(mtypes.ByteSlice2Byte32(mtypes.RandomBytes(32, []byte{}))) PrivKeyE, PubKeyE := device.RandomKeyPair()
PubKeyE := PrivKeyE.PublicKey()
idstr := fmt.Sprintf("%0"+strconv.Itoa(len(strconv.Itoa(ModeIDmax)))+"d", i) idstr := fmt.Sprintf("%0"+strconv.Itoa(len(strconv.Itoa(ModeIDmax)))+"d", i)
allec[i] = peerceconf allec[i] = peerceconf
@ -291,8 +270,8 @@ func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
peerceconf.Interface.IPv6LLPrefix = IPv6LLBlock peerceconf.Interface.IPv6LLPrefix = IPv6LLBlock
peerceconf.NodeID = i peerceconf.NodeID = i
peerceconf.NodeName = NetworkName + idstr peerceconf.NodeName = SMCfg.NetworkName + idstr
peerceconf.Interface.Name = NetworkName + idstr peerceconf.Interface.Name = SMCfg.NetworkName + idstr
peerceconf.DynamicRoute.SuperNode.PubKeyV4 = PubKeyS4.ToString() peerceconf.DynamicRoute.SuperNode.PubKeyV4 = PubKeyS4.ToString()
peerceconf.DynamicRoute.SuperNode.PubKeyV6 = PubKeyS6.ToString() peerceconf.DynamicRoute.SuperNode.PubKeyV6 = PubKeyS6.ToString()
peerceconf.DynamicRoute.SuperNode.PSKey = PSKeyE.ToString() peerceconf.DynamicRoute.SuperNode.PSKey = PSKeyE.ToString()
@ -300,19 +279,19 @@ func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
SuperPeerInfo = append(SuperPeerInfo, mtypes.SuperPeerInfo{ SuperPeerInfo = append(SuperPeerInfo, mtypes.SuperPeerInfo{
NodeID: i, NodeID: i,
Name: NetworkName + idstr, Name: SMCfg.NetworkName + idstr,
PubKey: PubKeyE.ToString(), PubKey: PubKeyE.ToString(),
PSKey: PSKeyE.ToString(), PSKey: PSKeyE.ToString(),
AdditionalCost: peerceconf.DynamicRoute.AdditionalCost, AdditionalCost: peerceconf.DynamicRoute.AdditionalCost,
SkipLocalIP: peerceconf.DynamicRoute.SuperNode.SkipLocalIP, SkipLocalIP: peerceconf.DynamicRoute.SuperNode.SkipLocalIP,
}) })
mtypesBytes, _ := yaml.Marshal(peerceconf) mtypesBytes, _ := yaml.Marshal(peerceconf)
ioutil.WriteFile(filepath.Join(CfgSavePath, NetworkName+"_edge"+idstr+".yaml"), mtypesBytes, 0o600) ioutil.WriteFile(filepath.Join(SMCfg.ConfigOutputDir, SMCfg.NetworkName+"_edge"+idstr+".yaml"), mtypesBytes, 0o600)
fmt.Println(filepath.Join(CfgSavePath, NetworkName+"_edge"+idstr+".yaml")) fmt.Println(filepath.Join(SMCfg.ConfigOutputDir, SMCfg.NetworkName+"_edge"+idstr+".yaml"))
} }
sconfig.Peers = SuperPeerInfo sconfig.Peers = SuperPeerInfo
mtypesBytes, _ := yaml.Marshal(sconfig) mtypesBytes, _ := yaml.Marshal(sconfig)
ioutil.WriteFile(filepath.Join(CfgSavePath, NetworkName+"_super.yaml"), mtypesBytes, 0o600) ioutil.WriteFile(filepath.Join(SMCfg.ConfigOutputDir, SMCfg.NetworkName+"_super.yaml"), mtypesBytes, 0o600)
fmt.Println(filepath.Join(CfgSavePath, NetworkName+"_super.yaml")) fmt.Println(filepath.Join(SMCfg.ConfigOutputDir, SMCfg.NetworkName+"_super.yaml"))
return nil return nil
} }

View File

@ -5,6 +5,10 @@
package gencfg package gencfg
import (
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
)
type SMCfg struct { type SMCfg struct {
ConfigOutputDir string `yaml:"Config output dir"` ConfigOutputDir string `yaml:"Config output dir"`
SuperConfigTemplate string `yaml:"ConfigTemplate for super node"` SuperConfigTemplate string `yaml:"ConfigTemplate for super node"`
@ -26,13 +30,43 @@ type SMCfg struct {
} `yaml:"Edge Node"` } `yaml:"Edge Node"`
} }
type PMG struct { type NMCfg struct {
ConfigOutputDir string `yaml:"Config output dir"` ConfigOutputDir string `yaml:"Config output dir"`
EdgeConfigTemplate string `yaml:"ConfigTemplate for edge node"` EdgeConfigTemplate string `yaml:"ConfigTemplate for edge node"`
NetworkName string `yaml:"Network name"` NetworkName string `yaml:"Network name"`
EdgeNodes []struct { EdgeNode struct {
NodeID string `yaml:"Node ID"` MacPrefix string `yaml:"MacAddress prefix"`
Endpoint string `yaml:"Endpoint(optional)"` IPv4Range string `yaml:"IPv4 range"`
} `yaml:"Edge Nodes"` IPv6Range string `yaml:"IPv6 range"`
DistanceMatrix string `yaml:"Distance matrix for all nodes"` IPv6LLRange string `yaml:"IPv6 LL range"`
} `yaml:"Edge Node"`
EdgeNodes map[mtypes.Vertex]edge_raw_info `yaml:"Edge Nodes"`
DistanceMatrix string `yaml:"Distance matrix for all nodes"`
}
type PMCfg struct {
ConfigOutputDir string `yaml:"Config output dir"`
EdgeConfigTemplate string `yaml:"ConfigTemplate for edge node"`
NetworkName string `yaml:"Network name"`
EdgeNode struct {
MacPrefix string `yaml:"MacAddress prefix"`
IPv4Range string `yaml:"IPv4 range"`
IPv6Range string `yaml:"IPv6 range"`
IPv6LLRange string `yaml:"IPv6 LL range"`
} `yaml:"Edge Node"`
EdgeNodes map[mtypes.Vertex]edge_raw_info `yaml:"Edge Nodes"`
}
type edge_raw_info struct {
Endpoint string `yaml:"Endpoint(optional)"`
PersistentKeepalive uint32 `yaml:"PersistentKeepalive"`
AdditionalCost float64 `yaml:"AdditionalCost"`
}
type edge_info struct {
Endpoint string
ConnectedEdge map[mtypes.Vertex]bool
PrivKey string
PubKey string
PersistentKeepalive uint32
} }

16
main.go
View File

@ -31,10 +31,6 @@ const (
ENV_EG_UAPI_DIR = "EG_UAPI_DIR" ENV_EG_UAPI_DIR = "EG_UAPI_DIR"
) )
func printUsage() {
fmt.Printf("Usage: %s -s/c CONFIG-PATH\n", os.Args[0])
}
var ( var (
tconfig = flag.String("config", "", "Config path for the interface.") tconfig = flag.String("config", "", "Config path for the interface.")
mode = flag.String("mode", "", "Running mode. [super|edge|solve|gencfg]") mode = flag.String("mode", "", "Running mode. [super|edge|solve|gencfg]")
@ -48,11 +44,11 @@ var (
func main() { func main() {
flag.Parse() flag.Parse()
if *version == true { if *version {
fmt.Printf("etherguard-go %s\n%s-%s\n%s\n\nA full mesh layer 2 VPN powered by Floyd Warshall algorithm.\nInformation available at https://github.com/KusakabeSi/EtherGuard-VPN.\nCopyright (C) Kusakabe Si <si@kskb.eu.org>.\n", Version, runtime.GOOS, runtime.GOARCH, tap.VPP_SUPPORT) fmt.Printf("etherguard-go %s\n%s-%s\n%s\n\nA full mesh layer 2 VPN powered by Floyd Warshall algorithm.\nInformation available at https://github.com/KusakabeSi/EtherGuard-VPN.\nCopyright (C) Kusakabe Si <si@kskb.eu.org>.\n", Version, runtime.GOOS, runtime.GOARCH, tap.VPP_SUPPORT)
return return
} }
if *help == true { if *help {
flag.Usage() flag.Usage()
return return
} }
@ -75,6 +71,8 @@ func main() {
switch *cfgmode { switch *cfgmode {
case "super": case "super":
err = gencfg.GenSuperCfg(*tconfig, *printExample) err = gencfg.GenSuperCfg(*tconfig, *printExample)
case "static":
err = gencfg.GenNMCfg(*tconfig, *printExample)
default: default:
err = fmt.Errorf("gencfg: generate config for %v mode are not implement", *cfgmode) err = fmt.Errorf("gencfg: generate config for %v mode are not implement", *cfgmode)
} }
@ -83,14 +81,12 @@ func main() {
flag.Usage() flag.Usage()
} }
if err != nil { if err != nil {
switch err.(type) { switch err := err.(type) {
case syscall.Errno: case syscall.Errno:
errno, _ := err.(syscall.Errno) os.Exit(int(err))
os.Exit(int(errno))
default: default:
fmt.Fprintf(os.Stderr, "Error :%v\n", err) fmt.Fprintf(os.Stderr, "Error :%v\n", err)
os.Exit(1) os.Exit(1)
} }
} }
return
} }

View File

@ -27,7 +27,7 @@ import (
) )
func printExampleEdgeConf() { func printExampleEdgeConf() {
tconfig := gencfg.GetExampleEdgeConf("") tconfig := gencfg.GetExampleEdgeConf("", true)
toprint, _ := yaml.Marshal(tconfig) toprint, _ := yaml.Marshal(tconfig)
fmt.Print(string(toprint)) fmt.Print(string(toprint))
} }
@ -110,10 +110,13 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// Config // Config
if econfig.DynamicRoute.P2P.UseP2P == false && econfig.DynamicRoute.SuperNode.UseSuperNode == false { if !econfig.DynamicRoute.P2P.UseP2P && !econfig.DynamicRoute.SuperNode.UseSuperNode {
econfig.LogLevel.LogNTP = false // NTP in static mode is useless econfig.LogLevel.LogNTP = false // NTP in static mode is useless
} }
graph := path.NewGraph(3, false, econfig.DynamicRoute.P2P.GraphRecalculateSetting, econfig.DynamicRoute.NTPConfig, econfig.LogLevel) graph, err := path.NewGraph(3, false, econfig.DynamicRoute.P2P.GraphRecalculateSetting, econfig.DynamicRoute.NTPConfig, econfig.LogLevel)
if err != nil {
return err
}
graph.SetNHTable(econfig.NextHopTable) graph.SetNHTable(econfig.NextHopTable)
the_device := device.NewDevice(thetap, econfig.NodeID, conn.NewDefaultBind(true, true, bindmode), logger, graph, false, configPath, &econfig, nil, nil, Version) the_device := device.NewDevice(thetap, econfig.NodeID, conn.NewDefaultBind(true, true, bindmode), logger, graph, false, configPath, &econfig, nil, nil, Version)
@ -133,7 +136,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
fmt.Println("Error decode base64 ", err) fmt.Println("Error decode base64 ", err)
return err return err
} }
the_device.NewPeer(pk, peerconf.NodeID, false) the_device.NewPeer(pk, peerconf.NodeID, false, peerconf.PersistentKeepalive)
if peerconf.EndPoint != "" { if peerconf.EndPoint != "" {
peer := the_device.LookupPeer(pk) peer := the_device.LookupPeer(pk)
err = peer.SetEndpointFromConnURL(peerconf.EndPoint, 0, peerconf.Static) err = peer.SetEndpointFromConnURL(peerconf.EndPoint, 0, peerconf.Static)
@ -158,7 +161,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
fmt.Println("Error decode base64 ", err) fmt.Println("Error decode base64 ", err)
return err return err
} }
peer, err := the_device.NewPeer(pk, mtypes.SuperNodeMessage, true) peer, err := the_device.NewPeer(pk, mtypes.NodeID_SuperNode, true, 0)
if err != nil { if err != nil {
return err return err
} }
@ -179,7 +182,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
fmt.Println("Error decode base64 ", err) fmt.Println("Error decode base64 ", err)
return err return err
} }
peer, err := the_device.NewPeer(pk, mtypes.SuperNodeMessage, true) peer, err := the_device.NewPeer(pk, mtypes.NodeID_SuperNode, true, 0)
if err != nil { if err != nil {
return err return err
} }
@ -192,7 +195,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
S6 = false S6 = false
} }
if !(S4 || S6) { if !(S4 || S6) {
return errors.New("Failed to connect to supernode.") return errors.New("failed to connect to supernode")
} }
} }
the_device.Chan_Supernode_OK <- struct{}{} the_device.Chan_Supernode_OK <- struct{}{}
@ -229,7 +232,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
cmdarg, err := shlex.Split(econfig.PostScript) cmdarg, err := shlex.Split(econfig.PostScript)
if err != nil { if err != nil {
return fmt.Errorf("Error parse PostScript %v\n", err) return fmt.Errorf("error parse PostScript %v", err)
} }
if econfig.LogLevel.LogInternal { if econfig.LogLevel.LogInternal {
fmt.Printf("PostScript: exec.Command(%v)\n", cmdarg) fmt.Printf("PostScript: exec.Command(%v)\n", cmdarg)
@ -241,7 +244,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
} }
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return fmt.Errorf("exec.Command(%v) failed with %v\n", cmdarg, err) return fmt.Errorf("exec.Command(%v) failed with %v", cmdarg, err)
} }
if econfig.LogLevel.LogInternal { if econfig.LogLevel.LogInternal {
fmt.Printf("PostScript output: %s\n", string(out)) fmt.Printf("PostScript output: %s\n", string(out))

View File

@ -7,13 +7,11 @@ package main
import ( import (
"crypto/md5" "crypto/md5"
"crypto/sha256"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -42,6 +40,7 @@ type http_shared_objects struct {
http_NhTableStr []byte http_NhTableStr []byte
http_PeerInfo mtypes.API_Peers http_PeerInfo mtypes.API_Peers
http_super_chains *mtypes.SUPER_Events http_super_chains *mtypes.SUPER_Events
http_pskdb device.PSKDB
http_passwords mtypes.Passwords http_passwords mtypes.Passwords
http_StateExpire time.Time http_StateExpire time.Time
@ -92,15 +91,6 @@ type PeerState struct {
LastSeen atomic.Value // time.Time LastSeen atomic.Value // time.Time
} }
type client struct {
ConnV4 net.Addr
ConnV6 net.Addr
InterV4 []net.Addr
InterV6 []net.Addr
notify4 string
notify6 string
}
func extractParamsStr(params url.Values, key string, w http.ResponseWriter) (string, error) { func extractParamsStr(params url.Values, key string, w http.ResponseWriter) (string, error) {
valA, has := params[key] valA, has := params[key]
if !has { if !has {
@ -151,7 +141,7 @@ func extractParamsUint(params url.Values, key string, bitSize int, w http.Respon
func extractParamsVertex(params url.Values, key string, w http.ResponseWriter) (mtypes.Vertex, error) { func extractParamsVertex(params url.Values, key string, w http.ResponseWriter) (mtypes.Vertex, error) {
val, err := extractParamsUint(params, key, 16, w) val, err := extractParamsUint(params, key, 16, w)
if err != nil { if err != nil {
return mtypes.BrokenMessage, err return mtypes.NodeID_Invalid, err
} }
return mtypes.Vertex(val), nil return mtypes.Vertex(val), nil
} }
@ -208,7 +198,7 @@ func edge_get_superparams(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
if NodeID >= mtypes.Special_NodeID { if NodeID >= mtypes.NodeID_Special {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Paramater NodeID: Can't use special nodeID.")) w.Write([]byte("Paramater NodeID: Can't use special nodeID."))
return return
@ -227,7 +217,7 @@ func edge_get_superparams(w http.ResponseWriter, r *http.Request) {
return return
} }
if _, has := httpobj.http_PeerState[PubKey]; has == false { if _, has := httpobj.http_PeerState[PubKey]; !has {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author.")) w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author."))
return return
@ -250,7 +240,6 @@ func edge_get_superparams(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte(SuperParamStr)) w.Write([]byte(SuperParamStr))
return
} }
func edge_get_peerinfo(w http.ResponseWriter, r *http.Request) { func edge_get_peerinfo(w http.ResponseWriter, r *http.Request) {
@ -268,7 +257,7 @@ func edge_get_peerinfo(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
if NodeID >= mtypes.Special_NodeID { if NodeID >= mtypes.NodeID_Special {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Paramater NodeID: Can't use special nodeID.")) w.Write([]byte("Paramater NodeID: Can't use special nodeID."))
return return
@ -291,7 +280,7 @@ func edge_get_peerinfo(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Paramater State: State not correct")) w.Write([]byte("Paramater State: State not correct"))
return return
} }
if _, has := httpobj.http_PeerState[PubKey]; has == false { if _, has := httpobj.http_PeerState[PubKey]; !has {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author.")) w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author."))
return return
@ -303,21 +292,11 @@ func edge_get_peerinfo(w http.ResponseWriter, r *http.Request) {
for PeerPubKey, peerinfo := range httpobj.http_PeerInfo { for PeerPubKey, peerinfo := range httpobj.http_PeerInfo {
if httpobj.http_sconfig.UsePSKForInterEdge { if httpobj.http_sconfig.UsePSKForInterEdge {
h := sha256.New() if NodeID == peerinfo.NodeID {
if NodeID > peerinfo.NodeID {
h.Write([]byte(PubKey))
h.Write([]byte(PeerPubKey))
} else if NodeID < peerinfo.NodeID {
h.Write([]byte(PeerPubKey))
h.Write([]byte(PubKey))
} else {
continue continue
} }
h.Write(httpobj.http_HashSalt) PSK := httpobj.http_pskdb.GetPSK(NodeID, peerinfo.NodeID)
bs := h.Sum(nil) peerinfo.PSKey = PSK.ToString()
var psk device.NoisePresharedKey
copy(psk[:], bs[:])
peerinfo.PSKey = psk.ToString()
} else { } else {
peerinfo.PSKey = "" peerinfo.PSKey = ""
} }
@ -332,7 +311,6 @@ func edge_get_peerinfo(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write(api_peerinfo_str_byte) w.Write(api_peerinfo_str_byte)
return
} }
func edge_get_nhtable(w http.ResponseWriter, r *http.Request) { func edge_get_nhtable(w http.ResponseWriter, r *http.Request) {
@ -350,7 +328,7 @@ func edge_get_nhtable(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
if NodeID >= mtypes.Special_NodeID { if NodeID >= mtypes.NodeID_Special {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Paramater NodeID: Can't use special nodeID.")) w.Write([]byte("Paramater NodeID: Can't use special nodeID."))
return return
@ -373,7 +351,7 @@ func edge_get_nhtable(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Paramater State: State not correct")) w.Write([]byte("Paramater State: State not correct"))
return return
} }
if _, has := httpobj.http_PeerState[PubKey]; has == false { if _, has := httpobj.http_PeerState[PubKey]; !has {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author.")) w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author."))
return return
@ -383,7 +361,6 @@ func edge_get_nhtable(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte(httpobj.http_NhTableStr)) w.Write([]byte(httpobj.http_NhTableStr))
return
} }
func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) { func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) {
@ -397,7 +374,7 @@ func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
if NodeID >= mtypes.Special_NodeID { if NodeID >= mtypes.NodeID_Special {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Paramater NodeID: Can't use special nodeID.")) w.Write([]byte("Paramater NodeID: Can't use special nodeID."))
return return
@ -436,7 +413,7 @@ func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) {
token, err := jwt.ParseWithClaims(string(JWTSig), &token_claims, func(token *jwt.Token) (interface{}, error) { token, err := jwt.ParseWithClaims(string(JWTSig), &token_claims, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect: // Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
} }
JWTSecretB := JWTSecret.Load().(mtypes.JWTSecret) JWTSecretB := JWTSecret.Load().(mtypes.JWTSecret)
return JWTSecretB[:], nil return JWTSecretB[:], nil
@ -448,7 +425,7 @@ func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) {
} }
if !token.Valid { if !token.Valid {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("Paramater JWTSig: Signature verification failed: Invalid token"))) w.Write([]byte("Paramater JWTSig: Signature verification failed: Invalid token"))
return return
} }
@ -471,7 +448,7 @@ func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) {
client_body, err = mtypes.GUzip(client_body) client_body, err = mtypes.GUzip(client_body)
if err != nil { if err != nil {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("Request body: gzip unzip failed"))) w.Write([]byte("Request body: gzip unzip failed"))
return return
} }
client_report, err := mtypes.ParseAPI_report_peerinfo(client_body) client_report, err := mtypes.ParseAPI_report_peerinfo(client_body)
@ -515,8 +492,7 @@ func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) {
PushNhTable(false) PushNhTable(false)
} }
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf("OK"))) w.Write([]byte("OK"))
return
} }
func checkPassword(s1 string, s2 string) bool { func checkPassword(s1 string, s2 string) bool {
@ -549,9 +525,9 @@ func manage_get_peerstate(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
if checkPassword(password, httpobj.http_passwords.ShowState) == false { if !checkPassword(password, httpobj.http_passwords.ShowState) {
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Wrong password")) w.Write([]byte("Paramater Password: Wrong password"))
return return
} }
httpobj.RLock() httpobj.RLock()
@ -560,7 +536,7 @@ func manage_get_peerstate(w http.ResponseWriter, r *http.Request) {
hs := HttpState{ hs := HttpState{
PeerInfo: make(map[mtypes.Vertex]HttpPeerInfo), PeerInfo: make(map[mtypes.Vertex]HttpPeerInfo),
NhTable: httpobj.http_graph.GetNHTable(false), NhTable: httpobj.http_graph.GetNHTable(false),
Infinity: path.Infinity, Infinity: mtypes.Infinity,
Edges: httpobj.http_graph.GetEdges(false, false), Edges: httpobj.http_graph.GetEdges(false, false),
Edges_Nh: httpobj.http_graph.GetEdges(true, true), Edges_Nh: httpobj.http_graph.GetEdges(true, true),
Dist: httpobj.http_graph.GetDtst(), Dist: httpobj.http_graph.GetDtst(),
@ -578,7 +554,6 @@ func manage_get_peerstate(w http.ResponseWriter, r *http.Request) {
} }
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write(httpobj.http_StateString_tmp) w.Write(httpobj.http_StateString_tmp)
return
} }
func manage_peeradd(w http.ResponseWriter, r *http.Request) { func manage_peeradd(w http.ResponseWriter, r *http.Request) {
@ -587,9 +562,9 @@ func manage_peeradd(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
if checkPassword(password, httpobj.http_passwords.AddPeer) == false { if !checkPassword(password, httpobj.http_passwords.AddPeer) {
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Wrong password")) w.Write([]byte("Paramater Password: Wrong password"))
return return
} }
@ -620,7 +595,7 @@ func manage_peeradd(w http.ResponseWriter, r *http.Request) {
SkipLocalIP := strings.EqualFold(SkipLocalIPS, "true") SkipLocalIP := strings.EqualFold(SkipLocalIPS, "true")
PSKey, err := extractParamsStr(r.Form, "PSKey", nil) PSKey, _ := extractParamsStr(r.Form, "PSKey", nil)
httpobj.Lock() httpobj.Lock()
defer httpobj.Unlock() defer httpobj.Unlock()
@ -642,7 +617,7 @@ func manage_peeradd(w http.ResponseWriter, r *http.Request) {
return return
} }
} }
if httpobj.http_sconfig.GraphRecalculateSetting.StaticMode == true { if httpobj.http_sconfig.GraphRecalculateSetting.StaticMode {
NhTableStr := r.Form.Get("NextHopTable") NhTableStr := r.Form.Get("NextHopTable")
if NhTableStr == "" { if NhTableStr == "" {
w.WriteHeader(http.StatusExpectationFailed) w.WriteHeader(http.StatusExpectationFailed)
@ -705,12 +680,11 @@ func manage_peeradd(w http.ResponseWriter, r *http.Request) {
ret_str_byte, _ := yaml.Marshal(&httpobj.http_econfig_tmp) ret_str_byte, _ := yaml.Marshal(&httpobj.http_econfig_tmp)
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write(ret_str_byte) w.Write(ret_str_byte)
return
} }
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.Broadcast toUpdate := mtypes.NodeID_Boardcast
var err error var err error
var NodeID mtypes.Vertex var NodeID mtypes.Vertex
@ -719,7 +693,7 @@ func manage_peerupdate(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
if checkPassword(password, httpobj.http_passwords.UpdatePeer) == false { if !checkPassword(password, httpobj.http_passwords.UpdatePeer) {
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Paramater Password: Wrong password")) w.Write([]byte("Paramater Password: Wrong password"))
return return
@ -787,7 +761,6 @@ func manage_peerupdate(w http.ResponseWriter, r *http.Request) {
for k, v := range Updated_params { for k, v := range Updated_params {
w.Write([]byte(fmt.Sprintf("%v = %v\n", k, v))) w.Write([]byte(fmt.Sprintf("%v = %v\n", k, v)))
} }
return
} }
func manage_superupdate(w http.ResponseWriter, r *http.Request) { func manage_superupdate(w http.ResponseWriter, r *http.Request) {
@ -799,7 +772,7 @@ func manage_superupdate(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
if checkPassword(password, httpobj.http_passwords.UpdateSuper) == false { if !checkPassword(password, httpobj.http_passwords.UpdateSuper) {
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Paramater Password: Wrong password")) w.Write([]byte("Paramater Password: Wrong password"))
return return
@ -817,7 +790,7 @@ func manage_superupdate(w http.ResponseWriter, r *http.Request) {
if err == nil { if err == nil {
if PeerAliveTimeout <= 0 { if PeerAliveTimeout <= 0 {
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("Paramater PeerAliveTimeout: Must > 0.\n"))) w.Write([]byte(fmt.Sprintf("Paramater PeerAliveTimeout %v: Must > 0.\n", PeerAliveTimeout)))
return return
} }
Updated_params["PeerAliveTimeout"] = fmt.Sprintf("%v", PeerAliveTimeout) Updated_params["PeerAliveTimeout"] = fmt.Sprintf("%v", PeerAliveTimeout)
@ -879,12 +852,11 @@ func manage_superupdate(w http.ResponseWriter, r *http.Request) {
for k, v := range Updated_params { for k, v := range Updated_params {
w.Write([]byte(fmt.Sprintf("%v = %v\n", k, v))) w.Write([]byte(fmt.Sprintf("%v = %v\n", k, v)))
} }
return
} }
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.Broadcast toDelete := mtypes.NodeID_Boardcast
var err error var err error
var NodeID mtypes.Vertex var NodeID mtypes.Vertex
@ -928,7 +900,7 @@ func manage_peerdel(w http.ResponseWriter, r *http.Request) {
toDelete = peerinfo.NodeID toDelete = peerinfo.NodeID
} }
} }
if toDelete == mtypes.Broadcast { if toDelete == mtypes.NodeID_Boardcast {
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
@ -949,7 +921,6 @@ func manage_peerdel(w http.ResponseWriter, r *http.Request) {
ioutil.WriteFile(httpobj.http_sconfig_path, mtypesBytes, 0644) ioutil.WriteFile(httpobj.http_sconfig_path, mtypesBytes, 0644)
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte("NodeID: " + toDelete.ToString() + " deleted.")) w.Write([]byte("NodeID: " + toDelete.ToString() + " deleted."))
return
} }
func HttpServer(edgeListen string, manageListen string, apiprefix string) (err error) { func HttpServer(edgeListen string, manageListen string, apiprefix string) (err error) {

View File

@ -45,16 +45,16 @@ func checkNhTable(NhTable mtypes.NextHopTable, peers []mtypes.SuperPeerInfo) err
id2 := peer2.NodeID id2 := peer2.NodeID
if dst, has := NhTable[id1]; has { if dst, has := NhTable[id1]; has {
if next, has2 := dst[id2]; has2 { if next, has2 := dst[id2]; has2 {
if _, hasa := allpeer[*next]; hasa { if _, hasa := allpeer[next]; hasa {
} else { } else {
return errors.New(fmt.Sprintf("NextHopTable[%v][%v]=%v which is not in the peer list", id1, id2, next)) return fmt.Errorf("NextHopTable[%v][%v]=%v which is not in the peer list", id1, id2, next)
} }
} else { } else {
return errors.New(fmt.Sprintf("NextHopTable[%v][%v] not found", id1, id2)) return fmt.Errorf("NextHopTable[%v][%v] not found", id1, id2)
} }
} else { } else {
return errors.New(fmt.Sprintf("NextHopTable[%v] not found", id1)) return fmt.Errorf("NextHopTable[%v] not found", id1)
} }
} }
} }
@ -62,7 +62,7 @@ func checkNhTable(NhTable mtypes.NextHopTable, peers []mtypes.SuperPeerInfo) err
} }
func printExampleSuperConf() { func printExampleSuperConf() {
sconfig := gencfg.GetExampleSuperConf("") sconfig := gencfg.GetExampleSuperConf("", true)
scprint, _ := yaml.Marshal(sconfig) scprint, _ := yaml.Marshal(sconfig)
fmt.Print(string(scprint)) fmt.Print(string(scprint))
} }
@ -80,7 +80,7 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
return err return err
} }
httpobj.http_sconfig = &sconfig httpobj.http_sconfig = &sconfig
http_econfig_tmp := gencfg.GetExampleEdgeConf(sconfig.EdgeTemplate) http_econfig_tmp := gencfg.GetExampleEdgeConf(sconfig.EdgeTemplate, true)
httpobj.http_econfig_tmp = &http_econfig_tmp httpobj.http_econfig_tmp = &http_econfig_tmp
NodeName := sconfig.NodeName NodeName := sconfig.NodeName
if len(NodeName) > 32 { if len(NodeName) > 32 {
@ -133,7 +133,10 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
Event_server_pong: make(chan mtypes.PongMsg, 1<<5), Event_server_pong: make(chan mtypes.PongMsg, 1<<5),
Event_server_register: make(chan mtypes.RegisterMsg, 1<<5), Event_server_register: make(chan mtypes.RegisterMsg, 1<<5),
} }
httpobj.http_graph = path.NewGraph(3, true, sconfig.GraphRecalculateSetting, mtypes.NTPInfo{}, sconfig.LogLevel) httpobj.http_graph, err = path.NewGraph(3, true, sconfig.GraphRecalculateSetting, mtypes.NTPInfo{}, sconfig.LogLevel)
if err != nil {
return err
}
httpobj.http_graph.SetNHTable(httpobj.http_sconfig.NextHopTable) httpobj.http_graph.SetNHTable(httpobj.http_sconfig.NextHopTable)
if sconfig.GraphRecalculateSetting.StaticMode { if sconfig.GraphRecalculateSetting.StaticMode {
err = checkNhTable(httpobj.http_sconfig.NextHopTable, sconfig.Peers) err = checkNhTable(httpobj.http_sconfig.NextHopTable, sconfig.Peers)
@ -142,10 +145,10 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
} }
} }
thetap4, _ := tap.CreateDummyTAP() thetap4, _ := tap.CreateDummyTAP()
httpobj.http_device4 = device.NewDevice(thetap4, mtypes.SuperNodeMessage, conn.NewDefaultBind(true, false, bindmode), logger4, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version) httpobj.http_device4 = device.NewDevice(thetap4, mtypes.NodeID_SuperNode, conn.NewDefaultBind(true, false, bindmode), logger4, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version)
defer httpobj.http_device4.Close() defer httpobj.http_device4.Close()
thetap6, _ := tap.CreateDummyTAP() thetap6, _ := tap.CreateDummyTAP()
httpobj.http_device6 = device.NewDevice(thetap6, mtypes.SuperNodeMessage, conn.NewDefaultBind(false, true, bindmode), logger6, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version) httpobj.http_device6 = device.NewDevice(thetap6, mtypes.NodeID_SuperNode, conn.NewDefaultBind(false, true, bindmode), logger6, httpobj.http_graph, true, configPath, nil, &sconfig, httpobj.http_super_chains, Version)
defer httpobj.http_device6.Close() defer httpobj.http_device6.Close()
if sconfig.PrivKeyV4 != "" { if sconfig.PrivKeyV4 != "" {
pk4, err := device.Str2PriKey(sconfig.PrivKeyV4) pk4, err := device.Str2PriKey(sconfig.PrivKeyV4)
@ -209,15 +212,15 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
envs["EG_NODE_NAME"] = sconfig.NodeName envs["EG_NODE_NAME"] = sconfig.NodeName
cmdarg, err := shlex.Split(sconfig.PostScript) cmdarg, err := shlex.Split(sconfig.PostScript)
if err != nil { if err != nil {
return fmt.Errorf("Error parse PostScript %v\n", err) return fmt.Errorf("error parse PostScript %v", err)
} }
if sconfig.LogLevel.LogInternal { if sconfig.LogLevel.LogInternal {
fmt.Printf("PostScript: exec.Command(%v)\n", cmdarg) fmt.Printf("PostScript: exec.Command(%v)", cmdarg)
} }
cmd := exec.Command(cmdarg[0], cmdarg[1:]...) cmd := exec.Command(cmdarg[0], cmdarg[1:]...)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return fmt.Errorf("exec.Command(%v) failed with %v\n", cmdarg, err) return fmt.Errorf("exec.Command(%v) failed with %v", cmdarg, err)
} }
if sconfig.LogLevel.LogInternal { if sconfig.LogLevel.LogInternal {
fmt.Printf("PostScript output: %s\n", string(out)) fmt.Printf("PostScript output: %s\n", string(out))
@ -241,19 +244,19 @@ func super_peeradd(peerconf mtypes.SuperPeerInfo) error {
// No lock, lock before call me // No lock, lock before call me
pk, err := device.Str2PubKey(peerconf.PubKey) pk, err := device.Str2PubKey(peerconf.PubKey)
if err != nil { if err != nil {
return fmt.Errorf("Error decode base64 :%v", err) return fmt.Errorf("error decode base64 :%v", err)
} }
if httpobj.http_sconfig.PrivKeyV4 != "" { if httpobj.http_sconfig.PrivKeyV4 != "" {
var psk device.NoisePresharedKey var psk device.NoisePresharedKey
if peerconf.PSKey != "" { if peerconf.PSKey != "" {
psk, err = device.Str2PSKey(peerconf.PSKey) psk, err = device.Str2PSKey(peerconf.PSKey)
if err != nil { if err != nil {
return fmt.Errorf("Error decode base64 :%v", err) return fmt.Errorf("error decode base64 :%v", err)
} }
} }
peer4, err := httpobj.http_device4.NewPeer(pk, peerconf.NodeID, false) peer4, err := httpobj.http_device4.NewPeer(pk, peerconf.NodeID, false, 0)
if err != nil { if err != nil {
return fmt.Errorf("Error create peer id :%v", err) return fmt.Errorf("error create peer id :%v", err)
} }
peer4.StaticConn = false peer4.StaticConn = false
if peerconf.PSKey != "" { if peerconf.PSKey != "" {
@ -265,12 +268,12 @@ func super_peeradd(peerconf mtypes.SuperPeerInfo) error {
if peerconf.PSKey != "" { if peerconf.PSKey != "" {
psk, err = device.Str2PSKey(peerconf.PSKey) psk, err = device.Str2PSKey(peerconf.PSKey)
if err != nil { if err != nil {
return fmt.Errorf("Error decode base64 :%v", err) return fmt.Errorf("error decode base64 :%v", err)
} }
} }
peer6, err := httpobj.http_device6.NewPeer(pk, peerconf.NodeID, false) peer6, err := httpobj.http_device6.NewPeer(pk, peerconf.NodeID, false, 0)
if err != nil { if err != nil {
return fmt.Errorf("Error create peer id :%v", err) return fmt.Errorf("error create peer id :%v", err)
} }
peer6.StaticConn = false peer6.StaticConn = false
if peerconf.PSKey != "" { if peerconf.PSKey != "" {
@ -310,6 +313,7 @@ func super_peerdel(toDelete mtypes.Vertex) {
return return
} }
PubKey := httpobj.http_PeerID2Info[toDelete].PubKey PubKey := httpobj.http_PeerID2Info[toDelete].PubKey
httpobj.http_pskdb.DelNode(toDelete)
delete(httpobj.http_PeerState, PubKey) delete(httpobj.http_PeerState, PubKey)
delete(httpobj.http_PeerIPs, PubKey) delete(httpobj.http_PeerIPs, PubKey)
delete(httpobj.http_PeerID2Info, toDelete) delete(httpobj.http_PeerID2Info, toDelete)
@ -327,7 +331,7 @@ func super_peerdel_notify(toDelete mtypes.Vertex, PubKey string) {
body, _ := mtypes.GetByte(&ServerUpdateMsg) body, _ := mtypes.GetByte(&ServerUpdateMsg)
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetSrc(mtypes.SuperNodeMessage) header.SetSrc(mtypes.NodeID_SuperNode)
header.SetTTL(0) header.SetTTL(0)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
copy(buf[path.EgHeaderLen:], body) copy(buf[path.EgHeaderLen:], body)
@ -355,19 +359,19 @@ func Event_server_event_hendler(graph *path.IG, events *mtypes.SUPER_Events) {
NodeID := reg_msg.Node_id NodeID := reg_msg.Node_id
httpobj.RLock() httpobj.RLock()
PubKey := httpobj.http_PeerID2Info[NodeID].PubKey PubKey := httpobj.http_PeerID2Info[NodeID].PubKey
if reg_msg.Node_id < mtypes.Special_NodeID { if reg_msg.Node_id < mtypes.NodeID_Special {
httpobj.http_PeerState[PubKey].LastSeen.Store(time.Now()) httpobj.http_PeerState[PubKey].LastSeen.Store(time.Now())
httpobj.http_PeerState[PubKey].JETSecret.Store(reg_msg.JWTSecret) httpobj.http_PeerState[PubKey].JETSecret.Store(reg_msg.JWTSecret)
httpobj.http_PeerState[PubKey].httpPostCount.Store(reg_msg.HttpPostCount) httpobj.http_PeerState[PubKey].httpPostCount.Store(reg_msg.HttpPostCount)
if httpobj.http_PeerState[PubKey].NhTableState.Load().(string) == reg_msg.NhStateHash == false { if httpobj.http_PeerState[PubKey].NhTableState.Load().(string) != reg_msg.NhStateHash {
httpobj.http_PeerState[PubKey].NhTableState.Store(reg_msg.NhStateHash) httpobj.http_PeerState[PubKey].NhTableState.Store(reg_msg.NhStateHash)
should_push_nh = true should_push_nh = true
} }
if httpobj.http_PeerState[PubKey].PeerInfoState.Load().(string) == reg_msg.PeerStateHash == false { if httpobj.http_PeerState[PubKey].PeerInfoState.Load().(string) != reg_msg.PeerStateHash {
httpobj.http_PeerState[PubKey].PeerInfoState.Store(reg_msg.PeerStateHash) httpobj.http_PeerState[PubKey].PeerInfoState.Store(reg_msg.PeerStateHash)
should_push_peer = true should_push_peer = true
} }
if httpobj.http_PeerState[PubKey].SuperParamStateClient.Load().(string) == reg_msg.SuperParamStateHash == false { if httpobj.http_PeerState[PubKey].SuperParamStateClient.Load().(string) != reg_msg.SuperParamStateHash {
httpobj.http_PeerState[PubKey].SuperParamStateClient.Store(reg_msg.SuperParamStateHash) httpobj.http_PeerState[PubKey].SuperParamStateClient.Store(reg_msg.SuperParamStateHash)
should_push_superparams = true should_push_superparams = true
} }
@ -388,16 +392,15 @@ func Event_server_event_hendler(graph *path.IG, events *mtypes.SUPER_Events) {
case pong_msg := <-events.Event_server_pong: case pong_msg := <-events.Event_server_pong:
var changed bool var changed bool
httpobj.RLock() httpobj.RLock()
if pong_msg.Src_nodeID < mtypes.Special_NodeID && pong_msg.Dst_nodeID < mtypes.Special_NodeID { if pong_msg.Src_nodeID < mtypes.NodeID_Special && pong_msg.Dst_nodeID < mtypes.NodeID_Special {
AdditionalCost_use := httpobj.http_PeerID2Info[pong_msg.Dst_nodeID].AdditionalCost AdditionalCost_use := httpobj.http_PeerID2Info[pong_msg.Dst_nodeID].AdditionalCost
if AdditionalCost_use < 0 { if AdditionalCost_use < 0 {
AdditionalCost_use = pong_msg.AdditionalCost pong_msg.AdditionalCost = AdditionalCost_use
} }
changed = httpobj.http_graph.UpdateLatency(pong_msg.Src_nodeID, pong_msg.Dst_nodeID, pong_msg.Timediff, pong_msg.TimeToAlive, AdditionalCost_use, true, true) changed = httpobj.http_graph.UpdateLatencyMulti([]mtypes.PongMsg{pong_msg}, true, true)
} else { } else {
if httpobj.http_graph.CheckAnyShouldUpdate() { changed = httpobj.http_graph.RecalculateNhTable(true)
changed = httpobj.http_graph.RecalculateNhTable(true)
}
} }
if changed { if changed {
NhTable := graph.GetNHTable(true) NhTable := graph.GetNHTable(true)
@ -433,13 +436,13 @@ func RoutinePushSettings(interval time.Duration) {
func RoutineTimeoutCheck() { func RoutineTimeoutCheck() {
for { for {
httpobj.http_super_chains.Event_server_register <- mtypes.RegisterMsg{ httpobj.http_super_chains.Event_server_register <- mtypes.RegisterMsg{
Node_id: mtypes.SuperNodeMessage, Node_id: mtypes.NodeID_SuperNode,
Version: "dummy", Version: "dummy",
} }
httpobj.http_super_chains.Event_server_pong <- mtypes.PongMsg{ httpobj.http_super_chains.Event_server_pong <- mtypes.PongMsg{
RequestID: 0, RequestID: 0,
Src_nodeID: mtypes.SuperNodeMessage, Src_nodeID: mtypes.NodeID_SuperNode,
Dst_nodeID: mtypes.SuperNodeMessage, Dst_nodeID: mtypes.NodeID_SuperNode,
} }
time.Sleep(httpobj.http_graph.TimeoutCheckInterval) time.Sleep(httpobj.http_graph.TimeoutCheckInterval)
} }
@ -448,7 +451,7 @@ func RoutineTimeoutCheck() {
func PushNhTable(force bool) { func PushNhTable(force bool) {
// No lock // No lock
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{ body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
Node_id: mtypes.SuperNodeMessage, Node_id: mtypes.NodeID_SuperNode,
Action: mtypes.UpdateNhTable, Action: mtypes.UpdateNhTable,
Code: 0, Code: 0,
Params: string(httpobj.http_NhTable_Hash[:]), Params: string(httpobj.http_NhTable_Hash[:]),
@ -459,9 +462,9 @@ func PushNhTable(force bool) {
} }
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage) header.SetDst(mtypes.NodeID_SuperNode)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
header.SetSrc(mtypes.SuperNodeMessage) header.SetSrc(mtypes.NodeID_SuperNode)
header.SetTTL(0) header.SetTTL(0)
copy(buf[path.EgHeaderLen:], body) copy(buf[path.EgHeaderLen:], body)
for pkstr, peerstate := range httpobj.http_PeerState { for pkstr, peerstate := range httpobj.http_PeerState {
@ -483,7 +486,7 @@ func PushNhTable(force bool) {
func PushPeerinfo(force bool) { func PushPeerinfo(force bool) {
//No lock //No lock
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{ body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
Node_id: mtypes.SuperNodeMessage, Node_id: mtypes.NodeID_SuperNode,
Action: mtypes.UpdatePeer, Action: mtypes.UpdatePeer,
Code: 0, Code: 0,
Params: string(httpobj.http_PeerInfo_hash[:]), Params: string(httpobj.http_PeerInfo_hash[:]),
@ -494,9 +497,9 @@ func PushPeerinfo(force bool) {
} }
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage) header.SetDst(mtypes.NodeID_SuperNode)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
header.SetSrc(mtypes.SuperNodeMessage) header.SetSrc(mtypes.NodeID_SuperNode)
header.SetTTL(0) header.SetTTL(0)
copy(buf[path.EgHeaderLen:], body) copy(buf[path.EgHeaderLen:], body)
for pkstr, peerstate := range httpobj.http_PeerState { for pkstr, peerstate := range httpobj.http_PeerState {
@ -525,7 +528,7 @@ func PushServerParams(force bool) {
if force || peerstate.SuperParamState.Load().(string) != peerstate.SuperParamStateClient.Load().(string) { if force || peerstate.SuperParamState.Load().(string) != peerstate.SuperParamStateClient.Load().(string) {
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{ body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
Node_id: mtypes.SuperNodeMessage, Node_id: mtypes.NodeID_SuperNode,
Action: mtypes.UpdateSuperParams, Action: mtypes.UpdateSuperParams,
Code: 0, Code: 0,
Params: peerstate.SuperParamState.Load().(string), Params: peerstate.SuperParamState.Load().(string),
@ -536,9 +539,9 @@ func PushServerParams(force bool) {
} }
buf := make([]byte, path.EgHeaderLen+len(body)) buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen]) header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage) header.SetDst(mtypes.NodeID_SuperNode)
header.SetPacketLength(uint16(len(body))) header.SetPacketLength(uint16(len(body)))
header.SetSrc(mtypes.SuperNodeMessage) header.SetSrc(mtypes.NodeID_SuperNode)
header.SetTTL(0) header.SetTTL(0)
copy(buf[path.EgHeaderLen:], body) copy(buf[path.EgHeaderLen:], body)

View File

@ -10,11 +10,11 @@ import (
type Vertex uint16 type Vertex uint16
const ( const (
Broadcast Vertex = math.MaxUint16 - iota // Normal boardcast, boardcast with route table NodeID_Boardcast Vertex = math.MaxUint16 - iota // Normal boardcast, boardcast with route table
ControlMessage 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
SuperNodeMessage Vertex = math.MaxUint16 - iota NodeID_SuperNode Vertex = math.MaxUint16 - iota
BrokenMessage Vertex = math.MaxUint16 - iota NodeID_Invalid Vertex = math.MaxUint16 - iota
Special_NodeID Vertex = BrokenMessage NodeID_Special Vertex = NodeID_Invalid
) )
type EdgeConfig struct { type EdgeConfig struct {
@ -79,11 +79,12 @@ type InterfaceConf struct {
} }
type PeerInfo struct { type PeerInfo struct {
NodeID Vertex `yaml:"NodeID"` NodeID Vertex `yaml:"NodeID"`
PubKey string `yaml:"PubKey"` PubKey string `yaml:"PubKey"`
PSKey string `yaml:"PSKey"` PSKey string `yaml:"PSKey"`
EndPoint string `yaml:"EndPoint"` EndPoint string `yaml:"EndPoint"`
Static bool `yaml:"Static"` PersistentKeepalive uint32 `yaml:"PersistentKeepalive"`
Static bool `yaml:"Static"`
} }
type SuperPeerInfo struct { type SuperPeerInfo struct {
@ -106,11 +107,11 @@ type LoggerInfo struct {
func (v *Vertex) ToString() string { func (v *Vertex) ToString() string {
switch *v { switch *v {
case Broadcast: case NodeID_Boardcast:
return "Boardcast" return "Boardcast"
case ControlMessage: case NodeID_AllPeer:
return "Control" return "Control"
case SuperNodeMessage: case NodeID_SuperNode:
return "Super" return "Super"
default: default:
return strconv.Itoa(int(*v)) return strconv.Itoa(int(*v))
@ -157,16 +158,17 @@ type P2PInfo struct {
} }
type GraphRecalculateSetting struct { type GraphRecalculateSetting struct {
StaticMode bool `yaml:"StaticMode"` StaticMode bool `yaml:"StaticMode"`
JitterTolerance float64 `yaml:"JitterTolerance"` ManualLatency DistTable `yaml:"ManualLatency"`
JitterToleranceMultiplier float64 `yaml:"JitterToleranceMultiplier"` JitterTolerance float64 `yaml:"JitterTolerance"`
DampingResistance float64 `yaml:"DampingResistance"` JitterToleranceMultiplier float64 `yaml:"JitterToleranceMultiplier"`
TimeoutCheckInterval float64 `yaml:"TimeoutCheckInterval"` DampingResistance float64 `yaml:"DampingResistance"`
RecalculateCoolDown float64 `yaml:"RecalculateCoolDown"` TimeoutCheckInterval float64 `yaml:"TimeoutCheckInterval"`
RecalculateCoolDown float64 `yaml:"RecalculateCoolDown"`
} }
type DistTable map[Vertex]map[Vertex]float64 type DistTable map[Vertex]map[Vertex]float64
type NextHopTable map[Vertex]map[Vertex]*Vertex type NextHopTable map[Vertex]map[Vertex]Vertex
type API_connurl struct { type API_connurl struct {
ExternalV4 map[string]float64 ExternalV4 map[string]float64

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
nonSecureRand "math/rand" nonSecureRand "math/rand"
"strconv"
"time" "time"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
@ -16,6 +17,18 @@ func S2TD(secs float64) time.Duration {
return time.Duration(secs * float64(time.Second)) return time.Duration(secs * float64(time.Second))
} }
func String2Float64(s string) (float64, error) {
if s == "Inf" {
return Infinity, nil
}
return strconv.ParseFloat(s, 64)
}
func String2NodeID(s string) (Vertex, error) {
ret, err := strconv.ParseUint(s, 10, 16)
return Vertex(ret), err
}
func RandomStr(length int, defaults string) (ret string) { func RandomStr(length int, defaults string) (ret string) {
bytes := RandomBytes(length, []byte(defaults)) bytes := RandomBytes(length, []byte(defaults))

View File

@ -21,6 +21,8 @@ func GetByte(structIn interface{}) (bb []byte, err error) {
return return
} }
const Infinity = float64(99999)
type RegisterMsg struct { type RegisterMsg struct {
Node_id Vertex Node_id Vertex
Version string Version string

View File

@ -34,7 +34,7 @@ const (
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")
return return
} }
e.buf = pac e.buf = pac

View File

@ -33,11 +33,6 @@ func (g *IG) InitNTP() {
} }
} }
type ntp_result_pair struct {
URL string
VAL ntp.Response
}
func (g *IG) RoutineSyncTime() { func (g *IG) RoutineSyncTime() {
if !g.ntp_info.UseNTP { if !g.ntp_info.UseNTP {
return return
@ -80,7 +75,7 @@ func (g *IG) SyncTimeMultiple(count int) {
results := make([]time.Duration, count) results := make([]time.Duration, count)
for _, url := range g.ntp_servers.Keys() { for _, url := range g.ntp_servers.Keys() {
val, has := g.ntp_servers.Get(url) val, has := g.ntp_servers.Get(url)
if has == false { if !has {
continue continue
} }
result := val.(ntp.Response) result := val.(ntp.Response)

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"math" "math"
"strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -15,8 +14,6 @@ import (
yaml "gopkg.in/yaml.v2" yaml "gopkg.in/yaml.v2"
) )
const Infinity = float64(99999)
func (g *IG) GetCurrentTime() time.Time { func (g *IG) GetCurrentTime() time.Time {
return time.Now().Add(g.ntp_offset).Round(0) return time.Now().Add(g.ntp_offset).Round(0)
} }
@ -35,23 +32,20 @@ type Fullroute struct {
// IG is a graph of integers that satisfies the Graph interface. // IG is a graph of integers that satisfies the Graph interface.
type IG struct { type IG struct {
Vert map[mtypes.Vertex]bool Vert map[mtypes.Vertex]bool
edges map[mtypes.Vertex]map[mtypes.Vertex]*Latency edges map[mtypes.Vertex]map[mtypes.Vertex]*Latency
edgelock *sync.RWMutex edgelock *sync.RWMutex
StaticMode bool gsetting mtypes.GraphRecalculateSetting
JitterTolerance float64 SuperNodeInfoTimeout time.Duration
JitterToleranceMultiplier float64 RecalculateCoolDown time.Duration
DampingResistance float64 TimeoutCheckInterval time.Duration
SuperNodeInfoTimeout time.Duration recalculateTime time.Time
RecalculateCoolDown time.Duration dlTable mtypes.DistTable
TimeoutCheckInterval time.Duration nhTable mtypes.NextHopTable
recalculateTime time.Time changed bool
dlTable mtypes.DistTable NhTableExpire time.Time
nhTable mtypes.NextHopTable IsSuperMode bool
changed bool loglevel mtypes.LoggerInfo
NhTableExpire time.Time
IsSuperMode bool
loglevel mtypes.LoggerInfo
ntp_wg sync.WaitGroup ntp_wg sync.WaitGroup
ntp_info mtypes.NTPInfo ntp_info mtypes.NTPInfo
@ -59,45 +53,53 @@ type IG struct {
ntp_servers orderedmap.OrderedMap // serverurl:lentancy ntp_servers orderedmap.OrderedMap // serverurl:lentancy
} }
func NewGraph(num_node int, IsSuperMode bool, theconfig mtypes.GraphRecalculateSetting, ntpinfo mtypes.NTPInfo, loglevel mtypes.LoggerInfo) *IG { func NewGraph(num_node int, IsSuperMode bool, theconfig mtypes.GraphRecalculateSetting, ntpinfo mtypes.NTPInfo, loglevel mtypes.LoggerInfo) (*IG, error) {
g := IG{ g := IG{
edgelock: &sync.RWMutex{}, edgelock: &sync.RWMutex{},
StaticMode: theconfig.StaticMode, gsetting: theconfig,
JitterTolerance: theconfig.JitterTolerance, RecalculateCoolDown: mtypes.S2TD(theconfig.RecalculateCoolDown),
JitterToleranceMultiplier: theconfig.JitterToleranceMultiplier, TimeoutCheckInterval: mtypes.S2TD(theconfig.TimeoutCheckInterval),
DampingResistance: theconfig.DampingResistance, ntp_info: ntpinfo,
RecalculateCoolDown: mtypes.S2TD(theconfig.RecalculateCoolDown),
TimeoutCheckInterval: mtypes.S2TD(theconfig.TimeoutCheckInterval),
ntp_info: ntpinfo,
} }
g.Vert = make(map[mtypes.Vertex]bool, num_node) g.Vert = make(map[mtypes.Vertex]bool, num_node)
g.edges = make(map[mtypes.Vertex]map[mtypes.Vertex]*Latency, num_node) g.edges = make(map[mtypes.Vertex]map[mtypes.Vertex]*Latency, num_node)
g.IsSuperMode = IsSuperMode g.IsSuperMode = IsSuperMode
g.loglevel = loglevel g.loglevel = loglevel
if theconfig.DampingResistance < 0 || theconfig.DampingResistance >= 1 {
return nil, fmt.Errorf("DampingResistance must in range [0,1)")
}
g.InitNTP() g.InitNTP()
return &g return &g, nil
} }
func (g *IG) GetWeightType(x float64) (y float64) { func (g *IG) GetWeightType(x float64) (y float64) {
x = math.Abs(x) x = math.Abs(x)
y = x y = x
if g.JitterTolerance > 0.001 && g.JitterToleranceMultiplier > 1 { if g.gsetting.JitterTolerance > 0.001 && g.gsetting.JitterToleranceMultiplier > 1 {
t := g.JitterTolerance t := g.gsetting.JitterTolerance
r := g.JitterToleranceMultiplier r := g.gsetting.JitterToleranceMultiplier
y = math.Pow(math.Ceil(math.Pow(x/t, 1/r)), r) * t y = math.Pow(math.Ceil(math.Pow(x/t, 1/r)), r) * t
} }
return y return y
} }
func (g *IG) ShouldUpdate(oldval float64, newval float64) bool { func (g *IG) ShouldUpdate(oldval float64, newval float64, withCooldown bool) bool {
if (oldval >= mtypes.Infinity) != (newval >= mtypes.Infinity) {
return true
}
if withCooldown {
if g.recalculateTime.Add(g.RecalculateCoolDown).After(time.Now()) {
return false
}
}
oldval = math.Abs(oldval * 1000) oldval = math.Abs(oldval * 1000)
newval = math.Abs(newval * 1000) newval = math.Abs(newval * 1000)
if g.IsSuperMode { if g.IsSuperMode {
if g.JitterTolerance > 0.001 && g.JitterToleranceMultiplier >= 1 { if g.gsetting.JitterTolerance > 0.001 && g.gsetting.JitterToleranceMultiplier >= 1 {
diff := math.Abs(newval - oldval) diff := math.Abs(newval - oldval)
x := math.Max(oldval, newval) x := math.Max(oldval, newval)
t := g.JitterTolerance t := g.gsetting.JitterTolerance
r := g.JitterToleranceMultiplier r := g.gsetting.JitterToleranceMultiplier
return diff > t+x*(r-1) // https://www.desmos.com/calculator/raoti16r5n return diff > t+x*(r-1) // https://www.desmos.com/calculator/raoti16r5n
} }
return oldval == newval return oldval == newval
@ -106,14 +108,14 @@ func (g *IG) ShouldUpdate(oldval float64, newval float64) bool {
} }
} }
func (g *IG) CheckAnyShouldUpdate() bool { func (g *IG) CheckAnyShouldUpdate(withCooldown bool) bool {
vert := g.Vertices() vert := g.Vertices()
for u, _ := range vert { for u := range vert {
for v, _ := range vert { for v := range vert {
if u != v { if u != v {
newVal := g.Weight(u, v, false) newVal := g.Weight(u, v, false)
oldVal := g.OldWeight(u, v, false) oldVal := g.OldWeight(u, v, false)
if g.ShouldUpdate(oldVal, newVal) { if g.ShouldUpdate(oldVal, newVal, withCooldown) {
return true return true
} }
} }
@ -123,33 +125,33 @@ func (g *IG) CheckAnyShouldUpdate() bool {
} }
func (g *IG) RecalculateNhTable(checkchange bool) (changed bool) { func (g *IG) RecalculateNhTable(checkchange bool) (changed bool) {
if g.StaticMode { if g.gsetting.StaticMode {
if g.changed { if g.changed {
changed = checkchange changed = checkchange
} }
return return
} }
if !g.CheckAnyShouldUpdate() { if !g.CheckAnyShouldUpdate(true) {
return return
} }
if g.recalculateTime.Add(g.RecalculateCoolDown).Before(time.Now()) {
dist, next, _ := g.FloydWarshall(false) dist, next, _ := g.FloydWarshall(false)
changed = false changed = false
if checkchange { if checkchange {
CheckLoop: CheckLoop:
for src, dsts := range next { for src, dsts := range next {
for dst, old_next := range dsts { for dst, old_next := range dsts {
nexthop := g.Next(src, dst) nexthop := g.Next(src, dst)
if old_next != nexthop { if old_next != nexthop {
changed = true changed = true
break CheckLoop break CheckLoop
}
} }
} }
} }
g.dlTable, g.nhTable = dist, next
g.recalculateTime = time.Now()
} }
g.dlTable, g.nhTable = dist, next
g.recalculateTime = time.Now()
return return
} }
@ -157,7 +159,7 @@ func (g *IG) RemoveVirt(v mtypes.Vertex, recalculate bool, checkchange bool) (ch
g.edgelock.Lock() g.edgelock.Lock()
delete(g.Vert, v) delete(g.Vert, v)
delete(g.edges, v) delete(g.edges, v)
for u, _ := range g.edges { for u := range g.edges {
delete(g.edges[u], v) delete(g.edges[u], v)
} }
g.edgelock.Unlock() g.edgelock.Unlock()
@ -184,8 +186,13 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
for _, pong_msg := range pong_info { for _, pong_msg := range pong_info {
u := pong_msg.Src_nodeID u := pong_msg.Src_nodeID
v := pong_msg.Dst_nodeID v := pong_msg.Dst_nodeID
w_in := pong_msg.Timediff newval := pong_msg.Timediff
w := w_in if _, ok := g.gsetting.ManualLatency[u]; ok {
if _, ok := g.gsetting.ManualLatency[u][v]; ok {
newval = g.gsetting.ManualLatency[u][v]
}
}
w := newval
additionalCost := pong_msg.AdditionalCost additionalCost := pong_msg.AdditionalCost
if additionalCost < 0 { if additionalCost < 0 {
additionalCost = 0 additionalCost = 0
@ -199,10 +206,10 @@ 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 != Infinity { if oldval != mtypes.Infinity {
w = oldval*g.DampingResistance + w_in*(1-g.DampingResistance) w = oldval*g.gsetting.DampingResistance + newval*(1-g.gsetting.DampingResistance)
} }
should_update = should_update || g.ShouldUpdate(oldval, w) should_update = should_update || g.ShouldUpdate(oldval, w, false)
if _, ok := g.edges[u][v]; ok { if _, ok := g.edges[u][v]; ok {
g.edges[u][v].ping = w g.edges[u][v].ping = w
g.edges[u][v].validUntil = time.Now().Add(mtypes.S2TD(pong_msg.TimeToAlive)) g.edges[u][v].validUntil = time.Now().Add(mtypes.S2TD(pong_msg.TimeToAlive))
@ -210,7 +217,7 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
} else { } else {
g.edges[u][v] = &Latency{ g.edges[u][v] = &Latency{
ping: w, ping: w,
ping_old: Infinity, ping_old: mtypes.Infinity,
validUntil: time.Now().Add(mtypes.S2TD(pong_msg.TimeToAlive)), validUntil: time.Now().Add(mtypes.S2TD(pong_msg.TimeToAlive)),
additionalCost: additionalCost / 1000, additionalCost: additionalCost / 1000,
} }
@ -231,7 +238,7 @@ func (g *IG) Vertices() map[mtypes.Vertex]bool {
} }
return vr return vr
} }
func (g IG) Neighbors(v mtypes.Vertex) (vs []mtypes.Vertex) { func (g *IG) Neighbors(v mtypes.Vertex) (vs []mtypes.Vertex) {
g.edgelock.RLock() g.edgelock.RLock()
defer g.edgelock.RUnlock() defer g.edgelock.RUnlock()
for k := range g.edges[v] { //copy a new list for k := range g.edges[v] { //copy a new list
@ -240,12 +247,12 @@ func (g IG) Neighbors(v mtypes.Vertex) (vs []mtypes.Vertex) {
return vs return vs
} }
func (g *IG) Next(u, v mtypes.Vertex) *mtypes.Vertex { func (g *IG) Next(u, v mtypes.Vertex) mtypes.Vertex {
if _, ok := g.nhTable[u]; !ok { if _, ok := g.nhTable[u]; !ok {
return nil return mtypes.NodeID_Invalid
} }
if _, ok := g.nhTable[u][v]; !ok { if _, ok := g.nhTable[u][v]; !ok {
return nil return mtypes.NodeID_Invalid
} }
return g.nhTable[u][v] return g.nhTable[u][v]
} }
@ -258,20 +265,20 @@ func (g *IG) Weight(u, v mtypes.Vertex, withAC bool) (ret float64) {
return 0 return 0
} }
if _, ok := g.edges[u]; !ok { if _, ok := g.edges[u]; !ok {
return Infinity return mtypes.Infinity
} }
if _, ok := g.edges[u][v]; !ok { if _, ok := g.edges[u][v]; !ok {
return Infinity return mtypes.Infinity
} }
if time.Now().After(g.edges[u][v].validUntil) { if time.Now().After(g.edges[u][v].validUntil) {
return Infinity return mtypes.Infinity
} }
ret = g.edges[u][v].ping ret = g.edges[u][v].ping
if withAC { if withAC {
ret += g.edges[u][v].additionalCost ret += g.edges[u][v].additionalCost
} }
if ret >= Infinity { if ret >= mtypes.Infinity {
return Infinity return mtypes.Infinity
} }
return return
} }
@ -283,17 +290,17 @@ func (g *IG) OldWeight(u, v mtypes.Vertex, withAC bool) (ret float64) {
return 0 return 0
} }
if _, ok := g.edges[u]; !ok { if _, ok := g.edges[u]; !ok {
return Infinity return mtypes.Infinity
} }
if _, ok := g.edges[u][v]; !ok { if _, ok := g.edges[u][v]; !ok {
return Infinity return mtypes.Infinity
} }
ret = g.edges[u][v].ping_old ret = g.edges[u][v].ping_old
if withAC { if withAC {
ret += g.edges[u][v].additionalCost ret += g.edges[u][v].additionalCost
} }
if ret >= Infinity { if ret >= mtypes.Infinity {
return Infinity return mtypes.Infinity
} }
return return
} }
@ -324,8 +331,8 @@ func (g *IG) SetOldWeight(u, v mtypes.Vertex, weight float64) {
func (g *IG) RemoveAllNegativeValue() { func (g *IG) RemoveAllNegativeValue() {
vert := g.Vertices() vert := g.Vertices()
for u, _ := range vert { for u := range vert {
for v, _ := range vert { for v := range vert {
if g.Weight(u, v, true) < 0 { if g.Weight(u, v, true) < 0 {
if g.loglevel.LogInternal { if g.loglevel.LogInternal {
fmt.Printf("Internal: Remove negative value : edge[%v][%v] = 0\n", u, v) fmt.Printf("Internal: Remove negative value : edge[%v][%v] = 0\n", u, v)
@ -348,28 +355,28 @@ func (g *IG) FloydWarshall(again bool) (dist mtypes.DistTable, next mtypes.NextH
vert := g.Vertices() vert := g.Vertices()
dist = make(mtypes.DistTable) dist = make(mtypes.DistTable)
next = make(mtypes.NextHopTable) next = make(mtypes.NextHopTable)
for u, _ := range vert { for u := range vert {
dist[u] = make(map[mtypes.Vertex]float64) dist[u] = make(map[mtypes.Vertex]float64)
next[u] = make(map[mtypes.Vertex]*mtypes.Vertex) next[u] = make(map[mtypes.Vertex]mtypes.Vertex)
for v, _ := range vert { for v := range vert {
dist[u][v] = Infinity dist[u][v] = mtypes.Infinity
} }
dist[u][u] = 0 dist[u][u] = 0
for _, v := range g.Neighbors(u) { for _, v := range g.Neighbors(u) {
w := g.Weight(u, v, true) w := g.Weight(u, v, true)
wo := g.Weight(u, v, false) wo := g.Weight(u, v, false)
if w < Infinity { if w < mtypes.Infinity {
v := v v := v
dist[u][v] = w dist[u][v] = w
next[u][v] = &v next[u][v] = v
} }
g.SetOldWeight(u, v, wo) g.SetOldWeight(u, v, wo)
} }
} }
for k, _ := range vert { for k := range vert {
for i, _ := range vert { for i := range vert {
for j, _ := range vert { for j := range vert {
if dist[i][k] < Infinity && dist[k][j] < Infinity { if dist[i][k] < mtypes.Infinity && dist[k][j] < mtypes.Infinity {
if dist[i][j] > dist[i][k]+dist[k][j] { if dist[i][j] > dist[i][k]+dist[k][j] {
dist[i][j] = dist[i][k] + dist[k][j] dist[i][j] = dist[i][k] + dist[k][j]
next[i][j] = next[i][k] next[i][j] = next[i][k]
@ -391,7 +398,7 @@ func (g *IG) FloydWarshall(again bool) (dist mtypes.DistTable, next mtypes.NextH
} else { } else {
dist = make(mtypes.DistTable) dist = make(mtypes.DistTable)
next = make(mtypes.NextHopTable) next = make(mtypes.NextHopTable)
err = errors.New("negative cycle detected again!") err = errors.New("negative cycle detected again")
if g.loglevel.LogInternal { if g.loglevel.LogInternal {
fmt.Println("Internal: Error: Negative cycle detected again") fmt.Println("Internal: Error: Negative cycle detected again")
} }
@ -402,24 +409,34 @@ func (g *IG) FloydWarshall(again bool) (dist mtypes.DistTable, next mtypes.NextH
return return
} }
func Path(u, v mtypes.Vertex, next mtypes.NextHopTable) (path []mtypes.Vertex) { func (g *IG) Path(u, v mtypes.Vertex) (path []mtypes.Vertex, err error) {
if next[u][v] == nil { g.edgelock.RLock()
return []mtypes.Vertex{} defer g.edgelock.RUnlock()
} footprint := make(map[mtypes.Vertex]bool)
path = []mtypes.Vertex{u}
for u != v { for u != v {
u = *next[u][v] if _, has := footprint[u]; has {
return path, fmt.Errorf("cycle detected in nhTable, s:%v e:%v path:%v", u, v, path)
}
if _, ok := g.nhTable[u]; !ok {
return path, fmt.Errorf("nhTable[%v] not exist", u)
}
if _, ok := g.nhTable[u][v]; !ok {
return path, fmt.Errorf("nhTable[%v][%v] not exist", u, v)
}
path = append(path, u) path = append(path, u)
footprint[u] = true
u = g.nhTable[u][v]
} }
return path path = append(path, u)
return path, nil
} }
func (g *IG) SetNHTable(nh mtypes.NextHopTable) { // set nhTable from supernode func (g *IG) SetNHTable(nh mtypes.NextHopTable) { // set nhTable from supernode
g.edgelock.Lock() g.edgelock.Lock()
defer g.edgelock.Unlock()
g.nhTable = nh g.nhTable = nh
g.changed = true g.changed = true
g.NhTableExpire = time.Now().Add(g.SuperNodeInfoTimeout) g.NhTableExpire = time.Now().Add(g.SuperNodeInfoTimeout)
g.edgelock.Unlock()
} }
func (g *IG) GetNHTable(recalculate bool) mtypes.NextHopTable { func (g *IG) GetNHTable(recalculate bool) mtypes.NextHopTable {
@ -436,9 +453,9 @@ func (g *IG) GetDtst() mtypes.DistTable {
func (g *IG) GetEdges(isOld bool, withAC bool) (edges map[mtypes.Vertex]map[mtypes.Vertex]float64) { func (g *IG) GetEdges(isOld bool, withAC bool) (edges map[mtypes.Vertex]map[mtypes.Vertex]float64) {
vert := g.Vertices() vert := g.Vertices()
edges = make(map[mtypes.Vertex]map[mtypes.Vertex]float64, len(vert)) edges = make(map[mtypes.Vertex]map[mtypes.Vertex]float64, len(vert))
for src, _ := range vert { for src := range vert {
edges[src] = make(map[mtypes.Vertex]float64, len(vert)) edges[src] = make(map[mtypes.Vertex]float64, len(vert))
for dst, _ := range vert { for dst := range vert {
if src != dst { if src != dst {
if isOld { if isOld {
edges[src][dst] = g.OldWeight(src, dst, withAC) edges[src][dst] = g.OldWeight(src, dst, withAC)
@ -454,15 +471,20 @@ func (g *IG) GetEdges(isOld bool, withAC bool) (edges map[mtypes.Vertex]map[mtyp
func (g *IG) GetBoardcastList(id mtypes.Vertex) (tosend map[mtypes.Vertex]bool) { func (g *IG) GetBoardcastList(id mtypes.Vertex) (tosend map[mtypes.Vertex]bool) {
tosend = make(map[mtypes.Vertex]bool) tosend = make(map[mtypes.Vertex]bool)
for _, element := range g.nhTable[id] { for _, element := range g.nhTable[id] {
tosend[*element] = true tosend[element] = true
} }
return return
} }
func (g *IG) GetBoardcastThroughList(self_id mtypes.Vertex, in_id mtypes.Vertex, src_id mtypes.Vertex) (tosend map[mtypes.Vertex]bool) { func (g *IG) GetBoardcastThroughList(self_id mtypes.Vertex, in_id mtypes.Vertex, src_id mtypes.Vertex) (tosend map[mtypes.Vertex]bool, errs []error) {
tosend = make(map[mtypes.Vertex]bool) tosend = make(map[mtypes.Vertex]bool)
for check_id, _ := range g.GetBoardcastList(self_id) { for check_id := range g.GetBoardcastList(self_id) {
for _, path_node := range Path(src_id, check_id, g.nhTable) { path, err := g.Path(src_id, check_id)
if err != nil {
errs = append(errs, err)
continue
}
for _, path_node := range path {
if path_node == self_id && check_id != in_id { if path_node == self_id && check_id != in_id {
tosend[check_id] = true tosend[check_id] = true
continue continue
@ -482,23 +504,39 @@ func printExample() {
6 Inf Inf Inf 0.5 Inf 0`) 6 Inf Inf Inf 0.5 Inf 0`)
} }
func a2n(s string) (ret float64) { func ParseDistanceMatrix(input string) ([]mtypes.PongMsg, error) {
if s == "Inf" { lines := strings.Split(input, "\n")
return Infinity verts := strings.Fields(lines[0])
ret := make([]mtypes.PongMsg, 0, len(verts)*len(verts))
for li, line := range lines[1:] {
element := strings.Fields(line)
src, err := mtypes.String2NodeID(element[0])
if err != nil {
return ret, err
}
if len(element) != len(verts) {
return ret, fmt.Errorf("parse error at line %v: element number mismatch to node id number", li)
}
for ei, sval := range element[1:] {
val, err := mtypes.String2Float64(sval)
if err != nil {
return ret, err
}
dst, err := mtypes.String2NodeID(verts[ei+1])
if err != nil {
return ret, err
}
if src != dst && val != mtypes.Infinity {
ret = append(ret, mtypes.PongMsg{
Src_nodeID: src,
Dst_nodeID: dst,
Timediff: val,
TimeToAlive: 999999,
})
}
}
} }
ret, err := strconv.ParseFloat(s, 64) return ret, nil
if err != nil {
panic(err)
}
return
}
func a2v(s string) mtypes.Vertex {
ret, err := strconv.ParseUint(s, 10, 16)
if err != nil {
panic(err)
}
return mtypes.Vertex(ret)
} }
func Solve(filePath string, pe bool) error { func Solve(filePath string, pe bool) error {
@ -507,26 +545,15 @@ func Solve(filePath string, pe bool) error {
return nil return nil
} }
g := NewGraph(3, false, mtypes.GraphRecalculateSetting{}, mtypes.NTPInfo{}, mtypes.LoggerInfo{LogInternal: true}) g, _ := NewGraph(3, false, mtypes.GraphRecalculateSetting{}, mtypes.NTPInfo{}, mtypes.LoggerInfo{LogInternal: false})
inputb, err := ioutil.ReadFile(filePath) inputb, err := ioutil.ReadFile(filePath)
if err != nil { if err != nil {
return err return err
} }
input := string(inputb) input := string(inputb)
lines := strings.Split(input, "\n") all_edge, _ := ParseDistanceMatrix(input)
verts := strings.Fields(lines[0]) g.UpdateLatencyMulti(all_edge, false, false)
for _, line := range lines[1:] {
element := strings.Fields(line)
src := a2v(element[0])
for index, sval := range element[1:] {
val := a2n(sval)
dst := a2v(verts[index+1])
if src != dst && val != Infinity {
g.UpdateLatency(src, dst, val, 99999, 0, false, false)
}
}
}
dist, next, err := g.FloydWarshall(false) dist, next, err := g.FloydWarshall(false)
if err != nil { if err != nil {
fmt.Println("Error:", err) fmt.Println("Error:", err)
@ -540,12 +567,16 @@ func Solve(filePath string, pe bool) error {
fmt.Println("\nHuman readable:") fmt.Println("\nHuman readable:")
fmt.Println("src\tdist\t\tpath") fmt.Println("src\tdist\t\tpath")
for _, U := range verts[1:] { all_vert := g.Vertices()
u := a2v(U) for u := range all_vert {
for _, V := range verts[1:] { for v := range all_vert {
v := a2v(V)
if u != v { if u != v {
fmt.Printf("%d -> %d\t%3f\t%s\n", u, v, dist[u][v], fmt.Sprint(Path(u, v, next))) path, err := g.Path(u, v)
pathstr := fmt.Sprint(path)
if err != nil {
pathstr = fmt.Sprint(path)
}
fmt.Printf("%d -> %d\t%3f\t%s\n", u, v, dist[u][v], pathstr)
} }
} }
} }

View File

@ -100,7 +100,8 @@ 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 := buf[offset:] packet := make([]byte, len(buf[offset:]))
copy(packet, buf[offset:])
switch tap.L2mode { switch tap.L2mode {
case KeyboardDebug: case KeyboardDebug:
src := Mac2charForm(packet[6:12]) src := Mac2charForm(packet[6:12])

View File

@ -14,7 +14,6 @@ type UdpSockTap struct {
recv *net.UDPConn recv *net.UDPConn
send *net.UDPAddr send *net.UDPAddr
static bool static bool
L2mode L2MODE
events chan Event events chan Event
} }
@ -28,7 +27,6 @@ func CreateUDPSockTAP(iconfig mtypes.InterfaceConf, NodeID mtypes.Vertex) (tapde
recv: nil, recv: nil,
send: nil, send: nil,
static: false, static: false,
L2mode: GetL2Mode(iconfig.L2HeaderMode),
events: make(chan Event, 1<<5), events: make(chan Event, 1<<5),
} }