Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_network.c File Reference

Network Engine. More...

#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include "nilorea/n_network.h"
#include "nilorea/n_network_msg.h"
#include "nilorea/n_reactor.h"
#include "nilorea/n_log.h"
#include "nilorea/n_hash.h"
#include "nilorea/n_base64.h"
#include "nilorea/n_zlib.h"
#include "nilorea/n_lz4.h"
#include "nilorea/n_time.h"
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <openssl/x509v3.h>
#include <sys/wait.h>
Include dependency graph for n_network.c:

Go to the source code of this file.

Data Structures

struct  NETW_SNI_ARG

Macros

#define _Thread_local   __thread
 thread-local pre-connection error buffer (DNS, socket creation)
#define N_WS_FRAME_MAX_PAYLOAD   (16U * 1024U * 1024U)
 upper bound on a single parsed WebSocket frame payload, to bound a proxy's reassembly buffer against a hostile or corrupt length field
#define neterrno   errno
 get last socket error code, linux version
#define NETW_CALL_RETRY(__retvar, __expression, __max_tries)
 network-aware retry macro: retries on EINTR and EAGAIN/EWOULDBLOCK
#define NETW_CONNECT_ABORT_POLL_MS   100
 Poll interval (milliseconds) at which an in-progress connect wakes to check the registered connect-abort callback (see netw_set_connect_abort_cb).

Functions

 __attribute__ ((unused))
static void _n_mock_parse_request (const char *buf, N_HTTP_REQUEST *req)
 Parse a raw HTTP request buffer into an N_HTTP_REQUEST.
static void _n_mock_request_clean (N_HTTP_REQUEST *req)
 Free the contents of an N_HTTP_REQUEST (does not free the struct itself).
static void _n_parse_query_params (N_URL *u, const char *qs)
static int _n_url_has_scheme (const char *s)
 test whether a reference string begins with its own URI scheme
static void _n_url_normalize_path (const char *path, char *out, size_t outsz)
 normalize a path by removing "." and ".." segments (RFC 3986 style)
