ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
udp.c File Reference

Go to the source code of this file.

Data Structures

struct  udp_peer
 acip quic udp endpoint is intentionally a small, concrete record. Fields such as socket, local, local_length, server_tls give callers the identity and current value they need. It is normally borrowed from, or owned by, the surrounding subsystem—not independently managed. More...
struct  quic_udp_endpoint

Macros

#define QUIC_UDP_CID_LENGTH   16
#define QUIC_UDP_PACKET_CAPACITY   1452
#define QUIC_UDP_MAX_CONNECTIONS   64
#define QUIC_UDP_READ_BATCH   128
#define QUIC_UDP_WRITE_BATCH   16
#define QUIC_RETRY_SECRET_LENGTH   32
#define QUIC_RETRY_TOKEN_LIFETIME   (10ULL * 1000000000ULL)

Typedefs

typedef struct udp_peer udp_peer_t
 acip quic udp endpoint is intentionally a small, concrete record. Fields such as socket, local, local_length, server_tls give callers the identity and current value they need. It is normally borrowed from, or owned by, the surrounding subsystem—not independently managed.

Functions

asciichat_error_t quic_udp_endpoint_create (const struct sockaddr *address, socklen_t length, quic_tls_t *server_tls, quic_udp_accept_fn accept, void *context, quic_udp_endpoint_t **out)
asciichat_error_t quic_udp_endpoint_address (const quic_udp_endpoint_t *endpoint, struct sockaddr_storage *address, socklen_t *length)
asciichat_error_t quic_udp_connect (quic_udp_endpoint_t *endpoint, quic_tls_t *client_tls, const char *server_name, const struct sockaddr *remote, socklen_t remote_length, uint64_t now_ns, quic_connection_t **out)
asciichat_error_t quic_udp_pump (quic_udp_endpoint_t *endpoint, uint64_t now, quic_connection_t **failed)
asciichat_error_t quic_udp_wait_parameters (const quic_udp_endpoint_t *endpoint, uint64_t now_ns, uint64_t maximum_wait_ns, uint64_t *wait_ns, bool *want_write)
asciichat_error_t quic_udp_wait (quic_udp_endpoint_t *endpoint, uint64_t wait_ns, bool want_write, bool *ready)
asciichat_error_t quic_udp_wake (quic_udp_endpoint_t *endpoint)
bool quic_udp_contains (const quic_udp_endpoint_t *endpoint, const quic_connection_t *connection)
asciichat_error_t quic_udp_close_peer (quic_udp_endpoint_t *endpoint, quic_connection_t *connection)
asciichat_error_t quic_udp_remove (quic_udp_endpoint_t *endpoint, quic_connection_t *connection)
void quic_udp_endpoint_destroy (quic_udp_endpoint_t **endpoint)
asciichat_error_t quic_udp_migrate (quic_udp_endpoint_t *endpoint, const struct sockaddr *address, socklen_t length, uint64_t now_ns)

Macro Definition Documentation

◆ QUIC_RETRY_SECRET_LENGTH

#define QUIC_RETRY_SECRET_LENGTH   32

Definition at line 14 of file udp.c.

◆ QUIC_RETRY_TOKEN_LIFETIME

#define QUIC_RETRY_TOKEN_LIFETIME   (10ULL * 1000000000ULL)

Definition at line 15 of file udp.c.

◆ QUIC_UDP_CID_LENGTH

#define QUIC_UDP_CID_LENGTH   16

Definition at line 9 of file udp.c.

◆ QUIC_UDP_MAX_CONNECTIONS

#define QUIC_UDP_MAX_CONNECTIONS   64

Definition at line 11 of file udp.c.

◆ QUIC_UDP_PACKET_CAPACITY

#define QUIC_UDP_PACKET_CAPACITY   1452

Definition at line 10 of file udp.c.

Referenced by quic_udp_close_peer().

◆ QUIC_UDP_READ_BATCH

#define QUIC_UDP_READ_BATCH   128

Definition at line 12 of file udp.c.

Referenced by quic_udp_pump().

◆ QUIC_UDP_WRITE_BATCH

#define QUIC_UDP_WRITE_BATCH   16

Definition at line 13 of file udp.c.

Referenced by quic_udp_pump().

Typedef Documentation

◆ udp_peer_t

typedef struct udp_peer udp_peer_t

