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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
use std::net::IpAddr;
use std::net::Ipv4Addr;
use std::net::Ipv6Addr;
use std::net::SocketAddr;
use std::time::Duration;
use serde::{Deserialize, Serialize};
pub use super::IpCidr;
pub use super::IpRoute;
pub use super::NetworkError;
pub use super::SocketStatus;
pub use super::StreamSecurity;
/// Represents a socket ID
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SocketId(u64);
impl From<u64> for SocketId {
fn from(value: u64) -> Self {
Self(value)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum FrameSerializationFormat {
Bincode,
#[cfg(feature = "json")]
Json,
#[cfg(feature = "messagepack")]
MessagePack,
#[cfg(feature = "cbor")]
Cbor,
}
/// Possible values which can be passed to the `TcpStream::shutdown` method.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
pub enum Shutdown {
/// Shut down the reading portion of the stream.
Read,
/// Shut down the writing portion of the stream.
Write,
/// Shut down both the reading and writing portions of the stream.
Both,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum RequestType {
/// Bridges this local network with a remote network, which is required in
/// order to make lower level networking calls (such as UDP/TCP)
Bridge {
network: String,
access_token: String,
security: StreamSecurity,
},
/// Flushes all the data by ensuring a full round trip is completed
Flush,
/// Disconnects from the remote network essentially unbridging it
Unbridge,
/// Acquires an IP address on the network and configures the routing tables
DhcpAcquire,
/// Adds a static IP address to the interface with a netmask prefix
IpAdd { ip: IpAddr, prefix: u8 },
/// Removes a static (or dynamic) IP address from the interface
IpRemove(IpAddr),
/// Clears all the assigned IP addresses for this interface
IpClear,
/// Lists all the IP addresses currently assigned to this interface
GetIpList,
/// Returns the hardware MAC address for this interface
GetMac,
/// Adds a default gateway to the routing table
GatewaySet(IpAddr),
/// Adds a specific route to the routing table
RouteAdd {
cidr: IpCidr,
via_router: IpAddr,
preferred_until: Option<Duration>,
expires_at: Option<Duration>,
},
/// Removes a routing rule from the routing table
RouteRemove(IpAddr),
/// Clears the routing table for this interface
RouteClear,
/// Lists all the routes defined in the routing table for this interface
GetRouteList,
/// Creates a low level socket that can read and write Ethernet packets
/// directly to the interface
BindRaw(SocketId),
/// Lists for TCP connections on a specific IP and Port combination
/// Multiple servers (processes or threads) can bind to the same port if they each set
/// the reuse-port and-or reuse-addr flags
ListenTcp {
socket_id: SocketId,
addr: SocketAddr,
only_v6: bool,
reuse_port: bool,
reuse_addr: bool,
},
/// Opens a UDP socket that listens on a specific IP and Port combination
/// Multiple servers (processes or threads) can bind to the same port if they each set
/// the reuse-port and-or reuse-addr flags
BindUdp {
socket_id: SocketId,
addr: SocketAddr,
reuse_port: bool,
reuse_addr: bool,
},
/// Creates a socket that can be used to send and receive ICMP packets
/// from a paritcular IP address
BindIcmp { socket_id: SocketId, addr: IpAddr },
/// Opens a TCP connection to a particular destination IP address and port
ConnectTcp {
socket_id: SocketId,
addr: SocketAddr,
peer: SocketAddr,
},
/// Performs DNS resolution for a specific hostname
Resolve {
host: String,
port: Option<u16>,
dns_server: Option<IpAddr>,
},
/// Closes the socket
Close,
/// Begins the process of accepting a socket and returns it later
BeginAccept(SocketId),
/// Returns the local address of this TCP listener
GetAddrLocal,
/// Returns the address (IP and Port) of the peer socket that this
/// is conencted to
GetAddrPeer,
/// Sets how many network hops the packets are permitted for new connections
SetTtl(u32),
/// Returns the maximum number of network hops before packets are dropped
GetTtl,
/// Returns the status/state of the socket
GetStatus,
/// Determines how long the socket will remain in a TIME_WAIT
/// after it disconnects (only the one that initiates the close will
/// be in a TIME_WAIT state thus the clients should always do this rather
/// than the server)
SetLinger(Option<Duration>),
/// Returns how long the socket will remain in a TIME_WAIT
/// after it disconnects
GetLinger,
/// Tells the raw socket and its backing switch that all packets
/// should be received by this socket even if they are not
/// destined for this device
SetPromiscuous(bool),
/// Returns if the socket is running in promiscuous mode whereby it
/// will receive all packets even if they are not destined for the
/// local interface
GetPromiscuous,
/// Sets the receive buffer size which acts as a trottle for how
/// much data is buffered on this side of the pipe
SetRecvBufSize(u64),
/// Size of the receive buffer that holds all data that has not
/// yet been read
GetRecvBufSize,
/// Sets the size of the send buffer which will hold the bytes of
/// data while they are being sent over to the peer
SetSendBufSize(u64),
/// Size of the send buffer that holds all data that is currently
/// being transmitted.
GetSendBufSize,
/// When NO_DELAY is set the data that needs to be transmitted to
/// the peer is sent immediately rather than waiting for a bigger
/// batch of data, this reduces latency but increases encapsulation
/// overhead.
SetNoDelay(bool),
/// Indicates if the NO_DELAY flag is set which means that data
/// is immediately sent to the peer without waiting. This reduces
/// latency but increases encapsulation overhead.
GetNoDelay,
/// When KEEP_ALIVE is set the connection will periodically send
/// an empty data packet to the server to make sure the connection
/// stays alive.
SetKeepAlive(bool),
/// Indicates if the KEEP_ALIVE flag is set which means that the
/// socket will periodically send an empty data packet to keep
/// the connection alive.
GetKeepAlive,
/// When DONT_ROUTE is set the packet will be sent directly
/// to the interface without passing through the routing logic.
SetDontRoute(bool),
/// Indicates if the packet will pass straight through to
/// the interface bypassing the routing logic.
GetDontRoute,
/// Shuts down either the READER or WRITER sides of the socket
/// connection.
Shutdown(Shutdown),
/// Return true if the socket is closed
IsClosed,
/// Sets a flag that means that the UDP socket is able
/// to receive and process broadcast packets.
SetBroadcast(bool),
/// Indicates if the SO_BROADCAST flag is set which means
/// that the UDP socket will receive and process broadcast
/// packets
GetBroadcast,
/// Sets a flag that indicates if multicast packets that
/// this socket is a member of will be looped back to
/// the sending socket. This applies to IPv4 addresses
SetMulticastLoopV4(bool),
/// Gets a flag that indicates if multicast packets that
/// this socket is a member of will be looped back to
/// the sending socket. This applies to IPv4 addresses
GetMulticastLoopV4,
/// Sets a flag that indicates if multicast packets that
/// this socket is a member of will be looped back to
/// the sending socket. This applies to IPv6 addresses
SetMulticastLoopV6(bool),
/// Gets a flag that indicates if multicast packets that
/// this socket is a member of will be looped back to
/// the sending socket. This applies to IPv6 addresses
GetMulticastLoopV6,
/// Sets the TTL for IPv4 multicast packets which is the
/// number of network hops before the packet is dropped
SetMulticastTtlV4(u32),
/// Gets the TTL for IPv4 multicast packets which is the
/// number of network hops before the packet is dropped
GetMulticastTtlV4,
/// Tells this interface that it will subscribe to a
/// particular multicast address. This applies to IPv4 addresses
JoinMulticastV4 {
multiaddr: Ipv4Addr,
iface: Ipv4Addr,
},
/// Tells this interface that it will unsubscribe to a
/// particular multicast address. This applies to IPv4 addresses
LeaveMulticastV4 {
multiaddr: Ipv4Addr,
iface: Ipv4Addr,
},
/// Tells this interface that it will subscribe to a
/// particular multicast address. This applies to IPv6 addresses
JoinMulticastV6 { multiaddr: Ipv6Addr, iface: u32 },
/// Tells this interface that it will unsubscribe to a
/// particular multicast address. This applies to IPv6 addresses
LeaveMulticastV6 { multiaddr: Ipv6Addr, iface: u32 },
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum ResponseType {
/// Nothing is returned (or noop)
None,
/// An error has occurred
Err(NetworkError),
/// Represents a duration of time
Duration(Duration),
/// Represents an amount (e.g. amount of bytes)
Amount(u64),
/// Returns a flag of true or false
Flag(bool),
/// List of IP addresses
IpAddressList(Vec<IpAddr>),
/// A single IP address
IpAddress(IpAddr),
/// List of socket addresses
SocketAddrList(Vec<SocketAddr>),
/// A single IP address
SocketAddr(SocketAddr),
/// Represents a MAC address
Mac([u8; 6]),
/// List of CIDR routes from a routing table
CidrList(Vec<IpCidr>),
/// List of IP routes from a routing table
RouteList(Vec<IpRoute>),
/// Reference to a socket
Socket(SocketId),
/// The TTL of a packet
Ttl(u32),
/// The status of the socket
Status(SocketStatus),
}
/// Message sent by the client to the server
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum MessageRequest {
Interface {
req: RequestType,
req_id: Option<u64>,
},
Socket {
socket: SocketId,
req: RequestType,
req_id: Option<u64>,
},
Send {
socket: SocketId,
data: Vec<u8>,
req_id: Option<u64>,
},
SendTo {
socket: SocketId,
data: Vec<u8>,
addr: SocketAddr,
req_id: Option<u64>,
},
Reconnect,
}
/// Message sent by the server back to a client
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum MessageResponse {
ResponseToRequest {
req_id: u64,
res: ResponseType,
},
Recv {
socket_id: SocketId,
data: Vec<u8>,
},
RecvWithAddr {
socket_id: SocketId,
data: Vec<u8>,
addr: SocketAddr,
},
Sent {
socket_id: SocketId,
req_id: u64,
amount: u64,
},
SendError {
socket_id: SocketId,
req_id: u64,
error: NetworkError,
},
FinishAccept {
socket_id: SocketId,
child_id: SocketId,
addr: SocketAddr,
},
Closed {
socket_id: SocketId,
},
}