static size_t _netw_alpn_encode (const char *const *protos, size_t count, unsigned char *out, size_t out_cap)
static int _netw_alpn_select_cb (SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
static void _netw_capture_connect_error (const char *fmt,...)
 capture a pre-connection error (thread-local)
static void _netw_capture_error (NETWORK *netw, const char *fmt,...)
 capture an error into a NETWORK handle's ring buffer
static void _netw_crypto_setup_failed (NETWORK *netw)
static int _netw_sni_servername_cb (SSL *ssl, int *al, void *arg)
static int _netw_ssl_handshake_step (NETWORK *netw)
 advance an in-flight TLS handshake by a single non-blocking step
static int _netw_ssl_server_defaults (SSL_CTX *ctx)
static int _netw_start_nonblock_connect (NETWORK *netw)
 create a non-blocking socket for netw->link.connect_rp and start connect()
static int _netw_timed_connect (NETWORK *netw, SOCKET sock, struct addrinfo *rp, int connect_timeout_ms)
 Connect a socket, optionally bounding the attempt by a timeout.
static SOCKET _proxy_tcp_connect (const char *host, int port)
 Helper: connect a plain TCP socket to host:port.
static ssize_t _sse_read_byte (NETWORK *netw, char *ch, volatile int *stop_flag)
 read one byte from an SSE connection (SSL or plain).
static ssize_t _sse_write (NETWORK *netw, const void *buf, size_t len)
 write bytes to an SSE connection (SSL or plain)
static int _ssl_use_pem (SSL *ssl, const char *key_pem, const char *cert_pem)
static ssize_t _ws_read (N_WS_CONN *conn, void *buf, size_t len)
 read exactly len bytes from a WebSocket connection
static ssize_t _ws_write (N_WS_CONN *conn, const void *buf, size_t len)
 write bytes to a WebSocket connection (SSL or plain)
int deplete_send_buffer (int fd, int timeout)
 wait until the socket is empty or timeout, checking each 100 msec.
char * get_in_addr (struct sockaddr *sa)
 get sockaddr, IPv4 or IPv6
__netw_code_type size_t htonst (size_t value)
 host to network size_t
static char * mp_disp_param (const char *disp, size_t dlen, const char *param)
static void mp_emit (char *buf, size_t *pos, LIST *parts, const char *dash)
static long mp_find (const unsigned char *hay, size_t hlen, const char *needle, size_t nlen)
static const char * mp_header_value (const char *block, size_t blen, const char *name, size_t *vlen)
static void mp_part_free (void *ptr)
static void mp_put (char *buf, size_t *pos, const void *src, size_t n)
static void mp_puts (char *buf, size_t *pos, const char *s)
static char * mp_strndup (const char *s, size_t len)
N_STR * n_http_build_multipart (LIST *parts, const char *boundary)
 build a multipart/form-data body from a LIST of N_HTTP_MULTIPART_PART* using boundary (without "--"); returns a new N_STR (free with free_nstr) or NULL.
int n_http_decompress_body (const N_STR *body, const char *encoding, N_STR **out)
 decompress an HTTP body per its Content-Encoding ("gzip"/"deflate"; identity/NULL/unknown copies through).
static int n_http_inflate (const unsigned char *src, size_t len, int window_bits, N_STR **out)
int n_http_multipart_boundary (const char *content_type, char *out, size_t outsz)
 copy the boundary token from a Content-Type value into out (without the leading "--").
void n_http_multipart_free (LIST **parts)
 free a LIST returned by n_http_parse_multipart and NULL the pointer
LIST * n_http_parse_multipart (const N_STR *body, const char *boundary)
 parse a multipart body (boundary given without "--") into a LIST of N_HTTP_MULTIPART_PART*; free with n_http_multipart_free.
int n_http_status_class (int status_code)
 leading digit of an HTTP status code (1..5), or 0 when outside 100..599
int n_http_status_is_client_error (int status_code)
 1 when status_code is a client error (4xx), else 0
int n_http_status_is_informational (int status_code)
 1 when status_code is informational (1xx), else 0
int n_http_status_is_redirect (int status_code)
 1 when status_code is a redirect (3xx), else 0
int n_http_status_is_server_error (int status_code)
 1 when status_code is a server error (5xx), else 0
int n_http_status_is_success (int status_code)
 1 when status_code is success (2xx), else 0
void n_mock_server_free (N_MOCK_SERVER **server)
 Free a mock server and close the listening socket.
void n_mock_server_run (N_MOCK_SERVER *server)
 Run the mock server accept loop.
N_MOCK_SERVER * n_mock_server_start (int port, void(*on_request)(N_HTTP_REQUEST *, N_HTTP_RESPONSE *, void *), void *user_data)
 Start a mock HTTP server: set up listener and return immediately.
void n_mock_server_stop (N_MOCK_SERVER *server)
 Signal the mock server to stop accepting connections.
void n_netw_clear_connect_errors (void)
 Clear pre-connection errors on this thread.
void n_netw_clear_errors (NETWORK *netw)
 Clear captured errors on a NETWORK handle.
const char * n_netw_get_connect_error (int index)
 Get pre-connection error message by index.
int n_netw_get_connect_error_count (void)
 Get number of pre-connection errors captured on this thread.
const char * n_netw_get_error (const NETWORK *netw, int index)
 Get captured error message by index (0 = oldest).
int n_netw_get_error_count (const NETWORK *netw)
 Get number of captured errors on a NETWORK handle.
void n_proxy_cfg_free (N_PROXY_CFG **cfg)
 Free an N_PROXY_CFG created by n_proxy_cfg_parse().
N_PROXY_CFG * n_proxy_cfg_parse (const char *url)
 Parse a proxy URL string into an N_PROXY_CFG struct.
int n_proxy_connect_socks5 (const N_PROXY_CFG *proxy, const char *target_host, int target_port)
 Open a TCP connection through a SOCKS5 proxy.
int n_proxy_connect_tunnel (const N_PROXY_CFG *proxy, const char *target_host, int target_port)
 Open a TCP connection through an HTTP proxy using CONNECT tunneling.
int n_proxy_connect_tunnel_ssl (const N_PROXY_CFG *proxy, const char *target_host, int target_port)
 Open a TCP connection through an HTTPS proxy using CONNECT tunneling.
void n_sse_conn_free (N_SSE_CONN **conn)
 Free an SSE connection structure.
N_SSE_CONN * n_sse_connect (const char *host, const char *port, const char *path, int use_ssl, const char *user_agent, void(*on_event)(N_SSE_EVENT *, N_SSE_CONN *, void *), void *user_data)
 Connect to an SSE endpoint and start reading events.
void n_sse_event_clean (N_SSE_EVENT *event)
 Free the contents of an SSE event (does not free the struct itself).
void n_sse_stop (N_SSE_CONN *conn)
 Signal the SSE connection to stop reading.
N_STR * n_url_build (const N_URL *u)
 build a URL string from parsed components
N_STR * n_url_canonicalize (const N_URL *u)
 produce a canonical URL string for deduplication
N_STR * n_url_canonicalize_string (const char *url)
 parse and canonicalize a URL string in one call
N_STR * n_url_decode (const char *str)
 decode a percent-encoded string (returns N_STR)
N_STR * n_url_encode (const char *str)
 percent-encode a string for use in URLs (delegates to n_str_url_encode())
void n_url_free (N_URL **u)
 free a N_URL and all its members
N_URL * n_url_parse (const char *url)
 parse a URL string into components
N_STR * n_url_resolve (const char *base, const char *ref)
 resolve a (possibly relative) URL reference against an absolute base
void n_ws_close (N_WS_CONN *conn)
 Send close frame and close the connection.
void n_ws_conn_free (N_WS_CONN **conn)
 Free a WebSocket connection structure.
N_WS_CONN * n_ws_connect (const char *host, const char *port, const char *path, int use_ssl)
 Connect to a WebSocket server (ws:// or wss://).
size_t n_ws_frame_build (int fin, int opcode, int do_mask, const unsigned char *payload, size_t len, const unsigned char mask_key[4], unsigned char *out, size_t out_cap)
 build a WebSocket frame into out (optionally masking the payload).
int n_ws_frame_parse (const unsigned char *buf, size_t len, N_WS_FRAME *frame, size_t *consumed)
 Parse one WebSocket frame from a byte buffer (stateless, no allocation).
int n_ws_recv (N_WS_CONN *conn, N_WS_MESSAGE *msg_out)
 Receive one WebSocket frame.
int n_ws_send (N_WS_CONN *conn, const char *payload, size_t len, int opcode)
 Send a WebSocket frame (client always masks).
void n_ws_unmask (unsigned char *dst, const unsigned char *src, size_t len, const unsigned char mask[4])
 XOR-unmask len bytes of src into dst using a 4-byte WebSocket mask key.
static char * netstrerror (int code)
 BSD style errno string NO WORKING ON REDHAT.
NETWORK * netw_accept_from (NETWORK *from)
 make a normal blocking 'accept' .
NETWORK * netw_accept_from_ex (NETWORK *from, size_t send_list_limit, size_t recv_list_limit, int blocking, int *retval)
 make a normal 'accept' .
NETWORK * netw_accept_nonblock_from (NETWORK *from, int blocking)
 make a normal blocking 'accept' .
NETWORK * netw_accept_ssl_with_sni_cb (NETWORK *listen, netw_sni_pick_cb pick, void *user_data)
 accept a TLS connection, selecting the server certificate per client SNI
int netw_add_msg (NETWORK *netw, N_STR *msg)
 Add a message to send in aimed NETWORK.
int netw_add_msg_ex (NETWORK *netw, char *str, unsigned int length)
 Add a message to send in aimed NETWORK.
int netw_adopt_client_fd (NETWORK **netw, SOCKET fd, const char *host, const char *port)
 Adopt an already-connected socket fd into a fresh client NETWORK.
int netw_bind_udp (NETWORK **netw, char *addr, char *port, int ip_version)
 Create a UDP bound socket for receiving datagrams.
int netw_build_http_response (N_STR **http_response, int status_code, const char *server_name, const char *content_type, char *additional_headers, N_STR *body)
 function to dynamically generate an HTTP response
size_t netw_calculate_urlencoded_size (const char *str, size_t len)
 function to calculate the required size for the URL-encoded string
int netw_close (NETWORK **netw)
 Closing a specified Network, destroy queues, free the structure.
int netw_connect (NETWORK **netw, char *host, char *port, int ip_version)
 Use this to connect a NETWORK to any listening one, unrestricted send/recv lists.
int netw_connect_check (NETWORK *netw)
 advance a non-blocking connect started by netw_connect_nonblock()
int netw_connect_ex (NETWORK **netw, char *host, char *port, size_t send_list_limit, size_t recv_list_limit, int ip_version, char *ssl_key_file, char *ssl_cert_file)
 Use this to connect a NETWORK to any listening one.
int netw_connect_ex_to (NETWORK **netw, char *host, char *port, size_t send_list_limit, size_t recv_list_limit, int ip_version, char *ssl_key_file, char *ssl_cert_file, int connect_timeout_ms)
 Use this to connect a NETWORK to any listening one.
int netw_connect_nonblock (NETWORK **netw, char *host, char *port, int ip_version)
 begin a non-blocking TCP connect without waiting for it to complete
int netw_connect_to (NETWORK **netw, char *host, char *port, int ip_version, int connect_timeout_ms)
 Connect a NETWORK with a bounded connection-establishment time.
int netw_connect_udp (NETWORK **netw, char *host, char *port, int ip_version)
 Connect a UDP socket to a remote host.
int netw_destroy_pool (NETWORK_POOL **netw_pool)
 free a NETWORK_POOL *pool
NETWORK_HTTP_INFO netw_extract_http_info (char *request)
 extract a lot of informations, mostly as pointers, and populate a NETWORK_HTTP_INFO structure
char * netw_extract_http_request_type (const char *request)
 function to extract the request method from an http request
int netw_get_http_date (char *buffer, size_t buffer_size)
 helper function to generate the current date in HTTP format
const char * netw_get_http_status_message (int status_code)
 helper function to convert status code to a human-readable message
N_STR * netw_get_msg (NETWORK *netw)
 Get a message from aimed NETWORK.
char * netw_get_openssl_error_string ()
 get the OpenSSL error string
int netw_get_queue_status (NETWORK *netw, size_t *nb_to_send, size_t *nb_to_read)
 retrieve network send queue status
int netw_get_state (NETWORK *netw, uint32_t *state, int *thr_engine_status)
 Get the state of a network.
int netw_get_url_from_http_request (const char *request, char *url, size_t size)
 Helper function to extract the URL from the HTTP request line.
const char * netw_guess_http_content_type (const char *url)
 function to guess the content type based on URL extension
int netw_info_destroy (NETWORK_HTTP_INFO http_request)
 destroy a NETWORK_HTTP_INFO loaded informations
static void netw_init_locks (void)
int netw_init_openssl (void)
 Do not directly use, internal api.
int netw_init_wsa (int mode, int v1, int v2)
 Do not directly use, internal api.
static int netw_is_ip_literal (const char *host)
 is host a numeric IP literal rather than a DNS name?
static void netw_kill_locks (void)
int netw_make_listening (NETWORK **netw, char *addr, char *port, int nbpending, int ip_version)
 Make a NETWORK be a Listening network.
NETWORK * netw_new (size_t send_list_limit, size_t recv_list_limit)
 Return an empty allocated network ready to be netw_closed.
NETWORK_POOL * netw_new_pool (size_t nb_min_element)
 return a new network pool of nb_min_element
HASH_TABLE * netw_parse_post_data (const char *post_data)
 Function to parse POST data.
int netw_pool_add (NETWORK_POOL *netw_pool, NETWORK *netw)
 add a NETWORK *netw to a NETWORK_POOL *pool
int netw_pool_broadcast (NETWORK_POOL *netw_pool, const NETWORK *from, N_STR *net_msg)
 add net_msg to all network in netork pool
size_t netw_pool_nbclients (NETWORK_POOL *netw_pool)
 return the number of networks in netw_pool
void netw_pool_netw_close (void *netw_ptr)
 close a network from a network pool
int netw_pool_remove (NETWORK_POOL *netw_pool, NETWORK *netw)
 remove a NETWORK *netw to a NETWORK_POOL *pool
void * netw_recv_func (void *NET)
 To Thread Receiving function.
void * netw_send_func (void *NET)
 Thread send function.
int netw_send_ident (NETWORK *netw, int type, int id, N_STR *name, N_STR *passwd)
 Add a formatted NETWMSG_IDENT message to the specified network.
int netw_send_ping (NETWORK *netw, int type, int id_from, int id_to, int time)
 Add a ping reply to the network.
int netw_send_position (NETWORK *netw, int id, double X, double Y, double vx, double vy, double acc_x, double acc_y, int time_stamp)
 Add a formatted NETWMSG_IDENT message to the specified network.
int netw_send_quit (NETWORK *netw)
 Add a formatted NETMSG_QUIT message to the specified network.
int netw_send_string_to (NETWORK *netw, int id_to, N_STR *name, N_STR *chan, N_STR *txt, int color)
 Add a string to the network, aiming a specific user.
int netw_send_string_to_all (NETWORK *netw, N_STR *name, N_STR *chan, N_STR *txt, int color)
 Add a string to the network, aiming all server-side users.
int netw_set (NETWORK *netw, int flag)
 Restart or reset the specified network ability.
int netw_set_blocking (NETWORK *netw, unsigned long int is_blocking)
 Modify blocking socket mode.
int netw_set_compression_mode (NETWORK *netw, int mode)
 Pick send-side payload compression algorithm.
void netw_set_connect_abort_cb (int(*cb)(void *ctx), void *ctx)
 Register a process-wide callback polled while a connect is in progress.
int netw_set_crypto (NETWORK *netw, char *key, char *certificate)
 activate SSL encryption on selected network, using key and certificate
int netw_set_crypto_chain (NETWORK *netw, char *key, char *certificate, char *ca_file)
 activate SSL encryption using key/certificate files and a CA file for chain verification
int netw_set_crypto_chain_pem (NETWORK *netw, const char *key_pem, const char *cert_pem, const char *ca_pem)
 activate SSL encryption using PEM strings for key, certificate, and CA
int netw_set_crypto_pem (NETWORK *netw, const char *key_pem, const char *cert_pem)
 activate SSL encryption using PEM-formatted key and certificate strings loaded from memory
int netw_set_crypto_pem_ctx (NETWORK *netw, const N_STR *key_pem, const N_STR *cert_pem)
 install an in-memory cert/key on a single accepted connection's SSL
int netw_set_user_id (NETWORK *netw, int id)
 associate an id and a network
int netw_setsockopt (NETWORK *netw, int optname, int value)
 Modify common socket options on the given netw.
int netw_ssl_connect (NETWORK **netw, char *host, char *port, int ip_version, char *ssl_key_file, char *ssl_cert_file)
 Use this to connect a NETWORK to any listening one, unrestricted send/recv lists.
int netw_ssl_connect_client (NETWORK **netw, char *host, char *port, int ip_version)
 Connect as an SSL client without providing a client certificate.
int netw_ssl_connect_client_to (NETWORK **netw, char *host, char *port, int ip_version, int connect_timeout_ms)
 Connect as an SSL client without providing a client certificate.
int netw_ssl_do_handshake (NETWORK *netw, const char *sni_hostname)
 Complete the SSL handshake on an already-connected NETWORK.
int netw_ssl_get_alpn (NETWORK *netw, char *out, size_t out_len)
 get the ALPN protocol the completed handshake selected
const char * netw_ssl_get_sni (NETWORK *netw)
 get the SNI server_name the peer requested in its ClientHello
int netw_ssl_get_verify_result (NETWORK *netw, const char *expected_host, char *errbuf, size_t errsz)
 evaluate the peer certificate of a completed TLS client connection
int netw_ssl_handshake_once (NETWORK *netw, const char *sni_hostname)
 non-blocking, resumable TLS client handshake
void netw_ssl_print_errors (SOCKET socket)
 print the queued OpenSSL errors for a given socket
SSL_CTX * netw_ssl_server_ctx_new (const char *key_file, const char *cert_chain_file)
 new standalone server SSL_CTX with the library's secure defaults
int netw_ssl_server_handshake (NETWORK *netw, netw_sni_pick_cb pick, void *user_data)
 upgrade an already-accepted plaintext connection to a TLS server, selecting the certificate per client SNI
int netw_ssl_server_handshake_ex (NETWORK *netw, netw_sni_pick_cb pick, void *user_data, const char *const *alpn, size_t alpn_count)
 upgrade an already-accepted plaintext connection to a TLS server, selecting the certificate per client SNI and the protocol per ALPN
int netw_ssl_server_handshake_once (NETWORK *netw, SSL_CTX *ctx)
 non-blocking, resumable TLS server handshake against a shared ctx
int netw_ssl_set_alpn (NETWORK *netw, const char *const *protos, size_t count)
 offer an ALPN protocol list on a TLS client connection, before its handshake
int netw_ssl_set_ca (NETWORK *netw, const char *ca_file, const char *ca_path)
 set custom CA verify location for SSL context
int netw_ssl_set_ciphers (NETWORK *netw, const char *cipher_list, const char *ciphersuites)
 set the cipher list (TLS 1.2 and below) and/or the ciphersuites (TLS 1.3)
int netw_ssl_set_client_cert (NETWORK *netw, const char *cert_file, const char *key_file)
 load a client certificate and private key for mTLS
int netw_ssl_set_verify (NETWORK *netw, int enable)
 enable or disable SSL peer certificate verification
int netw_ssl_set_versions (NETWORK *netw, int min_version, int max_version)
 set the minimum (and optionally maximum) TLS protocol version on a connection's SSL context
int netw_ssl_start_client (NETWORK *netw)
 Set up a client SSL_CTX on an already-connected NETWORK.
int netw_start_thr_engine (NETWORK *netw)
 Start the NETWORK netw Threaded Engine.
int netw_stop_thr_engine (NETWORK *netw)
 Stop a NETWORK connection sending and receing thread.
ssize_t netw_udp_recvfrom (NETWORK *netw, char *buf, uint32_t n, struct sockaddr *src_addr, socklen_t *src_len)
 recv data via UDP and capture the source address
ssize_t netw_udp_sendto (NETWORK *netw, char *buf, uint32_t n, struct sockaddr *dest_addr, socklen_t dest_len)
 send data via UDP to a specific destination address
int netw_unload_openssl (void)
 Do not directly use, internal api.
char * netw_urldecode (const char *str)
 Function to decode URL-encoded data.
char * netw_urlencode (const char *str, size_t len)
 function to perform URL encoding
N_STR * netw_wait_msg (NETWORK *netw, unsigned int refresh, size_t timeout)
 Wait a message from aimed NETWORK.
size_t ntohst (size_t value)
 network to host size_t
ssize_t recv_data (void *netw, char *buf, uint32_t n)
 recv data from the socket
ssize_t recv_data_once (void *netw, char *buf, uint32_t n)
 single-attempt recv for non-blocking sockets (reactor use).
ssize_t recv_php (SOCKET s, int *_code, char **buf)
 recv data from the socket
ssize_t recv_ssl_data (void *netw, char *buf, uint32_t n)
 recv data from the socket
ssize_t recv_ssl_data_once (void *netw, char *buf, uint32_t n)
 single-attempt TLS recv for non-blocking sockets (reactor use).
ssize_t recv_udp_data (void *netw, char *buf, uint32_t n)
 recv data via UDP from a connected socket
ssize_t send_data (void *netw, char *buf, uint32_t n)
 send data onto the socket
ssize_t send_data_once (void *netw, char *buf, uint32_t n)
 single-attempt send for non-blocking sockets (reactor use).
ssize_t send_php (SOCKET s, int _code, char *buf, int n)
 send data onto the socket
ssize_t send_ssl_data (void *netw, char *buf, uint32_t n)
 send data onto the socket
ssize_t send_ssl_data_once (void *netw, char *buf, uint32_t n)
 single-attempt TLS send for non-blocking sockets (reactor use).
ssize_t send_udp_data (void *netw, char *buf, uint32_t n)
 send data via UDP on a connected socket

Variables

static int(* _netw_connect_abort_cb )(void *) = NULL
 Optional connect-abort callback, or NULL.
static void * _netw_connect_abort_ctx = NULL
 Opaque context handed to _netw_connect_abort_cb on each poll.
long long g_netw_bytes_recv = 0
long long g_netw_bytes_sent = 0
 Add a message to send in aimed NETWORK.
 N_ENUM_netw_code_type
 network error code
static pthread_mutex_t * netw_ssl_lockarray
static int OPENSSL_IS_INITIALIZED = 0
static __thread int s_connect_err_count = 0
static __thread int s_connect_err_next = 0
static __thread char s_connect_errors [8][512]

Detailed Description

Network Engine.

Author
Castagnier Mickael
Version
1.0
Date
10/05/2005

Definition in file n_network.c.


Data Structure Documentation

◆ NETW_SNI_ARG

struct NETW_SNI_ARG

Definition at line 1867 of file n_network.c.

Collaboration diagram for NETW_SNI_ARG:
Data Fields
const char *const * alpn
size_t alpn_count
netw_sni_pick_cb pick
void * user_data

Macro Definition Documentation

◆ _Thread_local

#define _Thread_local   __thread

thread-local pre-connection error buffer (DNS, socket creation)

Definition at line 75 of file n_network.c.

Referenced by n_kafka_event_fdesc().

◆ N_WS_FRAME_MAX_PAYLOAD

#define N_WS_FRAME_MAX_PAYLOAD   (16U * 1024U * 1024U)

upper bound on a single parsed WebSocket frame payload, to bound a proxy's reassembly buffer against a hostile or corrupt length field

Definition at line 7691 of file n_network.c.

Referenced by n_ws_frame_parse().

◆ neterrno

◆ NETW_CALL_RETRY

#define NETW_CALL_RETRY ( __retvar,
__expression,
__max_tries )
Value:
do { \
int __nb_retries = 0; \
do { \
__retvar = (__expression); \
__nb_retries++; \
} while (__retvar == -1 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) && __nb_retries < (__max_tries)); \
if (__retvar == -1 && __nb_retries >= (__max_tries)) __retvar = -2; \
} while (0)

