1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use *;
// ```sequence
// Alice->Net: BindListner(addres, Alice:sender)
// note right of Alice: Alice waits for a connection
// Net->Alice: NewConn(conn_id, local, remote, write_buf_size)
// note right of Alice: Alice is told of the connection
// and has Bob handle it
// Alice->Net: BindConn(conn_id, Bob:sender)
// note left of Bob: Bob waits for bytes
// Net->Bob: RecvBytes(conn_id, bytes)
// note left of Bob: Bob sends some bytes
// Bob->Net: SendBytes(conn_id, bytes)
// note left of Bob: Bob may be told how
// much more he can send
// Net->Bob: SendReady(write_buf_size)
// note left of Bob: Bob Closes the connection
// Bob->Net: Close(conn_id)
// ```
/// This is where d3 meets Tcp or UDP. The Network leans heavily upon Mio
/// to provide the foundation for interacting with the network. The d3 network provides
/// an additional abstraction to adapt it for d3 machines and encapsulate Mio.
///
/// This sequence diagram illustrates a machine, Alice asking for a TCP listener to
/// be installed. When there is a connection, the network is told to send control
/// and data commands to the machine Bob.
///
/// ```text
/// +-------+ +-----+ +-----+
/// | Alice | | Net | | Bob |
/// +-------+ +-----+ +-----+
/// | | |
/// | BindListner(addres, Alice:sender) | |
/// |--------------------------------------------------->| |
/// | -------------------------------\ | |
/// |-| Alice waits for a connection | | |
/// | |------------------------------| | |
/// | | |
/// | NewConn(conn_id, local, remote, write_buf_size) | |
/// |<---------------------------------------------------| |
/// | ----------------------------------\ | |
/// |-| Alice is told of the connection | | |
/// | | and has Bob handle it | | |
/// | |---------------------------------| | |
/// | BindConn(conn_id, Bob:sender) | |
/// |--------------------------------------------------->| |
/// | | ----------------------\ |
/// | | | Bob waits for bytes |-|
/// | | |---------------------| |
/// | | |
/// | | RecvBytes(conn_id, bytes) |
/// | |----------------------------->|
/// | | -----------------------\ |
/// | | | Bob sends some bytes |-|
/// | | |----------------------| |
/// | | |
/// | | SendBytes(conn_id, bytes) |
/// | |<-----------------------------|
/// | | ------------------------\ |
/// | | | Bob may be told how |-|
/// | | | much more he can send | |
/// | | |-----------------------| |
/// | | SendReady(write_buf_size) |
/// | |----------------------------->|
/// | |----------------------------\ |
/// | || Bob Closes the connection |-|
/// | ||---------------------------| |
/// | | |
/// | | Close(conn_id) |
/// | |<-----------------------------|
/// | | |
/// ```
///
/// UDP is a bit simpler, as illusted by the following sequence diagram. Alice asks the
/// network to bind a UDP address. Whenever a packet arrives it is sent to Alice. Alice
/// can send a packet to the network too. Although there isn't a connection, in the network
/// sense, a conn_id is used, for both parity and as a shorthand for the local address.
///
/// ```text
/// +-------+ +-----+
/// | Alice | | Net |
/// +-------+ +-----+
/// | |
/// | BindUdpListener(address, Alice:sender) |
/// |------------------------------------------>|
/// | ------------------------------\ |
/// |-| Wait for a packet to arrive | |
/// | |-----------------------------| |
/// | |
/// | RecvPkt(conn_id, local, remote, bytes) |
/// |<------------------------------------------|
/// | -----------------------\ |
/// |-| Alice sends a packet | |
/// | |----------------------| |
/// | |
/// | SendPkt(conn_id, remote, bytes) |
/// |------------------------------------------>|
/// | |
/// ```
/// A network connection is always expressed as a NetConnId and identifies a specific
/// network connection.
pub type NetConnId = usize;
/// Shorthand for a sender, that can be sent NetCmd instructions.
pub type NetSender = ;