Internet overlay netmod (inet)
The main way to use Ratman with other people at the moment is via the internet overlay network module inet. It creates peering sessions over the internet and TCP. With that comes a significant amount of connection state logic and routing outside of Ratman, because each instance of inet can be connected with many other instances of inet.
Structure diagram
Following is a class structure diagram for the three main components
of the inet
driver. Note that Server
is a dispatch-type, meaning
that after allocation it copies itself to a private task-stack and
remains running until the containing application is shut down.
TODO: figure out why the mermaid graph is borked
classDiagram-v2
class InetEndpoint {
+Arc[Routes] routes
+ChannelPair channel
+start( bind )
+port()
+add_peers( peers )
+send( target, frame )
+send_all( frame )
+next()
}
class Routes {
+AtomicU16 latest
+BTreeMap[Target, Peer] inner
+next_target()
+add_peer( target, peer )
+remove_peer( target )
+exists( target )
+get_peer_by_id( target )
+get_all_valid()
}
class Server {
+Option[TcpListener] ipv4_listen
+TcpListener ipv6_listen
+port()
+run()
}
Flowchart
While the inet
driver doesn't have a lot of type components, their
interactions can get quite complex. Furthermore there are some
stateless function components that can't be expressed in a traditional
class diagram.
digraph G {
size="8,30!"
graph [fontname = "Handlee"]
node [fontname = "Handlee"]
edge [fontname = "Handlee"]
splines="polyline"
bgcolor=transparent
nodesep=0.5
subgraph cluster_0 {
color=orange
node [color=orange]
A [label="InetEndpoint::new"]
B [label="add_peers()"]
S [label="Listen for\nincoming connections"]
C [label="for each peer", shape=Mdiamond]
D [label="Resolve address"]
E [label="start_connection()"]
E1 [label="connect()"]
E2 [label="handshake()"]
E3 [label="Add peer\nto Arc<Routes>"]
E4 [label ="SPAWN peer.run()"]
E5 [label="setup_cleanuptask()"]
Z [label="SPAWN restart.recv()"]
A -> B
A -> S
B -> C
C -> D
D -> E
E -> E1
E1 -> E1 [label="retry"]
E1 -> E2
E2 -> E3
E2 -> E4
E3 -> E5
E5 -> Z
label = "Initialisation"
fontsize = 20
}
subgraph cluster_1 {
color=cyan
label = "Peer Frame Receiver"
node [color=cyan]
P1 [label="run() loop", shape=Mdiamond]
P2 [label="Read Frame"]
P22 [label="Release Mutex"]
P222 [label="break", style=filled]
P3 [label="receiver.send()"]
P1 -> P2 [label="Lock Mutex"]
P2 -> P22 [label="No Data"]
P22 -> P1 [label="yield_now()"]
P2 -> P222 [label="Read failed"]
P2 -> P3 [label="Valid Frame"]
}
subgraph cluster_2 {
color=green
label="Server loop"
node[color=green]
S1 [label="for each\nincoming", shape=Mdiamond]
S2 [label="SPAWN\nhandle_stream()"]
S22 [label="Drop stream"]
S3 [label="accept_connection()"]
S -> S1
S1 -> S2 [label="valid"]
S1 -> S22 [label="invalid"]
S2 -> S3
S3 -> E4 [label="valid"]
S3 -> S22 [label="invalid"]
}
}