network-aware retry macro: retries on EINTR and EAGAIN/EWOULDBLOCK

Definition at line 672 of file n_network.c.

Referenced by recv_data(), and send_data().

◆ NETW_CONNECT_ABORT_POLL_MS

#define NETW_CONNECT_ABORT_POLL_MS   100

Poll interval (milliseconds) at which an in-progress connect wakes to check the registered connect-abort callback (see netw_set_connect_abort_cb).

Definition at line 2389 of file n_network.c.

Referenced by _netw_timed_connect().

Function Documentation

◆ __attribute__()

__attribute__ ( (unused) )
Examples
ex_fluid.c, ex_gui_dictionary.c, and ex_gui_particles.c.

Definition at line 1288 of file n_network.c.

References line(), mode, netw_ssl_lockarray, and type().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _n_mock_parse_request()

void _n_mock_parse_request ( const char * buf,
N_HTTP_REQUEST * req )
static

Parse a raw HTTP request buffer into an N_HTTP_REQUEST.

Parameters
bufraw request data (null-terminated)
reqoutput request structure (must be zeroed by caller)

Definition at line 7803 of file n_network.c.

References N_HTTP_REQUEST::body, char_to_nstr(), N_HTTP_REQUEST::headers, line(), list_push(), N_HTTP_REQUEST::method, new_generic_list(), N_HTTP_REQUEST::path, and N_HTTP_REQUEST::query.