acip quic udp endpoint is intentionally a small, concrete record. Fields such as socket, local, local_length, server_tls give callers the identity and current value they need. It is normally borrowed from, or owned by, the surrounding subsystem—not independently managed.

The useful part of udp peer is in next, connection, pending_path, pending_length: together they describe what is pending, who owns it, and how much data is valid. Keep the object with its parent operation and use the parent cleanup path.

Function Documentation

◆ quic_udp_close_peer()

asciichat_error_t quic_udp_close_peer ( quic_udp_endpoint_t * endpoint,
quic_connection_t * connection )

Definition at line 339 of file udp.c.

339 {
340 if (!quic_udp_contains(endpoint, connection))
341 return SET_ERRNO(ERROR_INVALID_PARAM, "QUIC UDP connection is not owned by endpoint");
343 ngtcp2_path_storage path;
344 size_t length = 0;
345 asciichat_error_t result =
346 quic_connection_write_close(connection, &path, packet, sizeof(packet), &length, time_get_ns());
347 if (result != ASCIICHAT_OK || !length)
348 return result;
349 ngtcp2_addr *remote = &path.path.remote;
350 ssize_t sent = socket_sendto(endpoint->socket, packet, length, 0, remote->addr, (socklen_t)remote->addrlen);
351 if (sent < 0 || (size_t)sent != length)
352 return SET_ERRNO(ERROR_NETWORK, "Cannot send QUIC close packet");
353 return ASCIICHAT_OK;
354}
#define SET_ERRNO(code,...)
unsigned char uint8_t
Definition common.h:60
asciichat_error_t
Error and exit codes - unified status values (0-255).
Definition error_codes.h:44
@ ERROR_NETWORK
Definition error_codes.h:72
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_INVALID_PARAM
asciichat_error_t quic_connection_write_close(quic_connection_t *connection, ngtcp2_path_storage *path, void *packet, size_t capacity, size_t *length, uint64_t now_ns)
socket_t socket
Definition udp.c:34
bool quic_udp_contains(const quic_udp_endpoint_t *endpoint, const quic_connection_t *connection)
Definition udp.c:330
#define QUIC_UDP_PACKET_CAPACITY
Definition udp.c:10

References ASCIICHAT_OK, ERROR_INVALID_PARAM, ERROR_NETWORK, quic_connection_write_close(), quic_udp_contains(), QUIC_UDP_PACKET_CAPACITY, SET_ERRNO, and quic_udp_endpoint::socket.

◆ quic_udp_connect()

asciichat_error_t quic_udp_connect ( quic_udp_endpoint_t * endpoint,
quic_tls_t * client_tls,
const char * server_name,
const struct sockaddr * remote,
socklen_t remote_length,
uint64_t now_ns,
quic_connection_t ** out )

Definition at line 144 of file udp.c.

146 {
147 if (!out)
148 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing QUIC UDP connection output");
149 *out = NULL;
150 if (!endpoint || !client_tls || client_tls->server || !valid_sockaddr(remote, remote_length) ||
151 remote->sa_family != ((struct sockaddr *)&endpoint->local)->sa_family)
152 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC UDP connection configuration");
153 udp_peer_t *peer = new_peer(endpoint);
154 if (!peer)
155 return SET_ERRNO(ERROR_BUFFER_FULL, "QUIC UDP connection limit reached or allocation failed");
156 ngtcp2_path path = make_path(endpoint, remote, remote_length);
157 asciichat_error_t result = quic_connection_client_create(client_tls, server_name, &path, now_ns, &peer->connection);
158 if (result != ASCIICHAT_OK) {
159 SAFE_FREE(peer);
160 return result;
161 }
162 add_peer(endpoint, peer);
163 *out = peer->connection;
164 return ASCIICHAT_OK;
165}
#define SAFE_FREE(ptr)
Definition common.h:377
@ ERROR_BUFFER_FULL
asciichat_error_t quic_connection_client_create(quic_tls_t *tls, const char *server_name, const ngtcp2_path *path, uint64_t now_ns, quic_connection_t **out)
static bool size_t gotel_query_t * out
Definition queries.h:8
bool server
Definition tls.h:15
struct sockaddr_storage local
Definition udp.c:35
quic_connection_t * connection
Definition udp.c:27
struct udp_peer udp_peer_t
acip quic udp endpoint is intentionally a small, concrete record. Fields such as socket,...

