aboutsummaryrefslogtreecommitdiffstats
path: root/nodedb.py
diff options
context:
space:
mode:
Diffstat (limited to 'nodedb.py')
-rw-r--r--nodedb.py188
1 files changed, 61 insertions, 127 deletions
diff --git a/nodedb.py b/nodedb.py
index fa9caed..a45c7a1 100644
--- a/nodedb.py
+++ b/nodedb.py
@@ -5,7 +5,8 @@ from node import Node, Interface
from link import Link, LinkConnector
class NodeDB:
- def __init__(self):
+ def __init__(self, time=0):
+ self.time = time
self._nodes = []
self._links = []
@@ -18,15 +19,42 @@ class NodeDB:
def get_nodes(self):
return self._nodes
- def maybe_node_by_fuzzy_mac(self, mac):
- mac_a = mac.lower()
+ # remove all offlines nodes with lastseen < timestamp
+ def prune_offline(self, timestamp):
+ self._nodes = list(filter(lambda x: x.lastseen >= timestamp, self._nodes))
- for node in self._nodes:
- for mac_b in node.macs:
- if is_derived_mac(mac_a, mac_b):
- return node
+ # write persistent state to file
+ def dump_state(self, filename):
+ obj = []
- raise KeyError
+ for node in self._nodes:
+ obj.append({ 'id': node.id
+ , 'name': node.name
+ , 'lastseen': node.lastseen
+ , 'geo': node.gps
+ })
+
+ with open(filename, "w") as f:
+ json.dump(obj, f)
+
+ # load persistent state from file
+ def load_state(self, filename):
+ try:
+ with open(filename, "r") as f:
+ obj = json.load(f)
+ for n in obj:
+ try:
+ node = self.maybe_node_by_id(n['id'])
+ except:
+ node = Node()
+ node.id = n['id']
+ node.name = n['name']
+ node.lastseen = n['lastseen']
+ node.gps = n['geo']
+ self._nodes.append(node)
+
+ except:
+ pass
def maybe_node_by_mac(self, macs):
for node in self._nodes:
@@ -51,37 +79,28 @@ class NodeDB:
node = self.maybe_node_by_mac((x['of'], x['secondary']))
except:
node = Node()
+ node.lastseen = self.time
node.flags['online'] = True
- if 'legacy' in x:
- node.flags['legacy'] = True
self._nodes.append(node)
node.add_mac(x['of'])
node.add_mac(x['secondary'])
for x in vis_data:
-
if 'router' in x:
+ # TTs will be processed later
+ if x['label'] == "TT":
+ continue
+
try:
node = self.maybe_node_by_mac((x['router'], ))
except:
node = Node()
+ node.lastseen = self.time
node.flags['online'] = True
- if 'legacy' in x:
- node.flags['legacy'] = True
node.add_mac(x['router'])
self._nodes.append(node)
- # If it's a TT link and the MAC is very similar
- # consider this MAC as one of the routers
- # MACs
- if 'gateway' in x and x['label'] == "TT":
- if is_similar(x['router'], x['gateway']):
- node.add_mac(x['gateway'])
-
- # skip processing as regular link
- continue
-
try:
if 'neighbor' in x:
try:
@@ -95,16 +114,17 @@ class NodeDB:
node = self.maybe_node_by_mac((x['neighbor'], ))
except:
node = Node()
+ node.lastseen = self.time
node.flags['online'] = True
- if x['label'] == 'TT':
- node.flags['client'] = True
-
node.add_mac(x['neighbor'])
self._nodes.append(node)
for x in vis_data:
-
if 'router' in x:
+ # TTs will be processed later
+ if x['label'] == "TT":
+ continue
+
try:
if 'gateway' in x:
x['neighbor'] = x['gateway']
@@ -128,13 +148,9 @@ class NodeDB:
link.quality = x['label']
link.id = "-".join(sorted((link.source.interface, link.target.interface)))
- if x['label'] == "TT":
- link.type = "client"
-
self._links.append(link)
for x in vis_data:
-
if 'primary' in x:
try:
node = self.maybe_node_by_mac((x['primary'], ))
@@ -143,6 +159,16 @@ class NodeDB:
node.id = x['primary']
+ for x in vis_data:
+ if 'router' in x and x['label'] == 'TT':
+ try:
+ node = self.maybe_node_by_mac((x['router'], ))
+ node.add_mac(x['gateway'])
+ if not is_similar(x['router'], x['gateway']):
+ node.clientcount += 1
+ except:
+ pass
+
def reduce_links(self):
tmp_links = defaultdict(list)
@@ -171,13 +197,10 @@ class NodeDB:
try:
node = self.maybe_node_by_mac([mac])
except:
- try:
- node = self.maybe_node_by_fuzzy_mac(mac)
- except:
- # create an offline node
- node = Node()
- node.add_mac(mac)
- self._nodes.append(node)
+ # create an offline node
+ node = Node()
+ node.add_mac(mac)
+ self._nodes.append(node)
if 'name' in alias:
node.name = alias['name']
@@ -212,9 +235,6 @@ class NodeDB:
while changes > 0:
changes = 0
for link in self._links:
- if link.type == "client":
- continue
-
source_interface = self._nodes[link.source.id].interfaces[link.source.interface]
target_interface = self._nodes[link.target.id].interfaces[link.target.interface]
if source_interface.vpn or target_interface.vpn:
@@ -225,92 +245,6 @@ class NodeDB:
link.type = "vpn"
- def count_clients(self):
- for link in self._links:
- try:
- a = self.maybe_node_by_id(link.source.interface)
- b = self.maybe_node_by_id(link.target.interface)
-
- if a.flags['client']:
- client = a
- node = b
- elif b.flags['client']:
- client = b
- node = a
- else:
- continue
-
- node.clientcount += 1
- except:
- pass
-
- def obscure_clients(self):
-
- globalIdCounter = 0
- nodeCounters = {}
- clientIds = {}
-
- for node in self._nodes:
- if node.flags['client']:
- node.macs = set()
- clientIds[node.id] = None
-
- for link in self._links:
- ids = link.source.interface
- idt = link.target.interface
-
- try:
- node_source = self.maybe_node_by_fuzzy_mac(ids)
- node_target = self.maybe_node_by_id(idt)
-
- if not node_source.flags['client'] and not node_target.flags['client']:
- # if none of the nodes associated with this link are clients,
- # we do not want to obscure
- continue
-
- if ids in clientIds and idt in clientIds:
- # This is for corner cases, when a client
- # is linked to another client.
- clientIds[ids] = str(globalIdCounter)
- ids = str(globalIdCounter)
- globalIdCounter += 1
-
- clientIds[idt] = str(globalIdCounter)
- idt = str(globalIdCounter)
- globalIdCounter += 1
-
- elif ids in clientIds:
- newId = generateId(idt)
- clientIds[ids] = newId
- ids = newId
-
- link.source.interface = ids;
- node_source.id = ids;
-
- elif idt in clientIds:
- newId = generateId(ids,nodeCounters)
- clientIds[idt] = newId
- idt = newId
-
- link.target.interface = idt;
- node_target.id = idt;
-
- link.id = ids + "-" + idt
-
- except KeyError:
- pass
-
-# extends node id by incremented node counter
-def generateId(nodeId,nodeCounters):
- if nodeId in nodeCounters:
- n = nodeCounters[nodeId]
- nodeCounters[nodeId] = n + 1
- else:
- nodeCounters[nodeId] = 1
- n = 0
-
- return nodeId + "_" + str(n)
-
# compares two MACs and decides whether they are
# similar and could be from the same node
def is_similar(a, b):