updates to route monitor
This commit is contained in:
parent
04bd3a2f8f
commit
971a959a19
1 changed files with 62 additions and 28 deletions
|
@ -4,6 +4,7 @@ import enum
|
||||||
import select
|
import select
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import sys
|
||||||
import time
|
import time
|
||||||
from argparse import ArgumentDefaultsHelpFormatter
|
from argparse import ArgumentDefaultsHelpFormatter
|
||||||
from functools import cmp_to_key
|
from functools import cmp_to_key
|
||||||
|
@ -11,6 +12,8 @@ from queue import Queue
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from typing import Dict, Tuple
|
from typing import Dict, Tuple
|
||||||
|
|
||||||
|
import grpc
|
||||||
|
|
||||||
from core import utils
|
from core import utils
|
||||||
from core.api.grpc.client import CoreGrpcClient
|
from core.api.grpc.client import CoreGrpcClient
|
||||||
from core.api.grpc.core_pb2 import NodeType
|
from core.api.grpc.core_pb2 import NodeType
|
||||||
|
@ -56,14 +59,17 @@ class SdtClient:
|
||||||
|
|
||||||
|
|
||||||
class RouterMonitor:
|
class RouterMonitor:
|
||||||
def __init__(self, src_id: str, src: str, dst: str, pkt: str,
|
def __init__(self, session: int, src: str, dst: str, pkt: str, rate: int, dead: int,
|
||||||
sdt_host: str, sdt_port: int) -> None:
|
sdt_host: str, sdt_port: int) -> None:
|
||||||
self.queue = Queue()
|
self.queue = Queue()
|
||||||
self.core = CoreGrpcClient()
|
self.core = CoreGrpcClient()
|
||||||
self.src_id = src_id
|
self.session = session
|
||||||
|
self.src_id = None
|
||||||
self.src = src
|
self.src = src
|
||||||
self.dst = dst
|
self.dst = dst
|
||||||
self.pkt = pkt
|
self.pkt = pkt
|
||||||
|
self.rate = rate
|
||||||
|
self.dead = dead
|
||||||
self.seen = {}
|
self.seen = {}
|
||||||
self.running = False
|
self.running = False
|
||||||
self.route_time = None
|
self.route_time = None
|
||||||
|
@ -71,23 +77,44 @@ class RouterMonitor:
|
||||||
self.sdt = SdtClient((sdt_host, sdt_port))
|
self.sdt = SdtClient((sdt_host, sdt_port))
|
||||||
self.nodes = self.get_nodes()
|
self.nodes = self.get_nodes()
|
||||||
|
|
||||||
def get_nodes(self) -> Dict[str, str]:
|
def get_nodes(self) -> Dict[int, str]:
|
||||||
nodes = {}
|
|
||||||
with self.core.context_connect():
|
with self.core.context_connect():
|
||||||
|
if self.session is None:
|
||||||
|
self.session = self.get_session()
|
||||||
|
print("session: ", self.session)
|
||||||
|
try:
|
||||||
|
response = self.core.get_session(self.session)
|
||||||
|
nodes = response.session.nodes
|
||||||
|
node_map = {}
|
||||||
|
for node in nodes:
|
||||||
|
if node.type != NodeType.DEFAULT:
|
||||||
|
continue
|
||||||
|
node_map[node.id] = node.channel
|
||||||
|
if self.src_id is None:
|
||||||
|
response = self.core.get_node(self.session, node.id)
|
||||||
|
for netif in response.interfaces:
|
||||||
|
if self.src == netif.ip4:
|
||||||
|
self.src_id = node.id
|
||||||
|
break
|
||||||
|
except grpc.RpcError:
|
||||||
|
print(f"invalid session: {self.session}")
|
||||||
|
sys.exit(1)
|
||||||
|
if self.src_id is None:
|
||||||
|
print(f"could not find node with source address: {self.src}")
|
||||||
|
sys.exit(1)
|
||||||
|
print(f"monitoring src_id ({self.src_id}) src({self.src}) dst({self.dst}) pkt({self.pkt})")
|
||||||
|
return node_map
|
||||||
|
|
||||||
|
def get_session(self) -> int:
|
||||||
response = self.core.get_sessions()
|
response = self.core.get_sessions()
|
||||||
sessions = response.sessions
|
sessions = response.sessions
|
||||||
session = None
|
session = None
|
||||||
if sessions:
|
if sessions:
|
||||||
session = sessions[0]
|
session = sessions[0]
|
||||||
if not session:
|
if not session:
|
||||||
raise Exception("no current core sessions")
|
print("no current core sessions")
|
||||||
print("session: ", session.dir)
|
sys.exit(1)
|
||||||
response = self.core.get_session(session.id)
|
return session.id
|
||||||
for node in response.session.nodes:
|
|
||||||
if node.type != NodeType.DEFAULT:
|
|
||||||
continue
|
|
||||||
nodes[node.id] = node.channel
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
def start(self) -> None:
|
def start(self) -> None:
|
||||||
self.running = True
|
self.running = True
|
||||||
|
@ -107,7 +134,7 @@ class RouterMonitor:
|
||||||
elif node in self.seen:
|
elif node in self.seen:
|
||||||
del self.seen[node]
|
del self.seen[node]
|
||||||
|
|
||||||
if (time.monotonic() - self.route_time) >= ROUTE_TIME:
|
if (time.monotonic() - self.route_time) >= self.rate:
|
||||||
self.manage_routes()
|
self.manage_routes()
|
||||||
self.route_time = time.monotonic()
|
self.route_time = time.monotonic()
|
||||||
|
|
||||||
|
@ -148,7 +175,7 @@ class RouterMonitor:
|
||||||
|
|
||||||
def listen(self, node_id, node) -> None:
|
def listen(self, node_id, node) -> None:
|
||||||
cmd = (
|
cmd = (
|
||||||
f"tcpdump -lnv src host {self.src} and dst host {self.dst} and {self.pkt}"
|
f"tcpdump -lnvi any src host {self.src} and dst host {self.dst} and {self.pkt}"
|
||||||
)
|
)
|
||||||
node_cmd = f"vcmd -c {node} -- {cmd}"
|
node_cmd = f"vcmd -c {node} -- {cmd}"
|
||||||
p = subprocess.Popen(node_cmd, shell=True, stdout=subprocess.PIPE,
|
p = subprocess.Popen(node_cmd, shell=True, stdout=subprocess.PIPE,
|
||||||
|
@ -166,7 +193,7 @@ class RouterMonitor:
|
||||||
self.queue.put((RouteEnum.ADD, node_id, ttl))
|
self.queue.put((RouteEnum.ADD, node_id, ttl))
|
||||||
current = time.monotonic()
|
current = time.monotonic()
|
||||||
else:
|
else:
|
||||||
if (time.monotonic() - current) >= DEAD_TIME:
|
if (time.monotonic() - current) >= self.dead:
|
||||||
self.queue.put((RouteEnum.DEL, node_id, None))
|
self.queue.put((RouteEnum.DEL, node_id, None))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"listener error: {e}")
|
print(f"listener error: {e}")
|
||||||
|
@ -177,27 +204,34 @@ def main() -> None:
|
||||||
print("core-route-monitor requires tcpdump to be installed")
|
print("core-route-monitor requires tcpdump to be installed")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
desc = "core route monitor leverages tcpdump to monitor traffic and find route using TTL"
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="core route monitor",
|
description=desc,
|
||||||
formatter_class=ArgumentDefaultsHelpFormatter,
|
formatter_class=ArgumentDefaultsHelpFormatter
|
||||||
)
|
)
|
||||||
parser.add_argument("--id", required=True,
|
parser.add_argument("--src", required=True,
|
||||||
help="source node id for determining path")
|
|
||||||
parser.add_argument("--src", default="10.0.0.20",
|
|
||||||
help="source address for route monitoring")
|
help="source address for route monitoring")
|
||||||
parser.add_argument("--dst", default="10.0.2.20",
|
parser.add_argument("--dst", required=True,
|
||||||
help="destination address for route monitoring")
|
help="destination address for route monitoring")
|
||||||
|
parser.add_argument("--session", type=int,
|
||||||
|
help="session to monitor route")
|
||||||
parser.add_argument("--pkt", default="icmp", choices=PACKET_CHOICES,
|
parser.add_argument("--pkt", default="icmp", choices=PACKET_CHOICES,
|
||||||
help="packet type")
|
help="packet type")
|
||||||
|
parser.add_argument("--rate", type=int, default=ROUTE_TIME,
|
||||||
|
help="rate to update route, in seconds")
|
||||||
|
parser.add_argument("--dead", type=int, default=DEAD_TIME,
|
||||||
|
help="timeout to declare path dead, in seconds")
|
||||||
parser.add_argument("--sdt-host", default=SDT_HOST, help="sdt host address")
|
parser.add_argument("--sdt-host", default=SDT_HOST, help="sdt host address")
|
||||||
parser.add_argument("--sdt-port", type=int, default=SDT_PORT, help="sdt port")
|
parser.add_argument("--sdt-port", type=int, default=SDT_PORT, help="sdt port")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
monitor = RouterMonitor(
|
monitor = RouterMonitor(
|
||||||
args.id,
|
args.session,
|
||||||
args.src,
|
args.src,
|
||||||
args.dst,
|
args.dst,
|
||||||
args.pkt,
|
args.pkt,
|
||||||
|
args.rate,
|
||||||
|
args.dead,
|
||||||
args.sdt_host,
|
args.sdt_host,
|
||||||
args.sdt_port,
|
args.sdt_port,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue