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
id := peer.ID
delete(device.peers.keyMap, key)
if id == mtypes.SuperNodeMessage {
if id == mtypes.NodeID_SuperNode {
delete(device.peers.SuperPeer, key)
} else {
delete(device.peers.IDMap, id)
@ -412,7 +412,7 @@ func (device *Device) LookupPeerIDAtConfig(pk NoisePublicKey) (ID mtypes.Vertex,
if device.IsSuperNode {
var peerlist []mtypes.SuperPeerInfo
if device.SuperConfig == nil {
return 0, errors.New("Superconfig is nil")
return 0, errors.New("superconfig is nil")
}
peerlist = device.SuperConfig.Peers
pkstr := pk.ToString()
@ -424,7 +424,7 @@ func (device *Device) LookupPeerIDAtConfig(pk NoisePublicKey) (ID mtypes.Vertex,
} else {
var peerlist []mtypes.PeerInfo
if device.EdgeConfig == nil {
return 0, errors.New("EdgeConfig is nil")
return 0, errors.New("edgeconfig is nil")
}
peerlist = device.EdgeConfig.Peers
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 {
@ -452,20 +487,20 @@ func (device *Device) LookupPeerByStr(pks string) *Peer {
return device.LookupPeer(pk)
}
func (pk *NoisePublicKey) ToString() string {
func (pk NoisePublicKey) ToString() string {
if bytes.Equal(pk[:], make([]byte, len(pk))) {
return ""
}
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))) {
return ""
}
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))) {
return ""
}
@ -474,7 +509,7 @@ func (pk *NoisePresharedKey) ToString() (result string) {
func Str2PubKey(k string) (pk NoisePublicKey, err error) {
if k == "" {
err = errors.New("Empty public key string")
err = errors.New("empty public key string")
return
}
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) {
if k == "" {
err = errors.New("Empty private key string")
err = errors.New("empty private key string")
return
}
sk_slice, err := base64.StdEncoding.DecodeString(k)
@ -501,6 +536,16 @@ func Str2PSKey(k string) (pk NoisePresharedKey, err error) {
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 {
if peer, has := device.peers.IDMap[v]; has {
if peer.endpoint != nil {

View File

@ -18,7 +18,6 @@ import (
"github.com/KusakabeSi/EtherGuard-VPN/conn"
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
"github.com/KusakabeSi/EtherGuard-VPN/path"
"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)
if urls.IsEmpty() {
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) {
@ -61,18 +60,18 @@ func (et *endpoint_trylist) UpdateSuper(urls mtypes.API_connurl, UseLocalIP bool
_, err := conn.LookupIP(url, 0)
if err != nil {
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
}
if val, ok := et.trymap_super[url]; ok {
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
} else {
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{
URL: url,
@ -93,7 +92,7 @@ func (et *endpoint_trylist) UpdateP2P(url string) {
defer et.Unlock()
if _, ok := et.trymap_p2p[url]; !ok {
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{
URL: url,
@ -123,7 +122,7 @@ func (et *endpoint_trylist) GetNextTry() (bool, string) {
for url, v := range et.trymap_p2p {
if v.firstTry.After(time.Time{}) && v.firstTry.Add(et.timeout).Before(time.Now()) {
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)
}
@ -203,15 +202,15 @@ type Peer struct {
persistentKeepaliveInterval uint32 // accessed atomically
}
func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool) (*Peer, error) {
if isSuper == false {
if id < mtypes.Special_NodeID {
func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool, PersistentKeepalive uint32) (*Peer, error) {
if !isSuper {
if id < mtypes.NodeID_Special {
//pass check
} else {
return nil, errors.New(fmt.Sprint("ID ", uint32(id), " is a special NodeID"))
}
} else {
if id == mtypes.SuperNodeMessage {
if id == mtypes.NodeID_SuperNode {
//pass check
} else {
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() {
return nil, errors.New("device closed")
}
// lock resources
device.staticIdentity.RLock()
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())
}
peer := new(Peer)
atomic.SwapUint32(&peer.persistentKeepaliveInterval, PersistentKeepalive)
peer.LastPacketReceivedAdd1Sec.Store(&time.Time{})
peer.Lock()
defer peer.Unlock()
@ -246,7 +245,7 @@ func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool)
peer.cookieGenerator.Init(pk)
peer.device = device
peer.endpoint_trylist = NewEndpoint_trylist(peer, mtypes.S2TD(device.EdgeConfig.DynamicRoute.PeerAliveTimeout))
peer.SingleWayLatency = path.Infinity
peer.SingleWayLatency = mtypes.Infinity
peer.queue.outbound = newAutodrainingOutboundQueue(device)
peer.queue.inbound = newAutodrainingInboundQueue(device)
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
// 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.keyMap[pk] = peer
} else { // Regular peer, other edgenodes
@ -285,7 +284,6 @@ func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool)
if peer.device.isUp() {
peer.Start()
}
return peer, nil
}
@ -452,7 +450,7 @@ func (peer *Peer) Stop() {
}
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.")
return
}
@ -490,8 +488,15 @@ func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) {
return
}
peer.Lock()
if peer.ID == mtypes.SuperNodeMessage {
defer peer.Unlock()
if peer.ID == mtypes.NodeID_SuperNode {
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()
if err == nil {
IP := conn.LocalAddr().(*net.UDPAddr).IP
@ -504,7 +509,7 @@ func (peer *Peer) SetEndpointFromPacket(endpoint conn.Endpoint) {
}
peer.device.SaveToConfig(peer, endpoint)
peer.endpoint = endpoint
peer.Unlock()
}
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
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
}
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 {
if peerfile.NodeID == peer.ID && peerfile.PubKey == pubkeystr {
foundInFile = true
if peerfile.Static == false {
if !peerfile.Static {
peerfile.EndPoint = url
}
} 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)
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()
dst_nodeID = EgHeader.GetDst()
elem.packet = elem.packet[:EgHeader.GetPacketLength()+path.EgHeaderLen] // EG header + true packet
@ -471,21 +471,21 @@ func (peer *Peer) RoutineSequentialReceiver() {
if device.IsSuperNode {
switch dst_nodeID {
case mtypes.ControlMessage:
case mtypes.NodeID_AllPeer:
should_process = true
case mtypes.SuperNodeMessage:
case mtypes.NodeID_SuperNode:
should_process = true
default:
device.log.Errorf("Invalid dst_nodeID received. Check your code for bug")
}
} else {
switch dst_nodeID {
case mtypes.Broadcast:
case mtypes.NodeID_Boardcast:
should_receive = true
should_transfer = true
case mtypes.SuperNodeMessage:
case mtypes.NodeID_SuperNode:
should_process = true
case mtypes.ControlMessage:
case mtypes.NodeID_AllPeer:
packet := elem.packet[path.EgHeaderLen:] //true packet
if device.CheckNoDup(packet) {
should_process = true
@ -504,7 +504,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
should_process = true
}
default:
if device.graph.Next(device.ID, dst_nodeID) != nil {
if device.graph.Next(device.ID, dst_nodeID) != mtypes.NodeID_Invalid {
should_transfer = true
} else {
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)
} else {
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)
} 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[src_nodeID] = true //Don't send to conimg peer and source peer
skip_list[peer.ID] = true
@ -527,9 +527,9 @@ func (peer *Peer) RoutineSequentialReceiver() {
} else {
next_id := device.graph.Next(device.ID, dst_nodeID)
if next_id != nil {
if next_id != mtypes.NodeID_Invalid {
device.peers.RLock()
peer_out = device.peers.IDMap[*next_id]
peer_out = device.peers.IDMap[next_id]
device.peers.RUnlock()
if device.LogLevel.LogTransit {
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
send_list := device.graph.GetBoardcastList(device.ID)
for node_id, _ := range skip_list {
for node_id := range skip_list {
send_list[node_id] = false
}
device.peers.RLock()
for node_id, should_send := range send_list {
if should_send {
peer_out, _ := device.peers.IDMap[node_id]
device.SendPacket(peer_out, usage, packet, offset)
peer_out := device.peers.IDMap[node_id]
go device.SendPacket(peer_out, usage, packet, offset)
}
}
device.peers.RUnlock()
@ -95,20 +95,25 @@ func (device *Device) SpreadPacket(skip_list map[mtypes.Vertex]bool, usage path.
}
continue
}
device.SendPacket(peer_out, usage, packet, MessageTransportOffsetContent)
go device.SendPacket(peer_out, usage, packet, MessageTransportOffsetContent)
}
device.peers.RUnlock()
}
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()
for peer_id := range node_boardcast_list {
peer_out := device.peers.IDMap[peer_id]
if device.LogLevel.LogTransit {
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()
}
@ -120,7 +125,7 @@ func (device *Device) Send2Super(usage path.Usage, packet []byte, offset int) {
/*if device.LogTransit {
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()
@ -147,7 +152,7 @@ func (device *Device) process_received(msg_type path.Usage, peer *Peer, body []b
return device.server_process_Pong(peer, content)
}
default:
err = errors.New("Not a valid msg_type")
err = errors.New("not a valid msg_type")
}
} else {
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)
}
default:
err = errors.New("Not a valid msg_type")
err = errors.New("not a valid msg_type")
}
}
return
@ -229,7 +234,7 @@ func (device *Device) GeneratePingPacket(src_nodeID mtypes.Vertex, request_reply
if err != nil {
return nil, path.PingPacket, err
}
header.SetDst(mtypes.ControlMessage)
header.SetDst(mtypes.NodeID_AllPeer)
header.SetTTL(0)
header.SetSrc(device.ID)
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),
}
}
if compareVersion(content.Version, device.Version) == false {
if !compareVersion(content.Version, device.Version) {
ServerUpdateMsg = mtypes.ServerUpdateMsg{
Node_id: peer.ID,
Action: mtypes.ThrowError,
@ -284,12 +289,12 @@ func (device *Device) server_process_RegisterMsg(peer *Peer, content mtypes.Regi
return err
}
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.SetTTL(0)
header.SetPacketLength(uint16(len(body)))
copy(buf[path.EgHeaderLen:], body)
header.SetDst(mtypes.SuperNodeMessage)
header.SetDst(mtypes.NodeID_SuperNode)
device.SendPacket(peer, path.ServerUpdate, buf, MessageTransportOffsetContent)
return nil
}
@ -321,17 +326,17 @@ func (device *Device) process_ping(peer *Peer, content mtypes.PingMsg) error {
return err
}
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.SetTTL(device.EdgeConfig.DefaultTTL)
header.SetPacketLength(uint16(len(body)))
copy(buf[path.EgHeaderLen:], body)
if device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode {
header.SetDst(mtypes.SuperNodeMessage)
header.SetDst(mtypes.NodeID_SuperNode)
device.Send2Super(path.PongPacket, buf, MessageTransportOffsetContent)
}
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)
}
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
}
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.SetTTL(device.EdgeConfig.DefaultTTL)
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" ////////////////////////////////////////////////////////////////////////////////////////////////
req, err := http.NewRequest("GET", downloadurl, nil)
if err != nil {
device.log.Errorf(err.Error())
return err
}
q := req.URL.Query()
q.Add("NodeID", device.ID.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 {
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
device.graph.UpdateLatency(device.ID, peerinfo.NodeID, path.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
if device.graph.Weight(device.ID, peerinfo.NodeID, false) == mtypes.Infinity { // add node to graph
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
device.graph.UpdateLatency(peerinfo.NodeID, device.ID, path.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
if device.graph.Weight(peerinfo.NodeID, device.ID, false) == mtypes.Infinity { // add node to graph
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)
}
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" ////////////////////////////////////////////////////////////////////////////////////////////////
req, err := http.NewRequest("GET", downloadurl, nil)
if err != nil {
device.log.Errorf(err.Error())
return err
}
q := req.URL.Query()
q.Add("NodeID", device.ID.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" ////////////////////////////////////////////////////////////////////////////////////////////////
req, err := http.NewRequest("GET", downloadurl, nil)
if err != nil {
device.log.Errorf(err.Error())
return err
}
q := req.URL.Query()
q.Add("NodeID", device.ID.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 {
if peer.ID != mtypes.SuperNodeMessage {
if peer.ID != mtypes.NodeID_SuperNode {
if device.LogLevel.LogControl {
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 {
device.peers.RLock()
for pubkey, peer := range device.peers.keyMap {
if peer.ID >= mtypes.Special_NodeID {
if peer.ID >= mtypes.NodeID_Special {
continue
}
if peer.endpoint == nil {
@ -661,7 +678,7 @@ func (device *Device) process_RequestPeerMsg(content mtypes.QueryPeerMsg) error
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[0:path.EgHeaderLen])
header.SetDst(mtypes.ControlMessage)
header.SetDst(mtypes.NodeID_AllPeer)
header.SetTTL(device.EdgeConfig.DefaultTTL)
header.SetSrc(device.ID)
header.SetPacketLength(uint16(len(body)))
@ -688,13 +705,13 @@ func (device *Device) process_BoardcastPeerMsg(peer *Peer, content mtypes.Boardc
if device.LogLevel.LogControl {
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
device.graph.UpdateLatency(device.ID, content.NodeID, path.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
if device.graph.Weight(device.ID, content.NodeID, false) == mtypes.Infinity { // add node to graph
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
device.graph.UpdateLatency(content.NodeID, device.ID, path.Infinity, 0, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
if device.graph.Weight(content.NodeID, device.ID, false) == mtypes.Infinity { // add node to graph
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() {
//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) {
return
}
waitchan := make(<-chan time.Time)
var waitchan <-chan time.Time
for {
if device.EdgeConfig.DynamicRoute.SendPingInterval > 0 {
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) {
return
}
waitchan := time.After(8 * time.Second)
var waitchan <-chan time.Time
startchan <- struct{}{}
for {
if device.EdgeConfig.DynamicRoute.SendPingInterval > 0 {
@ -830,7 +847,7 @@ func (device *Device) RoutineRegister(startchan chan struct{}) {
})
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[0:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage)
header.SetDst(mtypes.NodeID_SuperNode)
header.SetTTL(0)
header.SetSrc(device.ID)
header.SetPacketLength(uint16(len(body)))
@ -843,7 +860,7 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
if !(device.EdgeConfig.DynamicRoute.SuperNode.UseSuperNode) {
return
}
waitchan := make(<-chan time.Time)
var waitchan <-chan time.Time
for {
if device.SuperConfig.HttpPostInterval > 0 {
waitchan = time.After(mtypes.S2TD(device.SuperConfig.HttpPostInterval))
@ -852,7 +869,6 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
}
select {
case <-waitchan:
break
case <-startchan:
if device.LogLevel.LogControl {
fmt.Println("Control: Start RoutinePostPeerInfo()")
@ -872,7 +888,7 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
Src_nodeID: device.ID,
Dst_nodeID: id,
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)
if device.LogLevel.LogControl {
@ -914,13 +930,17 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
PostCount: device.HttpPostCount,
BodyHash: bodyhash,
})
tokenString, err := token.SignedString(device.JWTSecret[:])
tokenString, _ := token.SignedString(device.JWTSecret[:])
// Construct post request
client := &http.Client{
Timeout: 8 * time.Second,
}
downloadurl := device.EdgeConfig.DynamicRoute.SuperNode.EndpointEdgeAPIUrl + "/edge/post/nodeinfo"
req, err := http.NewRequest("POST", downloadurl, bytes.NewReader(body))
if err != nil {
device.log.Errorf(err.Error())
continue
}
q := req.URL.Query()
q.Add("NodeID", device.ID.ToString())
q.Add("PubKey", device.staticIdentity.publicKey.ToString())
@ -955,10 +975,8 @@ func (device *Device) RoutineRecalculateNhTable() {
}
for {
if time.Now().After(device.graph.NhTableExpire) {
if device.graph.CheckAnyShouldUpdate() {
device.graph.RecalculateNhTable(false)
}
}
time.Sleep(device.graph.TimeoutCheckInterval)
}
@ -971,7 +989,7 @@ func (device *Device) RoutineSpreadAllMyNeighbor() {
timeout := mtypes.S2TD(device.EdgeConfig.DynamicRoute.P2P.SendPeerInterval)
for {
device.process_RequestPeerMsg(mtypes.QueryPeerMsg{
Request_ID: uint32(mtypes.Broadcast),
Request_ID: uint32(mtypes.NodeID_Boardcast),
})
time.Sleep(timeout)
}

View File

@ -251,14 +251,14 @@ func (device *Device) RoutineReadFromTUN() {
//add custom header dst_node, src_node, ttl
size += path.EgHeaderLen
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()
dstMacAddr := tap.GetDstMacAddr(elem.packet[path.EgHeaderLen:])
// lookup peer
if tap.IsNotUnicast(dstMacAddr) {
dst_nodeID = mtypes.Broadcast
dst_nodeID = mtypes.NodeID_Boardcast
} else if val, ok := device.l2fib.Load(dstMacAddr); !ok { //Lookup failed
dst_nodeID = mtypes.Broadcast
dst_nodeID = mtypes.NodeID_Boardcast
} else {
dst_nodeID = val.(*IdAndTime).ID
}
@ -275,12 +275,12 @@ func (device *Device) RoutineReadFromTUN() {
continue
}
if dst_nodeID != mtypes.Broadcast {
if dst_nodeID != mtypes.NodeID_Boardcast {
var peer *Peer
next_id := device.graph.Next(device.ID, dst_nodeID)
if next_id != nil {
if next_id != mtypes.NodeID_Invalid {
device.peers.RLock()
peer = device.peers.IDMap[*next_id]
peer = device.peers.IDMap[next_id]
device.peers.RUnlock()
if peer == nil {
continue

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,17 +10,17 @@ import (
"github.com/KusakabeSi/EtherGuard-VPN/path"
)
func GetExampleEdgeConf(templatePath string) mtypes.EdgeConfig {
tconfig := mtypes.EdgeConfig{}
func GetExampleEdgeConf(templatePath string, getDemo bool) mtypes.EdgeConfig {
econfig := mtypes.EdgeConfig{}
if templatePath != "" {
err := mtypes.ReadYaml(templatePath, &tconfig)
err := mtypes.ReadYaml(templatePath, &econfig)
if err == nil {
return tconfig
return econfig
}
}
v1 := mtypes.Vertex(1)
v2 := mtypes.Vertex(2)
tconfig = mtypes.EdgeConfig{
econfig = mtypes.EdgeConfig{
Interface: mtypes.InterfaceConf{
IType: "tap",
Name: "tap1",
@ -73,9 +73,17 @@ func GetExampleEdgeConf(templatePath string) mtypes.EdgeConfig {
StaticMode: false,
JitterTolerance: 50,
JitterToleranceMultiplier: 1.1,
DampingResistance: 0.8,
DampingResistance: 0.9,
TimeoutCheckInterval: 5,
RecalculateCoolDown: 5,
ManualLatency: mtypes.DistTable{
mtypes.Vertex(1): {
mtypes.Vertex(2): 2,
},
mtypes.Vertex(2): {
mtypes.Vertex(1): 2,
},
},
},
},
NTPConfig: mtypes.NTPInfo{
@ -109,10 +117,10 @@ func GetExampleEdgeConf(templatePath string) mtypes.EdgeConfig {
},
NextHopTable: mtypes.NextHopTable{
mtypes.Vertex(1): {
mtypes.Vertex(2): &v2,
mtypes.Vertex(2): v2,
},
mtypes.Vertex(2): {
mtypes.Vertex(1): &v1,
mtypes.Vertex(1): v1,
},
},
ResetConnInterval: 86400,
@ -122,12 +130,13 @@ func GetExampleEdgeConf(templatePath string) mtypes.EdgeConfig {
PubKey: "dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=",
PSKey: "juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=",
EndPoint: "127.0.0.1:3002",
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)
@ -141,11 +150,17 @@ func GetExampleEdgeConf(templatePath string) mtypes.EdgeConfig {
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
econfig.NextHopTable = next
} else {
econfig.Peers = []mtypes.PeerInfo{}
econfig.NextHopTable = make(mtypes.NextHopTable)
econfig.DynamicRoute.P2P.GraphRecalculateSetting.ManualLatency = make(mtypes.DistTable)
}
return econfig
}
func GetExampleSuperConf(templatePath string) mtypes.SuperConfig {
func GetExampleSuperConf(templatePath string, getDemo bool) mtypes.SuperConfig {
sconfig := mtypes.SuperConfig{}
if templatePath != "" {
err := mtypes.ReadYaml(templatePath, &sconfig)
@ -189,18 +204,18 @@ func GetExampleSuperConf(templatePath string) mtypes.SuperConfig {
},
GraphRecalculateSetting: mtypes.GraphRecalculateSetting{
StaticMode: false,
JitterTolerance: 50,
JitterTolerance: 30,
JitterToleranceMultiplier: 1.01,
DampingResistance: 0.8,
DampingResistance: 0.9,
TimeoutCheckInterval: 5,
RecalculateCoolDown: 5,
},
NextHopTable: mtypes.NextHopTable{
mtypes.Vertex(1): {
mtypes.Vertex(2): &v2,
mtypes.Vertex(2): v2,
},
mtypes.Vertex(2): {
mtypes.Vertex(1): &v1,
mtypes.Vertex(1): v1,
},
},
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
}

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

View File

@ -5,6 +5,10 @@
package gencfg
import (
"github.com/KusakabeSi/EtherGuard-VPN/mtypes"
)
type SMCfg struct {
ConfigOutputDir string `yaml:"Config output dir"`
SuperConfigTemplate string `yaml:"ConfigTemplate for super node"`
@ -26,13 +30,43 @@ type SMCfg struct {
} `yaml:"Edge Node"`
}
type PMG struct {
type NMCfg struct {
ConfigOutputDir string `yaml:"Config output dir"`
EdgeConfigTemplate string `yaml:"ConfigTemplate for edge node"`
NetworkName string `yaml:"Network name"`
EdgeNodes []struct {
NodeID string `yaml:"Node ID"`
Endpoint string `yaml:"Endpoint(optional)"`
} `yaml:"Edge Nodes"`
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"`
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"
)
func printUsage() {
fmt.Printf("Usage: %s -s/c CONFIG-PATH\n", os.Args[0])
}
var (
tconfig = flag.String("config", "", "Config path for the interface.")
mode = flag.String("mode", "", "Running mode. [super|edge|solve|gencfg]")
@ -48,11 +44,11 @@ var (
func main() {
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)
return
}
if *help == true {
if *help {
flag.Usage()
return
}
@ -75,6 +71,8 @@ func main() {
switch *cfgmode {
case "super":
err = gencfg.GenSuperCfg(*tconfig, *printExample)
case "static":
err = gencfg.GenNMCfg(*tconfig, *printExample)
default:
err = fmt.Errorf("gencfg: generate config for %v mode are not implement", *cfgmode)
}
@ -83,14 +81,12 @@ func main() {
flag.Usage()
}
if err != nil {
switch err.(type) {
switch err := err.(type) {
case syscall.Errno:
errno, _ := err.(syscall.Errno)
os.Exit(int(errno))
os.Exit(int(err))
default:
fmt.Fprintf(os.Stderr, "Error :%v\n", err)
os.Exit(1)
}
}
return
}

View File

@ -27,7 +27,7 @@ import (
)
func printExampleEdgeConf() {
tconfig := gencfg.GetExampleEdgeConf("")
tconfig := gencfg.GetExampleEdgeConf("", true)
toprint, _ := yaml.Marshal(tconfig)
fmt.Print(string(toprint))
}
@ -110,10 +110,13 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
////////////////////////////////////////////////////
// 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
}
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)
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)
return err
}
the_device.NewPeer(pk, peerconf.NodeID, false)
the_device.NewPeer(pk, peerconf.NodeID, false, peerconf.PersistentKeepalive)
if peerconf.EndPoint != "" {
peer := the_device.LookupPeer(pk)
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)
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 {
return err
}
@ -179,7 +182,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
fmt.Println("Error decode base64 ", 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 {
return err
}
@ -192,7 +195,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
S6 = false
}
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{}{}
@ -229,7 +232,7 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
cmdarg, err := shlex.Split(econfig.PostScript)
if err != nil {
return fmt.Errorf("Error parse PostScript %v\n", err)
return fmt.Errorf("error parse PostScript %v", err)
}
if econfig.LogLevel.LogInternal {
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()
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 {
fmt.Printf("PostScript output: %s\n", string(out))

View File

@ -7,13 +7,11 @@ package main
import (
"crypto/md5"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"strconv"
"strings"
"sync"
@ -42,6 +40,7 @@ type http_shared_objects struct {
http_NhTableStr []byte
http_PeerInfo mtypes.API_Peers
http_super_chains *mtypes.SUPER_Events
http_pskdb device.PSKDB
http_passwords mtypes.Passwords
http_StateExpire time.Time
@ -92,15 +91,6 @@ type PeerState struct {
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) {
valA, has := params[key]
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) {
val, err := extractParamsUint(params, key, 16, w)
if err != nil {
return mtypes.BrokenMessage, err
return mtypes.NodeID_Invalid, err
}
return mtypes.Vertex(val), nil
}
@ -208,7 +198,7 @@ func edge_get_superparams(w http.ResponseWriter, r *http.Request) {
if err != nil {
return
}
if NodeID >= mtypes.Special_NodeID {
if NodeID >= mtypes.NodeID_Special {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Paramater NodeID: Can't use special nodeID."))
return
@ -227,7 +217,7 @@ func edge_get_superparams(w http.ResponseWriter, r *http.Request) {
return
}
if _, has := httpobj.http_PeerState[PubKey]; has == false {
if _, has := httpobj.http_PeerState[PubKey]; !has {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author."))
return
@ -250,7 +240,6 @@ func edge_get_superparams(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(SuperParamStr))
return
}
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 {
return
}
if NodeID >= mtypes.Special_NodeID {
if NodeID >= mtypes.NodeID_Special {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Paramater NodeID: Can't use special nodeID."))
return
@ -291,7 +280,7 @@ func edge_get_peerinfo(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Paramater State: State not correct"))
return
}
if _, has := httpobj.http_PeerState[PubKey]; has == false {
if _, has := httpobj.http_PeerState[PubKey]; !has {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author."))
return
@ -303,21 +292,11 @@ func edge_get_peerinfo(w http.ResponseWriter, r *http.Request) {
for PeerPubKey, peerinfo := range httpobj.http_PeerInfo {
if httpobj.http_sconfig.UsePSKForInterEdge {
h := sha256.New()
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 {
if NodeID == peerinfo.NodeID {
continue
}
h.Write(httpobj.http_HashSalt)
bs := h.Sum(nil)
var psk device.NoisePresharedKey
copy(psk[:], bs[:])
peerinfo.PSKey = psk.ToString()
PSK := httpobj.http_pskdb.GetPSK(NodeID, peerinfo.NodeID)
peerinfo.PSKey = PSK.ToString()
} else {
peerinfo.PSKey = ""
}
@ -332,7 +311,6 @@ func edge_get_peerinfo(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(api_peerinfo_str_byte)
return
}
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 {
return
}
if NodeID >= mtypes.Special_NodeID {
if NodeID >= mtypes.NodeID_Special {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Paramater NodeID: Can't use special nodeID."))
return
@ -373,7 +351,7 @@ func edge_get_nhtable(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Paramater State: State not correct"))
return
}
if _, has := httpobj.http_PeerState[PubKey]; has == false {
if _, has := httpobj.http_PeerState[PubKey]; !has {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Paramater PubKey: Not found in httpobj.http_PeerState, this shouldn't happen. Please report to the author."))
return
@ -383,7 +361,6 @@ func edge_get_nhtable(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(httpobj.http_NhTableStr))
return
}
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 {
return
}
if NodeID >= mtypes.Special_NodeID {
if NodeID >= mtypes.NodeID_Special {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("Paramater NodeID: Can't use special nodeID."))
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) {
// Don't forget to validate the alg is what you expect:
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)
return JWTSecretB[:], nil
@ -448,7 +425,7 @@ func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) {
}
if !token.Valid {
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
}
@ -471,7 +448,7 @@ func edge_post_nodeinfo(w http.ResponseWriter, r *http.Request) {
client_body, err = mtypes.GUzip(client_body)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(fmt.Sprintf("Request body: gzip unzip failed")))
w.Write([]byte("Request body: gzip unzip failed"))
return
}
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)
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf("OK")))
return
w.Write([]byte("OK"))
}
func checkPassword(s1 string, s2 string) bool {
@ -549,9 +525,9 @@ func manage_get_peerstate(w http.ResponseWriter, r *http.Request) {
if err != nil {
return
}
if checkPassword(password, httpobj.http_passwords.ShowState) == false {
if !checkPassword(password, httpobj.http_passwords.ShowState) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Wrong password"))
w.Write([]byte("Paramater Password: Wrong password"))
return
}
httpobj.RLock()
@ -560,7 +536,7 @@ func manage_get_peerstate(w http.ResponseWriter, r *http.Request) {
hs := HttpState{
PeerInfo: make(map[mtypes.Vertex]HttpPeerInfo),
NhTable: httpobj.http_graph.GetNHTable(false),
Infinity: path.Infinity,
Infinity: mtypes.Infinity,
Edges: httpobj.http_graph.GetEdges(false, false),
Edges_Nh: httpobj.http_graph.GetEdges(true, true),
Dist: httpobj.http_graph.GetDtst(),
@ -578,7 +554,6 @@ func manage_get_peerstate(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusOK)
w.Write(httpobj.http_StateString_tmp)
return
}
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 {
return
}
if checkPassword(password, httpobj.http_passwords.AddPeer) == false {
if !checkPassword(password, httpobj.http_passwords.AddPeer) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Wrong password"))
w.Write([]byte("Paramater Password: Wrong password"))
return
}
@ -620,7 +595,7 @@ func manage_peeradd(w http.ResponseWriter, r *http.Request) {
SkipLocalIP := strings.EqualFold(SkipLocalIPS, "true")
PSKey, err := extractParamsStr(r.Form, "PSKey", nil)
PSKey, _ := extractParamsStr(r.Form, "PSKey", nil)
httpobj.Lock()
defer httpobj.Unlock()
@ -642,7 +617,7 @@ func manage_peeradd(w http.ResponseWriter, r *http.Request) {
return
}
}
if httpobj.http_sconfig.GraphRecalculateSetting.StaticMode == true {
if httpobj.http_sconfig.GraphRecalculateSetting.StaticMode {
NhTableStr := r.Form.Get("NextHopTable")
if NhTableStr == "" {
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)
w.WriteHeader(http.StatusOK)
w.Write(ret_str_byte)
return
}
func manage_peerupdate(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
toUpdate := mtypes.Broadcast
toUpdate := mtypes.NodeID_Boardcast
var err error
var NodeID mtypes.Vertex
@ -719,7 +693,7 @@ func manage_peerupdate(w http.ResponseWriter, r *http.Request) {
if err != nil {
return
}
if checkPassword(password, httpobj.http_passwords.UpdatePeer) == false {
if !checkPassword(password, httpobj.http_passwords.UpdatePeer) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Paramater Password: Wrong password"))
return
@ -787,7 +761,6 @@ func manage_peerupdate(w http.ResponseWriter, r *http.Request) {
for k, v := range Updated_params {
w.Write([]byte(fmt.Sprintf("%v = %v\n", k, v)))
}
return
}
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 {
return
}
if checkPassword(password, httpobj.http_passwords.UpdateSuper) == false {
if !checkPassword(password, httpobj.http_passwords.UpdateSuper) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Paramater Password: Wrong password"))
return
@ -817,7 +790,7 @@ func manage_superupdate(w http.ResponseWriter, r *http.Request) {
if err == nil {
if PeerAliveTimeout <= 0 {
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
}
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 {
w.Write([]byte(fmt.Sprintf("%v = %v\n", k, v)))
}
return
}
func manage_peerdel(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
toDelete := mtypes.Broadcast
toDelete := mtypes.NodeID_Boardcast
var err error
var NodeID mtypes.Vertex
@ -928,7 +900,7 @@ func manage_peerdel(w http.ResponseWriter, r *http.Request) {
toDelete = peerinfo.NodeID
}
}
if toDelete == mtypes.Broadcast {
if toDelete == mtypes.NodeID_Boardcast {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(fmt.Sprintf("Paramater PrivKey: \"%v\" not found", PubKey)))
return
@ -949,7 +921,6 @@ func manage_peerdel(w http.ResponseWriter, r *http.Request) {
ioutil.WriteFile(httpobj.http_sconfig_path, mtypesBytes, 0644)
w.WriteHeader(http.StatusOK)
w.Write([]byte("NodeID: " + toDelete.ToString() + " deleted."))
return
}
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
if dst, has := NhTable[id1]; has {
if next, has2 := dst[id2]; has2 {
if _, hasa := allpeer[*next]; hasa {
if _, hasa := allpeer[next]; hasa {
} 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 {
return errors.New(fmt.Sprintf("NextHopTable[%v][%v] not found", id1, id2))
return fmt.Errorf("NextHopTable[%v][%v] not found", id1, id2)
}
} 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() {
sconfig := gencfg.GetExampleSuperConf("")
sconfig := gencfg.GetExampleSuperConf("", true)
scprint, _ := yaml.Marshal(sconfig)
fmt.Print(string(scprint))
}
@ -80,7 +80,7 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
return err
}
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
NodeName := sconfig.NodeName
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_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)
if sconfig.GraphRecalculateSetting.StaticMode {
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()
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()
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()
if 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
cmdarg, err := shlex.Split(sconfig.PostScript)
if err != nil {
return fmt.Errorf("Error parse PostScript %v\n", err)
return fmt.Errorf("error parse PostScript %v", err)
}
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:]...)
out, err := cmd.CombinedOutput()
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 {
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
pk, err := device.Str2PubKey(peerconf.PubKey)
if err != nil {
return fmt.Errorf("Error decode base64 :%v", err)
return fmt.Errorf("error decode base64 :%v", err)
}
if httpobj.http_sconfig.PrivKeyV4 != "" {
var psk device.NoisePresharedKey
if peerconf.PSKey != "" {
psk, err = device.Str2PSKey(peerconf.PSKey)
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 {
return fmt.Errorf("Error create peer id :%v", err)
return fmt.Errorf("error create peer id :%v", err)
}
peer4.StaticConn = false
if peerconf.PSKey != "" {
@ -265,12 +268,12 @@ func super_peeradd(peerconf mtypes.SuperPeerInfo) error {
if peerconf.PSKey != "" {
psk, err = device.Str2PSKey(peerconf.PSKey)
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 {
return fmt.Errorf("Error create peer id :%v", err)
return fmt.Errorf("error create peer id :%v", err)
}
peer6.StaticConn = false
if peerconf.PSKey != "" {
@ -310,6 +313,7 @@ func super_peerdel(toDelete mtypes.Vertex) {
return
}
PubKey := httpobj.http_PeerID2Info[toDelete].PubKey
httpobj.http_pskdb.DelNode(toDelete)
delete(httpobj.http_PeerState, PubKey)
delete(httpobj.http_PeerIPs, PubKey)
delete(httpobj.http_PeerID2Info, toDelete)
@ -327,7 +331,7 @@ func super_peerdel_notify(toDelete mtypes.Vertex, PubKey string) {
body, _ := mtypes.GetByte(&ServerUpdateMsg)
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetSrc(mtypes.SuperNodeMessage)
header.SetSrc(mtypes.NodeID_SuperNode)
header.SetTTL(0)
header.SetPacketLength(uint16(len(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
httpobj.RLock()
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].JETSecret.Store(reg_msg.JWTSecret)
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)
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)
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)
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:
var changed bool
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
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 {
if httpobj.http_graph.CheckAnyShouldUpdate() {
changed = httpobj.http_graph.RecalculateNhTable(true)
}
}
if changed {
NhTable := graph.GetNHTable(true)
@ -433,13 +436,13 @@ func RoutinePushSettings(interval time.Duration) {
func RoutineTimeoutCheck() {
for {
httpobj.http_super_chains.Event_server_register <- mtypes.RegisterMsg{
Node_id: mtypes.SuperNodeMessage,
Node_id: mtypes.NodeID_SuperNode,
Version: "dummy",
}
httpobj.http_super_chains.Event_server_pong <- mtypes.PongMsg{
RequestID: 0,
Src_nodeID: mtypes.SuperNodeMessage,
Dst_nodeID: mtypes.SuperNodeMessage,
Src_nodeID: mtypes.NodeID_SuperNode,
Dst_nodeID: mtypes.NodeID_SuperNode,
}
time.Sleep(httpobj.http_graph.TimeoutCheckInterval)
}
@ -448,7 +451,7 @@ func RoutineTimeoutCheck() {
func PushNhTable(force bool) {
// No lock
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
Node_id: mtypes.SuperNodeMessage,
Node_id: mtypes.NodeID_SuperNode,
Action: mtypes.UpdateNhTable,
Code: 0,
Params: string(httpobj.http_NhTable_Hash[:]),
@ -459,9 +462,9 @@ func PushNhTable(force bool) {
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage)
header.SetDst(mtypes.NodeID_SuperNode)
header.SetPacketLength(uint16(len(body)))
header.SetSrc(mtypes.SuperNodeMessage)
header.SetSrc(mtypes.NodeID_SuperNode)
header.SetTTL(0)
copy(buf[path.EgHeaderLen:], body)
for pkstr, peerstate := range httpobj.http_PeerState {
@ -483,7 +486,7 @@ func PushNhTable(force bool) {
func PushPeerinfo(force bool) {
//No lock
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
Node_id: mtypes.SuperNodeMessage,
Node_id: mtypes.NodeID_SuperNode,
Action: mtypes.UpdatePeer,
Code: 0,
Params: string(httpobj.http_PeerInfo_hash[:]),
@ -494,9 +497,9 @@ func PushPeerinfo(force bool) {
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage)
header.SetDst(mtypes.NodeID_SuperNode)
header.SetPacketLength(uint16(len(body)))
header.SetSrc(mtypes.SuperNodeMessage)
header.SetSrc(mtypes.NodeID_SuperNode)
header.SetTTL(0)
copy(buf[path.EgHeaderLen:], body)
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) {
body, err := mtypes.GetByte(mtypes.ServerUpdateMsg{
Node_id: mtypes.SuperNodeMessage,
Node_id: mtypes.NodeID_SuperNode,
Action: mtypes.UpdateSuperParams,
Code: 0,
Params: peerstate.SuperParamState.Load().(string),
@ -536,9 +539,9 @@ func PushServerParams(force bool) {
}
buf := make([]byte, path.EgHeaderLen+len(body))
header, _ := path.NewEgHeader(buf[:path.EgHeaderLen])
header.SetDst(mtypes.SuperNodeMessage)
header.SetDst(mtypes.NodeID_SuperNode)
header.SetPacketLength(uint16(len(body)))
header.SetSrc(mtypes.SuperNodeMessage)
header.SetSrc(mtypes.NodeID_SuperNode)
header.SetTTL(0)
copy(buf[path.EgHeaderLen:], body)

View File

@ -10,11 +10,11 @@ import (
type Vertex uint16
const (
Broadcast 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
SuperNodeMessage Vertex = math.MaxUint16 - iota
BrokenMessage Vertex = math.MaxUint16 - iota
Special_NodeID Vertex = BrokenMessage
NodeID_Boardcast Vertex = math.MaxUint16 - iota // Normal boardcast, boardcast with route table
NodeID_AllPeer Vertex = math.MaxUint16 - iota // p2p mode: boardcast to every know peer and prevent dup. super mode: send to supernode
NodeID_SuperNode Vertex = math.MaxUint16 - iota
NodeID_Invalid Vertex = math.MaxUint16 - iota
NodeID_Special Vertex = NodeID_Invalid
)
type EdgeConfig struct {
@ -83,6 +83,7 @@ type PeerInfo struct {
PubKey string `yaml:"PubKey"`
PSKey string `yaml:"PSKey"`
EndPoint string `yaml:"EndPoint"`
PersistentKeepalive uint32 `yaml:"PersistentKeepalive"`
Static bool `yaml:"Static"`
}
@ -106,11 +107,11 @@ type LoggerInfo struct {
func (v *Vertex) ToString() string {
switch *v {
case Broadcast:
case NodeID_Boardcast:
return "Boardcast"
case ControlMessage:
case NodeID_AllPeer:
return "Control"
case SuperNodeMessage:
case NodeID_SuperNode:
return "Super"
default:
return strconv.Itoa(int(*v))
@ -158,6 +159,7 @@ type P2PInfo struct {
type GraphRecalculateSetting struct {
StaticMode bool `yaml:"StaticMode"`
ManualLatency DistTable `yaml:"ManualLatency"`
JitterTolerance float64 `yaml:"JitterTolerance"`
JitterToleranceMultiplier float64 `yaml:"JitterToleranceMultiplier"`
DampingResistance float64 `yaml:"DampingResistance"`
@ -166,7 +168,7 @@ type GraphRecalculateSetting struct {
}
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 {
ExternalV4 map[string]float64

View File

@ -7,6 +7,7 @@ import (
"fmt"
"io/ioutil"
nonSecureRand "math/rand"
"strconv"
"time"
"gopkg.in/yaml.v2"
@ -16,6 +17,18 @@ func S2TD(secs float64) time.Duration {
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) {
bytes := RandomBytes(length, []byte(defaults))

View File

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

View File

@ -34,7 +34,7 @@ const (
func NewEgHeader(pac []byte) (e EgHeader, err error) {
if len(pac) != EgHeaderLen {
err = errors.New("Invalid packet size")
err = errors.New("invalid packet size")
return
}
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() {
if !g.ntp_info.UseNTP {
return
@ -80,7 +75,7 @@ func (g *IG) SyncTimeMultiple(count int) {
results := make([]time.Duration, count)
for _, url := range g.ntp_servers.Keys() {
val, has := g.ntp_servers.Get(url)
if has == false {
if !has {
continue
}
result := val.(ntp.Response)

View File

@ -5,7 +5,6 @@ import (
"fmt"
"io/ioutil"
"math"
"strconv"
"strings"
"sync"
"time"
@ -15,8 +14,6 @@ import (
yaml "gopkg.in/yaml.v2"
)
const Infinity = float64(99999)
func (g *IG) GetCurrentTime() time.Time {
return time.Now().Add(g.ntp_offset).Round(0)
}
@ -38,10 +35,7 @@ type IG struct {
Vert map[mtypes.Vertex]bool
edges map[mtypes.Vertex]map[mtypes.Vertex]*Latency
edgelock *sync.RWMutex
StaticMode bool
JitterTolerance float64
JitterToleranceMultiplier float64
DampingResistance float64
gsetting mtypes.GraphRecalculateSetting
SuperNodeInfoTimeout time.Duration
RecalculateCoolDown time.Duration
TimeoutCheckInterval time.Duration
@ -59,13 +53,10 @@ type IG struct {
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{
edgelock: &sync.RWMutex{},
StaticMode: theconfig.StaticMode,
JitterTolerance: theconfig.JitterTolerance,
JitterToleranceMultiplier: theconfig.JitterToleranceMultiplier,
DampingResistance: theconfig.DampingResistance,
gsetting: theconfig,
RecalculateCoolDown: mtypes.S2TD(theconfig.RecalculateCoolDown),
TimeoutCheckInterval: mtypes.S2TD(theconfig.TimeoutCheckInterval),
ntp_info: ntpinfo,
@ -74,30 +65,41 @@ func NewGraph(num_node int, IsSuperMode bool, theconfig mtypes.GraphRecalculateS
g.edges = make(map[mtypes.Vertex]map[mtypes.Vertex]*Latency, num_node)
g.IsSuperMode = IsSuperMode
g.loglevel = loglevel
if theconfig.DampingResistance < 0 || theconfig.DampingResistance >= 1 {
return nil, fmt.Errorf("DampingResistance must in range [0,1)")
}
g.InitNTP()
return &g
return &g, nil
}
func (g *IG) GetWeightType(x float64) (y float64) {
x = math.Abs(x)
y = x
if g.JitterTolerance > 0.001 && g.JitterToleranceMultiplier > 1 {
t := g.JitterTolerance
r := g.JitterToleranceMultiplier
if g.gsetting.JitterTolerance > 0.001 && g.gsetting.JitterToleranceMultiplier > 1 {
t := g.gsetting.JitterTolerance
r := g.gsetting.JitterToleranceMultiplier
y = math.Pow(math.Ceil(math.Pow(x/t, 1/r)), r) * t
}
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)
newval = math.Abs(newval * 1000)
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)
x := math.Max(oldval, newval)
t := g.JitterTolerance
r := g.JitterToleranceMultiplier
t := g.gsetting.JitterTolerance
r := g.gsetting.JitterToleranceMultiplier
return diff > t+x*(r-1) // https://www.desmos.com/calculator/raoti16r5n
}
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()
for u, _ := range vert {
for v, _ := range vert {
for u := range vert {
for v := range vert {
if u != v {
newVal := g.Weight(u, v, false)
oldVal := g.OldWeight(u, v, false)
if g.ShouldUpdate(oldVal, newVal) {
if g.ShouldUpdate(oldVal, newVal, withCooldown) {
return true
}
}
@ -123,16 +125,16 @@ func (g *IG) CheckAnyShouldUpdate() bool {
}
func (g *IG) RecalculateNhTable(checkchange bool) (changed bool) {
if g.StaticMode {
if g.gsetting.StaticMode {
if g.changed {
changed = checkchange
}
return
}
if !g.CheckAnyShouldUpdate() {
if !g.CheckAnyShouldUpdate(true) {
return
}
if g.recalculateTime.Add(g.RecalculateCoolDown).Before(time.Now()) {
dist, next, _ := g.FloydWarshall(false)
changed = false
if checkchange {
@ -149,7 +151,7 @@ func (g *IG) RecalculateNhTable(checkchange bool) (changed bool) {
}
g.dlTable, g.nhTable = dist, next
g.recalculateTime = time.Now()
}
return
}
@ -157,7 +159,7 @@ func (g *IG) RemoveVirt(v mtypes.Vertex, recalculate bool, checkchange bool) (ch
g.edgelock.Lock()
delete(g.Vert, v)
delete(g.edges, v)
for u, _ := range g.edges {
for u := range g.edges {
delete(g.edges[u], v)
}
g.edgelock.Unlock()
@ -184,8 +186,13 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
for _, pong_msg := range pong_info {
u := pong_msg.Src_nodeID
v := pong_msg.Dst_nodeID
w_in := pong_msg.Timediff
w := w_in
newval := pong_msg.Timediff
if _, ok := g.gsetting.ManualLatency[u]; ok {
if _, ok := g.gsetting.ManualLatency[u][v]; ok {
newval = g.gsetting.ManualLatency[u][v]
}
}
w := newval
additionalCost := pong_msg.AdditionalCost
if additionalCost < 0 {
additionalCost = 0
@ -199,10 +206,10 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
g.edgelock.Unlock()
oldval := g.OldWeight(u, v, false)
g.edgelock.Lock()
if oldval != Infinity {
w = oldval*g.DampingResistance + w_in*(1-g.DampingResistance)
if oldval != mtypes.Infinity {
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 {
g.edges[u][v].ping = w
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 {
g.edges[u][v] = &Latency{
ping: w,
ping_old: Infinity,
ping_old: mtypes.Infinity,
validUntil: time.Now().Add(mtypes.S2TD(pong_msg.TimeToAlive)),
additionalCost: additionalCost / 1000,
}
@ -231,7 +238,7 @@ func (g *IG) Vertices() map[mtypes.Vertex]bool {
}
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()
defer g.edgelock.RUnlock()
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
}
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 {
return nil
return mtypes.NodeID_Invalid
}
if _, ok := g.nhTable[u][v]; !ok {
return nil
return mtypes.NodeID_Invalid
}
return g.nhTable[u][v]
}
@ -258,20 +265,20 @@ func (g *IG) Weight(u, v mtypes.Vertex, withAC bool) (ret float64) {
return 0
}
if _, ok := g.edges[u]; !ok {
return Infinity
return mtypes.Infinity
}
if _, ok := g.edges[u][v]; !ok {
return Infinity
return mtypes.Infinity
}
if time.Now().After(g.edges[u][v].validUntil) {
return Infinity
return mtypes.Infinity
}
ret = g.edges[u][v].ping
if withAC {
ret += g.edges[u][v].additionalCost
}
if ret >= Infinity {
return Infinity
if ret >= mtypes.Infinity {
return mtypes.Infinity
}
return
}
@ -283,17 +290,17 @@ func (g *IG) OldWeight(u, v mtypes.Vertex, withAC bool) (ret float64) {
return 0
}
if _, ok := g.edges[u]; !ok {
return Infinity
return mtypes.Infinity
}
if _, ok := g.edges[u][v]; !ok {
return Infinity
return mtypes.Infinity
}
ret = g.edges[u][v].ping_old
if withAC {
ret += g.edges[u][v].additionalCost
}
if ret >= Infinity {
return Infinity
if ret >= mtypes.Infinity {
return mtypes.Infinity
}
return
}
@ -324,8 +331,8 @@ func (g *IG) SetOldWeight(u, v mtypes.Vertex, weight float64) {
func (g *IG) RemoveAllNegativeValue() {
vert := g.Vertices()
for u, _ := range vert {
for v, _ := range vert {
for u := range vert {
for v := range vert {
if g.Weight(u, v, true) < 0 {
if g.loglevel.LogInternal {
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()
dist = make(mtypes.DistTable)
next = make(mtypes.NextHopTable)
for u, _ := range vert {
for u := range vert {
dist[u] = make(map[mtypes.Vertex]float64)
next[u] = make(map[mtypes.Vertex]*mtypes.Vertex)
for v, _ := range vert {
dist[u][v] = Infinity
next[u] = make(map[mtypes.Vertex]mtypes.Vertex)
for v := range vert {
dist[u][v] = mtypes.Infinity
}
dist[u][u] = 0
for _, v := range g.Neighbors(u) {
w := g.Weight(u, v, true)
wo := g.Weight(u, v, false)
if w < Infinity {
if w < mtypes.Infinity {
v := v
dist[u][v] = w
next[u][v] = &v
next[u][v] = v
}
g.SetOldWeight(u, v, wo)
}
}
for k, _ := range vert {
for i, _ := range vert {
for j, _ := range vert {
if dist[i][k] < Infinity && dist[k][j] < Infinity {
for k := range vert {
for i := range vert {
for j := range vert {
if dist[i][k] < mtypes.Infinity && dist[k][j] < mtypes.Infinity {
if dist[i][j] > dist[i][k]+dist[k][j] {
dist[i][j] = dist[i][k] + dist[k][j]
next[i][j] = next[i][k]
@ -391,7 +398,7 @@ func (g *IG) FloydWarshall(again bool) (dist mtypes.DistTable, next mtypes.NextH
} else {
dist = make(mtypes.DistTable)
next = make(mtypes.NextHopTable)
err = errors.New("negative cycle detected again!")
err = errors.New("negative cycle detected again")
if g.loglevel.LogInternal {
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
}
func Path(u, v mtypes.Vertex, next mtypes.NextHopTable) (path []mtypes.Vertex) {
if next[u][v] == nil {
return []mtypes.Vertex{}
}
path = []mtypes.Vertex{u}
func (g *IG) Path(u, v mtypes.Vertex) (path []mtypes.Vertex, err error) {
g.edgelock.RLock()
defer g.edgelock.RUnlock()
footprint := make(map[mtypes.Vertex]bool)
for u != v {
u = *next[u][v]
path = append(path, u)
if _, has := footprint[u]; has {
return path, fmt.Errorf("cycle detected in nhTable, s:%v e:%v path:%v", u, v, path)
}
return 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)
footprint[u] = true
u = g.nhTable[u][v]
}
path = append(path, u)
return path, nil
}
func (g *IG) SetNHTable(nh mtypes.NextHopTable) { // set nhTable from supernode
g.edgelock.Lock()
defer g.edgelock.Unlock()
g.nhTable = nh
g.changed = true
g.NhTableExpire = time.Now().Add(g.SuperNodeInfoTimeout)
g.edgelock.Unlock()
}
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) {
vert := g.Vertices()
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))
for dst, _ := range vert {
for dst := range vert {
if src != dst {
if isOld {
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) {
tosend = make(map[mtypes.Vertex]bool)
for _, element := range g.nhTable[id] {
tosend[*element] = true
tosend[element] = true
}
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)
for check_id, _ := range g.GetBoardcastList(self_id) {
for _, path_node := range Path(src_id, check_id, g.nhTable) {
for check_id := range g.GetBoardcastList(self_id) {
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 {
tosend[check_id] = true
continue
@ -482,23 +504,39 @@ func printExample() {
6 Inf Inf Inf 0.5 Inf 0`)
}
func a2n(s string) (ret float64) {
if s == "Inf" {
return Infinity
}
ret, err := strconv.ParseFloat(s, 64)
func ParseDistanceMatrix(input string) ([]mtypes.PongMsg, error) {
lines := strings.Split(input, "\n")
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 {
panic(err)
return ret, err
}
return
}
func a2v(s string) mtypes.Vertex {
ret, err := strconv.ParseUint(s, 10, 16)
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 {
panic(err)
return ret, err
}
return mtypes.Vertex(ret)
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,
})
}
}
}
return ret, nil
}
func Solve(filePath string, pe bool) error {
@ -507,26 +545,15 @@ func Solve(filePath string, pe bool) error {
return nil
}
g := NewGraph(3, false, mtypes.GraphRecalculateSetting{}, mtypes.NTPInfo{}, mtypes.LoggerInfo{LogInternal: true})
g, _ := NewGraph(3, false, mtypes.GraphRecalculateSetting{}, mtypes.NTPInfo{}, mtypes.LoggerInfo{LogInternal: false})
inputb, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}
input := string(inputb)
lines := strings.Split(input, "\n")
verts := strings.Fields(lines[0])
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)
}
}
}
all_edge, _ := ParseDistanceMatrix(input)
g.UpdateLatencyMulti(all_edge, false, false)
dist, next, err := g.FloydWarshall(false)
if err != nil {
fmt.Println("Error:", err)
@ -540,12 +567,16 @@ func Solve(filePath string, pe bool) error {
fmt.Println("\nHuman readable:")
fmt.Println("src\tdist\t\tpath")
for _, U := range verts[1:] {
u := a2v(U)
for _, V := range verts[1:] {
v := a2v(V)
all_vert := g.Vertices()
for u := range all_vert {
for v := range all_vert {
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)
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 {
case KeyboardDebug:
src := Mac2charForm(packet[6:12])

View File

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