6 Struct NETWORK
gullradriel edited this page 2026-11-02 12:42:25 +01:00

NETWORK

Module: NETWORK ENGINE: connect, accept, send and recv wrappers. Network Queue, thread-safe add/get message, ssl/tls secured communications

Structure of a NETWORK.

#include "n_network.h"

Public Attributes

Name
int wait_close_timeout
network wait close timeout value ( < 1 disabled, >= 1 timeout sec )
int user_id
if part of a user property, id of the user
int transport_type
transport type: NETWORK_TCP (0) or NETWORK_UDP (1)
int threaded_engine_status
Threaded network engine state for this network.
int tcpnodelay
state of naggle algorythm, 0 untouched, 1 forcibly disabled
uint32_t state
state of the connection , NETW_RUN, NETW_QUIT, NETW_STOP , NETW_ERR
SSL * ssl
SSL handle.
int so_sndtimeo
send timeout value, msecs ( -1 untouched, 0 none )
int so_sndbuf
size of the socket send buffer, 0 untouched, else size in bytes
int so_reuseaddr
so reuseaddr state
int so_rcvtimeo
receive timeout value, msecs ( -1 untouched, 0 none )
int so_rcvbuf
size of the socket recv buffer, 0 untouched, else size in bytes
int so_linger
close lingering value (-1 disabled, 0 force close, >0 linger )
int so_keepalive
so keepalive state
pthread_mutex_t sendbolt
mutex for threaded access of send_buf
pthread_t send_thr
sending thread
int send_queue_consecutive_wait
send queue consecutive pool interval, used when there are still items to send, in usec
netw_func send_data_once
single-attempt send (non-blocking / reactor use).
netw_func send_data
send func ptr
LIST * send_buf
sending buffer (for outgoing queuing )
sem_t send_blocker
block sending func
pthread_mutex_t recvbolt
mutex for threaded access of recv buf
pthread_t recv_thr
receiving thread
netw_func recv_data_once
single-attempt recv, same contract as send_data_once.
netw_func recv_data
receive func ptr
LIST * recv_buf
reveicing buffer (for incomming usage)
int reactor_write_armed
1 = EPOLLOUT currently registered
int reactor_send_wants_read
TLS-over-reactor: the in-flight send returned NETW_IO_WANT_READ (renegotiation), the reactor retries the write drain after the next readable event instead of waiting on EPOLLOUT.
size_t reactor_send_off
bytes already sent to socket
size_t reactor_send_len
total bytes in reactor_send_buf
char * reactor_send_buf
malloc'd framed bytes, NULL when idle
int reactor_registered
Reactor close-handshake latch.
int reactor_recv_wants_write
TLS-over-reactor: recv returned NETW_IO_WANT_WRITE, the reactor re-runs the readable drain after the next writable event.
uint32_t reactor_read_pkt_state
state word for the in-flight frame
uint32_t reactor_read_pkt_length
payload length for the in-flight frame
int reactor_read_phase
0=STATE, 1=LENGTH, 2=PAYLOAD
size_t reactor_read_payload_have
bytes accumulated into reactor_read_payload
char * reactor_read_payload
malloc'd accumulator for payload bytes
int reactor_read_hdr_have
bytes accumulated in reactor_read_hdr_buf
unsigned char[4] reactor_read_hdr_buf
accumulator for header words
int reactor_mode
Opt-in epoll-reactor mode flag.
void * reactor_handle
Back-pointer to the registered reactor.
int reactor_close_acked
Close handshake.
LIST * pools
pointers to network pools if members of any
char[8][512] netw_errors
per-connection error capture ring buffer (max 8 entries, 512 chars each)
int netw_err_next
next write slot in ring buffer
int netw_err_count
number of captured errors
int nb_running_threads
nb running threads, if > 0 thread engine is still running
int nb_pending
Nb pending connection,if listening.
int mode
NETWORK mode , 1 listening, 0 connecting.
const SSL_METHOD * method
SSL method container.
N_SOCKET link
networking socket
char * key
openssl key file
int in_dirty_list
Dirty-list membership flag.
int handshake_timeout
on a listener: deadline in msecs for the TLS handshake of each accepted connection ( 0 none )
pthread_mutex_t eventbolt
mutex for threaded access of state event
int deplete_socket_timeout
deplete socket send buffer timeout ( 0 disabled, > 0 wait for timeout and check unset/unack datas)
int deplete_queues_timeout
deplete network queues timeout ( 0 disabled, > 0 wait for timeout and check unset/unack datas)
SSL_CTX * ctx
SSL context holder.
int crypto_mode
tell if the socket have to be encrypted (flags NETW_CRYPTO_*)
int crypto_algo
if encryption is on, which one (flags NETW_ENCRYPT_*)
long long connect_tcp_usec
Measured TCP connect time of the most recent connect, in microseconds (0 if not measured).
long long connect_dns_usec
Measured DNS resolution time of the most recent connect, in microseconds (0 if not measured).
int compress_mode
Per-packet compression mode, see NETW_COMPRESS_MODE.
char * certificate
openssl certificate file
int addr_infos_loaded
Internal flag to know if we have to free addr infos.

