rapido
rapido.h
Go to the documentation of this file.
1
4#ifndef rapido_h
5#define rapido_h
6
7#include <stdint.h>
8#include <stdio.h>
9#include <stdbool.h>
10#include <unistd.h>
11#include <sys/socket.h>
12#include "picotls.h"
13
14typedef uint32_t rapido_connection_id_t;
15typedef uint32_t rapido_stream_id_t;
16
17#define CLIENT_STREAM(sid) (((sid)&0x1) == 0)
18#define SERVER_STREAM(sid) (((sid)&0x1) == 1)
19
20#define TLS_SESSION_ID_LEN 32
21
22typedef uint8_t rapido_address_id_t;
23typedef struct {
24 uint64_t bs;
25 uint32_t start;
27
28#define SET_LEN 64ull
29#define SET_HAS(bs, e) (bs & (1ull << ((uint64_t)(e))))
30#define SET_ADD(bs, e) bs = (bs | (1ull << ((uint64_t)(e))))
31#define SET_REMOVE(bs, e) bs = (bs & (~(1ull << ((uint64_t)e))))
32
33void rapido_set_add(rapido_set_t *set, uint32_t value);
34bool rapido_set_has(rapido_set_t *set, uint32_t value);
35void rapido_set_add(rapido_set_t *set, uint32_t value);
36void rapido_set_remove(rapido_set_t *set, uint32_t value);
37size_t rapido_set_size(rapido_set_t *set);
38#define rapido_set_iter(set, i, v, bl) \
39 do { \
40 if ((set)->bs == 0) break; \
41 for (int i = 0; i < SET_LEN; i++) { \
42 if (SET_HAS((set)->bs, i)) { \
43 v = (set)->start + i; \
44 bl \
45 } \
46 } \
47 } while (0)
48
52typedef struct {
53 size_t capacity;
54 size_t size;
55 size_t item_size;
56 uint8_t *data;
58
59#define rapido_array_iter(a, i, e, bl) \
60 do { \
61 for (int i = 0; i < (a)->capacity; i++) { \
62 size_t offset = (1 + (a)->item_size) * i; \
63 if ((a)->data[offset] == true) { \
64 e = (void *)(a)->data + offset + 1; \
65 bl \
66 } \
67 } \
68 } while (0)
69
73typedef struct {
74 size_t capacity;
75 size_t size;
76 size_t front_index;
77 size_t back_index;
78 size_t item_size;
79 uint8_t *data;
81
85typedef struct {
86 size_t capacity;
87 size_t size;
88 size_t front_index;
89 size_t back_index;
90 uint8_t *data;
92
93#define RANGES_LEN 64
94
96typedef struct {
98 uint64_t low;
99 uint64_t high;
100 } ranges[RANGES_LEN];
101 size_t size;
103
109typedef struct {
110 struct {
111 void *data;
112 size_t capacity;
113 size_t offset;
114 } buffer;
115 rapido_range_list_t ranges;
116 size_t read_offset;
118
119void *rapido_queue_pop(rapido_queue_t *queue);
120
121#define rapido_queue_drain(q, e, bl) \
122 do { \
123 while ((q)->size) { \
124 e = rapido_queue_pop(q); \
125 bl \
126 } \
127 } while (0)
128
129typedef struct {
130 uint64_t tls_record_sequence; // The TLS Record sequence number of this record
131 size_t ciphertext_len; // The total length of the record as transmitted on the wire
132 bool ack_eliciting; // Whether receiving this record is expected to trigger the sending of an ACK. It also
133 // implies that the sender of this record will retransmit the frames
134 uint64_t sent_time; // The time at which the record was sent
136
137typedef struct {
138 ptls_context_t *tls_ctx;
139 char *server_name;
140
141 rapido_array_t local_addresses;
142 rapido_address_id_t next_local_address_id;
143
144 rapido_array_t listen_sockets;
145 rapido_array_t pending_connections;
146
147 rapido_array_t sessions;
148
149 bool is_server; // For QLOG macros
150 struct {
151 FILE *out;
152 uint64_t reference_time;
153 } qlog;
155
156typedef struct {
157 ptls_t *tls;
158 ptls_context_t *tls_ctx;
159
160 rapido_array_t connections;
161 rapido_connection_id_t next_connection_id;
162 rapido_array_t streams;
163 rapido_stream_id_t next_stream_id;
164
165 rapido_array_t local_addresses;
166 rapido_address_id_t next_local_address_id;
167 rapido_set_t addresses_advertised;
168 rapido_array_t remote_addresses;
169 rapido_address_id_t next_remote_address_id;
170
171 rapido_array_t tls_session_ids;
172 bool is_server;
173 bool is_closed;
174
175 rapido_queue_t pending_notifications;
176
177 union {
178 struct {
179
180 } client;
181 struct {
182 rapido_array_t listen_sockets;
183 rapido_array_t pending_connections;
184 size_t tls_session_ids_sent;
185 } server;
186 };
187
188 struct {
189 FILE *out;
190 uint64_t reference_time;
191 } qlog;
192
193 struct {
194 bool enable_ping_probes;
195 bool no_delay;
196 } config;
198
199typedef struct {
200 rapido_connection_id_t connection_id;
201 int socket;
202 rapido_address_id_t local_address_id;
203 rapido_address_id_t remote_address_id;
204 struct sockaddr_storage peer_address;
205 socklen_t peer_address_len;
206 bool is_closed;
207
208 rapido_set_t attached_streams;
209 rapido_queue_t frame_queue;
210
211 struct st_ptls_traffic_protection_t *encryption_ctx;
212 struct st_ptls_traffic_protection_t *decryption_ctx;
213 struct st_ptls_traffic_protection_t *own_decryption_ctx; // Cryptographic material to decrypt the records we sent when
214 // retransmitting
215 struct {
216 ptls_buffer_t rec;
217 ptls_buffer_t mess;
218 } tls_recvbuf; // Used by picotls for reassembling fragmented TLS records
219
220 rapido_buffer_t receive_buffer;
221 bool receive_buffer_fragmented;
222 rapido_buffer_t send_buffer;
223
224 rapido_queue_t sent_records;
225 size_t sent_offset;
226 uint64_t last_received_record_sequence;
227
228 bool require_ack;
229 uint64_t last_receive_time;
230 size_t non_ack_eliciting_count;
231 uint64_t last_send_time;
232
233 rapido_set_t retransmit_connections;
234
235 struct {
236 uint64_t bytes_received;
237 uint64_t bytes_sent;
238 } stats;
239
240 ptls_t *tls;
241 void *app_ptr;
243
244#define rapido_time_to_send(conn_info, bytes_len) ((((((uint64_t) bytes_len) * 1000000ul) / (conn_info).congestion_window) * (conn_info).smoothed_rtt) / 1000000ul)
245#define rapido_time_to_drain(conn_info) (rapido_time_to_send(conn_info, (conn_info).bytes_queued_for_sending))
246#define rapido_time_to_transfer(conn_info, bytes_len) (rapido_time_to_drain(conn_info) + rapido_time_to_send(conn_info, bytes_len) + (conn_info).smoothed_rtt)
247
248typedef struct {
249 uint64_t smoothed_rtt;
250 uint64_t congestion_window;
251 uint64_t bytes_queued_for_sending;
253
254typedef struct {
255 int socket;
256 ptls_context_t *tls_ctx;
257 ptls_t *tls;
258 ptls_handshake_properties_t tls_properties;
259 uint8_t tls_session_id[TLS_SESSION_ID_LEN];
260 rapido_address_id_t local_address_id;
262
263typedef uint8_t *(*rapido_stream_producer_t)(rapido_session_t *, rapido_stream_id_t, void *, uint64_t, size_t *);
264
265typedef struct {
266 uint64_t offset;
267 void *app_ctx;
269
270typedef struct {
271 rapido_stream_id_t stream_id;
272
273 rapido_set_t connections;
274
275 rapido_range_buffer_t read_buffer;
276 size_t read_fin;
277 bool fin_received;
278
279 rapido_buffer_t send_buffer;
280 size_t write_offset;
281 size_t write_fin;
282 bool fin_set;
283 bool fin_sent;
284
285 rapido_stream_producer_t producer;
286 void *producer_ctx;
287 rapido_queue_t write_callbacks;
288
289 uint64_t bytes_received;
290 uint64_t bytes_sent;
292
293typedef struct {
294 enum {
295 rapido_new_connection,
296 rapido_connection_reset,
297 rapido_connection_closed,
298 rapido_new_stream,
299 rapido_stream_has_data,
300 rapido_stream_data_was_written,
301 rapido_stream_closed,
302 rapido_new_connection_token,
303 rapido_new_remote_address,
304 rapido_session_closed,
305 } notification_type;
306
307 union {
308 rapido_connection_id_t connection_id;
309 rapido_stream_id_t stream_id;
310 rapido_address_id_t address_id;
311 void *app_ctx;
312 };
313
314 uint64_t timestamp;
316
318rapido_server_t *rapido_new_server(ptls_context_t *tls_ctx, const char *server_name, FILE *qlog_out);
319
321rapido_address_id_t rapido_add_server_address(rapido_server_t *server, struct sockaddr *addr, socklen_t addr_len, bool add_listen_socket);
323int rapido_remove_server_address(rapido_session_t *session, rapido_address_id_t local_address_id);
325int rapido_run_server_network(rapido_server_t *server, int timeout);
328
330rapido_session_t *rapido_new_session(ptls_context_t *tls_ctx, bool is_server, const char *server_name, FILE *qlog_out);
331
333rapido_address_id_t rapido_add_address(rapido_session_t *session, struct sockaddr *addr, socklen_t addr_len);
335rapido_address_id_t rapido_add_remote_address(rapido_session_t *session, struct sockaddr *addr, socklen_t addr_len);
337int rapido_remove_address(rapido_session_t *session, rapido_address_id_t local_address_id);
338
340rapido_connection_id_t rapido_create_connection(rapido_session_t *session, uint8_t local_address_id, uint8_t remote_address_id);
342rapido_connection_id_t rapido_client_add_connection(rapido_session_t *session, int fd, uint8_t local_address_id, uint8_t remote_address_id);
344int rapido_run_network(rapido_session_t *session, int timeout);
346int rapido_retransmit_connection(rapido_session_t *session, rapido_connection_id_t connection_id, rapido_set_t connections);
348int rapido_close_connection(rapido_session_t *session, rapido_connection_id_t connection_id);
350int rapido_close_session(rapido_session_t *session, rapido_connection_id_t connection_id);
351
353rapido_stream_id_t rapido_open_stream(rapido_session_t *session);
355int rapido_attach_stream(rapido_session_t *session, rapido_stream_id_t stream_id, rapido_connection_id_t connection_id);
357int rapido_detach_stream(rapido_session_t *session, rapido_stream_id_t stream_id, rapido_connection_id_t connection_id);
359int rapido_add_to_stream(rapido_session_t *session, rapido_stream_id_t stream_id, void *data, size_t len);
361int rapido_add_to_stream_notify(rapido_session_t *session, rapido_stream_id_t stream_id, void *data, size_t len, void *app_ctx);
363int rapido_set_stream_producer(rapido_session_t *session, rapido_stream_id_t stream_id, rapido_stream_producer_t producer,
364 void *producer_ctx);
366void *rapido_read_stream(rapido_session_t *session, rapido_stream_id_t stream_id, size_t *len);
368int rapido_close_stream(rapido_session_t *session, rapido_stream_id_t stream_id);
369
371int rapido_session_accept_new_connection(rapido_session_t *session, int accept_fd, rapido_address_id_t local_address_id);
373int rapido_server_accept_new_connection(rapido_server_t *server, int accept_fd, rapido_address_id_t local_address_id);
375size_t rapido_server_add_new_connection(rapido_array_t *pending_connections, ptls_context_t *tls_ctx, ptls_t *tls,
376 const char *server_name, int conn_fd, rapido_address_id_t local_address_id);
378int rapido_client_process_handshake(rapido_session_t *session, rapido_connection_id_t connection_id, uint8_t *buffer, size_t *len);
380int rapido_server_process_handshake(rapido_server_t *server, rapido_session_t *session, rapido_array_t *pending_connections, size_t pending_connection_index, uint8_t *buffer, size_t *len, ptls_buffer_t *handshake_buffer, rapido_session_t **created_session, rapido_connection_t **created_connection);
382void rapido_process_incoming_data(rapido_session_t *session, rapido_connection_id_t connection_id, uint64_t current_time, uint8_t *buffer, size_t *len);
384int rapido_connection_wants_to_send(rapido_session_t *session, rapido_connection_t *connection, uint64_t current_time, bool *is_blocked);
386void rapido_prepare_data(rapido_session_t *session, rapido_connection_id_t connection_id, uint64_t current_time, uint8_t *buffer, size_t *len);
388void rapido_connection_set_app_ptr(rapido_session_t *session, rapido_connection_id_t connection_id, void *app_ptr);
390void *rapido_connection_get_app_ptr(rapido_session_t *session, rapido_connection_id_t connection_id);
392void rapido_connection_get_info(rapido_session_t * session, rapido_connection_id_t connection_id, rapido_connection_info_t *info);
393
398
399#endif
void rapido_process_incoming_data(rapido_session_t *session, rapido_connection_id_t connection_id, uint64_t current_time, uint8_t *buffer, size_t *len)
Processes incoming data received after the handshake.
Definition: rapido.c:1929
bool rapido_set_has(rapido_set_t *set, uint32_t value)
Returns whether the set contains the given value.
Definition: rapido.c:313
rapido_address_id_t rapido_add_address(rapido_session_t *session, struct sockaddr *addr, socklen_t addr_len)
Adds a local address to the session.
Definition: rapido.c:810
int rapido_close_stream(rapido_session_t *session, rapido_stream_id_t stream_id)
Marks the end of this stream.
Definition: rapido.c:1072
int rapido_retransmit_connection(rapido_session_t *session, rapido_connection_id_t connection_id, rapido_set_t connections)
Marks the given set of connections as eligible for retransmitting the content of the given connection...
Definition: rapido.c:2356
int rapido_add_to_stream_notify(rapido_session_t *session, rapido_stream_id_t stream_id, void *data, size_t len, void *app_ctx)
Adds the given data to the end of the stream and registers a notification containing the given applic...
Definition: rapido.c:1046
rapido_address_id_t rapido_add_remote_address(rapido_session_t *session, struct sockaddr *addr, socklen_t addr_len)
Adds a remote address to the session.
Definition: rapido.c:832
rapido_server_t * rapido_new_server(ptls_context_t *tls_ctx, const char *server_name, FILE *qlog_out)
Creates a new rapido server.
Definition: rapido.c:716
rapido_connection_id_t rapido_client_add_connection(rapido_session_t *session, int fd, uint8_t local_address_id, uint8_t remote_address_id)
Adds the given file descriptor to the session as a new connection with the given local and remote add...
Definition: rapido.c:871
int rapido_remove_server_address(rapido_session_t *session, rapido_address_id_t local_address_id)
Removes a local address from the server.
int rapido_add_to_stream(rapido_session_t *session, rapido_stream_id_t stream_id, void *data, size_t len)
Adds the given data to the end of the stream.
Definition: rapido.c:1039
int rapido_server_process_handshake(rapido_server_t *server, rapido_session_t *session, rapido_array_t *pending_connections, size_t pending_connection_index, uint8_t *buffer, size_t *len, ptls_buffer_t *handshake_buffer, rapido_session_t **created_session, rapido_connection_t **created_connection)
Processes data received by a server during the handshake.
Definition: rapido.c:1722
rapido_application_notification_t * rapido_next_server_notification(rapido_server_t *server, size_t *session_index)
Pops the next notification and gets the index of the corresponding session.
Definition: rapido.c:765
int rapido_close_connection(rapido_session_t *session, rapido_connection_id_t connection_id)
Gracefully closes the connection.
Definition: rapido.c:969
int rapido_remove_address(rapido_session_t *session, rapido_address_id_t local_address_id)
Removes a local address from the session.
Definition: rapido.c:852
int rapido_session_accept_new_connection(rapido_session_t *session, int accept_fd, rapido_address_id_t local_address_id)
Adds a given file descriptor as a new connection to a session.
Definition: rapido.c:1691
int rapido_attach_stream(rapido_session_t *session, rapido_stream_id_t stream_id, rapido_connection_id_t connection_id)
Marks the connection as eligible to send content of this stream.
Definition: rapido.c:1013
rapido_session_t * rapido_new_session(ptls_context_t *tls_ctx, bool is_server, const char *server_name, FILE *qlog_out)
Creates a new rapido session.
Definition: rapido.c:798
int rapido_detach_stream(rapido_session_t *session, rapido_stream_id_t stream_id, rapido_connection_id_t connection_id)
Removes the mark of elibility of this connection for sending the content of this stream.
Definition: rapido.c:1027
void rapido_connection_get_info(rapido_session_t *session, rapido_connection_id_t connection_id, rapido_connection_info_t *info)
Returns TCP-level information on the given connection.
Definition: rapido.c:2161
int rapido_server_free(rapido_server_t *server)
Deallocates the memory zones referenced in this server structure.
Definition: rapido.c:2369
void rapido_prepare_data(rapido_session_t *session, rapido_connection_id_t connection_id, uint64_t current_time, uint8_t *buffer, size_t *len)
Prepares data to send.
Definition: rapido.c:2083
int rapido_run_network(rapido_session_t *session, int timeout)
Runs the session for some time.
Definition: rapido.c:2176
rapido_connection_id_t rapido_create_connection(rapido_session_t *session, uint8_t local_address_id, uint8_t remote_address_id)
Creates a new connection for the session with the given local and remote addresses.
Definition: rapido.c:942
void rapido_set_remove(rapido_set_t *set, uint32_t value)
Removes the given value from the set.
Definition: rapido.c:341
void * rapido_queue_pop(rapido_queue_t *queue)
Returns a pointer to an element poped from the front of the queue.
Definition: rapido.c:387
void rapido_connection_set_app_ptr(rapido_session_t *session, rapido_connection_id_t connection_id, void *app_ptr)
Sets an application pointer associated with the given connection.
Definition: rapido.c:2149
rapido_stream_id_t rapido_open_stream(rapido_session_t *session)
Add a new stream to the session.
Definition: rapido.c:1004
rapido_address_id_t rapido_add_server_address(rapido_server_t *server, struct sockaddr *addr, socklen_t addr_len, bool add_listen_socket)
Adds a local address to the server, and creates a listen socket bound to the address when required.
Definition: rapido.c:743
int rapido_client_process_handshake(rapido_session_t *session, rapido_connection_id_t connection_id, uint8_t *buffer, size_t *len)
Processes data received by a client during the handshake and returns whether the handshake is complet...
Definition: rapido.c:1893
void * rapido_read_stream(rapido_session_t *session, rapido_stream_id_t stream_id, size_t *len)
Returns a pointer to read at most the *len following bytes from this stream.
Definition: rapido.c:1066
int rapido_session_free(rapido_session_t *session)
Deallocates the memory zones referenced in this session structure.
Definition: rapido.c:2392
void * rapido_connection_get_app_ptr(rapido_session_t *session, rapido_connection_id_t connection_id)
Gets an application pointer associated with the given connection.
Definition: rapido.c:2155
int rapido_connection_wants_to_send(rapido_session_t *session, rapido_connection_t *connection, uint64_t current_time, bool *is_blocked)
Returns whether the given connection wants to send data.
Definition: rapido.c:1439
int rapido_close_session(rapido_session_t *session, rapido_connection_id_t connection_id)
Gracefully closes the session and send the TLS alert on the given connection.
Definition: rapido.c:977
int rapido_set_stream_producer(rapido_session_t *session, rapido_stream_id_t stream_id, rapido_stream_producer_t producer, void *producer_ctx)
Sets the given function and associated context as a data producer for this stream.
Definition: rapido.c:1057
int rapido_server_accept_new_connection(rapido_server_t *server, int accept_fd, rapido_address_id_t local_address_id)
Accepts from a given file descriptor and adds the new connection to the server.
Definition: rapido.c:1709
int rapido_run_server_network(rapido_server_t *server, int timeout)
Runs the server for some time.
Definition: rapido.c:2303
void rapido_set_add(rapido_set_t *set, uint32_t value)
Adds the given value to the set when it can contains, otherwise fails.
Definition: rapido.c:320
size_t rapido_set_size(rapido_set_t *set)
Returns the number of element in the set.
Definition: rapido.c:347
size_t rapido_server_add_new_connection(rapido_array_t *pending_connections, ptls_context_t *tls_ctx, ptls_t *tls, const char *server_name, int conn_fd, rapido_address_id_t local_address_id)
Adds the new connection to pending connections and returns its index within the latter array.
Definition: rapido.c:1672
Definition: rapido.h:293
A growing array allocating capacity * item_size bytes.
Definition: rapido.h:52
A growing and cycling byte buffer.
Definition: rapido.h:85
Definition: rapido.h:248
Definition: rapido.h:199
Definition: rapido.h:254
A growing and cycling queue allocating capacity * item_size bytes.
Definition: rapido.h:73
A growing and cycling buffer, also tracking the ranges of bytes present in the buffer following a glo...
Definition: rapido.h:109
A uin64_t interval list, sorted by ascending order.
Definition: rapido.h:96
Definition: rapido.h:129
Definition: rapido.h:137
Definition: rapido.h:156
Definition: rapido.h:23
Definition: rapido.h:270
Definition: rapido.h:265