Path solver and beta release

This commit is contained in:
KusakabeSi
2021-08-25 13:21:26 +00:00
parent f8fe962f6a
commit 4443b8bddf
8 changed files with 118 additions and 48 deletions

2
.vscode/launch.json vendored
View File

@@ -11,7 +11,7 @@
"mode": "auto", "mode": "auto",
"program": "${workspaceFolder}", "program": "${workspaceFolder}",
"env": {"CGO_CFLAGS":"-I/usr/include/memif"}, "env": {"CGO_CFLAGS":"-I/usr/include/memif"},
"args":["-config","example_config/super_mode/n1.yaml","-mode","edge"/*,"-example"*/], "args":["-config","example_config/static_mode/path.txt","-mode","solve"/*,"-example"*/],
} }
] ]
} }

View File

@@ -1,9 +1,16 @@
### Build ### Requirement
```
Install VPP and Go
```bash
echo "deb [trusted=yes] https://packagecloud.io/fdio/release/ubuntu focal main" > /etc/apt/sources.list.d/99fd.io.list echo "deb [trusted=yes] https://packagecloud.io/fdio/release/ubuntu focal main" > /etc/apt/sources.list.d/99fd.io.list
curl -L https://packagecloud.io/fdio/release/gpgkey | sudo apt-key add - curl -L https://packagecloud.io/fdio/release/gpgkey | sudo apt-key add -
apt-get update add-apt-repository ppa:longsleep/golang-backports
apt-get install vpp vpp-plugin-core python3-vpp-api vpp-dbg vpp-dev libmemif libmemif-dev wireguard-tools apt-get -y update
apt-get install vpp vpp-plugin-core python3-vpp-api vpp-dbg vpp-dev libmemif libmemif-dev wireguard-tools golang-go build-essential golang-go
```
### Build
```bash
export CGO_CFLAGS="-I/usr/include/memif" export CGO_CFLAGS="-I/usr/include/memif"
make make
``` ```

View File

