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
/// why are we handling protocols ourselves and not using the built-in APNS feature?
/// ================================================================================
///
/// first, I would re-emphasize that we could have used APNS feature of iroh[1], they have built
/// in protocol handling support. but it does not work because if you want to use more than one
/// protocol, you have to create more than one connection with the peer.
///
/// [1]: https://docs.rs/iroh/latest/iroh/endpoint/struct.Builder.html#method.alpns
///
/// why would we want that? say a peer wants to do multiple types of things at the same time. for
/// example, do a ping to check if connection is open, or to send both http and tcp proxy at the
/// same time. consider I am on call with you but also browsing a folder you have shared.
///
/// from the docs it is not clear if creating another connection, after one connection is already
/// established is a cheap operation or not. in my opinion, it cannot be cheap because ALPN is used
/// as part of TLS connection handshake process.
///
/// this is how the `client hello` message looks like during initial TLS connection handshake:
///
/// > Handshake Type: Client Hello (1)
/// > Length: 141
/// > Version: TLS 1.2 (0x0303)
/// > Random: dd67b5943e5efd0740519f38071008b59efbd68ab3114587...
/// > Session ID Length: 0
/// > Cipher Suites Length: 10
/// > Cipher Suites (5 suites)
/// > Compression Methods Length: 1
/// > Compression Methods (1 method)
/// > Extensions Length: 90
/// > [other extensions omitted]
/// > Extension: application_layer_protocol_negotiation (len=14)
/// > Type: application_layer_protocol_negotiation (16)
/// > Length: 14
/// > ALPN Extension Length: 12
/// > ALPN Protocol
/// > ALPN string length: 2
/// > ALPN Next Protocol: h2
/// > ALPN string length: 8
/// > ALPN Next Protocol: http/1.1
///
/// as you see, the ALPN is part of the `client hello` message, and it is sent during the initial
/// connection handshake. so if we want to use more than one protocol, we have to do one more
/// `client hello` hand-shake proces.
///
/// so we are using multiple [bidirectional][3] streams over a single connection. each new stream
/// con be used for a same or different protocol.
///
/// [3]: https://docs.rs/iroh/latest/iroh/endpoint/struct.Connection.html#method.open_bi
///
/// note: this is not a settled decision. if we are doing audio video streaming, we may not get the
/// optimal performance, and we may have to use multiple connections; this approach is to be
/// verified in the future.
///
/// the protocol "protocol"
/// =======================
///
/// the protocol: the peer / side that wants to communicate will be considered the "client", and
/// will initiate the bidirectional stream using `iroh::Connection::open_bi()` method. the server
/// will have an infinite loop to accept incoming bidirectional streams. for the loop to end, the
/// client must send a "quit" message and wait for ack from the server before closing the connection.
///
/// the bidirectional stream will contain new line terminal JSON text indicating the protocol, and
/// the rest of the message will be handled by the protocol-specific handler.
///
/// the protocol JSON line will be called header line, or stream header.
///
/// the stream header can contain protocol-specific information also, e.g., the request to proxy to
/// a server may include information about the server to proxy to in the protocol header. so that
/// the lower level protocol handler need not worry about further ways to extract protocol-specific
/// data.
///
/// security philosophy: more protocols, more liabilities
/// =====================================================
///
/// the goal of the ftn network is to make sure there are only a few protocols. all protocol
/// handlers are security risk, they are written in Rust, possibly using C and other libraries.
/// their code has to be reviewed for potential security issues.
///
/// this is why fastn is a full stack web application. fastn programs are compiled in JS code, and
/// in future to webassembly, and JS engines have decent security sandbox. we do not allow npm/deno
/// etc., and only run the most sandboxed, browser like JS code. fastn applications can also use
/// webassembly compiled code, which again is sandboxed.