Skip to content

Network Graph

Status Implemented
Revision 2026-10-27, skywire f37a464a4
Code pkg/deployment/netgraph, pkg/deployment/tpd/api/charts.go, pkg/tpviz/netview

Abstract

The network graph is a web page that shows the transports of the network as a graph of visors. The package pkg/deployment/netgraph lays out the graph and renders the page. Transport Discovery (TPD) serves it at /graph and supplies the transports.

Overview

The graph is not a separate service. netgraph.Page is an http.Handler that the TPD mounts beside its charts page. The page calls back into TPD for its data: the transports, a color for some visors, and the grouping of visors. The page is drawn in the browser by cosmos-go, a WebGL engine in the netview module.

Addressing

The page is served by the TPD over dmsg HTTP at dmsg://<tpd-pk>:80, under the paths in the table below. It exists only while the TPD charts are running. Otherwise the paths answer 404 (API.GraphPage).

Data Formats

Inputs

netgraph.Page takes these functions.

Field Signature TPD value
Source func(ctx) ([]Link, error) API.graphLinks: every transport in the TPD transport cache, including transports between a visor and itself
Marks func(ctx) map[string]string API.roleColors: a color for each visor that runs a dmsg server
Groups func(ctx) map[string]string API.ipGroups: one key for visors that share a public IP

netgraph.Link has the two visor keys in hex, A and B, and the transport type Type. netgraph.Mark is a legend entry with a name and a color.

The TPD takes the roles from dmsg discovery (the clients by server CXO feed, or /dmsg-discovery/all_servers and /dmsg-discovery/servers/clients over HTTP). A server with an entry in discovery is colored as a registered dmsg server. A visor that clients delegate to without an entry is colored as a LAN dmsg server. The roles are refreshed every 10 minutes (dmsgRolesEvery).

ipGroups joins visors that share a public IP in the Address Resolver bindings feed (see Address Resolver). The IPs are the public addresses of stcpr, sudph, squicr and swtr bindings.

Graph

netgraph.Build produces a netgraph.Graph. A node is a visor key. An edge is a pair of visors joined by at least one transport. An edge holds a mask with one bit for each transport type that joins the pair. Types are ordered by transport count, at most 8 are kept (maxTypes), and the rarest share the type other. A graph with more than 65535 nodes is empty.

Visors that share a group key are numbered as a group when two or more of them appear in the graph. Group numbers hide the keys.

Interfaces

HTTP API

None of these routes requires authentication.

Method and path Response
GET /graph the HTML page; 503 until the transports are known; 405 for methods other than GET and HEAD
GET /graph/engine.wasm the netview WebAssembly module
GET /graph/engine.js the wasm_exec.js loader of the module

The page response has Cache-Control: public, max-age=300 and a restrictive Content-Security-Policy header.

The page embeds its data as JSON with these members: t the type names, k the visor keys, x and y the positions, d the transport count of each visor, c the marked colors, g the group numbers and e the edges. The edges are packed into five bytes each: two little endian 16 bit node indexes and the type mask. The field is base64 encoded.

Behaviour

A layout is kept for RefreshEvery, 15 minutes. After that the next request recomputes it from the transports of the TPD cache (refreshed every 30 s, transportsCacheDelay). If recomputation fails, the previous page is served.

The layout is a force directed layout in a unit square. Every pair of visors repels and every edge pulls its ends together. Gravity centers the graph, and visors of a group are drawn together. The pull on an edge falls with the degree of the visor. The layout runs 220 iterations from a spiral start. If more than 90 percent of the visors have a position from the previous layout it starts from those positions and runs 60 iterations.

Security Considerations

The page lists the public keys of all visors that have a transport. The groups view shows group numbers and sizes and not the shared IP addresses.

References

  • Transport Discovery
  • Address Resolver