Public Attributes Documentation

variable wait_close_timeout

int wait_close_timeout;

network wait close timeout value ( < 1 disabled, >= 1 timeout sec )

variable user_id

int user_id;

if part of a user property, id of the user

variable transport_type

int transport_type;

transport type: NETWORK_TCP (0) or NETWORK_UDP (1)

variable threaded_engine_status

int threaded_engine_status;

Threaded network engine state for this network.

NETW_THR_ENGINE_STARTED or NETW_THR_ENGINE_STOPPED

variable tcpnodelay

int tcpnodelay;

state of naggle algorythm, 0 untouched, 1 forcibly disabled

variable state

uint32_t state;

state of the connection , NETW_RUN, NETW_QUIT, NETW_STOP , NETW_ERR

variable ssl

SSL * ssl;

SSL handle.

variable so_sndtimeo

int so_sndtimeo;

send timeout value, msecs ( -1 untouched, 0 none )

variable so_sndbuf

int so_sndbuf;

size of the socket send buffer, 0 untouched, else size in bytes

variable so_reuseaddr

int so_reuseaddr;

so reuseaddr state

variable so_rcvtimeo

int so_rcvtimeo;

receive timeout value, msecs ( -1 untouched, 0 none )

variable so_rcvbuf

int so_rcvbuf;

size of the socket recv buffer, 0 untouched, else size in bytes

variable so_linger

int so_linger;

close lingering value (-1 disabled, 0 force close, >0 linger )

variable so_keepalive

int so_keepalive;

so keepalive state

variable sendbolt

pthread_mutex_t sendbolt;

mutex for threaded access of send_buf

variable send_thr

pthread_t send_thr;

sending thread

variable send_queue_consecutive_wait

int send_queue_consecutive_wait;

send queue consecutive pool interval, used when there are still items to send, in usec

variable send_data_once

netw_func send_data_once;

single-attempt send (non-blocking / reactor use).

Contract: one transport attempt; > 0 bytes written, NETW_IO_WANT_READ / NETW_IO_WANT_WRITE when the transport needs that readiness to progress, NETW_SOCKET_DISCONNECTED, or NETW_SOCKET_ERROR. Dispatches to the TLS variant when crypto is set, this is what lets the epoll reactor carry TLS connections.

variable send_data

netw_func send_data;

send func ptr

variable send_buf

LIST * send_buf;

sending buffer (for outgoing queuing )

variable send_blocker

sem_t send_blocker;

block sending func

variable recvbolt

pthread_mutex_t recvbolt;

mutex for threaded access of recv buf

variable recv_thr

pthread_t recv_thr;

receiving thread

variable recv_data_once

netw_func recv_data_once;

single-attempt recv, same contract as send_data_once.

variable recv_data

netw_func recv_data;

receive func ptr

variable recv_buf

LIST * recv_buf;

reveicing buffer (for incomming usage)

variable reactor_write_armed

int reactor_write_armed;

1 = EPOLLOUT currently registered

variable reactor_send_wants_read

int reactor_send_wants_read;