References ASCIICHAT_OK, udp_peer::connection, ERROR_BUFFER_FULL, ERROR_INVALID_PARAM, quic_udp_endpoint::local, out, quic_connection_client_create(), SAFE_FREE, quic_tls_t::server, and SET_ERRNO.

Referenced by quic_connect().

◆ quic_udp_contains()

bool quic_udp_contains ( const quic_udp_endpoint_t * endpoint,
const quic_connection_t * connection )

Definition at line 330 of file udp.c.

330 {
331 if (!endpoint || !connection)
332 return false;
333 for (const udp_peer_t *peer = endpoint->peers; peer; peer = peer->next)
334 if (peer->connection == connection)
335 return true;
336 return false;
337}
udp_peer_t * peers
Definition udp.c:41
struct udp_peer * next
Definition udp.c:26

References udp_peer::connection, udp_peer::next, and quic_udp_endpoint::peers.

Referenced by quic_udp_close_peer().

◆ quic_udp_endpoint_address()

asciichat_error_t quic_udp_endpoint_address ( const quic_udp_endpoint_t * endpoint,
struct sockaddr_storage * address,
socklen_t * length )

Definition at line 106 of file udp.c.

107 {
108 if (!endpoint || !address || !length)
109 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC UDP address output");
110 *address = endpoint->local;
111 *length = endpoint->local_length;
112 return ASCIICHAT_OK;
113}
socklen_t local_length
Definition udp.c:36

References ASCIICHAT_OK, ERROR_INVALID_PARAM, quic_udp_endpoint::local, quic_udp_endpoint::local_length, and SET_ERRNO.

Referenced by quic_endpoint_address().

◆ quic_udp_endpoint_create()

asciichat_error_t quic_udp_endpoint_create ( const struct sockaddr * address,
socklen_t length,
quic_tls_t * server_tls,
quic_udp_accept_fn accept,
void * context,
quic_udp_endpoint_t ** out )

Definition at line 67 of file udp.c.

68 {
69 if (!out)
70 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing QUIC UDP endpoint output");
71 *out = NULL;
72 if (!valid_sockaddr(address, length) || (!!server_tls != !!accept) || (server_tls && !server_tls->server))
73 return SET_ERRNO(ERROR_INVALID_PARAM, "QUIC UDP requires a concrete bind address and valid listener");
74 quic_udp_endpoint_t *endpoint = SAFE_CALLOC(1, sizeof(*endpoint), quic_udp_endpoint_t *);
75 if (!endpoint)
76 return SET_ERRNO(ERROR_MEMORY, "Cannot allocate QUIC UDP endpoint");
77 endpoint->socket = socket_create("quic_udp", address->sa_family, SOCK_DGRAM, 0);
78 if (endpoint->socket == INVALID_SOCKET_VALUE || socket_bind(endpoint->socket, address, length) != 0 ||
79 socket_set_nonblocking(endpoint->socket, true) != 0) {
80 if (endpoint->socket != INVALID_SOCKET_VALUE)
81 socket_close(endpoint->socket);
82 SAFE_FREE(endpoint);
83 return SET_ERRNO(ERROR_NETWORK, "Cannot bind QUIC UDP endpoint");
84 }
85 endpoint->local_length = sizeof(endpoint->local);
86 if (socket_getsockname(endpoint->socket, (struct sockaddr *)&endpoint->local, &endpoint->local_length) != 0) {
87 socket_close(endpoint->socket);
88 SAFE_FREE(endpoint);
89 return SET_ERRNO(ERROR_NETWORK, "Cannot obtain QUIC UDP endpoint address");
90 }
91 endpoint->server_tls = server_tls;
92 if (server_tls) {
93 if (sodium_init() < 0) {
94 socket_close(endpoint->socket);
95 SAFE_FREE(endpoint);
96 return SET_ERRNO(ERROR_CRYPTO, "Cannot initialize QUIC Retry token secret");
97 }
98 randombytes_buf(endpoint->retry_secret, sizeof(endpoint->retry_secret));
99 }
100 endpoint->accept = accept;
101 endpoint->context = context;
102 *out = endpoint;
103 return ASCIICHAT_OK;
104}
#define SAFE_CALLOC(count, size, cast)
Definition common.h:275
@ ERROR_MEMORY
Definition error_codes.h:51
@ ERROR_CRYPTO
Definition error_codes.h:93
quic_tls_t * server_tls
Definition udp.c:37
uint8_t retry_secret[32]
Definition udp.c:38
void * context
Definition udp.c:40
quic_udp_accept_fn accept
Definition udp.c:39
struct quic_udp_endpoint quic_udp_endpoint_t
Definition udp.h:14