Referenced by n_mock_server_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _n_mock_request_clean()

void _n_mock_request_clean ( N_HTTP_REQUEST * req)
static

Free the contents of an N_HTTP_REQUEST (does not free the struct itself).

Parameters
reqrequest to clean

Definition at line 7880 of file n_network.c.

References N_HTTP_REQUEST::body, free_nstr, N_HTTP_REQUEST::headers, and list_destroy().

Referenced by n_mock_server_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _n_parse_query_params()

void _n_parse_query_params ( N_URL * u,
const char * qs )
static

Definition at line 8030 of file n_network.c.

References eq(), N_URL_PARAM::key, N_URL_MAX_PARAMS, N_URL::nb_params, N_URL::params, and N_URL_PARAM::value.

Referenced by n_url_parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _n_url_has_scheme()

int _n_url_has_scheme ( const char * s)
static

test whether a reference string begins with its own URI scheme

Parameters
sthe reference string
Returns
1 when s starts with "scheme:" (alpha followed by alnum/+/-/.), 0 otherwise

Definition at line 8209 of file n_network.c.

Referenced by n_url_resolve().

Here is the caller graph for this function:

◆ _n_url_normalize_path()

void _n_url_normalize_path ( const char * path,
char * out,
size_t outsz )
static

normalize a path by removing "." and ".." segments (RFC 3986 style)

