mirror of
https://github.com/pablorevilla-meshtastic/meshview.git
synced 2026-10-31 03:01:58 +01:00
Bound the traceroute data a request has to draw (#182)
* Bound the traceroute data a request has to draw Every TRACEROUTE message is stored as a new row under its packet id, and its route can list any number of hops. /graph/traceroute decodes every row, looks up every node on every route and runs Graphviz over the result inside the request handler, so a publisher can make one page view take a very long time and stall every other request meanwhile: - 3,000 rows of 8 random hops for one packet id: the graph took about 43 s and other requests waited up to 24 s. - 150 rows of 400 hops: about 40 s, then a 500, with other requests waiting about 10 s. Real traceroutes are small. In 17 days of bay-area traffic no packet id had more than 72 rows, and none of 66,709 routes had more than 8 hops in either direction, which is the firmware's limit. get_traceroute() now returns at most the 200 earliest rows, and the TRACEROUTE decoder treats a route longer than 8 hops as undecodable, which every caller already skips. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Remove a blank line that fails the ruff format check `ruff format --check .` (the Ruff workflow, ruff 0.13.3) fails on develop because of this line, so every pull request's lint job is red regardless of its content. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Nathan <201262769+nullrouten0@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2 files changed
+21
-1
No files matched your search
@@ -17,12 +17,25 @@ def text_message(payload):
|
||||
return payload.decode("utf-8")
|
||||
|
||||
|
||||
# The firmware keeps at most 8 hops in each direction (none of 66,709 real traceroutes in 17
|
||||
# days of bay-area traffic had more). A longer route can only be forged, and one with
|
||||
# thousands of hops makes every page that draws it slow, so treat it as undecodable.
|
||||
MAX_ROUTE_HOPS = 8
|
||||
|
||||
|
||||
def route_discovery(payload):
|
||||
route = RouteDiscovery.FromString(payload)
|
||||
if max(len(route.route), len(route.route_back)) > MAX_ROUTE_HOPS:
|
||||
return None
|
||||
return route
|
||||
|
||||
|
||||
DECODE_MAP = {
|
||||
PortNum.POSITION_APP: Position.FromString,
|
||||
PortNum.NEIGHBORINFO_APP: NeighborInfo.FromString,
|
||||
PortNum.NODEINFO_APP: User.FromString,
|
||||
PortNum.TELEMETRY_APP: Telemetry.FromString,
|
||||
PortNum.TRACEROUTE_APP: RouteDiscovery.FromString,
|
||||
PortNum.TRACEROUTE_APP: route_discovery,
|
||||
PortNum.ROUTING_APP: Routing.FromString,
|
||||
PortNum.TEXT_MESSAGE_APP: text_message,
|
||||
PortNum.MAP_REPORT_APP: MapReport.FromString,
|
||||
|
||||
@@ -152,12 +152,19 @@ async def has_packets(node_id, portnum):
|
||||
)
|
||||
|
||||
|
||||
# Every TRACEROUTE message stores a row under its packet id, so anyone who can publish can add
|
||||
# thousands. Real ones have a few dozen (one per gateway that heard it; the most seen in 17 days
|
||||
# of bay-area traffic was 72), so only the earliest rows are used.
|
||||
MAX_TRACEROUTE_ROWS = 200
|
||||
|
||||
|
||||
async def get_traceroute(packet_id):
|
||||
async with database.async_session() as session:
|
||||
result = await session.execute(
|
||||
select(Traceroute)
|
||||
.where(Traceroute.packet_id == packet_id)
|
||||
.order_by(Traceroute.import_time_us)
|
||||
.limit(MAX_TRACEROUTE_ROWS)
|
||||
)
|
||||
return result.scalars()
|
||||
|
||||
|
||||
Reference in new issue
Block a user