From 2595f796c3f8a074680396baf02edc815578eacc Mon Sep 17 00:00:00 2001 From: Glenn Fiedler Date: Sat, 11 Jul 2026 17:02:23 -0400 Subject: [PATCH 1/3] Add BSD support (OpenBSD, FreeBSD) The time/sleep platform block now covers all unix systems via NETCODE_PLATFORM_UNIX instead of only __linux, and falls back to CLOCK_MONOTONIC on systems that do not have the linux-specific CLOCK_MONOTONIC_RAW (the BSDs). Co-Authored-By: Claude Fable 5 --- netcode.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/netcode.c b/netcode.c index b257255..efab25f 100755 --- a/netcode.c +++ b/netcode.c @@ -5325,7 +5325,7 @@ int netcode_generate_connect_token( int num_server_addresses, // --------------------------------------------------------------- -#if __APPLE__ +#if NETCODE_PLATFORM == NETCODE_PLATFORM_MAC // MacOS @@ -5356,12 +5356,20 @@ double netcode_time() return ( (double) ( current - start ) ) * ( (double) timebase_info.numer ) / ( (double) timebase_info.denom ) / 1000000000.0; } -#elif __linux +#elif NETCODE_PLATFORM == NETCODE_PLATFORM_UNIX -// linux +// linux and other unix systems (openbsd, freebsd etc.) #include +// linux has CLOCK_MONOTONIC_RAW, but other unix systems only have CLOCK_MONOTONIC + +#ifdef CLOCK_MONOTONIC_RAW +#define NETCODE_MONOTONIC_CLOCK CLOCK_MONOTONIC_RAW +#else +#define NETCODE_MONOTONIC_CLOCK CLOCK_MONOTONIC +#endif + void netcode_sleep( double time ) { struct timespec ts; @@ -5376,17 +5384,17 @@ double netcode_time() if ( start == -1 ) { struct timespec ts; - clock_gettime( CLOCK_MONOTONIC_RAW, &ts ); + clock_gettime( NETCODE_MONOTONIC_CLOCK, &ts ); start = ts.tv_sec + ( (double) ( ts.tv_nsec ) ) / 1000000000.0; return 0.0; } struct timespec ts; - clock_gettime( CLOCK_MONOTONIC_RAW, &ts ); + clock_gettime( NETCODE_MONOTONIC_CLOCK, &ts ); double current = ts.tv_sec + ( (double) ( ts.tv_nsec ) ) / 1000000000.0; return current - start; } -#elif defined( _WIN32 ) +#elif NETCODE_PLATFORM == NETCODE_PLATFORM_WINDOWS // windows From 03af1e9338ce7de944eaaaf1e77aa62d15964ea8 Mon Sep 17 00:00:00 2001 From: Glenn Fiedler Date: Sat, 11 Jul 2026 17:28:34 -0400 Subject: [PATCH 2/3] Bump version to 1.3.5 Co-Authored-By: Claude Fable 5 --- CMakeLists.txt | 2 +- netcode.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9be634..c38d33f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16) -project(netcode VERSION 1.3.4 LANGUAGES C CXX) +project(netcode VERSION 1.3.5 LANGUAGES C CXX) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/netcode.h b/netcode.h index b3b1af8..5e4b9b0 100755 --- a/netcode.h +++ b/netcode.h @@ -25,10 +25,10 @@ #ifndef NETCODE_H #define NETCODE_H -#define NETCODE_VERSION_FULL "1.3.4" +#define NETCODE_VERSION_FULL "1.3.5" #define NETCODE_VERSION_MAJOR 1 #define NETCODE_VERSION_MINOR 3 -#define NETCODE_VERSION_PATCH 4 +#define NETCODE_VERSION_PATCH 5 /* IMPORTANT: netcode is single-threaded by design and is not thread safe. From 714698373dc550fc3b4f2d0a9fca4c68efd96b72 Mon Sep 17 00:00:00 2001 From: Glenn Fiedler Date: Sat, 11 Jul 2026 17:14:47 -0400 Subject: [PATCH 3/3] Back off socket buffer sizes to the OS limit instead of failing Linux and windows clamp SO_SNDBUF/SO_RCVBUF requests that exceed the OS limit, but the BSDs reject them with ENOBUFS. OpenBSD's default sb_max is 2MB, so requesting the default 4MB socket buffers made every socket create fail and no client or server could start. Halve the request until the OS accepts it (floor 256KB, then fail as before) and log at INFO level when the size was reduced. Co-Authored-By: Claude Fable 5 --- netcode.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/netcode.c b/netcode.c index efab25f..9b9f4d1 100755 --- a/netcode.c +++ b/netcode.c @@ -680,20 +680,43 @@ int netcode_socket_create( struct netcode_socket_t * s, struct netcode_address_t } } - // increase socket send and receive buffer sizes + // increase socket send and receive buffer sizes. linux and windows clamp requests that + // exceed the OS limit, but the BSDs reject them instead, so back off until accepted. - if ( setsockopt( s->handle, SOL_SOCKET, SO_SNDBUF, (char*)&send_buffer_size, sizeof(int) ) != 0 ) { - netcode_printf( NETCODE_LOG_LEVEL_ERROR, "error: failed to set socket send buffer size\n" ); - netcode_socket_destroy( s ); - return NETCODE_SOCKET_ERROR_SOCKOPT_SNDBUF_FAILED; + int size = send_buffer_size; + while ( setsockopt( s->handle, SOL_SOCKET, SO_SNDBUF, (char*)&size, sizeof(int) ) != 0 ) + { + size /= 2; + if ( size < 256 * 1024 ) + { + netcode_printf( NETCODE_LOG_LEVEL_ERROR, "error: failed to set socket send buffer size\n" ); + netcode_socket_destroy( s ); + return NETCODE_SOCKET_ERROR_SOCKOPT_SNDBUF_FAILED; + } + } + if ( size != send_buffer_size ) + { + netcode_printf( NETCODE_LOG_LEVEL_INFO, "socket send buffer size reduced from %d to %d\n", send_buffer_size, size ); + } } - if ( setsockopt( s->handle, SOL_SOCKET, SO_RCVBUF, (char*)&receive_buffer_size, sizeof(int) ) != 0 ) { - netcode_printf( NETCODE_LOG_LEVEL_ERROR, "error: failed to set socket receive buffer size\n" ); - netcode_socket_destroy( s ); - return NETCODE_SOCKET_ERROR_SOCKOPT_RCVBUF_FAILED; + int size = receive_buffer_size; + while ( setsockopt( s->handle, SOL_SOCKET, SO_RCVBUF, (char*)&size, sizeof(int) ) != 0 ) + { + size /= 2; + if ( size < 256 * 1024 ) + { + netcode_printf( NETCODE_LOG_LEVEL_ERROR, "error: failed to set socket receive buffer size\n" ); + netcode_socket_destroy( s ); + return NETCODE_SOCKET_ERROR_SOCKOPT_RCVBUF_FAILED; + } + } + if ( size != receive_buffer_size ) + { + netcode_printf( NETCODE_LOG_LEVEL_INFO, "socket receive buffer size reduced from %d to %d\n", receive_buffer_size, size ); + } } // bind to port