Parameters
paththe input path (may be NULL or empty)
outdestination buffer
outszsize of out

Definition at line 8114 of file n_network.c.

Referenced by n_url_canonicalize(), and n_url_resolve().

Here is the caller graph for this function:

◆ _netw_alpn_encode()

size_t _netw_alpn_encode ( const char *const * protos,
size_t count,
unsigned char * out,
size_t out_cap )
static

Definition at line 1907 of file n_network.c.

Referenced by netw_ssl_set_alpn().

Here is the caller graph for this function:

◆ _netw_alpn_select_cb()

int _netw_alpn_select_cb ( SSL * ssl,
const unsigned char ** out,
unsigned char * outlen,
const unsigned char * in,
unsigned int inlen,
void * arg )
static

Definition at line 1879 of file n_network.c.

References NETW_SNI_ARG::alpn, and NETW_SNI_ARG::alpn_count.

Referenced by netw_ssl_server_handshake_ex().

Here is the caller graph for this function:

◆ _netw_capture_connect_error()

void _netw_capture_connect_error ( const char * fmt,
... )
static

capture a pre-connection error (thread-local)

Definition at line 95 of file n_network.c.

References _netw_capture_connect_error(), s_connect_err_count, s_connect_err_next, and s_connect_errors.

Referenced by _netw_capture_connect_error(), and netw_connect_ex_to().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _netw_capture_error()