References quic_udp_endpoint::accept, ASCIICHAT_OK, quic_udp_endpoint::context, ERROR_CRYPTO, ERROR_INVALID_PARAM, ERROR_MEMORY, ERROR_NETWORK, quic_udp_endpoint::local, quic_udp_endpoint::local_length, out, quic_udp_endpoint::retry_secret, SAFE_CALLOC, SAFE_FREE, quic_tls_t::server, quic_udp_endpoint::server_tls, SET_ERRNO, and quic_udp_endpoint::socket.

Referenced by quic_endpoint_open(), and quic_udp_migrate().

◆ quic_udp_endpoint_destroy()

void quic_udp_endpoint_destroy ( quic_udp_endpoint_t ** endpoint)

Definition at line 372 of file udp.c.

372 {
373 if (!endpoint || !*endpoint)
374 return;
375 while ((*endpoint)->peers)
376 (void)quic_udp_remove(*endpoint, (*endpoint)->peers->connection);
377 socket_close((*endpoint)->socket);
378 sodium_memzero((*endpoint)->retry_secret, sizeof((*endpoint)->retry_secret));
379 SAFE_FREE(*endpoint);
380 *endpoint = NULL;
381}
asciichat_error_t quic_udp_remove(quic_udp_endpoint_t *endpoint, quic_connection_t *connection)
Definition udp.c:356

References udp_peer::connection, quic_udp_endpoint::peers, quic_udp_remove(), and SAFE_FREE.

Referenced by quic_endpoint_destroy(), quic_endpoint_open(), and quic_udp_migrate().

◆ quic_udp_migrate()

asciichat_error_t quic_udp_migrate ( quic_udp_endpoint_t * endpoint,
const struct sockaddr * address,
socklen_t length,
uint64_t now_ns )

Definition at line 383 of file udp.c.

384 {
385 if (!endpoint || endpoint->server_tls || endpoint->count != 1 || !valid_sockaddr(address, length))
386 return SET_ERRNO(ERROR_INVALID_PARAM, "QUIC migration requires a single client connection and concrete address");
387 if (endpoint->peers->pending_length)
388 return SET_ERRNO(ERROR_BUFFER_FULL, "Flush the pending UDP packet before migrating");
389 quic_udp_endpoint_t *candidate = NULL;
390 asciichat_error_t result = quic_udp_endpoint_create(address, length, NULL, NULL, NULL, &candidate);
391 if (result != ASCIICHAT_OK)
392 return result;
393 result = quic_connection_migrate(endpoint->peers->connection, (struct sockaddr *)&candidate->local,
394 candidate->local_length, now_ns);
395 if (result == ASCIICHAT_OK) {
396 socket_t old_socket = endpoint->socket;
397 endpoint->socket = candidate->socket;
398 candidate->socket = old_socket;
399 endpoint->local = candidate->local;
400 endpoint->local_length = candidate->local_length;
401 }
402 quic_udp_endpoint_destroy(&candidate);
403 return result;
404}
int socket_t
asciichat_error_t quic_connection_migrate(quic_connection_t *connection, const struct sockaddr *local, socklen_t length, uint64_t now_ns)
size_t count
Definition udp.c:42
size_t pending_length
Definition udp.c:30
void quic_udp_endpoint_destroy(quic_udp_endpoint_t **endpoint)
Definition udp.c:372
asciichat_error_t quic_udp_endpoint_create(const struct sockaddr *address, socklen_t length, quic_tls_t *server_tls, quic_udp_accept_fn accept, void *context, quic_udp_endpoint_t **out)
Definition udp.c:67

References ASCIICHAT_OK, udp_peer::connection, quic_udp_endpoint::count, ERROR_BUFFER_FULL, ERROR_INVALID_PARAM, quic_udp_endpoint::local, quic_udp_endpoint::local_length, quic_udp_endpoint::peers, udp_peer::pending_length, quic_connection_migrate(), quic_udp_endpoint_create(), quic_udp_endpoint_destroy(), quic_udp_endpoint::server_tls, SET_ERRNO, and quic_udp_endpoint::socket.

Referenced by quic_endpoint_migrate().

◆ quic_udp_pump()