@@ -213,7 +213,7 @@ func (device *Device) process_ping(content path.PingMsg) error {
Timediff: device.graph.GetCurrentTime().Sub(content.Time), Timediff: device.graph.GetCurrentTime().Sub(content.Time),
} }
if device.DRoute.P2P.UseP2P && time.Now().After(device.graph.NhTableExpire) { if device.DRoute.P2P.UseP2P && time.Now().After(device.graph.NhTableExpire) {
device.graph.UpdateLentancy(content.Src_nodeID, device.ID, PongMSG.Timediff, false) device.graph.UpdateLentancy(content.Src_nodeID, device.ID, PongMSG.Timediff, true, false)
} }
body, err := path.GetByte(&PongMSG) body, err := path.GetByte(&PongMSG)
if err != nil { if err != nil {
@@ -240,7 +240,7 @@ func (device *Device) process_ping(content path.PingMsg) error {
func (device *Device) process_pong(peer *Peer, content path.PongMsg) error { func (device *Device) process_pong(peer *Peer, content path.PongMsg) error {
if device.DRoute.P2P.UseP2P { if device.DRoute.P2P.UseP2P {
if time.Now().After(device.graph.NhTableExpire) { if time.Now().After(device.graph.NhTableExpire) {
device.graph.UpdateLentancy(content.Src_nodeID, content.Dst_nodeID, content.Timediff, false) device.graph.UpdateLentancy(content.Src_nodeID, content.Dst_nodeID, content.Timediff, true, false)
} }
if !peer.AskedForNeighbor { if !peer.AskedForNeighbor {
QueryPeerMsg := path.QueryPeerMsg{ QueryPeerMsg := path.QueryPeerMsg{
@@ -314,10 +314,10 @@ func (device *Device) process_UpdatePeerMsg(content path.UpdatePeerMsg) error {
fmt.Println("Control: Add new peer to local ID:" + peerinfo.NodeID.ToString() + " PubKey:" + pubkey) fmt.Println("Control: Add new peer to local ID:" + peerinfo.NodeID.ToString() + " PubKey:" + pubkey)
} }
if device.graph.Weight(device.ID, peerinfo.NodeID) == path.Infinity { // add node to graph if device.graph.Weight(device.ID, peerinfo.NodeID) == path.Infinity { // add node to graph
device.graph.UpdateLentancy(device.ID, peerinfo.NodeID, path.S2TD(path.Infinity), false) device.graph.UpdateLentancy(device.ID, peerinfo.NodeID, path.S2TD(path.Infinity), true, false)
} }
if device.graph.Weight(peerinfo.NodeID, device.ID) == path.Infinity { // add node to graph if device.graph.Weight(peerinfo.NodeID, device.ID) == path.Infinity { // add node to graph
device.graph.UpdateLentancy(peerinfo.NodeID, device.ID, path.S2TD(path.Infinity), false) device.graph.UpdateLentancy(peerinfo.NodeID, device.ID, path.S2TD(path.Infinity), true, false)
} }
device.NewPeer(sk, peerinfo.NodeID) device.NewPeer(sk, peerinfo.NodeID)
thepeer = device.LookupPeer(sk) thepeer = device.LookupPeer(sk)
@@ -614,10 +614,10 @@ func (device *Device) process_BoardcastPeerMsg(peer *Peer, content path.Boardcas
fmt.Println("Control: Add new peer to local ID:" + content.NodeID.ToString() + " PubKey:" + base64.StdEncoding.EncodeToString(content.PubKey[:])) fmt.Println("Control: Add new peer to local ID:" + content.NodeID.ToString() + " PubKey:" + base64.StdEncoding.EncodeToString(content.PubKey[:]))
} }
if device.graph.Weight(device.ID, content.NodeID) == path.Infinity { // add node to graph if device.graph.Weight(device.ID, content.NodeID) == path.Infinity { // add node to graph
device.graph.UpdateLentancy(device.ID, content.NodeID, path.S2TD(path.Infinity), false) device.graph.UpdateLentancy(device.ID, content.NodeID, path.S2TD(path.Infinity), true, false)
} }
if device.graph.Weight(content.NodeID, device.ID) == path.Infinity { // add node to graph if device.graph.Weight(content.NodeID, device.ID) == path.Infinity { // add node to graph
device.graph.UpdateLentancy(content.NodeID, device.ID, path.S2TD(path.Infinity), false) device.graph.UpdateLentancy(content.NodeID, device.ID, path.S2TD(path.Infinity), true, false)
} }
device.NewPeer(sk, content.NodeID) device.NewPeer(sk, content.NodeID)
thepeer = device.LookupPeer(sk) thepeer = device.LookupPeer(sk)

View File

@@ -0,0 +1,7 @@
X 1 2 3 4 5 6
1 0 0.5 Inf Inf Inf Inf
2 0.5 0 0.5 0.5 Inf Inf
3 Inf 0.5 0 0.5 0.5 Inf
4 Inf 0.5 0.5 0 Inf 0.5
5 Inf Inf 0.5 Inf 0 Inf
6 Inf Inf Inf 0.5 Inf 0

View File

@@ -44,7 +44,7 @@ func readYaml(filePath string, out interface{}) (err error) {
var ( var (
tconfig = flag.String("config", "", "Config path for the interface.") tconfig = flag.String("config", "", "Config path for the interface.")
mode = flag.String("mode", "edge", "Running mode. [super|edge]") mode = flag.String("mode", "", "Running mode. [super|edge|solve]")
printExample = flag.Bool("example", false, "Print example config") printExample = flag.Bool("example", false, "Print example config")
nouapi = flag.Bool("no-uapi", false, "Do not use UAPI") nouapi = flag.Bool("no-uapi", false, "Do not use UAPI")
version = flag.Bool("version", false, "Show version") version = flag.Bool("version", false, "Show version")
@@ -73,8 +73,8 @@ func main() {
err = Edge(*tconfig, !*nouapi, *printExample) err = Edge(*tconfig, !*nouapi, *printExample)
case "super": case "super":
err = Super(*tconfig, !*nouapi, *printExample) err = Super(*tconfig, !*nouapi, *printExample)
case "path": case "solve":
path.Solve() err = path.Solve(*tconfig, *printExample)
default: default:
flag.Usage() flag.Usage()
} }

View File

@@ -108,18 +108,18 @@ func printExampleEdgeConf() {
} }
g := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting, tconfig.DynamicRoute.NTPconfig, false) g := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting, tconfig.DynamicRoute.NTPconfig, false)
g.UpdateLentancy(1, 2, path.S2TD(0.5), false) g.UpdateLentancy(1, 2, path.S2TD(0.5), false,false)
g.UpdateLentancy(2, 1, path.S2TD(0.5), false) g.UpdateLentancy(2, 1, path.S2TD(0.5), false,false)
g.UpdateLentancy(2, 3, path.S2TD(0.5), false) g.UpdateLentancy(2, 3, path.S2TD(0.5), false,false)
g.UpdateLentancy(3, 2, path.S2TD(0.5), false) g.UpdateLentancy(3, 2, path.S2TD(0.5), false,false)
g.UpdateLentancy(2, 4, path.S2TD(0.5), false) g.UpdateLentancy(2, 4, path.S2TD(0.5), false,false)
g.UpdateLentancy(4, 2, path.S2TD(0.5), false) g.UpdateLentancy(4, 2, path.S2TD(0.5), false,false)
g.UpdateLentancy(3, 4, path.S2TD(0.5), false) g.UpdateLentancy(3, 4, path.S2TD(0.5), false,false)
g.UpdateLentancy(4, 3, path.S2TD(0.5), false) g.UpdateLentancy(4, 3, path.S2TD(0.5), false,false)
g.UpdateLentancy(5, 3, path.S2TD(0.5), false) g.UpdateLentancy(5, 3, path.S2TD(0.5), false,false)
g.UpdateLentancy(3, 5, path.S2TD(0.5), false) g.UpdateLentancy(3, 5, path.S2TD(0.5), false,false)
g.UpdateLentancy(6, 4, path.S2TD(0.5), false) g.UpdateLentancy(6, 4, path.S2TD(0.5), false,false)
g.UpdateLentancy(4, 6, path.S2TD(0.5), false) g.UpdateLentancy(4, 6, path.S2TD(0.5), false,false)
_, next := path.FloydWarshall(g) _, next := path.FloydWarshall(g)
tconfig.NextHopTable = next tconfig.NextHopTable = next
toprint, _ := yaml.Marshal(tconfig) toprint, _ := yaml.Marshal(tconfig)

View File

@@ -252,7 +252,7 @@ func Event_server_event_hendler(graph *path.IG, events path.SUPER_Events) {
http_NhTableStr = NhTablestr http_NhTableStr = NhTablestr
PushUpdate() PushUpdate()
case pong_msg := <-events.Event_server_pong: case pong_msg := <-events.Event_server_pong:
changed := graph.UpdateLentancy(pong_msg.Src_nodeID, pong_msg.Dst_nodeID, pong_msg.Timediff, true) changed := graph.UpdateLentancy(pong_msg.Src_nodeID, pong_msg.Dst_nodeID, pong_msg.Timediff, true, true)
if changed { if changed {
NhTable := graph.GetNHTable(false) NhTable := graph.GetNHTable(false)
NhTablestr, _ := json.Marshal(NhTable) NhTablestr, _ := json.Marshal(NhTable)

View File

@@ -2,7 +2,10 @@ package path
import ( import (
"fmt" "fmt"
"io/ioutil"
"math" "math"
"strconv"
"strings"
"sync" "sync"
"time" "time"
@@ -31,8 +34,8 @@ type Latency struct {
} }
type Fullroute struct { type Fullroute struct {
Dist config.DistTable `json:"total distance"` Next config.NextHopTable `yaml:"NextHopTable"`
Next config.NextHopTable `json:"next hop"` Dist config.DistTable `yaml:"DistanceTable"`
} }
// IG is a graph of integers that satisfies the Graph interface. // IG is a graph of integers that satisfies the Graph interface.
@@ -104,7 +107,7 @@ func (g *IG) ShouldUpdate(u config.Vertex, v config.Vertex, newval float64) bool
} }
return oldval == newval return oldval == newval
} else { } else {
return g.GetWeightType(oldval) == g.GetWeightType(newval) return g.GetWeightType(oldval) != g.GetWeightType(newval)
} }
} }
@@ -131,7 +134,7 @@ func (g *IG) RecalculateNhTable(checkchange bool) (changed bool) {
return return
} }
func (g *IG) UpdateLentancy(u, v config.Vertex, dt time.Duration, checkchange bool) (changed bool) { func (g *IG) UpdateLentancy(u, v config.Vertex, dt time.Duration, recalculate bool, checkchange bool) (changed bool) {
g.edgelock.Lock() g.edgelock.Lock()
g.Vert[u] = true g.Vert[u] = true
g.Vert[v] = true g.Vert[v] = true
@@ -144,7 +147,7 @@ func (g *IG) UpdateLentancy(u, v config.Vertex, dt time.Duration, checkchange bo
time: time.Now(), time: time.Now(),
} }
g.edgelock.Unlock() g.edgelock.Unlock()
if g.ShouldUpdate(u, v, w) { if g.ShouldUpdate(u, v, w) && recalculate {
changed = g.RecalculateNhTable(checkchange) changed = g.RecalculateNhTable(checkchange)
} }
return return
@@ -296,28 +299,81 @@ func (g *IG) GetBoardcastThroughList(self_id config.Vertex, in_id config.Vertex,
return return
} }
func Solve() { func printExample() {
var g IG fmt.Println(`X 1 2 3 4 5 6
//g.Init() 1 0 0.5 Inf Inf Inf Inf
g.UpdateLentancy(1, 2, S2TD(0.5), false) 2 0.5 0 0.5 0.5 Inf Inf
g.UpdateLentancy(2, 1, S2TD(0.5), false) 3 Inf 0.5 0 0.5 0.5 Inf
g.UpdateLentancy(2, 3, S2TD(2), false) 4 Inf 0.5 0.5 0 Inf 0.5
g.UpdateLentancy(3, 2, S2TD(2), false) 5 Inf Inf 0.5 Inf 0 Inf
g.UpdateLentancy(2, 4, S2TD(0.7), false) 6 Inf Inf Inf 0.5 Inf 0`)
g.UpdateLentancy(4, 2, S2TD(2), false) }
dist, next := FloydWarshall(g)
fmt.Println("pair\tdist\tpath") func a2n(s string) (ret float64) {
for u, m := range dist { if s == "Inf" {
for v, d := range m { return Infinity
if u != v { }
fmt.Printf("%d -> %d\t%3f\t%s\n", u, v, d, fmt.Sprint(Path(u, v, next))) ret, err := strconv.ParseFloat(s, 64)
if err != nil {
panic(err)
}
return
}
func a2v(s string) config.Vertex {
ret, err := strconv.Atoi(s)
if err != nil {
panic(err)
}
return config.Vertex(ret)
}
func Solve(filePath string, pe bool) error {
if pe {
printExample()
return nil
}
g := NewGraph(3, false, config.GraphRecalculateSetting{
NodeReportTimeout: 9999,
}, config.NTPinfo{}, 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.UpdateLentancy(src, dst, S2TD(val), false, false)
} }
} }
} }
fmt.Print("Finish") dist, next := FloydWarshall(g)
rr, _ := yaml.Marshal(Fullroute{ rr, _ := yaml.Marshal(Fullroute{
Dist: dist, Dist: dist,
Next: next, Next: next,
}) })
fmt.Print(string(rr)) fmt.Print(string(rr))
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)
if u != v {
fmt.Printf("%d -> %d\t%3f\t%s\n", u, v, dist[u][v], fmt.Sprint(Path(u, v, next)))
}
}
}
return nil
} }