◆ _netw_crypto_setup_failed()

void _netw_crypto_setup_failed ( NETWORK * netw)
static

Definition at line 1384 of file n_network.c.

References __n_assert, and netw.

Referenced by netw_set_crypto(), and netw_set_crypto_pem().

Here is the caller graph for this function:

◆ _netw_sni_servername_cb()

int _netw_sni_servername_cb ( SSL * ssl,
int * al,
void * arg )
static

Definition at line 1984 of file n_network.c.

References _ssl_use_pem(), N_STR::data, free_nstr, NETW_SNI_ARG::pick, and NETW_SNI_ARG::user_data.

Referenced by netw_ssl_server_handshake_ex().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _netw_ssl_handshake_step()

int _netw_ssl_handshake_step ( NETWORK * netw)
static

advance an in-flight TLS handshake by a single non-blocking step

Parameters
netwthe NETWORK whose netw->ssl handshake to drive
Returns
TRUE when the handshake is complete, NETW_IO_WANT_READ / NETW_IO_WANT_WRITE when it must be retried once the socket is readable / writable, FALSE on a fatal error

Definition at line 3112 of file n_network.c.

References _netw_capture_error(), _str, LOG_ERR, n_log, netw, NETW_IO_WANT_READ, and NETW_IO_WANT_WRITE.

Referenced by netw_ssl_handshake_once(), and netw_ssl_server_handshake_once().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _netw_ssl_server_defaults()

int _netw_ssl_server_defaults ( SSL_CTX * ctx)
static

Definition at line 1401 of file n_network.c.

References __n_assert, LOG_ERR, and n_log.

Referenced by netw_set_crypto(), netw_set_crypto_pem(), netw_ssl_server_ctx_new(), and netw_ssl_server_handshake_ex().

Here is the caller graph for this function:

◆ _netw_start_nonblock_connect()

int _netw_start_nonblock_connect ( NETWORK * netw)
static

create a non-blocking socket for netw->link.connect_rp and start connect()

Advances netw->link.connect_rp past any address whose socket()/connect() fails outright, so on return the connect is in flight (or already complete) on netw->link.sock.

Parameters
netwthe NETWORK whose connect_rp to try
Returns
TRUE if a connect is in progress/complete, FALSE if every remaining address failed

Definition at line 2712 of file n_network.c.

References neterrno, netw, and netw_set_blocking().

Referenced by netw_connect_check(), and netw_connect_nonblock().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _netw_timed_connect()

int _netw_timed_connect ( NETWORK * netw,
SOCKET sock,
struct addrinfo * rp,
int connect_timeout_ms )
static

Connect a socket, optionally bounding the attempt by a timeout.

With connect_timeout_ms <= 0 this performs the historical blocking connect() (the OS decides when to give up). With a positive timeout the socket is switched to non-blocking, connect() is issued, and select() waits up to the timeout for completion; the socket is always restored to blocking mode before returning so the rest of the stack sees a normal blocking socket.

Parameters
netwNETWORK owning the socket (its link.sock must equal sock)
sockthe socket to connect
rpaddrinfo describing the target address
connect_timeout_msconnect timeout in milliseconds, 0 = none
Returns
0 on success, -1 on error or timeout

Definition at line 2411 of file n_network.c.

References _netw_connect_abort_cb, _netw_connect_abort_ctx, get_usec(), neterrno, netw, NETW_CONNECT_ABORT_POLL_MS, netw_set_blocking(), and start_HiTimer().

Referenced by netw_connect_ex_to().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _proxy_tcp_connect()

SOCKET _proxy_tcp_connect ( const char * host,
int port )
static

Helper: connect a plain TCP socket to host:port.

Parameters
hosthostname
portport number
Returns
socket fd on success, INVALID_SOCKET on failure.

Definition at line 8363 of file n_network.c.

References LOG_ERR, n_log, port, and port_str.