asciichat_error_t quic_udp_pump ( quic_udp_endpoint_t * endpoint,
uint64_t now,
quic_connection_t ** failed )

Definition at line 222 of file udp.c.

222 {
223 if (!endpoint || !failed)
224 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC UDP pump arguments");
225 *failed = NULL;
226 for (unsigned i = 0; i < QUIC_UDP_READ_BATCH; ++i) {
227 uint8_t data[65536];
228 struct sockaddr_storage remote = {0};
229 socklen_t remote_length = sizeof(remote);
230 ssize_t received =
231 socket_recvfrom(endpoint->socket, data, sizeof(data), 0, (struct sockaddr *)&remote, &remote_length);
232 if (received < 0) {
233 int error = socket_get_last_error();
234 if (socket_is_would_block_error(error))
235 break;
236 /* An ICMP error for an earlier datagram does not identify a QUIC
237 * connection and must not terminate a shared listener. */
238 if (socket_is_connection_reset_error(error))
239 continue;
240 return SET_ERRNO(ERROR_NETWORK, "QUIC UDP receive failed");
241 }
242 if (!received || !valid_sockaddr((struct sockaddr *)&remote, remote_length))
243 continue;
244 asciichat_error_t result =
245 receive_one(endpoint, data, (size_t)received, (struct sockaddr *)&remote, remote_length, now, failed);
246 if (result != ASCIICHAT_OK)
247 return result;
248 }
249 for (udp_peer_t *peer = endpoint->peers; peer; peer = peer->next) {
250 if (quic_connection_expiry(peer->connection) <= now) {
251 asciichat_error_t result = quic_connection_handle_expiry(peer->connection, now);
252 if (result != ASCIICHAT_OK) {
253 *failed = peer->connection;
254 return result;
255 }
256 }
257 for (unsigned i = 0; i < QUIC_UDP_WRITE_BATCH; ++i) {
258 if (!peer->pending_length) {
259 asciichat_error_t result = quic_connection_write(peer->connection, &peer->pending_path, peer->pending,
260 sizeof(peer->pending), &peer->pending_length, now);
261 if (result != ASCIICHAT_OK) {
262 *failed = peer->connection;
263 return result;
264 }
265 if (!peer->pending_length)
266 break;
267 }
268 ngtcp2_addr *remote = &peer->pending_path.path.remote;
269 ssize_t sent = socket_sendto(endpoint->socket, peer->pending, peer->pending_length, 0, remote->addr,
270 (socklen_t)remote->addrlen);
271 if (sent < 0 && socket_is_would_block_error(socket_get_last_error()))
272 break;
273 if (sent < 0 || (size_t)sent != peer->pending_length)
274 return SET_ERRNO(ERROR_NETWORK, "QUIC UDP send failed");
275 peer->pending_length = 0;
276 asciichat_error_t result = quic_connection_packet_sent(peer->connection, now);
277 if (result != ASCIICHAT_OK) {
278 *failed = peer->connection;
279 return result;
280 }
281 }
282 }
283 return ASCIICHAT_OK;
284}
asciichat_error_t quic_connection_handle_expiry(quic_connection_t *connection, uint64_t now_ns)
asciichat_error_t quic_connection_write(quic_connection_t *connection, ngtcp2_path_storage *path, void *packet, size_t capacity, size_t *length, uint64_t now_ns)
asciichat_error_t quic_connection_packet_sent(quic_connection_t *connection, uint64_t now_ns)
uint64_t quic_connection_expiry(const quic_connection_t *connection)
#define QUIC_UDP_READ_BATCH
Definition udp.c:12
#define QUIC_UDP_WRITE_BATCH
Definition udp.c:13

References ASCIICHAT_OK, udp_peer::connection, ERROR_INVALID_PARAM, ERROR_NETWORK, udp_peer::next, quic_udp_endpoint::peers, udp_peer::pending, udp_peer::pending_length, udp_peer::pending_path, quic_connection_expiry(), quic_connection_handle_expiry(), quic_connection_packet_sent(), quic_connection_write(), QUIC_UDP_READ_BATCH, QUIC_UDP_WRITE_BATCH, SET_ERRNO, and quic_udp_endpoint::socket.

◆ quic_udp_remove()

asciichat_error_t quic_udp_remove ( quic_udp_endpoint_t * endpoint,
quic_connection_t * connection )

Definition at line 356 of file udp.c.

