CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
net_shared.h
1#pragma once
2#include <cx/buffer/buffer.h>
4#include <cx/buffer/bufring.h>
6#include <cx/stype/stype.h>
7#include <cx/thread/prqueue.h>
8
9typedef struct NetSocket NetSocket;
10typedef struct NetQueue NetQueue;
11typedef struct NetFlow NetFlow;
12
15
17typedef intptr NetSockHandle;
18
20#define NET_INVALID_HANDLE ((NetSockHandle)-1)
21
23typedef enum {
24 NQ_None = 0x00,
25
28
34 NQ_AutoAccept = 0x02
36
47
109
110// Backend hook called when a send leaves data queued on a socket, so the backend can arrange
111// for it to drain later. Not used by application code; each backend supplies its own.
112typedef void (*NetSendPumpFn)(void* ctx, NetSocket* sock);
113
114// Backend hook that interrupts a parked wait so the loop recomputes its timeout. Arming a timer
115// nearer than the deadline the backend is currently sleeping on calls this; without it the timer
116// would not fire until whatever the backend was already waiting for woke it. Each backend supplies
117// its own (a self-pipe write, a select wake socket, a posted completion).
118typedef void (*NetWakeFn)(void* ctx);
119
121typedef enum {
122 NSO_None = 0x00,
123
128
130 NSO_Peek = 0x02
132
151
161
175
182
185#define NET_FILTER_RING_SEGSZ 16384
186
195typedef enum {
198
203 NFN_AppCustom = 1000
205
210typedef uint64 NetTimerId;
211
213typedef enum {
214 NTF_None = 0x00,
215
220 NTF_Repeat = 0x01
222
223// Internal delivery hook for a timer armed by the framework itself rather than by an application.
224// A timer with one of these attached is fired INLINE on whichever thread ran the sweep, not
225// through the flow's inbox, so it must do no more than the connect state machine does: claim a
226// transition and hand off. Application timers always leave this NULL and arrive as NET_Timer.
227typedef void (*NetTimerFn)(NetFlow* flow, NetTimerId id, void* ctx);
228
229// One armed timer, stored in the queue's binary min-heap (see NetQueue::timers). `flow` is a
230// strong reference: an armed timer is a reason to keep its flow alive, and the flow drops them
231// all on its terminal path so a long deadline on a dead connection cannot pin one indefinitely.
232typedef struct NetTimerEntry {
233 int64 deadline; // absolute clockTimer() microseconds
234 int64 interval; // re-arm delay for NTF_Repeat; unused otherwise
235 NetTimerId id;
236 NetFlow* flow; // owner, strong
237 NetTimerFn fn; // NULL -> deliver NET_Timer through the flow instead
238 void* ctx; // context for fn
239 flags_t flags; // NetTimerFlags
240} NetTimerEntry;
241
267
269typedef enum {
272 NA_IPv6 = 2
274
283typedef struct NetAddr {
285 union {
286 uint8 ipv4[4];
287 uint8 ipv6[16];
288 };
289 uint32 scope;
290 uint16 port;
293
294// NetAddr is a full stype so it can be used as a hashtable key -- the datagram flow table is
295// keyed on it. Comparison and hashing look only at the bytes that are actually meaningful for
296// the address's type, rather than doing a plain memcmp of the whole struct, which would treat
297// two identical IPv4 peers as different since part of the union is left unset.
299#define SType_NetAddr NetAddr*
300#define STStorageType_NetAddr NetAddr
301#define STypeArg_NetAddr(type, val) stgeneric(opaque, &(val))
302#define STypeArgPtr_NetAddr(type, val) &stgeneric(opaque, (val))
303#define STypeCheckedArg_NetAddr(type, val) stType(type), stArg(type, val)
304#define STypeCheckedPtrArg_NetAddr(type, val) stType(type), stArgPtr(type, val)
305
318
328typedef struct NetPktInfo {
335
336 uint8 ecn;
338 bool haveEcn;
340
341// Hook that diverts a received datagram before it reaches the socket's flow table. cxquic installs
342// one on the UDP endpoint socket behind a QUIC listener, so arriving packets are demultiplexed by
343// Connection ID -- which is what lets a connection survive its peer changing address -- instead of
344// by the peer address the flow table is keyed on. It takes ownership of `buf` and does its own
345// submit; its return value becomes the ingest result. A socket with no hook installed is unchanged.
346// `ctx` is the object the hook was installed with, referenced for the length of the call.
347typedef bool (*NetDatagramRouteFn)(ObjInst* ctx, NetSocket* sock, NetAddr* peer,
348 const NetPktInfo* info, Buffer* buf);
349
350// Internally a NetMessage is any packet in flight: the library rides its own bookkeeping
351// messages (NetMessageKind, net_private.h) through flow inboxes alongside data, but drainFlow()
352// translates those into NetEvents and retires them before any handler runs, so an application
353// never sees one -- hence the consumer-oriented documentation below.
354
361typedef struct NetMessage {
362 struct NetMessage* next; // internal: intrusive link for the flow inbox / NetMsgQueue
363
369
370 // internal: how many bytes a stream receive appended to the socket's ring; overloaded as a
371 // NetErrorCode by some internal message kinds
372 size_t bytes;
373
375
382
383 union {
384 // internal: the accepted socket in transit to a NET_Accepted event
385 NetSocket* asock;
386 // internal: which timer fired, for NMSG_Timer. Shares storage with asock because the two
387 // kinds are mutually exclusive, so on 64-bit this costs the message header nothing.
388 NetTimerId timerId;
389 };
390
391 uint8 kind; // internal: NetMessageKind (net_private.h)
392 uint8 reason; // internal: NetCloseReason, for a flow's terminal message
393 uint8 flags; // internal: NetMessageFlags (net_private.h) -- how `buf` must be reclaimed
395
396// Type-specific socket buffers, selected by NetSocketType. Internal to the socket
397// implementation -- application code does not touch this directly.
398typedef struct NetSocketBufs {
399 union {
400 struct {
401 BufRing recv; // Inbound byte stream
402 BufChain send; // Outbound; owns app buffers with no copy on the way in
403 } stream;
404 struct {
405 PrQueue send; // NetMessage entries, each with its own destination address
406 } dgram;
407 };
408} NetSocketBufs;
409
420
427#define netMsgQueueEmpty(q) ((q)->head == NULL)
428
436_meta_inline void netMsgQueuePush(_Inout_ NetMsgQueue* q, _Inout_ NetMessage* msg)
437{
438 msg->next = NULL;
439 if (q->tail)
440 q->tail->next = msg;
441 else
442 q->head = msg;
443 q->tail = msg;
444}
445
453_Check_return_ _Ret_maybenull_ _meta_inline NetMessage* netMsgQueuePop(_Inout_ NetMsgQueue* q)
454{
455 NetMessage* msg = q->head;
456 if (!msg)
457 return NULL;
458
459 q->head = msg->next;
460 if (!q->head)
461 q->tail = NULL;
462 msg->next = NULL;
463 return msg;
464}
465
467
490
598
600typedef struct NetEvent {
604
611
617 void* ctx;
618
620 union {
622 struct {
626
628 struct {
629 NetSocket* newSocket; //< Socket for newly accepted connection
631
633 struct {
634 size_t bytes;
635 size_t total;
636
644
646 struct {
647 NetErrorCode err;
649
651 struct {
654
656 struct {
657 struct NetMessage* msg;
659
661 struct {
664
666 struct {
669 };
671
675typedef void (*NetEventCB)(_In_ NetEvent* event);
676
690
714typedef void (*NetConnectPrepCB)(_Inout_ NetSocket* sock, _In_opt_ void* ctx);
715
Buffer chain implementation for efficient streaming I/O.
Simple buffer management.
Ring buffer implementation for efficient streaming I/O.
#define saDeclare(name)
Definition sarray.h:93
void(* NetConnectPrepCB)(NetSocket *sock, void *ctx)
Definition net_shared.h:714
NetEventType
Network event types.
Definition net_shared.h:495
void(* NetEventCB)(NetEvent *event)
Definition net_shared.h:675
@ NET_FlowClosed
A flow is being torn down; release any state hanging off flow->user.
Definition net_shared.h:584
@ NET_Connection
A connection attempt resolved.
Definition net_shared.h:502
@ NET_SendReady
The send backlog drained; sending can resume.
Definition net_shared.h:544
@ NET_Accepted
A listening socket accepted an incoming connection.
Definition net_shared.h:523
@ NET_FilterNotify
A filter raised an out-of-band notification.
Definition net_shared.h:515
@ NET_DataReceived
Data arrived on a socket.
Definition net_shared.h:536
@ NET_FlowOpen
A flow was created for a new peer.
Definition net_shared.h:566
@ NET_Error
An error surfaced asynchronously on the socket.
Definition net_shared.h:554
@ NET_Timer
A timer armed on this flow reached its deadline.
Definition net_shared.h:596
@ NET_FlowRefused
A packet arrived from a source with no flow, and none could be created.
Definition net_shared.h:577
NetEcn
Explicit Congestion Notification codepoint, as carried in the IP header.
Definition net_shared.h:312
NetAddrType
Network address types.
Definition net_shared.h:269
NetCloseReason
Definition net_shared.h:166
NetTimerFlags
Flags controlling how an armed timer behaves.
Definition net_shared.h:213
intptr NetSockHandle
Platform-neutral OS socket handle: a Windows SOCKET or a Unix file descriptor.
Definition net_shared.h:17
NetConnectPref
Definition net_shared.h:40
uint64 NetTimerId
Handle to an armed timer, unique for the lifetime of its queue.
Definition net_shared.h:210
NetSocketOpFlags
Flags for socket send/receive operations.
Definition net_shared.h:121
NetQueueFlags
Flags for creating a NetQueue.
Definition net_shared.h:23
NetConnectionState
Network connection states (for event notification)
Definition net_shared.h:177
NetErrorCode
Network error codes.
Definition net_shared.h:243
NetSocketState
State of a network socket.
Definition net_shared.h:153
void netMsgQueuePush(NetMsgQueue *q, NetMessage *msg)
Definition net_shared.h:436
NetFilterNotify
Definition net_shared.h:195
NetMessage * netMsgQueuePop(NetMsgQueue *q)
Definition net_shared.h:453
NetSocketType
Socket types.
Definition net_shared.h:134
@ NET_ECN_CE
Congestion experienced: a router marked this packet on the way.
Definition net_shared.h:316
@ NET_ECN_Ect0
ECN-capable transport, codepoint 0.
Definition net_shared.h:315
@ NET_ECN_NotEct
Not ECN-capable: a congested router drops this packet.
Definition net_shared.h:313
@ NET_ECN_Ect1
ECN-capable transport, codepoint 1.
Definition net_shared.h:314
@ NA_Unknown
Unknown or invalid.
Definition net_shared.h:270
@ NA_IPv6
IPv6 address.
Definition net_shared.h:272
@ NA_IPv4
IPv4 address.
Definition net_shared.h:271
@ NCR_Error
Connection reset or other fatal socket error.
Definition net_shared.h:171
@ NCR_Shutdown
The queue is shutting down.
Definition net_shared.h:173
@ NCR_None
Not closing.
Definition net_shared.h:167
@ NCR_SocketClosed
The owning socket was closed with flows still live.
Definition net_shared.h:172
@ NCR_Reclaimed
Reclaimed under flow cap pressure (resurrectable)
Definition net_shared.h:168
@ NCR_AppClosed
Application called netflowClose()
Definition net_shared.h:169
@ NCR_PeerClosed
Stream peer closed the connection cleanly.
Definition net_shared.h:170
@ NTF_Repeat
Re-arm automatically after each fire, at the same delay.
Definition net_shared.h:220
@ NCP_PreferV6
Interleave, but IPv6 leads regardless of resolver order.
Definition net_shared.h:43
@ NCP_Default
Interleave; the first address the resolver returned leads.
Definition net_shared.h:41
@ NCP_V6Only
Discard every IPv4 result.
Definition net_shared.h:45
@ NCP_V4Only
Discard every IPv6 result.
Definition net_shared.h:44
@ NCP_PreferV4
Interleave, but IPv4 leads regardless of resolver order.
Definition net_shared.h:42
@ NSO_Immediate
Definition net_shared.h:127
@ NSO_Peek
For receive operations, peek at the data without removing it from the socket buffer.
Definition net_shared.h:130
@ NSO_None
No special options.
Definition net_shared.h:122
@ NQ_AutoAccept
Automatically add accepted sockets to the queue.
Definition net_shared.h:34
@ NQ_SelectOnly
Force use of the select() API, even if more efficient backends are available.
Definition net_shared.h:27
@ NCS_Connecting
Connection in progress.
Definition net_shared.h:179
@ NCS_Connected
Connected.
Definition net_shared.h:180
@ NCS_NotConnected
Not connected.
Definition net_shared.h:178
@ NERR_Interrupted
Interrupted by a signal before anything was transferred.
Definition net_shared.h:265
@ NERR_HostUnreachable
Host is unreachable.
Definition net_shared.h:249
@ NERR_NetworkDown
Network is down.
Definition net_shared.h:250
@ NERR_ConnectionRefused
Connection was refused by the remote host.
Definition net_shared.h:246
@ NERR_ConnectionReset
Connection was reset by peer.
Definition net_shared.h:254
@ NERR_AddressInUse
Address already in use.
Definition net_shared.h:251
@ NERR_WouldBlock
The operation would have blocked; no data available yet.
Definition net_shared.h:260
@ NERR_Unknown
Unknown error.
Definition net_shared.h:245
@ NERR_AlreadyConnected
Socket is already connected.
Definition net_shared.h:252
@ NERR_None
No error.
Definition net_shared.h:244
@ NERR_Timeout
Connection timed out.
Definition net_shared.h:247
@ NERR_NetworkUnreachable
Network is unreachable.
Definition net_shared.h:248
@ NERR_NotConnected
Socket is not connected.
Definition net_shared.h:253
@ NS_Closed
Socket is closed and cannot be reused.
Definition net_shared.h:159
@ NS_Connected
Socket is connected (default for bound connectionless sockets)
Definition net_shared.h:155
@ NS_Resolving
Waiting for name resolution.
Definition net_shared.h:158
@ NS_Listening
Socket is listening for incoming connections.
Definition net_shared.h:156
@ NS_Connecting
Socket is in the process of connecting.
Definition net_shared.h:157
@ NS_Init
Socket is not yet used.
Definition net_shared.h:154
@ NFN_Secured
The filter's secure channel is up; the application may send now.
Definition net_shared.h:197
@ NFN_None
No notification.
Definition net_shared.h:196
@ NFN_AppCustom
First code reserved for application-defined filter notifications.
Definition net_shared.h:203
@ NST_Quic
QUIC connection or listener, implemented by cxquic on top of a datagram socket.
Definition net_shared.h:149
@ NST_Stream
Definition net_shared.h:137
@ NST_Datagram
Definition net_shared.h:141
#define stDeclare(name)
Definition stype.h:1908
Lock-free pointer FIFO queue.
Dynamic arrays with type-safe generic programming.
uint16 port
Port number.
Definition net_shared.h:290
uint8 ipv6[16]
IPv6 address.
Definition net_shared.h:287
uint8 ipv4[4]
IPv4 address.
Definition net_shared.h:286
uint32 scope
Scope ID (for IPv6)
Definition net_shared.h:289
NetAddrType type
Address type (NA_IPv4, NA_IPv6)
Definition net_shared.h:284
Network Event Structure.
Definition net_shared.h:600
struct NetEvent::@11::@17 filter
NET_FilterNotify.
struct NetEvent::@11::@15 recv
NET_DataReceived.
struct NetEvent::@11::@13 conn
NET_Connection event data.
NetCloseReason reason
Why the flow is being torn down.
Definition net_shared.h:662
size_t total
Total bytes pending in receive buffer.
Definition net_shared.h:635
NetQueue * queue
Originating NetQueue.
Definition net_shared.h:602
NetErrorCode err
Error code if connection failed (NERR_None if successful)
Definition net_shared.h:624
NetSocket * socket
Associated socket.
Definition net_shared.h:603
struct NetMessage * msg
Datagram: the packet itself. NULL for stream sockets.
Definition net_shared.h:642
NetTimerId id
Which of the flow's armed timers reached its deadline.
Definition net_shared.h:667
NetEventType event
Type of event.
Definition net_shared.h:601
struct NetEvent::@11::@19 closed
NET_FlowClosed.
struct NetEvent::@11::@18 refused
NET_FlowRefused (NET_FlowOpen carries no event data; the flow itself is the payload)
struct NetEvent::@11::@16 error
NET_Error.
struct NetEvent::@11::@14 accept
NET_Accepted.
void * ctx
The context pointer passed to netflowSetHandlers / netsocketSetHandlers / netqueueSetHandlers when th...
Definition net_shared.h:617
NetConnectionState state
Current connection state.
Definition net_shared.h:623
NetFlow * flow
Flow the event belongs to, or NULL for socket-wide events.
Definition net_shared.h:610
size_t bytes
Number of bytes received.
Definition net_shared.h:634
struct NetEvent::@11::@20 timer
NET_Timer.
NetFilterNotify notify
Which notification the filter raised (NFN_Secured, ...)
Definition net_shared.h:652
A single ordering domain: one connection, or one datagram peer.
Definition flow.h:116
Set of event handlers, registered per flow, per socket, or queue-wide.
Definition net_shared.h:678
NetEventCB flowClosed
NET_FlowClosed: release state hanging off flow->user.
Definition net_shared.h:686
NetEventCB sendReady
NET_SendReady: send buffer drained below the low watermark.
Definition net_shared.h:683
NetEventCB error
NET_Error: a queued send failed asynchronously.
Definition net_shared.h:687
NetEventCB flowRefused
NET_FlowRefused: packet from an unknown source, no flow made.
Definition net_shared.h:685
NetEventCB connection
NET_Connection: established, failed, or state changed.
Definition net_shared.h:679
NetEventCB accepted
NET_Accepted: new incoming connection.
Definition net_shared.h:681
NetEventCB flowOpen
NET_FlowOpen: a flow was created; set up state on flow->user.
Definition net_shared.h:684
NetEventCB recv
NET_DataReceived: stream data or a complete datagram.
Definition net_shared.h:682
NetEventCB timer
NET_Timer: a timer armed on the flow reached its deadline.
Definition net_shared.h:688
NetEventCB filterNotify
NET_FilterNotify: a filter raised a notification (NFN_Secured, ...)
Definition net_shared.h:680
A received packet, as delivered to a handler.
Definition net_shared.h:361
NetPktInfo info
What the IP layer carried with this datagram, where the platform could report it.
Definition net_shared.h:381
NetAddr addr
Source / destination address.
Definition net_shared.h:374
Buffer buf
Message data (NULL for stream data, which is buffered in the socket's ring)
Definition net_shared.h:368
Simple intrusive FIFO of NetMessage, linked through NetMessage::next.
Definition net_shared.h:416
NetMessage * tail
Newest queued message, or NULL if empty.
Definition net_shared.h:418
NetMessage * head
Oldest queued message, or NULL if empty.
Definition net_shared.h:417
Per-datagram information the IP layer carries alongside the payload.
Definition net_shared.h:328
bool haveEcn
ecn is filled in
Definition net_shared.h:338
uint8 ecn
NetEcn codepoint; only meaningful when haveEcn is set.
Definition net_shared.h:336
NetAddr local
Receive: the local address the datagram arrived on. Send: the address to leave from.
Definition net_shared.h:334
bool haveLocal
local is filled in
Definition net_shared.h:337
int64 connectAttemptTimeout
Shorter timeout for connect attempts other than the last remaining address of their family,...
Definition net_shared.h:101
bool noReclaim
Never reclaim, even at the cap.
Definition net_shared.h:68
int64 reclaimMinIdle
Minimum time a flow must have been idle before cap-pressure reclaim may evict it, in microseconds (0 ...
Definition net_shared.h:80
uint32 reclaimBatch
Flows to reclaim per cap hit.
Definition net_shared.h:67
uint32 recvBufInitial
Buffers preallocated at queue creation.
Definition net_shared.h:63
int64 connectTimeout
How long a single connect attempt may run before it's cancelled and the next resolved address is trie...
Definition net_shared.h:93
int32 nthreads
Number of worker threads, or 0 for polled mode.
Definition net_shared.h:59
size_t recvBufSize
Size of each pooled receive buffer.
Definition net_shared.h:62
flags_t flags
NetQueueFlags.
Definition net_shared.h:60
NetConnectPref connectPref
Default address-family preference for connects on this queue (see NetConnectPref)
Definition net_shared.h:107
uint32 maxflows
Cap on concurrent flows across the queue (0 = unlimited)
Definition net_shared.h:66
uint32 recvBufMax
Hard cap on live buffers; the receive memory ceiling.
Definition net_shared.h:64
size_t sendHigh
Default send high watermark for sockets on this queue.
Definition net_shared.h:82
NetQueue manages one or more sockets and a thread pool of workers.
Definition queue.h:79
Runtime type system and type descriptor infrastructure.