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",
"program": "${workspaceFolder}",
"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
curl -L https://packagecloud.io/fdio/release/gpgkey | sudo apt-key add -
apt-get update
apt-get install vpp vpp-plugin-core python3-vpp-api vpp-dbg vpp-dev libmemif libmemif-dev wireguard-tools
add-apt-repository ppa:longsleep/golang-backports
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"
make
```

View File

@ -213,7 +213,7 @@ func (device *Device) process_ping(content path.PingMsg) error {
Timediff: device.graph.GetCurrentTime().Sub(content.Time),
}
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)
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 {
if device.DRoute.P2P.UseP2P {
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 {
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)
}
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
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)
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[:]))
}
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
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)
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 (
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")
nouapi = flag.Bool("no-uapi", false, "Do not use UAPI")
version = flag.Bool("version", false, "Show version")
@ -73,8 +73,8 @@ func main() {
err = Edge(*tconfig, !*nouapi, *printExample)
case "super":
err = Super(*tconfig, !*nouapi, *printExample)
case "path":
path.Solve()
case "solve":
err = path.Solve(*tconfig, *printExample)
default:
flag.Usage()
}

View File

@ -108,18 +108,18 @@ func printExampleEdgeConf() {
}
g := path.NewGraph(3, false, tconfig.DynamicRoute.P2P.GraphRecalculateSetting, tconfig.DynamicRoute.NTPconfig, false)
g.UpdateLentancy(1, 2, path.S2TD(0.5), false)
g.UpdateLentancy(2, 1, path.S2TD(0.5), false)
g.UpdateLentancy(2, 3, path.S2TD(0.5), false)
g.UpdateLentancy(3, 2, path.S2TD(0.5), false)
g.UpdateLentancy(2, 4, path.S2TD(0.5), false)
g.UpdateLentancy(4, 2, path.S2TD(0.5), false)
g.UpdateLentancy(3, 4, path.S2TD(0.5), false)
g.UpdateLentancy(4, 3, path.S2TD(0.5), false)
g.UpdateLentancy(5, 3, path.S2TD(0.5), false)
g.UpdateLentancy(3, 5, path.S2TD(0.5), false)
g.UpdateLentancy(6, 4, path.S2TD(0.5), false)
g.UpdateLentancy(4, 6, path.S2TD(0.5), false)
g.UpdateLentancy(1, 2, path.S2TD(0.5), false,false)
g.UpdateLentancy(2, 1, path.S2TD(0.5), false,false)
g.UpdateLentancy(2, 3, path.S2TD(0.5), false,false)
g.UpdateLentancy(3, 2, path.S2TD(0.5), false,false)
g.UpdateLentancy(2, 4, path.S2TD(0.5), false,false)
g.UpdateLentancy(4, 2, path.S2TD(0.5), false,false)
g.UpdateLentancy(3, 4, path.S2TD(0.5), false,false)
g.UpdateLentancy(4, 3, path.S2TD(0.5), false,false)
g.UpdateLentancy(5, 3, path.S2TD(0.5), false,false)
g.UpdateLentancy(3, 5, path.S2TD(0.5), false,false)
g.UpdateLentancy(6, 4, path.S2TD(0.5), false,false)
g.UpdateLentancy(4, 6, path.S2TD(0.5), false,false)
_, next := path.FloydWarshall(g)
tconfig.NextHopTable = next
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
PushUpdate()
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 {
NhTable := graph.GetNHTable(false)
NhTablestr, _ := json.Marshal(NhTable)

View File

@ -2,7 +2,10 @@ package path
import (
"fmt"
"io/ioutil"
"math"
"strconv"
"strings"
"sync"
"time"
@ -31,8 +34,8 @@ type Latency struct {
}
type Fullroute struct {
Dist config.DistTable `json:"total distance"`
Next config.NextHopTable `json:"next hop"`
Next config.NextHopTable `yaml:"NextHopTable"`
Dist config.DistTable `yaml:"DistanceTable"`
}
// 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
} 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
}
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.Vert[u] = 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(),
}
g.edgelock.Unlock()
if g.ShouldUpdate(u, v, w) {
if g.ShouldUpdate(u, v, w) && recalculate {
changed = g.RecalculateNhTable(checkchange)
}
return
@ -296,28 +299,81 @@ func (g *IG) GetBoardcastThroughList(self_id config.Vertex, in_id config.Vertex,
return
}
func Solve() {
var g IG
//g.Init()
g.UpdateLentancy(1, 2, S2TD(0.5), false)
g.UpdateLentancy(2, 1, S2TD(0.5), false)
g.UpdateLentancy(2, 3, S2TD(2), false)
g.UpdateLentancy(3, 2, S2TD(2), false)
g.UpdateLentancy(2, 4, S2TD(0.7), false)
g.UpdateLentancy(4, 2, S2TD(2), false)
dist, next := FloydWarshall(g)
fmt.Println("pair\tdist\tpath")
for u, m := range dist {
for v, d := range m {
if u != v {
fmt.Printf("%d -> %d\t%3f\t%s\n", u, v, d, fmt.Sprint(Path(u, v, next)))
func printExample() {
fmt.Println(`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`)
}
func a2n(s string) (ret float64) {
if s == "Inf" {
return Infinity
}
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{
Dist: dist,
Next: next,
})
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
}