Started implementing the graph
This commit is contained in:
		
							parent
							
								
									c63fd27867
								
							
						
					
					
						commit
						1fd59e6156
					
				
							
								
								
									
										7
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								main.go
									
									
									
									
									
								
							| @ -23,7 +23,7 @@ var ( | |||||||
| 	wsserverForNodes *websocketserver.Server | 	wsserverForNodes *websocketserver.Server | ||||||
| 	respondDaemon    *respond.Daemon | 	respondDaemon    *respond.Daemon | ||||||
| 	nodes            = models.NewNodes() | 	nodes            = models.NewNodes() | ||||||
| 	aliases          = models.NewNodes() | 	//aliases          = models.NewNodes()
 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
| @ -35,10 +35,11 @@ func main() { | |||||||
| 	saveInterval := time.Second * time.Duration(config.Nodes.SaveInterval) | 	saveInterval := time.Second * time.Duration(config.Nodes.SaveInterval) | ||||||
| 
 | 
 | ||||||
| 	if config.Nodes.Enable { | 	if config.Nodes.Enable { | ||||||
| 		go nodes.Saver(config.Nodes.NodesPath, saveInterval) | 		go nodes.Saver(config.Nodes.NodesPath, config.Nodes.GraphsPath, saveInterval) | ||||||
| 	} | 	} | ||||||
| 	if config.Nodes.AliasesEnable { | 	if config.Nodes.AliasesEnable { | ||||||
| 		go aliases.Saver(config.Nodes.AliasesPath, saveInterval) | 		// FIXME what does this do?
 | ||||||
|  | 		//go aliases.Saver(config.Nodes.AliasesPath, saveInterval)
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if config.Webserver.Enable { | 	if config.Webserver.Enable { | ||||||
|  | |||||||
							
								
								
									
										103
									
								
								models/graph.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								models/graph.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,103 @@ | |||||||
|  | package models | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Graph struct { | ||||||
|  | 	Version int `json:"version"` | ||||||
|  | 	Batadv  struct { | ||||||
|  | 		Links []*GraphLink `json:"links"` | ||||||
|  | 	} `json:"batadv"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type GraphLink struct { | ||||||
|  | 	Source   string  `json:"source"` | ||||||
|  | 	Target   string  `json:"target"` | ||||||
|  | 	VPN      bool    `json:"vpn"` | ||||||
|  | 	TQ       float32 `json:"tq"` | ||||||
|  | 	Bidirect bool    `json:"bidirect"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type GraphBuilder struct { | ||||||
|  | 	macToID map[string]string     // mapping from MAC address to node id
 | ||||||
|  | 	links   map[string]*GraphLink // mapping from $idA-$idB to existing link
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (nodes *Nodes) BuildGraph() *Graph { | ||||||
|  | 	builder := &GraphBuilder{ | ||||||
|  | 		macToID: make(map[string]string), | ||||||
|  | 		links:   make(map[string]*GraphLink), | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	builder.readNodes(nodes.List) | ||||||
|  | 
 | ||||||
|  | 	graph := &Graph{Version: 2} | ||||||
|  | 	graph.Batadv.Links = builder.Links() | ||||||
|  | 	return graph | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (builder *GraphBuilder) readNodes(nodes map[string]*Node) { | ||||||
|  | 	// Fill mac->id map
 | ||||||
|  | 	for sourceId, node := range nodes { | ||||||
|  | 		if neighbours := node.Neighbours; neighbours != nil { | ||||||
|  | 			for sourceAddress, _ := range neighbours.Batadv { | ||||||
|  | 				builder.macToID[sourceAddress] = sourceId | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Add links
 | ||||||
|  | 	for sourceId, node := range nodes { | ||||||
|  | 		if neighbours := node.Neighbours; neighbours != nil { | ||||||
|  | 			for _, batadvNeighbours := range neighbours.Batadv { | ||||||
|  | 				for targetAddress, link := range batadvNeighbours.Neighbours { | ||||||
|  | 					if targetId, found := builder.macToID[targetAddress]; found { | ||||||
|  | 						builder.addLink(targetId, sourceId, link.Tq) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (builder *GraphBuilder) Links() []*GraphLink { | ||||||
|  | 	i := 0 | ||||||
|  | 	links := make([]*GraphLink, len(builder.links)) | ||||||
|  | 
 | ||||||
|  | 	for _, link := range builder.links { | ||||||
|  | 		links[i] = link | ||||||
|  | 		i += 1 | ||||||
|  | 	} | ||||||
|  | 	return links | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (builder *GraphBuilder) addLink(targetId string, sourceId string, linkTq int) { | ||||||
|  | 	// Order IDs to get generate the key
 | ||||||
|  | 	var key string | ||||||
|  | 	if strings.Compare(sourceId, targetId) > 0 { | ||||||
|  | 		key = fmt.Sprintf("%s-%s", sourceId, targetId) | ||||||
|  | 	} else { | ||||||
|  | 		key = fmt.Sprintf("%s-%s", targetId, sourceId) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var tq float32 | ||||||
|  | 	if linkTq > 0 { | ||||||
|  | 		tq = float32(1.0 / (float32(linkTq) / 255.0)) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if link, ok := builder.links[key]; !ok { | ||||||
|  | 		builder.links[key] = &GraphLink{ | ||||||
|  | 			Source: sourceId, | ||||||
|  | 			Target: targetId, | ||||||
|  | 			TQ:     tq, | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		// Use lowest of both link qualities
 | ||||||
|  | 		if tq < link.TQ { | ||||||
|  | 			link.TQ = tq | ||||||
|  | 		} | ||||||
|  | 		link.Bidirect = true | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -62,25 +62,25 @@ func (nodes *Nodes) Get(nodeID string) *Node { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Saves the cached DB to json file periodically
 | // Saves the cached DB to json file periodically
 | ||||||
| func (nodes *Nodes) Saver(outputFile string, saveInterval time.Duration) { | func (nodes *Nodes) Saver(nodesPath string, graphPath string, saveInterval time.Duration) { | ||||||
| 	c := time.Tick(saveInterval) | 	c := time.Tick(saveInterval) | ||||||
| 
 | 
 | ||||||
| 	for range c { | 	for range c { | ||||||
| 		nodes.save(outputFile) | 		log.Println("saving", len(nodes.List), "nodes") | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (nodes *Nodes) save(outputFile string) { |  | ||||||
| 		nodes.Timestamp = time.Now() | 		nodes.Timestamp = time.Now() | ||||||
| 
 |  | ||||||
| 		nodes.Lock() | 		nodes.Lock() | ||||||
| 	data, err := json.Marshal(nodes) | 		save(nodes, nodesPath) | ||||||
|  | 		save(nodes.BuildGraph(), graphPath) | ||||||
| 		nodes.Unlock() | 		nodes.Unlock() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func save(input interface{}, outputFile string) { | ||||||
|  | 	data, err := json.Marshal(input) | ||||||
| 
 | 
 | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Panic(err) | 		log.Panic(err) | ||||||
| 	} | 	} | ||||||
| 	log.Println("saving", len(nodes.List), "nodes") |  | ||||||
| 
 | 
 | ||||||
| 	tmpFile := outputFile + ".tmp" | 	tmpFile := outputFile + ".tmp" | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user