TLS-over-reactor: the in-flight send returned NETW_IO_WANT_READ (renegotiation), the reactor retries the write drain after the next readable event instead of waiting on EPOLLOUT.

Always 0 on cleartext sockets.

variable reactor_send_off

size_t reactor_send_off;

bytes already sent to socket

variable reactor_send_len

size_t reactor_send_len;

total bytes in reactor_send_buf

variable reactor_send_buf

char * reactor_send_buf;

malloc'd framed bytes, NULL when idle

variable reactor_registered

int reactor_registered;

Reactor close-handshake latch.

Set to 1 by [n_reactor_register](n__reactor_8c#user-content-function-n_reactor_register) and never cleared by the reactor (unlike [reactor_mode](Struct-NETWORK#user-content-variable-reactor_mode), which the reactor clears mid-unregister). [netw_close](Module-NETWORKING#user-content-function-netw_close) keys its decision to run [n_reactor_close_netw_sync](n__reactor_8c#user-content-function-n_reactor_close_netw_sync) on THIS flag rather than on the live [reactor_mode](Struct-NETWORK#user-content-variable-reactor_mode): otherwise, if the reactor clears reactor_mode during a peer-EOF unregister in the instant before netw_close reads it, the game thread would skip the ack-wait and free the NETWORK while the reactor is still inside [n_reactor_unregister](n__reactor_8c#user-content-function-n_reactor_unregister) (a use-after-free / data race). With the latch the game thread always waits for [reactor_close_acked](Struct-NETWORK#user-content-variable-reactor_close_acked), which the reactor publishes as the last thing it ever does with the NETWORK. Acquire/release __atomic access, same contract as the other reactor flags.

variable reactor_recv_wants_write

int reactor_recv_wants_write;

TLS-over-reactor: recv returned NETW_IO_WANT_WRITE, the reactor re-runs the readable drain after the next writable event.

Always 0 on cleartext sockets.

variable reactor_read_pkt_state

uint32_t reactor_read_pkt_state;

state word for the in-flight frame

variable reactor_read_pkt_length

uint32_t reactor_read_pkt_length;

payload length for the in-flight frame

variable reactor_read_phase

int reactor_read_phase;

0=STATE, 1=LENGTH, 2=PAYLOAD

variable reactor_read_payload_have

size_t reactor_read_payload_have;

bytes accumulated into reactor_read_payload

variable reactor_read_payload

char * reactor_read_payload;

malloc'd accumulator for payload bytes

variable reactor_read_hdr_have

int reactor_read_hdr_have;

bytes accumulated in reactor_read_hdr_buf

variable reactor_read_hdr_buf

unsigned char[4] reactor_read_hdr_buf;

accumulator for header words

variable reactor_mode

int reactor_mode;

Opt-in epoll-reactor mode flag.

0 (default) = classic per-connection thread engine; 1 = registered with an [n_reactor](n__reactor_8h#user-content-typedef-n_reactor). Atomically set by [n_reactor_register](n__reactor_8c#user-content-function-n_reactor_register), cleared by [n_reactor_unregister](n__reactor_8c#user-content-function-n_reactor_unregister). Read concurrently from the game thread (e.g. [netw_close](Module-NETWORKING#user-content-function-netw_close), [netw_add_msg](Module-NETWORKING#user-content-function-netw_add_msg)), always access via [netw_atomic_read_reactor_mode](Module-NETWORKING#user-content-define-netw_atomic_read_reactor_mode) / [netw_atomic_write_reactor_mode](Module-NETWORKING#user-content-define-netw_atomic_write_reactor_mode) so the read/clear race during peer-driven unregister is well-defined under TSan. Always 0 on platforms where N_REACTOR_AVAILABLE == 0.

variable reactor_handle

void * reactor_handle;

Back-pointer to the registered reactor.

Opaque void * so n_network.h doesn't need to include n_reactor.h (avoids a header-ordering dependency since n_reactor.h includes n_network.h itself). NULL when reactor_mode == 0. Same atomicity contract as [reactor_mode](Struct-NETWORK#user-content-variable-reactor_mode): use [netw_atomic_read_reactor_handle](Module-NETWORKING#user-content-define-netw_atomic_read_reactor_handle) / [netw_atomic_write_reactor_handle](Module-NETWORKING#user-content-define-netw_atomic_write_reactor_handle).

variable reactor_close_acked

int reactor_close_acked;

Close handshake.

Game thread sets NETW_EXIT_ASKED, notifies the reactor, and waits on this flag. [n_reactor_unregister](n__reactor_8c#user-content-function-n_reactor_unregister) publishes it with a release store as its final action, so EVERY unregister path (the EXIT_ASKED sweep, a peer EOF / EPOLLRDHUP, or a hard I/O error) releases the waiter, not just the sweep. The acquire-load on the game side observes, and is ordered after, every side effect of unregister (epoll DEL, cleared reactor_mode, freed accumulators, list removal) before it closes the socket / frees the NETWORK. Reset to 0 in [n_reactor_register](n__reactor_8c#user-content-function-n_reactor_register). Always accessed via __atomic builtins (release on the reactor side, acquire on the game side); plain volatile would give no happens-before and is a data race.

variable pools

LIST * pools;

pointers to network pools if members of any

variable netw_errors

char[8][512] netw_errors;

per-connection error capture ring buffer (max 8 entries, 512 chars each)

variable netw_err_next

int netw_err_next;

next write slot in ring buffer

variable netw_err_count

int netw_err_count;

number of captured errors

variable nb_running_threads

int nb_running_threads;

nb running threads, if > 0 thread engine is still running

variable nb_pending

int nb_pending;

Nb pending connection,if listening.

variable mode

int mode;

NETWORK mode , 1 listening, 0 connecting.

variable method

const SSL_METHOD * method;

SSL method container.

N_SOCKET link;

networking socket

variable key

char * key;

openssl key file

variable in_dirty_list

int in_dirty_list;

Dirty-list membership flag.

CAS-guards a NETWORK's membership in the reactor's dirty_pending list. Producer side ([n_reactor_notify_send](n__reactor_8c#user-content-function-n_reactor_notify_send)) attempts a 0-to-1 CAS; on success it pushes the NETWORK onto the dirty list and writes the wake-eventfd. Consumer side ([n_reactor_run](n__reactor_8c#user-content-function-n_reactor_run) wake handler) clears the flag BEFORE draining so a concurrent producer can immediately re-add the NETWORK for the next pass: no message can be lost.

variable handshake_timeout

int handshake_timeout;

on a listener: deadline in msecs for the TLS handshake of each accepted connection ( 0 none )

variable eventbolt

pthread_mutex_t eventbolt;

mutex for threaded access of state event

variable deplete_socket_timeout

int deplete_socket_timeout;

deplete socket send buffer timeout ( 0 disabled, > 0 wait for timeout and check unset/unack datas)

variable deplete_queues_timeout

int deplete_queues_timeout;

deplete network queues timeout ( 0 disabled, > 0 wait for timeout and check unset/unack datas)

variable ctx

SSL_CTX * ctx;

SSL context holder.

variable crypto_mode

int crypto_mode;

tell if the socket have to be encrypted (flags NETW_CRYPTO_*)

variable crypto_algo

int crypto_algo;

if encryption is on, which one (flags NETW_ENCRYPT_*)

variable connect_tcp_usec

long long connect_tcp_usec;

Measured TCP connect time of the most recent connect, in microseconds (0 if not measured).

Populated by netw_connect_ex_to.

variable connect_dns_usec

long long connect_dns_usec;

Measured DNS resolution time of the most recent connect, in microseconds (0 if not measured).

Populated by netw_connect_ex_to so callers can report a connect-phase timing breakdown.

variable compress_mode

int compress_mode;

Per-packet compression mode, see NETW_COMPRESS_MODE.

Set via netw_set_compression_mode(); default is NETW_COMPRESS_ZLIB to preserve the behaviour from when a single unconditional compression path was the only option. Any NETW_COMPRESSED_* flag on the wire is honoured on recv regardless of this field, so two peers with different send-side picks still interop.

variable certificate

char * certificate;

openssl certificate file

variable addr_infos_loaded

int addr_infos_loaded;

Internal flag to know if we have to free addr infos.