Line data Source code
1 : #ifndef HEADER_fd_src_waltz_quic_fd_quic_h
2 : #define HEADER_fd_src_waltz_quic_fd_quic_h
3 :
4 : /* fd_quic_t is a partial implementation of QUIC -- an encrypted,
5 : multiplexing transport layer network protocol.
6 :
7 : For now, IPv4 over Ethernet (EN10MB) flows are supported.
8 :
9 : This API is non-blocking and single-threaded. Any requests to the
10 : peer (such as "open a connection") are queued and processed on RX
11 : or service call. The user is notified of events via callbacks.
12 : The user must further ensure that RX (via fd_aio_t) is dispatched
13 : only from the thread with the active join to the target fd_quic_t.
14 :
15 : Scaling is achieved via fd_quic_t instances and steering of RX flows.
16 : For example, incoming RX that exceeds the throughput of one fd_quic_t
17 : may be load balanced based on QUIC dest conn ID, or UDP src flow ID.
18 :
19 : This implementation aims to be compliant to RFC 9000 and RFC 9001:
20 : - https://datatracker.ietf.org/doc/html/rfc9000
21 : - https://datatracker.ietf.org/doc/html/rfc9001
22 :
23 : ### Memory Management
24 :
25 : fd_quic is entirely pre-allocated. Currently, a QUIC object reserves
26 : space for a number of connection slots, with uniform stream,
27 : reassembly, and ACK buffers.
28 :
29 : ### Memory Layout
30 :
31 : fd_quic_t is the publicly exported memory layout of a QUIC object.
32 : The private memory region of a QUIC object extends beyond the end of
33 : this struct. fd_quic_t is not intended to be allocated directly,
34 : refer to the below for details.
35 :
36 : ### Lifecycle
37 :
38 : The below state diagram shows the lifecycle of an fd_quic_t.
39 :
40 : ┌───────────┐ new ┌───────────┐ join ┌──────────┐
41 : │ ├───────►│ ├──────►│ │
42 : │ allocated │ │ formatted │ │ joined │
43 : │ │◄───────┤ │◄──────┤ │
44 : └───────────┘ delete └───────────┘ leave └───▲───┬──┘
45 : │ │ set config
46 : │ │ set callbacks
47 : fini │ │ init
48 : ┌──┴───▼──┐
49 : ┌───│ │
50 : service │ │ ready │
51 : └──►│ │
52 : └─────────┘
53 :
54 : ### Lifecycle: Allocation & Formatting
55 :
56 : A QUIC object resides in a contiguous pre-allocated memory region.
57 : (Usually, in a Firedancer workspace) The footprint and internal
58 : layout depends on the pre-configured fd_quic_limits_t parameters.
59 : These limits are constant throughout the lifetime of an fd_quic_t.
60 :
61 : Use fd_quic_{align,footprint} to determine size and alignment of the
62 : memory region to be used. Use fd_quic_new to format such a memory
63 : region and to obtain an opaque handle. In the formatted state, the
64 : fd_quic_t is position-independent (may be mapped at different virtual
65 : addresses). This is useful for separating allocation and runtime use
66 : into different steps.
67 :
68 : ### Lifecycle: Joining
69 :
70 : Given an opaque handle, fd_quic_join runs basic coherence checks and
71 : returns a typed pointer to the object. The object is not modified
72 : by this operation. Each object may have multiple active joins, but
73 : only one of them may write. (Typically, a single join is used for
74 : service, and secondary joins for read-only monitoring)
75 :
76 : ### Lifecycle: Usage
77 :
78 : fd_quic_init initializes an fd_quic_t for use. On success, the QUIC
79 : becomes ready to serve from the thread that init was called from (it
80 : is invalid to service QUIC from another thread). */
81 :
82 : /* TODO provide fd_quic on non-hosted targets */
83 :
84 : #include "fd_quic_common.h"
85 : #include "fd_quic_enum.h"
86 :
87 : #include "../aio/fd_aio.h"
88 : #include "../tls/fd_tls.h"
89 :
90 : /* FD_QUIC_API marks public API declarations. No-op for now. */
91 : #define FD_QUIC_API
92 :
93 : /* Forward declarations */
94 :
95 : struct fd_quic_conn;
96 : typedef struct fd_quic_conn fd_quic_conn_t;
97 :
98 : struct fd_quic_stream;
99 : typedef struct fd_quic_stream fd_quic_stream_t;
100 :
101 : struct fd_quic_state_private;
102 : typedef struct fd_quic_state_private fd_quic_state_t;
103 :
104 : /* fd_quic_limits_t defines the memory layout of an fd_quic_t object.
105 : Limits are immutable and valid for the lifetime of an fd_quic_t
106 : (i.e. outlasts joins, until fd_quic_delete) */
107 :
108 : struct __attribute__((aligned(16UL))) fd_quic_limits {
109 : ulong conn_cnt; /* instance-wide, max concurrent conn count */
110 : ulong handshake_cnt; /* instance-wide, max concurrent handshake count */
111 :
112 : ulong conn_id_cnt; /* per-conn, max conn ID count (min 4UL) */
113 : ulong stream_id_cnt; /* per-conn, max concurrent stream ID count */
114 : ulong rx_stream_cnt; /* per-conn, max concurrent stream count */
115 : ulong inflight_pkt_cnt; /* per-conn, max inflight packet count */
116 :
117 : ulong tx_buf_sz; /* per-stream, tx buf sz in bytes */
118 : /* the user consumes rx directly from the network buffer */
119 :
120 : ulong stream_pool_cnt; /* instance-wide, number of streams in stream pool */
121 : };
122 : typedef struct fd_quic_limits fd_quic_limits_t;
123 :
124 : /* fd_quic_now_t is the clock source used internally by quic for
125 : scheduling events. context is an arbitrary pointer earlier provided
126 : by the caller during config. Returns the time in ns since epoch.
127 : epoch is arbitrary but must stay consistent. */
128 :
129 : typedef ulong
130 : (*fd_quic_now_t)( void * context );
131 :
132 : /* fd_quic_config_t defines mutable config of an fd_quic_t. The config is
133 : immutable during an active join. */
134 :
135 : struct __attribute__((aligned(16UL))) fd_quic_config {
136 : /* Protocol config ***************************************/
137 :
138 : /* role: one of FD_QUIC_ROLE_{CLIENT,SERVER} */
139 : int role;
140 :
141 : /* retry: whether address validation using retry packets is enabled (RFC 9000, Section 8.1.2) */
142 : int retry;
143 :
144 : /* idle_timeout: Upper bound on conn idle timeout (ns).
145 : Also sent to peer via max_idle_timeout transport param.
146 : If the peer specifies a lower idle timeout, that is used instead. */
147 : ulong idle_timeout;
148 2121 : # define FD_QUIC_DEFAULT_IDLE_TIMEOUT (ulong)(1e9) /* 1s */
149 :
150 : /* ack_delay: median delay on outgoing ACKs. Greater delays allow
151 : fd_quic to coalesce packet ACKs. */
152 : ulong ack_delay;
153 2124 : # define FD_QUIC_DEFAULT_ACK_DELAY (ulong)(50e6) /* 50ms */
154 :
155 : /* ack_threshold: immediately send an ACK when the number of
156 : unacknowledged stream bytes exceeds this value. */
157 : ulong ack_threshold;
158 2124 : # define FD_QUIC_DEFAULT_ACK_THRESHOLD (65536UL) /* 64 KiB */
159 :
160 : /* TLS config ********************************************/
161 :
162 : /* identity_key: Ed25519 public key of node identity */
163 : uchar identity_public_key[ 32 ];
164 :
165 : /* Callback for signing TLS 1.3 certificate verify payload */
166 : fd_tls_sign_fn_t sign;
167 : void * sign_ctx;
168 :
169 0 : # define FD_QUIC_PATH_LEN 1023UL
170 : char keylog_file[ FD_QUIC_PATH_LEN+1UL ];
171 :
172 : /* Server name indication (client only)
173 : FIXME: Extend server to validate SNI */
174 : # define FD_QUIC_SNI_LEN (255UL)
175 : char sni[ FD_QUIC_SNI_LEN+1UL ];
176 :
177 : ulong initial_rx_max_stream_data; /* per-stream, rx buf sz in bytes, set by the user. */
178 :
179 : /* Network config ****************************************/
180 :
181 : struct { /* Link layer config */
182 : /* src_mac_addr: Source MAC address to set for outgoing traffic */
183 : uchar src_mac_addr[6];
184 :
185 : /* dst_mac_addr: Destination MAC address to set for outgoing traffic
186 : Usually corresponds to the MAC address of the host's default gateway.
187 : FIXME: Replace with ARP table
188 : FIXME: This shouldn't be part of QUIC, but the fd_aio_out */
189 : uchar dst_mac_addr[6];
190 : } link;
191 :
192 : struct { /* Internet config */
193 : uint ip_addr; /* IP address (for outgoing traffic) */
194 : ushort listen_udp_port; /* UDP port (server only) */
195 :
196 : struct { /* Ephemeral UDP port range (client only) */
197 : ushort lo;
198 : ushort hi;
199 : /* we need an ephemeral UDP port range for at least two reasons:
200 : 1. Some network hardware assumes src_ip:src_port:dst_ip:dst_port is a unique connection
201 : 2. For receive-side scaling, the server will be using the source port for load balancing */
202 : } ephem_udp_port;
203 :
204 : /* dscp: Differentiated services code point.
205 : Set on all outgoing IPv4 packets. */
206 : uchar dscp;
207 : } net;
208 : };
209 :
210 : /* Callback API *******************************************************/
211 :
212 : /* Note: QUIC library invokes callbacks during RX or service. Callback
213 : may only invoke fd_quic API methods labelled CB-safe. Callbacks are
214 : not re-entrant. */
215 :
216 : /* fd_quic_cb_conn_new_t: server received a new conn and completed
217 : handshakes. */
218 : typedef void
219 : (* fd_quic_cb_conn_new_t)( fd_quic_conn_t * conn,
220 : void * quic_ctx );
221 :
222 : /* fd_quic_cb_conn_handshake_complete_t: client completed a handshake
223 : of a conn it created. */
224 : typedef void
225 : (* fd_quic_cb_conn_handshake_complete_t)( fd_quic_conn_t * conn,
226 : void * quic_ctx );
227 :
228 : /* fd_quic_cb_conn_final_t: Conn termination notification. The conn
229 : object is freed immediately after returning. User should destroy any
230 : remaining references to conn in this callback. */
231 : typedef void
232 : (* fd_quic_cb_conn_final_t)( fd_quic_conn_t * conn,
233 : void * quic_ctx );
234 :
235 : /* fd_quic_cb_stream_new_t is called when the peer creates a new stream.
236 : Callback should set "context" within the supplied stream object but
237 : may not change any other stream fields. quic_ctx is the user-provided
238 : QUIC context. Note that this differs from the stream context. */
239 : typedef void
240 : (* fd_quic_cb_stream_new_t)( fd_quic_stream_t * stream,
241 : void * quic_ctx );
242 :
243 : /* fd_quic_cb_stream_notify_t signals a notable stream event.
244 : stream_ctx object is the user-provided stream context set in the new
245 : callback.
246 :
247 : TODO will only one notify max be served?
248 : TODO will stream be deallocated immediately after callback?
249 :
250 : notify_type is one of FD_QUIC_NOTIFY_{...} */
251 : typedef void
252 : (* fd_quic_cb_stream_notify_t)( fd_quic_stream_t * stream,
253 : void * stream_ctx,
254 : int notify_type );
255 :
256 : /* fd_quic_cb_stream_receive_t is called when new data is received from
257 : stream. Each buffer is received in a separate callback.
258 :
259 : args
260 : stream_context is user supplied stream context set in callback
261 : stream_id the quic stream id
262 : data the bytes received
263 : data_sz the number of bytes received
264 : offset the offset in the stream of the first byte in data
265 : fin bool - true if the last byte of data is the last
266 : byte on the receive side of the stream */
267 : typedef void
268 : (* fd_quic_cb_stream_receive_t)( fd_quic_stream_t * stream,
269 : void * stream_ctx,
270 : uchar const * data,
271 : ulong data_sz,
272 : ulong offset,
273 : int fin );
274 :
275 : /* fd_quic_cb_tls_keylog_t is called when a new encryption secret
276 : becomes available. line is a cstr containing the secret in NSS key
277 : log format (intended for tests only). */
278 :
279 : typedef void
280 : (* fd_quic_cb_tls_keylog_t)( void * quic_ctx,
281 : char const * line );
282 :
283 : /* fd_quic_callbacks_t defines the set of user-provided callbacks that
284 : are invoked by the QUIC library. Resets on leave. */
285 :
286 : struct fd_quic_callbacks {
287 : /* Function pointers to user callbacks */
288 :
289 : void * quic_ctx; /* user-provided context pointer
290 : for instance-wide callbacks */
291 :
292 : fd_quic_cb_conn_new_t conn_new; /* non-NULL, with quic_ctx */
293 : fd_quic_cb_conn_handshake_complete_t conn_hs_complete; /* non-NULL, with quic_ctx */
294 : fd_quic_cb_conn_final_t conn_final; /* non-NULL, with quic_ctx */
295 : fd_quic_cb_stream_new_t stream_new; /* non-NULL, with stream_ctx */
296 : fd_quic_cb_stream_notify_t stream_notify; /* non-NULL, with stream_ctx */
297 : fd_quic_cb_stream_receive_t stream_receive; /* non-NULL, with stream_ctx */
298 : fd_quic_cb_tls_keylog_t tls_keylog; /* nullable, with quic_ctx */
299 :
300 : /* Clock source */
301 :
302 : fd_quic_now_t now; /* non-NULL */
303 : void * now_ctx; /* user-provided context pointer for now_fn calls */
304 :
305 : };
306 : typedef struct fd_quic_callbacks fd_quic_callbacks_t;
307 :
308 : /* fd_quic metrics ****************************************************/
309 :
310 : /* TODO: evaluate performance impact of metrics */
311 :
312 : union fd_quic_metrics {
313 : ulong ul[ 46 ];
314 : struct {
315 : /* Network metrics */
316 : ulong net_rx_pkt_cnt; /* number of IP packets received */
317 : ulong net_rx_byte_cnt; /* total bytes received (including IP, UDP, QUIC headers) */
318 : ulong net_tx_pkt_cnt; /* number of IP packets sent */
319 : ulong net_tx_byte_cnt; /* total bytes sent */
320 :
321 : /* Conn metrics */
322 : ulong conn_active_cnt; /* number of active conns */
323 : ulong conn_created_cnt; /* number of conns created */
324 : ulong conn_closed_cnt; /* number of conns gracefully closed */
325 : ulong conn_aborted_cnt; /* number of conns aborted */
326 : ulong conn_timeout_cnt; /* number of conns timed out */
327 : ulong conn_retry_cnt; /* number of conns established with retry */
328 : ulong conn_err_no_slots_cnt; /* number of conns that failed to create due to lack of slots */
329 : ulong conn_err_tls_fail_cnt; /* number of conns that aborted due to TLS failure */
330 : ulong conn_err_retry_fail_cnt; /* number of conns that failed during retry (e.g. invalid token) */
331 :
332 : /* Frame metrics */
333 : ulong frame_rx_cnt[ 22 ]; /* number of frames received (indexed by implementation-defined IDs) */
334 :
335 : /* Handshake metrics */
336 : ulong hs_created_cnt; /* number of handshake flows created */
337 : ulong hs_err_alloc_fail_cnt; /* number of handshakes dropped due to alloc fail */
338 :
339 : /* Stream metrics */
340 : ulong stream_opened_cnt; /* number of streams opened */
341 : ulong stream_closed_cnt[5]; /* indexed by FD_QUIC_STREAM_NOTIFY_{...} */
342 : ulong stream_active_cnt; /* number of active streams */
343 : ulong stream_rx_event_cnt; /* number of stream RX events */
344 : ulong stream_rx_byte_cnt; /* total stream payload bytes received */
345 : };
346 : };
347 : typedef union fd_quic_metrics fd_quic_metrics_t;
348 :
349 : /* Assertion: fd_quic_metrics_t::ul must cover the whole struct */
350 :
351 : FD_STATIC_ASSERT( sizeof(((fd_quic_metrics_t *)(0))->ul)==sizeof(fd_quic_metrics_t), layout );
352 :
353 : /* fd_quic_t memory layout ********************************************/
354 :
355 : struct fd_quic {
356 : ulong magic; /* ==FD_QUIC_MAGIC */
357 :
358 : fd_quic_limits_t limits; /* position-independent, persistent, read only */
359 : fd_quic_config_t config; /* position-independent, persistent, writable pre init */
360 : fd_quic_callbacks_t cb; /* position-dependent, reset on join, writable pre init */
361 : fd_quic_metrics_t metrics; /* position-independent, persistent, read only */
362 :
363 : fd_aio_t aio_rx; /* local AIO */
364 : fd_aio_t aio_tx; /* remote AIO */
365 :
366 : /* ... private variable-length structures follow ... */
367 : };
368 :
369 : FD_PROTOTYPES_BEGIN
370 :
371 : /* debugging */
372 :
373 : ulong
374 : fd_quic_conn_get_pkt_meta_free_count( fd_quic_conn_t * conn );
375 :
376 :
377 : /* Object lifecycle ***************************************************/
378 :
379 : /* fd_quic_{align,footprint} return the required alignment and footprint
380 : of a memory region suitable for use as an fd_quic_t. align returns
381 : FD_QUIC_ALIGN. limits is a temporary reference to the requested
382 :
383 : On failure, footprint will silently return 0 (and thus can be used by
384 : the caller to validate fd_quic_new params) */
385 :
386 : FD_QUIC_API FD_FN_CONST ulong
387 : fd_quic_align( void );
388 :
389 : FD_QUIC_API FD_FN_PURE ulong
390 : fd_quic_footprint( fd_quic_limits_t const * limits );
391 :
392 : /* fd_quic_new formats an unused memory region for use as a QUIC client
393 : or server. mem is a non-NULL pointer to this region in the local
394 : address with the required footprint and alignment. limits is a
395 : temporary reference, identical to the one given to fd_quic_footprint
396 : used to figure out the required footprint. */
397 :
398 : FD_QUIC_API void *
399 : fd_quic_new( void * mem,
400 : fd_quic_limits_t const * limits );
401 :
402 : /* fd_quic_join joins the caller to the fd_quic. shquic points to the
403 : first byte of the memory region backing the QUIC in the caller's
404 : address space.
405 :
406 : Returns a pointer in the local address space to the public fd_quic_t
407 : region on success (do not assume this to be just a cast of shquic)
408 : and NULL on failure (logs details). Reasons for failure are that
409 : shquic is obviously not a pointer to a correctly formatted QUIC
410 : object. Every successful join should have a matching leave. The
411 : lifetime of the join is until the matching leave or the thread group
412 : is terminated. */
413 :
414 : FD_QUIC_API fd_quic_t *
415 : fd_quic_join( void * shquic );
416 :
417 : /* fd_quic_leave leaves a current local join and frees all dynamically
418 : managed resources (heap allocs, OS handles). Returns the given quic
419 : on success and NULL on failure (logs details). Reasons for failure
420 : include quic is NULL or no active join */
421 :
422 : FD_QUIC_API void *
423 : fd_quic_leave( fd_quic_t * quic );
424 :
425 : /* fd_quic_delete unformats a memory region used as an fd_quic_t.
426 : Assumes nobody is joined to the region. Returns the given quic
427 : pointer on success and NULL if used obviously in error (e.g. quic is
428 : obviously not an fd_quic_t ... logs details). The ownership of the
429 : memory region is transferred ot the caller. */
430 :
431 : FD_QUIC_API void *
432 : fd_quic_delete( fd_quic_t * quic );
433 :
434 : /* Configuration ******************************************************/
435 :
436 : /* fd_quic_{limits,config}_from_env populates the given QUIC limits or
437 : config from command-line args and env vars. If parg{c,v} are non-
438 : NULL, they are updated to strip the parsed args. The last element of
439 : the *argv array must be NULL. Returns given config on success and
440 : NULL on failure (logs details). It is up to the caller to properly
441 : initialize the given limits/config. */
442 :
443 : FD_QUIC_API fd_quic_limits_t *
444 : fd_quic_limits_from_env( int * pargc,
445 : char *** pargv,
446 : fd_quic_limits_t * limits );
447 :
448 : FD_QUIC_API fd_quic_config_t *
449 : fd_quic_config_from_env( int * pargc,
450 : char *** pargv,
451 : fd_quic_config_t * config );
452 :
453 : /* fd_quic_get_aio_net_rx returns this QUIC's aio base class. Valid
454 : for lifetime of QUIC. While pointer to aio can be obtained before
455 : init, calls to aio may only be dispatched by the thread with
456 : exclusive access to QUIC that owns it. */
457 :
458 : FD_QUIC_API fd_aio_t const *
459 : fd_quic_get_aio_net_rx( fd_quic_t * quic );
460 :
461 : /* fd_quic_set_aio_net_tx sets the fd_aio_t used by the fd_quic_t to
462 : send tx data to the network driver. Cleared on fini. */
463 :
464 : FD_QUIC_API void
465 : fd_quic_set_aio_net_tx( fd_quic_t * quic,
466 : fd_aio_t const * aio_tx );
467 :
468 : /* Initialization *****************************************************/
469 :
470 : /* fd_quic_init initializes the QUIC such that it is ready to serve.
471 : permits the calling thread exclusive access during which no other
472 : thread may write to the QUIC. Exclusive rights get released when the
473 : thread exits or calls fd_quic_fini.
474 :
475 : Requires valid configuration and external objects (aio, callbacks).
476 : Returns given quic on success and NULL on failure (logs details).
477 : Performs various heap allocations and file system accesses such
478 : reading certs. Reasons for failure include invalid config or
479 : fd_tls error. */
480 :
481 : FD_QUIC_API fd_quic_t *
482 : fd_quic_init( fd_quic_t * quic );
483 :
484 : /* fd_quic_fini releases exclusive access over a QUIC. Zero-initializes
485 : references to external objects (aio, callbacks). Frees any heap
486 : allocs made by fd_quic_init. Returns quic. */
487 :
488 : FD_QUIC_API fd_quic_t *
489 : fd_quic_fini( fd_quic_t * quic );
490 :
491 : /* NOTE: Calling any of the below requires valid initialization from
492 : this thread group. */
493 :
494 : /* Connection API *****************************************************/
495 :
496 : /* fd_quic_connect initiates a new client connection to a remote QUIC
497 : server. On success, returns a pointer to the conn object managed by
498 : QUIC. On failure, returns NULL. Reasons for failure include quic
499 : not a valid join or out of free conns. Lifetime of returned conn is
500 : until conn_final callback.
501 :
502 : args
503 : dst_ip_addr destination ip address
504 : dst_udp_port destination port number
505 : sni server name indication cstr, max 253 chars, nullable */
506 :
507 : FD_QUIC_API fd_quic_conn_t *
508 : fd_quic_connect( fd_quic_t * quic, /* requires exclusive access */
509 : uint dst_ip_addr,
510 : ushort dst_udp_port,
511 : char const * sni );
512 :
513 : /* fd_quic_conn_close asynchronously initiates a shutdown of the conn.
514 : The given reason code is returned to the peer via a CONNECTION_CLOSE
515 : frame, if possible. Causes conn_final callback to be issued
516 : eventually. */
517 :
518 : FD_QUIC_API void
519 : fd_quic_conn_close( fd_quic_conn_t * conn,
520 : uint reason );
521 :
522 : /* Service API ********************************************************/
523 :
524 : /* fd_quic_get_next_wakeup returns the next requested service time.
525 : The returned timestamp is relative to a value previously returned by
526 : fd_quic_now_t. This is only intended for unit tests. */
527 :
528 : FD_QUIC_API ulong
529 : fd_quic_get_next_wakeup( fd_quic_t * quic );
530 :
531 : /* fd_quic_service services the next QUIC connection, including stream
532 : transmit ops, ACK transmit, loss timeout, and idle timeout. The
533 : user should call service at high frequency. Returns 1 if the service
534 : call did any work, or 0 otherwise. */
535 :
536 : FD_QUIC_API int
537 : fd_quic_service( fd_quic_t * quic );
538 :
539 : /* fd_quic_svc_validate checks for violations of service queue and free
540 : list invariants, such as cycles in linked lists. Prints to warning/
541 : error log and exits the process if checks fail. Intended for use in
542 : tests. */
543 :
544 : void
545 : fd_quic_svc_validate( fd_quic_t * quic );
546 :
547 : /* Stream Send API ****************************************************/
548 :
549 : /* fd_quic_conn_new_stream creates a new unidirectional stream on the
550 : given conn. On success, returns the newly created stream.
551 : On failure, returns NULL. Reasons for failure include invalid conn
552 : state or out of stream quota.
553 :
554 : The user does not own the returned pointer: its lifetime is managed
555 : by the connection. */
556 :
557 : FD_QUIC_API fd_quic_stream_t *
558 : fd_quic_conn_new_stream( fd_quic_conn_t * conn );
559 :
560 : /* fd_quic_stream_send sends a chunk on a stream in order.
561 :
562 : Use fd_quic_conn_new_stream to create a new stream for sending
563 : or use the new stream callback to obtain a stream for replying.
564 :
565 : args
566 : stream the stream to send on
567 : data points to first byte of buffer (ignored if data_sz==0)
568 : data_sz number of bytes to send
569 : fin final: bool
570 : set to indicate the stream is finalized by the last byte
571 : in the batch
572 : If the last buffer in the batch was rejected, the FIN
573 : flag is not set, and may be applied in a future send
574 : or via the fd_quic_stream_fin(...) function
575 :
576 : returns
577 : 0 success
578 : <0 one of FD_QUIC_SEND_ERR_{INVAL_STREAM,INVAL_CONN,AGAIN} */
579 : FD_QUIC_API int
580 : fd_quic_stream_send( fd_quic_stream_t * stream,
581 : void const * data,
582 : ulong data_sz,
583 : int fin );
584 :
585 : /* fd_quic_stream_fin: finish sending on a stream. Called to signal
586 : no more data will be sent to self-to-peer flow of stream. Peer may
587 : continue sending data on their side of the stream. Caller should
588 : only call stream_fin once per stream, except when fin was already
589 : indicated via stream_send. */
590 :
591 : FD_QUIC_API void
592 : fd_quic_stream_fin( fd_quic_stream_t * stream );
593 :
594 : FD_QUIC_API void
595 : fd_quic_process_packet( fd_quic_t * quic,
596 : uchar * data,
597 : ulong data_sz );
598 :
599 : uint
600 : fd_quic_tx_buffered_raw( fd_quic_t * quic,
601 : uchar ** tx_ptr_ptr,
602 : uchar * tx_buf,
603 : ulong tx_buf_sz,
604 : ulong * tx_sz,
605 : uchar const dst_mac_addr[ static 6 ],
606 : ushort * ipv4_id,
607 : uint dst_ipv4_addr,
608 : ushort src_udp_port,
609 : ushort dst_udp_port,
610 : int flush );
611 :
612 : FD_PROTOTYPES_END
613 :
614 : /* Convenience exports for consumers of API */
615 : #include "fd_quic_conn.h"
616 : #include "fd_quic_stream.h"
617 :
618 : /* FD_DEBUG_MODE: set to enable debug-only code
619 : TODO move to util? */
620 : #ifdef FD_DEBUG_MODE
621 : #define FD_DEBUG(...) __VA_ARGS__
622 : #else
623 : #define FD_DEBUG(...)
624 : #endif
625 :
626 : #endif /* HEADER_fd_src_waltz_quic_fd_quic_h */
|