356 {
357 if (!endpoint || !connection)
358 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC UDP removal");
359 udp_peer_t **next = &endpoint->peers;
360 while (*next && (*next)->connection != connection)
361 next = &(*next)->next;
362 if (!*next)
363 return SET_ERRNO(ERROR_INVALID_PARAM, "QUIC UDP connection is not owned by endpoint");
364 udp_peer_t *peer = *next;
365 *next = peer->next;
366 --endpoint->count;
368 SAFE_FREE(peer);
369 return ASCIICHAT_OK;
370}
void quic_connection_destroy(quic_connection_t **connection)

References ASCIICHAT_OK, udp_peer::connection, quic_udp_endpoint::count, ERROR_INVALID_PARAM, udp_peer::next, quic_udp_endpoint::peers, quic_connection_destroy(), SAFE_FREE, and SET_ERRNO.

Referenced by quic_connect(), quic_endpoint_stop(), quic_release(), and quic_udp_endpoint_destroy().

◆ quic_udp_wait()

asciichat_error_t quic_udp_wait ( quic_udp_endpoint_t * endpoint,
uint64_t wait_ns,
bool want_write,
bool * ready )

Definition at line 304 of file udp.c.

304 {
305 if (!endpoint || !ready)
306 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC UDP wait");
307 *ready = false;
308 struct pollfd fd = {.fd = endpoint->socket, .events = (short)(POLLIN | (want_write ? POLLOUT : 0))};
309 int64_t timeout = wait_ns > INT64_MAX ? INT64_MAX : (int64_t)wait_ns;
310 int result = socket_poll(&fd, 1, timeout);
311 if (result < 0)
312 return SET_ERRNO(ERROR_NETWORK, "QUIC UDP poll failed");
313 if (result > 0 && (fd.revents & (POLLERR | POLLNVAL)))
314 return SET_ERRNO(ERROR_NETWORK, "QUIC UDP socket poll reported an error");
315 *ready = result > 0;
316 return ASCIICHAT_OK;
317}

References ASCIICHAT_OK, ERROR_INVALID_PARAM, ERROR_NETWORK, SET_ERRNO, and quic_udp_endpoint::socket.

◆ quic_udp_wait_parameters()

asciichat_error_t quic_udp_wait_parameters ( const quic_udp_endpoint_t * endpoint,
uint64_t now_ns,
uint64_t maximum_wait_ns,
uint64_t * wait_ns,
bool * want_write )

Definition at line 286 of file udp.c.

287 {
288 if (!endpoint || !wait_ns || !want_write || now_ns == UINT64_MAX)
289 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC UDP wait parameters");
290 *wait_ns = maximum_wait_ns;
291 *want_write = false;
292 for (const udp_peer_t *peer = endpoint->peers; peer; peer = peer->next) {
293 uint64_t expiry = quic_connection_expiry(peer->connection);
294 if (expiry <= now_ns)
295 *wait_ns = 0;
296 else if (expiry != UINT64_MAX && expiry - now_ns < *wait_ns)
297 *wait_ns = expiry - now_ns;
298 if (peer->pending_length)
299 *want_write = true;
300 }
301 return ASCIICHAT_OK;
302}
unsigned long long uint64_t
Definition common.h:63

References ASCIICHAT_OK, udp_peer::connection, ERROR_INVALID_PARAM, udp_peer::next, quic_udp_endpoint::peers, udp_peer::pending_length, quic_connection_expiry(), and SET_ERRNO.

◆ quic_udp_wake()

asciichat_error_t quic_udp_wake ( quic_udp_endpoint_t * endpoint)

Definition at line 319 of file udp.c.

319 {
320 if (!endpoint)
321 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid QUIC UDP wake");
322 const uint8_t wake = 0;
323 ssize_t sent = socket_sendto(endpoint->socket, &wake, sizeof(wake), 0, (struct sockaddr *)&endpoint->local,
324 endpoint->local_length);
325 if (sent != (ssize_t)sizeof(wake))
326 return SET_ERRNO(ERROR_NETWORK, "Cannot wake QUIC UDP endpoint");
327 return ASCIICHAT_OK;
328}

References ASCIICHAT_OK, ERROR_INVALID_PARAM, ERROR_NETWORK, quic_udp_endpoint::local, quic_udp_endpoint::local_length, SET_ERRNO, and quic_udp_endpoint::socket.

Referenced by quic_worker_wake().