Referenced by n_proxy_connect_socks5(), n_proxy_connect_tunnel(), and n_proxy_connect_tunnel_ssl().

Here is the caller graph for this function:

◆ _sse_read_byte()

ssize_t _sse_read_byte ( NETWORK * netw,
char * ch,
volatile int * stop_flag )
static

read one byte from an SSE connection (SSL or plain).

Uses a short poll timeout so the caller can check stop_flag.

Parameters
netwNETWORK connection
choutput byte
stop_flagpointer to atomic stop flag (checked on timeout)
Returns
1 on success, 0 on timeout (retry), -1 on error or EOF

Definition at line 7441 of file n_network.c.

References __n_assert, netw, and NETW_ENCRYPT_OPENSSL.

Referenced by n_sse_connect().

Here is the caller graph for this function:

◆ _sse_write()

ssize_t _sse_write ( NETWORK * netw,
const void * buf,
size_t len )
static

write bytes to an SSE connection (SSL or plain)

Parameters
netwNETWORK connection
bufdata to write
lennumber of bytes
Returns
number of bytes written, or -1 on error

Definition at line 7484 of file n_network.c.

References __n_assert, netw, and NETW_ENCRYPT_OPENSSL.

Referenced by n_sse_connect().

Here is the caller graph for this function:

◆ _ssl_use_pem()

int _ssl_use_pem ( SSL * ssl,
const char * key_pem,
const char * cert_pem )
static

Definition at line 1808 of file n_network.c.

References cert.

Referenced by _netw_sni_servername_cb(), and netw_set_crypto_pem_ctx().

Here is the caller graph for this function:

◆ _ws_read()

ssize_t _ws_read ( N_WS_CONN * conn,
void * buf,
size_t len )
static

read exactly len bytes from a WebSocket connection

Parameters
connWebSocket connection
bufoutput buffer
lennumber of bytes to read
Returns
number of bytes read, or -1 on error

Definition at line 6964 of file n_network.c.

References __n_assert, NETWORK::crypto_algo, NETWORK::link, N_WS_CONN::netw, NETW_ENCRYPT_OPENSSL, N_SOCKET::sock, and NETWORK::ssl.

Referenced by n_ws_recv().

Here is the caller graph for this function:

◆ _ws_write()

ssize_t _ws_write ( N_WS_CONN * conn,
const void * buf,
size_t len )
static

write bytes to a WebSocket connection (SSL or plain)

Parameters
connWebSocket connection
bufdata to write
lennumber of bytes
Returns
number of bytes written, or -1 on error

Definition at line 6948 of file n_network.c.

References __n_assert, NETWORK::crypto_algo, NETWORK::link, N_WS_CONN::netw, NETW_ENCRYPT_OPENSSL, N_SOCKET::sock, and NETWORK::ssl.

Referenced by n_ws_connect(), and n_ws_send().

Here is the caller graph for this function:

◆ get_in_addr()

char * get_in_addr ( struct sockaddr * sa)

get sockaddr, IPv4 or IPv6

Parameters
saaddrinfo to get
Returns
socket address

Definition at line 828 of file n_network.c.

Referenced by netw_accept_from_ex(), netw_bind_udp(), netw_connect_check(), netw_connect_ex_to(), netw_connect_udp(), and netw_make_listening().

Here is the caller graph for this function:

◆ mp_disp_param()

char * mp_disp_param ( const char * disp,
size_t dlen,
const char * param )
static

Definition at line 6670 of file n_network.c.

References key, and mp_strndup().

Referenced by n_http_parse_multipart().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mp_emit()

void mp_emit ( char * buf,
size_t * pos,
LIST * parts,
const char * dash )
static

◆ mp_find()

long mp_find ( const unsigned char * hay,
size_t hlen,
const char * needle,
size_t nlen )
static

Definition at line 6572 of file n_network.c.

Referenced by n_http_parse_multipart().

Here is the caller graph for this function:

◆ mp_header_value()

const char * mp_header_value ( const char * block,
size_t blen,
const char * name,
size_t * vlen )
static

Definition at line 6642 of file n_network.c.

Referenced by n_http_parse_multipart().

Here is the caller graph for this function:

◆ mp_part_free()

void mp_part_free ( void * ptr)
static

◆ mp_put()

void mp_put ( char * buf,
size_t * pos,
const void * src,
size_t n )
static

Definition at line 6792 of file n_network.c.

Referenced by mp_emit(), and mp_puts().

Here is the caller graph for this function:

◆ mp_puts()

void mp_puts ( char * buf,
size_t * pos,
const char * s )
static

Definition at line 6799 of file n_network.c.

References mp_put().

Referenced by mp_emit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mp_strndup()

char * mp_strndup ( const char * s,
size_t len )
static

Definition at line 6584 of file n_network.c.

References Malloc.

Referenced by mp_disp_param(), and n_http_parse_multipart().

Here is the caller graph for this function:

◆ n_http_inflate()

int n_http_inflate ( const unsigned char * src,
size_t len,
int window_bits,
N_STR ** out )
static

Definition at line 6481 of file n_network.c.

References char_to_nstr_ex().

Referenced by n_http_decompress_body().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ netstrerror()

char * netstrerror ( int code)
static

BSD style errno string NO WORKING ON REDHAT.

Get the last socket error code as a heap-allocated string, POSIX version.

Parameters
codeerror code (typically errno)
Returns
strdup-style string that the caller must Free, or NULL on allocation failure

Definition at line 700 of file n_network.c.

Referenced by netw_accept_from_ex(), netw_bind_udp(), netw_close(), netw_connect_check(), netw_connect_ex_to(), netw_connect_udp(), netw_make_listening(), netw_set_blocking(), netw_setsockopt(), netw_udp_recvfrom(), netw_udp_sendto(), recv_data(), recv_data_once(), recv_php(), recv_ssl_data(), recv_ssl_data_once(), recv_udp_data(), send_data(), send_data_once(), send_php(), send_ssl_data(), send_ssl_data_once(), and send_udp_data().

Here is the caller graph for this function:

◆ netw_get_openssl_error_string()

char * netw_get_openssl_error_string ( )

get the OpenSSL error string

Returns
allocated string containing the error messages, or NULL

Definition at line 1200 of file n_network.c.

◆ netw_init_locks()

void netw_init_locks ( void )
static

Definition at line 1305 of file n_network.c.

References netw_ssl_lockarray.

Referenced by netw_init_openssl().

Here is the caller graph for this function:

◆ netw_is_ip_literal()

int netw_is_ip_literal ( const char * host)
static

is host a numeric IP literal rather than a DNS name?

A certificate carries an IP in a different subjectAltName form from a name, so the two need different verification calls. Judged by inet_pton rather than by scanning for dots, so "1.2.3.4.example.com" is correctly a name.

Parameters
hostThe string to test. NULL or empty is not a literal.
Returns
1 when host is an IPv4 or IPv6 literal, 0 otherwise.

Definition at line 3034 of file n_network.c.

Referenced by netw_ssl_do_handshake().

Here is the caller graph for this function:

◆ netw_kill_locks()

void netw_kill_locks ( void )
static

Definition at line 1319 of file n_network.c.

References netw_ssl_lockarray.

Referenced by netw_unload_openssl().

Here is the caller graph for this function:

◆ netw_new()

NETWORK * netw_new ( size_t send_list_limit,
size_t recv_list_limit )

Return an empty allocated network ready to be netw_closed.

Parameters
send_list_limitThread engine number of tosend message limit. From UNLIMITED_LIST_ITEMS (0) to MAX_LIST_ITEMS (SIZE_MAX).
recv_list_limitThread engine number of received message limit. From UNLIMITED_LIST_ITEMS (0) to MAX_LIST_ITEMS (SIZE_MAX).
Returns
NULL or a new empty network

Definition at line 714 of file n_network.c.

References __n_assert, Free, LOG_ERR, Malloc, MAX_LIST_ITEMS, n_log, netw, netw_atomic_write_state, netw_close(), NETW_COMPRESS_ZLIB, NETW_ENCRYPT_NONE, NETW_EXITED, NETW_THR_ENGINE_STOPPED, NETWORK_TCP, new_generic_list(), recv_data(), recv_data_once(), send_data(), and send_data_once().

Referenced by netw_accept_from_ex(), netw_adopt_client_fd(), netw_bind_udp(), netw_connect_ex_to(), netw_connect_nonblock(), netw_connect_udp(), and netw_make_listening().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ netw_ssl_print_errors()

void netw_ssl_print_errors ( SOCKET socket)

print the queued OpenSSL errors for a given socket

Parameters
socketthe socket to report errors for

Drains the per-thread OpenSSL error queue, logging each entry at LOG_ERR, except the benign "unexpected eof while reading" (a peer closing the connection without a TLS close_notify, common from browsers) which is logged at LOG_DEBUG so it does not masquerade as a real TLS failure.

Definition at line 1231 of file n_network.c.

References LOG_DEBUG, LOG_ERR, and n_log.

Referenced by netw_accept_from_ex(), netw_set_crypto(), netw_set_crypto_chain(), netw_set_crypto_pem(), netw_set_crypto_pem_ctx(), netw_ssl_do_handshake(), netw_ssl_handshake_once(), netw_ssl_server_ctx_new(), netw_ssl_server_handshake_ex(), netw_ssl_server_handshake_once(), netw_ssl_set_ca(), netw_ssl_set_client_cert(), and netw_ssl_start_client().

Here is the caller graph for this function:

Variable Documentation

◆ _netw_connect_abort_cb

int(* _netw_connect_abort_cb) (void *) ( void * ) = NULL
static

Optional connect-abort callback, or NULL.

See netw_set_connect_abort_cb.

Definition at line 2392 of file n_network.c.

Referenced by _netw_timed_connect(), and netw_set_connect_abort_cb().

◆ _netw_connect_abort_ctx

void* _netw_connect_abort_ctx = NULL
static

Opaque context handed to _netw_connect_abort_cb on each poll.

Definition at line 2394 of file n_network.c.

Referenced by _netw_timed_connect(), and netw_set_connect_abort_cb().

◆ g_netw_bytes_recv

long long g_netw_bytes_recv = 0

Definition at line 4311 of file n_network.c.

Referenced by netw_bytes_stats_get(), and netw_get_msg().

◆ g_netw_bytes_sent

long long g_netw_bytes_sent = 0

Add a message to send in aimed NETWORK.

Parameters
netwNETWORK where add the message
msgthe message to add
Returns
TRUE if success FALSE on error

Definition at line 4310 of file n_network.c.

Referenced by netw_add_msg(), and netw_bytes_stats_get().

◆ N_ENUM_netw_code_type

N_ENUM_netw_code_type

network error code

Definition at line 138 of file n_network.c.

◆ netw_ssl_lockarray

pthread_mutex_t* netw_ssl_lockarray
static

Definition at line 1286 of file n_network.c.

Referenced by __attribute__(), netw_init_locks(), and netw_kill_locks().

◆ OPENSSL_IS_INITIALIZED

int OPENSSL_IS_INITIALIZED = 0
static

Definition at line 1329 of file n_network.c.

Referenced by netw_init_openssl(), and netw_unload_openssl().

◆ s_connect_err_count

__thread int s_connect_err_count = 0
static

◆ s_connect_err_next

__thread int s_connect_err_next = 0
static

◆ s_connect_errors

__thread char s_connect_errors[8][512]
static

Definition at line 77 of file n_network.c.

Referenced by _netw_capture_connect_error(), and n_netw_get_connect_error().