From 320f0fe0f46916c99d5671548dafd973b3258ab7 Mon Sep 17 00:00:00 2001 From: Fletcher Dunn Date: Sun, 8 Sep 2024 17:50:08 -0700 Subject: [PATCH 01/20] Move MacOS to its own workflow, so it can have its own badge --- .github/workflows/build.yml | 39 -------------------------------- .github/workflows/macos.yml | 44 +++++++++++++++++++++++++++++++++++++ README.md | 2 +- 3 files changed, 45 insertions(+), 40 deletions(-) create mode 100644 .github/workflows/macos.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e0dbc2a..27e1c1b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -91,42 +91,3 @@ jobs: run: test_connection.exe identity quick lane_quick_queueanddrain lane_quick_priority_and_background shell: cmd - build-and-test-osx: - name: Build And Test MacOS - runs-on: macos-latest - steps: - - uses: actions/checkout@v3 - - name: Install Vcpkg - run: | - git clone https://github.com/Microsoft/vcpkg.git - cd vcpkg - ./bootstrap-vcpkg.sh - ./vcpkg integrate install - - - name: Configure CMake - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake - -DBUILD_TESTS=ON - - - name: Build - # Build the program with the given configuration - run: cmake --build ${{github.workspace}}/build --config Release - - - name: Test - working-directory: ${{github.workspace}}/build - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest -C Release - - - name: Test crypto - working-directory: ${{github.workspace}}/build/bin - run: ./test_crypto - shell: bash - - - name: Test connection - working-directory: ${{github.workspace}}/build/bin - run: ./test_connection identity quick lane_quick_queueanddrain lane_quick_priority_and_background - shell: bash diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 0000000..9151848 --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,44 @@ +name: MacOS +on: [push, pull_request] + +jobs: + + build-and-test-macos: + name: Build And Test MacOS + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + - name: Install Vcpkg + run: | + git clone https://github.com/Microsoft/vcpkg.git + cd vcpkg + ./bootstrap-vcpkg.sh + ./vcpkg integrate install + + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: cmake -B ${{github.workspace}}/build + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake + -DBUILD_TESTS=ON + + - name: Build + # Build the program with the given configuration + run: cmake --build ${{github.workspace}}/build --config Release + + #- name: Test + # working-directory: ${{github.workspace}}/build + # # Execute tests defined by the CMake configuration. + # # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + # run: ctest -C Release + + - name: Test crypto + working-directory: ${{github.workspace}}/build/bin + run: ./test_crypto + shell: bash + + - name: Test connection + working-directory: ${{github.workspace}}/build/bin + run: ./test_connection identity quick lane_quick_queueanddrain lane_quick_priority_and_background + shell: bash diff --git a/README.md b/README.md index b64f475..5817d7e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # GameNetworkingSockets -[![Windows, Ubuntu, OSX](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/build.yml/badge.svg)](https://github.com/ValveSoftware/GameNetworkingSockets/actions) [![Linux flavors](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/linux-flavors.yml/badge.svg)](https://github.com/ValveSoftware/GameNetworkingSockets/actions) +[![Windows, Ubuntu](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/build.yml/badge.svg)](https://github.com/ValveSoftware/GameNetworkingSockets/actions) [![MacOS](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/macos.yml/badge.svg)](https://github.com/ValveSoftware/GameNetworkingSockets/actions) [![Linux flavors](https://github.com/ValveSoftware/GameNetworkingSockets/actions/workflows/linux-flavors.yml/badge.svg)](https://github.com/ValveSoftware/GameNetworkingSockets/actions) GameNetworkingSockets is a basic transport layer for games. The features are: From 6e7ec281b296bed7f2c9bd0486b2a5a5d7eecebc Mon Sep 17 00:00:00 2001 From: Assassinsorrow <49711232+Assassinsorrow@users.noreply.github.com> Date: Wed, 7 Sep 2022 11:18:12 +0200 Subject: [PATCH 02/20] Look for vcpkg submodule at top level CmakeLists.txt --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90899a4..61f3159 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required(VERSION 3.9) # If vcpkg present as submodule, bring in the toolchain -if( EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake ) - message(STATUS "Found ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake; using it!") - set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake +if( EXISTS ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake ) + message(STATUS "Found ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake; using it!") + set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake CACHE STRING "Vcpkg toolchain file") endif() From 6aa4e785c97da12f7ba087cd0a6af6cf3ca92ee7 Mon Sep 17 00:00:00 2001 From: Tomas Maly Date: Sun, 30 Jul 2023 13:49:09 +0200 Subject: [PATCH 03/20] test multiple crypto libraries on multiple versions of windows --- .github/workflows/build.yml | 11 ++++++++--- CMakeLists.txt | 20 +++++++++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 27e1c1b..02efbf6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,8 +33,13 @@ jobs: build-and-test-windows: #if: false # Temporarily disable - name: Build And Test Windows - runs-on: windows-latest + name: Build And Test Windows ${{ matrix.os-version }} ${{ matrix.crypto }} + runs-on: windows-${{ matrix.os-version }} + strategy: + fail-fast: false + matrix: + os-version: [2019, 2022] + crypto: [OpenSSL, BCrypt] env: VCPKG_ROOT: ${{ github.workspace }}/vcpkg steps: @@ -65,7 +70,7 @@ jobs: run: | mkdir build cd build - cmake -S .. -G Ninja -DBUILD_TESTS=ON -DBUILD_EXAMPLES=ON -DBUILD_TOOLS=ON -DCMAKE_TOOLCHAIN_FILE=${{env.VCPKG_ROOT}}/scripts/buildsystems/vcpkg.cmake + cmake -S .. -G Ninja -DBUILD_TESTS=ON -DBUILD_EXAMPLES=ON -DBUILD_TOOLS=ON -DCMAKE_TOOLCHAIN_FILE=${{env.VCPKG_ROOT}}/scripts/buildsystems/vcpkg.cmake -DUSE_CRYPTO=${{matrix.crypto}} shell: cmd # Mark all directories as safe so checkouts performed in CMakeLists.txt don't cause "unsafe repository" errors. diff --git a/CMakeLists.txt b/CMakeLists.txt index 61f3159..d1489cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,15 +84,17 @@ if (WIN32) string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - # - # Check whether BCrypt can be used with this SDK version - # - cmake_push_check_state() - set(CMAKE_REQUIRED_LIBRARIES bcrypt) - check_symbol_exists(BCryptEncrypt windows.h BCRYPT_AVAILABLE) - cmake_pop_check_state() - if (NOT BCRYPT_AVAILABLE AND USE_CRYPTO STREQUAL "BCrypt") - message(FATAL_ERROR "You're on Windows but BCrypt seems to be unavailable, you will need OpenSSL") + if (USE_CRYPTO STREQUAL "BCrypt") + # + # Check whether BCrypt can be used with this SDK version + # + cmake_push_check_state() + set(CMAKE_REQUIRED_LIBRARIES bcrypt) + check_symbol_exists(BCryptEncrypt windows.h BCRYPT_AVAILABLE) + cmake_pop_check_state() + if (NOT BCRYPT_AVAILABLE) + message(FATAL_ERROR "You're on Windows but BCrypt seems to be unavailable, you will need OpenSSL") + endif() endif() endif() From 5020374ad73bd0fdc3e20e20e39f901267cccc63 Mon Sep 17 00:00:00 2001 From: Tomas Maly Date: Sun, 30 Jul 2023 14:48:39 +0200 Subject: [PATCH 04/20] improved test if bcrypt is available --- CMakeLists.txt | 6 ++---- cmake/tryCompileTestBCrypt.cpp | 9 +++++++++ 2 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 cmake/tryCompileTestBCrypt.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d1489cb..6beb1f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,11 +88,9 @@ if (WIN32) # # Check whether BCrypt can be used with this SDK version # - cmake_push_check_state() - set(CMAKE_REQUIRED_LIBRARIES bcrypt) - check_symbol_exists(BCryptEncrypt windows.h BCRYPT_AVAILABLE) - cmake_pop_check_state() + try_compile(BCRYPT_AVAILABLE "${CMAKE_CURRENT_BINARY_DIR}/tryCompile" SOURCES "${CMAKE_CURRENT_LIST_DIR}/cmake/tryCompileTestBCrypt.cpp" OUTPUT_VARIABLE BCRYPT_AVAILABILITY_TEST_MESSAGES) if (NOT BCRYPT_AVAILABLE) + message(STATUS ${BCRYPT_AVAILABILITY_TEST_MESSAGES}) message(FATAL_ERROR "You're on Windows but BCrypt seems to be unavailable, you will need OpenSSL") endif() endif() diff --git a/cmake/tryCompileTestBCrypt.cpp b/cmake/tryCompileTestBCrypt.cpp new file mode 100644 index 0000000..510dc7c --- /dev/null +++ b/cmake/tryCompileTestBCrypt.cpp @@ -0,0 +1,9 @@ +#include +#include +#include +#pragma comment(lib, "bcrypt.lib") + +int main(int, char **) +{ + printf("%p\n", &BCryptEncrypt); +} From 62b395172f157ca4f01eea3387d1131400f8d604 Mon Sep 17 00:00:00 2001 From: Tomas Maly Date: Sun, 30 Jul 2023 23:55:40 +0200 Subject: [PATCH 05/20] use link_libraries in try_compile instead of pragma lib in cpp --- CMakeLists.txt | 2 +- cmake/tryCompileTestBCrypt.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6beb1f9..9796b83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,7 @@ if (WIN32) # # Check whether BCrypt can be used with this SDK version # - try_compile(BCRYPT_AVAILABLE "${CMAKE_CURRENT_BINARY_DIR}/tryCompile" SOURCES "${CMAKE_CURRENT_LIST_DIR}/cmake/tryCompileTestBCrypt.cpp" OUTPUT_VARIABLE BCRYPT_AVAILABILITY_TEST_MESSAGES) + try_compile(BCRYPT_AVAILABLE "${CMAKE_CURRENT_BINARY_DIR}/tryCompile" SOURCES "${CMAKE_CURRENT_LIST_DIR}/cmake/tryCompileTestBCrypt.cpp" LINK_LIBRARIES bcrypt OUTPUT_VARIABLE BCRYPT_AVAILABILITY_TEST_MESSAGES) if (NOT BCRYPT_AVAILABLE) message(STATUS ${BCRYPT_AVAILABILITY_TEST_MESSAGES}) message(FATAL_ERROR "You're on Windows but BCrypt seems to be unavailable, you will need OpenSSL") diff --git a/cmake/tryCompileTestBCrypt.cpp b/cmake/tryCompileTestBCrypt.cpp index 510dc7c..6c63f74 100644 --- a/cmake/tryCompileTestBCrypt.cpp +++ b/cmake/tryCompileTestBCrypt.cpp @@ -1,7 +1,6 @@ #include #include #include -#pragma comment(lib, "bcrypt.lib") int main(int, char **) { From e449ea68279bdde7b0fccf74122e1d665a0c783d Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sun, 29 Sep 2024 15:14:54 -0500 Subject: [PATCH 06/20] cmake : fix producing a trivial_signaling_server rather than trivial_signaling_server.exe PE executable on Windows --- examples/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 83c80a1..45dc5b2 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -8,7 +8,11 @@ if( ENABLE_ICE AND ( BUILD_EXAMPLES OR BUILD_TESTS ) ) else() set(SIGNAL_SERVER_TARGET trivial_signaling_server) - set(SIGNAL_SERVER_OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/trivial_signaling_server) + if ( WIN32 ) + set(SIGNAL_SERVER_OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/trivial_signaling_server.exe) + else() + set(SIGNAL_SERVER_OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/trivial_signaling_server) + endif() set(SIGNAL_SERVER_SRCS trivial_signaling_server.go ) From 8343dd9c4a57f0eb0ce1f24003a3461fb65cbf60 Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sun, 22 Sep 2024 17:14:15 -0500 Subject: [PATCH 07/20] fix some dead links --- BUILDING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 00daa4c..0a8d83a 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -63,7 +63,7 @@ for more. ## Windows / Visual Studio -To build gamenetworkingsockets on Windows, it's recommended to obtain thge dependencies by using vcpkg in ["manifest mode"](https://vcpkg.readthedocs.io/en/latest/users/manifests/). The following instructions assume that you will follow the vcpkg recommendations and install vcpkg as a subfolder. If you want to use "classic mode" or install vcpkg somewhere else, you're on your own. +To build gamenetworkingsockets on Windows, it's recommended to obtain thge dependencies by using vcpkg in ["manifest mode"](https://learn.microsoft.com/en-us/vcpkg/concepts/manifest-mode). The following instructions assume that you will follow the vcpkg recommendations and install vcpkg as a subfolder. If you want to use "classic mode" or install vcpkg somewhere else, you're on your own. If you don't want to use vcpkg, try the [manual instructions](BUILDING_WINDOWS_MANUAL.md). @@ -128,7 +128,7 @@ $ brew install protobuf ## MSYS2 You can also build this project on [MSYS2](https://www.msys2.org). First, -follow the [instructions](https://github.com/msys2/msys2/wiki/MSYS2-installation) on the +follow the [instructions](https://www.msys2.org/wiki/MSYS2-installation) on the MSYS2 website for updating your MSYS2 install. **Be sure to follow the instructions at the site above to update MSYS2 before From 538ae81ec96e8612f5cbf173662fac2ad937449f Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sun, 29 Sep 2024 15:33:45 -0500 Subject: [PATCH 08/20] test_p2p : make the RunProcessInThread a daemon thread so we cleanly exit on error. --- tests/test_p2p.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_p2p.py b/tests/test_p2p.py index 5fd71da..0850d90 100755 --- a/tests/test_p2p.py +++ b/tests/test_p2p.py @@ -19,6 +19,7 @@ class RunProcessInThread(threading.Thread): def __init__( self, tag, cmdline, env, **popen_kwargs ): threading.Thread.__init__( self, name=tag ) + self.daemon = True self.tag = tag self.cmdline = cmdline if env: @@ -63,6 +64,7 @@ class RunProcessInThread(threading.Thread): threading.Thread.join( self, timeout ) if self.isAlive(): self.WriteLn( "Still running after %d seconds. Killing" % timeout ) + global g_failed g_failed = True self.process.kill() From 405e2bfc759d239024c07852d570bcf248ca5e57 Mon Sep 17 00:00:00 2001 From: Timothee 'TTimo' Besset Date: Sun, 29 Sep 2024 15:55:53 -0500 Subject: [PATCH 09/20] fix test_p2p on Windows --- tests/test_p2p.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_p2p.py b/tests/test_p2p.py index 0850d90..aa1e35b 100755 --- a/tests/test_p2p.py +++ b/tests/test_p2p.py @@ -62,7 +62,7 @@ class RunProcessInThread(threading.Thread): # Wait for thread to shutdown. Nuke process if we don't exit in time def join( self, timeout ): threading.Thread.join( self, timeout ) - if self.isAlive(): + if self.is_alive(): self.WriteLn( "Still running after %d seconds. Killing" % timeout ) global g_failed g_failed = True @@ -90,7 +90,7 @@ def StartClientInThread( role, local, remote ): ] env = dict( os.environ ) - if os.name == 'nt' and not os.path.exists( 'steamnetworkingsockets.dll' ): + if os.name == 'nt' and not os.path.exists( 'steamnetworkingsockets.dll' ) and not os.path.exists( 'GameNetworkingSockets.dll' ): bindir = os.path.abspath('../../../bin') if not os.path.exists( bindir ): print( "Can't find steamnetworkingsockets.dll" ) From 725e273c7442bac7a8bc903c0b210b1c15c34d92 Mon Sep 17 00:00:00 2001 From: Lily Wang <494550702@qq.com> Date: Thu, 29 Dec 2022 03:23:57 -0800 Subject: [PATCH 10/20] Add find_dependency(Protobuf) --- cmake/GameNetworkingSocketsConfig.cmake.in | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/GameNetworkingSocketsConfig.cmake.in b/cmake/GameNetworkingSocketsConfig.cmake.in index 1a27988..5076a6e 100644 --- a/cmake/GameNetworkingSocketsConfig.cmake.in +++ b/cmake/GameNetworkingSocketsConfig.cmake.in @@ -3,6 +3,7 @@ include(CMakeFindDependencyMacro) find_dependency(Threads) +find_dependency(Protobuf) if(@USE_CRYPTO@ STREQUAL "OpenSSL") find_dependency(OpenSSL) From a246ee39c32cc4b34580dc24d434ac9a4007a74b Mon Sep 17 00:00:00 2001 From: Fletcher Dunn Date: Thu, 24 Jul 2025 09:38:11 -0700 Subject: [PATCH 11/20] Add a way to read jitter in SteamNetConnectionRealTimeStatus_t --- include/steam/steamnetworkingtypes.h | 11 +++++++++- .../steamnetworkingsockets_connections.cpp | 4 ++++ .../steamnetworking_statsutils.h | 20 +++++++++++++++++++ .../steamnetworkingsockets_stats.cpp | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/include/steam/steamnetworkingtypes.h b/include/steam/steamnetworkingtypes.h index 4488423..651bc66 100644 --- a/include/steam/steamnetworkingtypes.h +++ b/include/steam/steamnetworkingtypes.h @@ -802,8 +802,17 @@ struct SteamNetConnectionRealTimeStatus_t /// Nagle delay is ignored for the purposes of this calculation. SteamNetworkingMicroseconds m_usecQueueTime; + /// Highest packet jitter experienced, since the last time this information + /// was returned. (The high water mark is cleared each time you fetch the info.) + /// + /// - The units are microseconds, although the measurement precision is usually + /// not nearly this precise. + /// - A negative value means "no data available". + /// - Not all connections are able to measure jitter. + int32 m_usecMaxJitter; + // Internal stuff, room to change API easily - uint32 reserved[16]; + uint32 reserved[15]; }; /// Quick status of a particular lane diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_connections.cpp b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_connections.cpp index 061cb7d..cd529e8 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_connections.cpp +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_connections.cpp @@ -1953,6 +1953,10 @@ EResult CSteamNetworkConnectionBase::APIGetRealTimeStatus( SteamNetConnectionRea pStatus->m_flOutBytesPerSec = m_statsEndToEnd.m_sent.m_bytes.m_flRate; pStatus->m_flInPacketsPerSec = m_statsEndToEnd.m_recv.m_packets.m_flRate; pStatus->m_flInBytesPerSec = m_statsEndToEnd.m_recv.m_bytes.m_flRate; + + // Max jitter, and clear it + pStatus->m_usecMaxJitter = m_statsEndToEnd.m_usecAPIRealtimeStatusMaxJitter; + m_statsEndToEnd.m_usecAPIRealtimeStatusMaxJitter = -1; } SNP_PopulateRealTimeStatus( pStatus, nLanes, pLanes, usecNow ); diff --git a/src/steamnetworkingsockets/steamnetworking_statsutils.h b/src/steamnetworkingsockets/steamnetworking_statsutils.h index fad7187..2aa2c75 100644 --- a/src/steamnetworkingsockets/steamnetworking_statsutils.h +++ b/src/steamnetworkingsockets/steamnetworking_statsutils.h @@ -1077,6 +1077,10 @@ struct LinkStatsTrackerEndToEnd : public LinkStatsTrackerBase /// Time when the current interval started SteamNetworkingMicroseconds m_usecSpeedIntervalStart; + /// Jitter value that is returned in GetConnectionRealTimeStatus and then + /// cleared. + int m_usecAPIRealtimeStatusMaxJitter; + ///// TX Speed, should match CMsgSteamDatagramLinkLifetimeStats //int m_nTXSpeed; //int m_nTXSpeedMax; @@ -1169,6 +1173,22 @@ protected: } } + inline void InternalProcessJitterSample( int usecJitter ) + { + LinkStatsTrackerBase::InternalProcessJitterSample( usecJitter ); + + // Update user high water mark. + // + // Use absolute value here...I think? + // If one packet is delayed and then the next packet arrives on time, the second + // jitter value will be negative, and both packets will be counted as bad, even + // though only the second one was. (Arriving early usually isn't a problem, it's + // arriving late that's bad). However, for the use cases for this is currently + // intended, it's OK. With any reasonable packet rate, we assume the app + // won't be checking this value fast enough for it to matter. + m_usecAPIRealtimeStatusMaxJitter = std::max( m_usecAPIRealtimeStatusMaxJitter, abs( usecJitter ) ); + } + private: void UpdateSpeedInterval( SteamNetworkingMicroseconds usecNow ); diff --git a/src/steamnetworkingsockets/steamnetworkingsockets_stats.cpp b/src/steamnetworkingsockets/steamnetworkingsockets_stats.cpp index 5e929a1..d8f21c2 100644 --- a/src/steamnetworkingsockets/steamnetworkingsockets_stats.cpp +++ b/src/steamnetworkingsockets/steamnetworkingsockets_stats.cpp @@ -768,6 +768,7 @@ void LinkStatsTrackerEndToEnd::InitInternal( SteamNetworkingMicroseconds usecNow m_usecWhenStartedConnectedState = 0; m_usecWhenEndedConnectedState = 0; + m_usecAPIRealtimeStatusMaxJitter = -1; //m_TXSpeedSample.Clear(); //m_nTXSpeed = 0; From 4eaaddafb5deb97b608077502272b64848c917ea Mon Sep 17 00:00:00 2001 From: Fletcher Dunn Date: Thu, 2 Oct 2025 19:45:18 -0700 Subject: [PATCH 12/20] Change an assert to use a warning P4:10010414,10010418 (cherry picked from commit cd00b5e6c64f72009a82a0000ac7cb148cbf2b5f) --- .../clientlib/steamnetworkingsockets_lowlevel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp index 951f51d..1f97027 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp @@ -852,7 +852,7 @@ bool IsRouteToAddressProbablyLocal( netadr_t addr ) ); if ( r != NO_ERROR ) { - AssertMsg2( false, "GetBestRoute2 failed with result %d for address '%s'", r, CUtlNetAdrRender( addr ).String() ); + SpewWarning( "GetBestRoute2 failed with result %d for address '%s'\n", r, CUtlNetAdrRender( addr ).String() ); return false; } if ( bestRoute.Protocol == MIB_IPPROTO_LOCAL ) @@ -860,7 +860,7 @@ bool IsRouteToAddressProbablyLocal( netadr_t addr ) netadr_t nextHop; if ( !nextHop.SetFromSockadr( &bestRoute.NextHop ) ) { - AssertMsg( false, "GetBestRoute2 returned invalid next hop address" ); + SpewWarning( "GetBestRoute2 returned invalid next hop address\n" ); return false; } From 096c19525b8d2a9b897a6e668c9612eff750b4c7 Mon Sep 17 00:00:00 2001 From: Fletcher Dunn Date: Fri, 3 Oct 2025 22:09:50 -0700 Subject: [PATCH 13/20] Remove call to GetTypeName() from assert Protobuf changed this somewhere along the way. It's not adding much value and this is the only call site, so deleting it is easier than making a compatibilty shim function. --- src/steamnetworkingsockets/steamnetworkingsockets_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/steamnetworkingsockets/steamnetworkingsockets_internal.h b/src/steamnetworkingsockets/steamnetworkingsockets_internal.h index 50dba23..ec72fbf 100644 --- a/src/steamnetworkingsockets/steamnetworkingsockets_internal.h +++ b/src/steamnetworkingsockets/steamnetworkingsockets_internal.h @@ -670,7 +670,7 @@ extern bool BSteamNetworkingIdentityToProtobufInternal( const SteamNetworkingIde #define SteamNetworkingIdentityToProtobuf( identity, msg, field_identity_string, field_identity_legacy_binary, field_legacy_steam_id ) \ { SteamDatagramErrMsg identityToProtobufErrMsg; \ if ( !BSteamNetworkingIdentityToProtobuf( identity, msg, field_identity_string, field_identity_legacy_binary, field_legacy_steam_id, identityToProtobufErrMsg ) ) { \ - AssertMsg2( false, "Failed to serialize identity to %s message. %s", msg.GetTypeName().c_str(), identityToProtobufErrMsg ); \ + AssertMsg( false, "Failed to serialize identity to message. %s", identityToProtobufErrMsg ); \ } \ } From fa569cbf46b3b1eae9cfdc8769c4db2ac8dbf17d Mon Sep 17 00:00:00 2001 From: Amin Date: Mon, 28 Jul 2025 00:06:06 -0400 Subject: [PATCH 14/20] remove windows server 2019 and add windows latest --- .github/workflows/build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 02efbf6..ff76973 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,8 @@ jobs: strategy: fail-fast: false matrix: - os-version: [2019, 2022] + # Windows Server 2019 has been retired. The Windows Server 2019 image has been removed as of 2025-06-30. For more details, see https://github.com/actions/runner-images/issues/12045 + os-version: [2022, latest] crypto: [OpenSSL, BCrypt] env: VCPKG_ROOT: ${{ github.workspace }}/vcpkg From 9b38d11026e0483c0f86e5cf92b33686007edd5e Mon Sep 17 00:00:00 2001 From: Amin Date: Mon, 28 Jul 2025 00:08:36 -0400 Subject: [PATCH 15/20] add windows 2025 runner to ci pipeline --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ff76973..2e9d4ee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,7 +39,7 @@ jobs: fail-fast: false matrix: # Windows Server 2019 has been retired. The Windows Server 2019 image has been removed as of 2025-06-30. For more details, see https://github.com/actions/runner-images/issues/12045 - os-version: [2022, latest] + os-version: [2022, 2025] crypto: [OpenSSL, BCrypt] env: VCPKG_ROOT: ${{ github.workspace }}/vcpkg From b744f1b1a9ab5d8e543b261383ab9ffaeecf29dc Mon Sep 17 00:00:00 2001 From: Exil_S <112499822+xXExilXx@users.noreply.github.com> Date: Wed, 22 Jan 2025 22:51:04 +0100 Subject: [PATCH 16/20] Fixed typo in line 66 thge > the --- BUILDING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILDING.md b/BUILDING.md index 0a8d83a..d6610fe 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -63,7 +63,7 @@ for more. ## Windows / Visual Studio -To build gamenetworkingsockets on Windows, it's recommended to obtain thge dependencies by using vcpkg in ["manifest mode"](https://learn.microsoft.com/en-us/vcpkg/concepts/manifest-mode). The following instructions assume that you will follow the vcpkg recommendations and install vcpkg as a subfolder. If you want to use "classic mode" or install vcpkg somewhere else, you're on your own. +To build gamenetworkingsockets on Windows, it's recommended to obtain the dependencies by using vcpkg in ["manifest mode"](https://learn.microsoft.com/en-us/vcpkg/concepts/manifest-mode). The following instructions assume that you will follow the vcpkg recommendations and install vcpkg as a subfolder. If you want to use "classic mode" or install vcpkg somewhere else, you're on your own. If you don't want to use vcpkg, try the [manual instructions](BUILDING_WINDOWS_MANUAL.md). From 517fff0cf6866ba163f4f016b0ef28f365c06c05 Mon Sep 17 00:00:00 2001 From: Pavel Solodovnikov Date: Wed, 14 May 2025 00:22:38 +0300 Subject: [PATCH 17/20] Fix incorrect control buffer length when filling `WSAMSG` for `WSARecvMsg` Somehow, this bug causes problems with listen sockets on Windows 11 platform. After some number of client connections being abruptly terminated (e.g. client has crashed), the host just stops to invoke connection state change callbacks for the still opened listen socket. In this particular case, `WSARecvMsg` always returns -1 (SOCKET_ERROR) and `WSAGetLastError()` returns 10014 (WSAEFAULT), which indicates there's a problem with function arguments. So, it seems, that in some cases Windows will try to use the control data, but if there's been some problem with it, the connection will just remain in the broken state forever. Signed-off-by: Pavel Solodovnikov --- .../clientlib/steamnetworkingsockets_lowlevel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp index 1f97027..51092f3 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp @@ -2373,7 +2373,7 @@ static bool DrainSocket( CRawUDPSocketImpl *pSock ) { msg.dwBufferCount = 1; msg.lpBuffers = (WSABUF *)&iov_buf; - msg.Control.len = sizeof(buf); + msg.Control.len = sizeof(buf_control); msg.Control.buf = buf_control; msg.dwFlags = 0; From 3c26f1a187a42135f92aebeff872b2a8a51330b6 Mon Sep 17 00:00:00 2001 From: Fletcher Dunn Date: Thu, 9 Apr 2026 16:58:25 -0700 Subject: [PATCH 18/20] Fix off-by-one causing us to not de-dup if items in slots 0 and 1 were the same --- .../steamnetworkingsockets_certstore.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp b/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp index 18df112..7104d21 100644 --- a/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp +++ b/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp @@ -78,8 +78,8 @@ void CertAuthParameter::Setup( const T *pItems, int n ) std::sort( m_vecItems.begin(), m_vecItems.end() ); // Remove duplicates. We assume both that duplicates are rare - // and lists are small, so that O(n^2) is OK here. - for ( int i = len(m_vecItems)-1 ; i > 1 ; --i ) + // and lists are small, so that O(n^2) is OK here. + for ( int i = len(m_vecItems)-1 ; i > 0 ; --i ) { if ( m_vecItems[i-1] == m_vecItems[i] ) erase_at( m_vecItems, i ); @@ -603,7 +603,7 @@ const CertAuthScope *CertStore_CheckCASignature( const std::string &signed_data, V_strcpy_safe( errMsg, "No signature" ); return nullptr; } - + // Locate the cert if ( nCAKeyID == 0 ) { From 1835c6c6bcacd88958ac9a255adc56f604c650d4 Mon Sep 17 00:00:00 2001 From: Fletcher Dunn Date: Thu, 9 Apr 2026 16:59:14 -0700 Subject: [PATCH 19/20] Fix cut/paste bug --- src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp b/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp index 7104d21..6e0b64b 100644 --- a/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp +++ b/src/steamnetworkingsockets/steamnetworkingsockets_certstore.cpp @@ -739,7 +739,7 @@ bool CheckCertAppID( const CMsgSteamDatagramCertificate &msgCert, const CertAuth if ( !pCACertAuthScope || pCACertAuthScope->m_apps.HasItem( nAppID ) ) return true; V_sprintf_safe( errMsg, "Cert is not restricted by appid, but CA trust chain is, and does not authorize %u", nAppID ); - return true; + return false; } // Search cert for the one they are trying From 0d721a5327039d830aab3a5d4ce459f99eeb16f1 Mon Sep 17 00:00:00 2001 From: Fletcher Dunn Date: Thu, 9 Apr 2026 17:44:29 -0700 Subject: [PATCH 20/20] Detect overflow in DeserializeVarInt to ensure that we never do UB --- .../steamnetworkingsockets_internal.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/steamnetworkingsockets/steamnetworkingsockets_internal.h b/src/steamnetworkingsockets/steamnetworkingsockets_internal.h index ec72fbf..52a5002 100644 --- a/src/steamnetworkingsockets/steamnetworkingsockets_internal.h +++ b/src/steamnetworkingsockets/steamnetworkingsockets_internal.h @@ -133,7 +133,7 @@ enum EDualWifiEnable { k_nDualWifiEnable_Disable = 0, - k_nDualWifiEnable_Enable = 1, // + k_nDualWifiEnable_Enable = 1, // k_nDualWifiEnable_DoNotEnumerate = 2, // Enumerate primary adapters, but don't actually try to enable any Dual Wifi support k_nDualWifiEnable_DoNotBind = 3, // Try to turn on Dual Wifi and locate the secondary adapter, but don't actually bind k_nDualWifiEnable_ForceSimulate = 4, // Don't really do any DualWifi work, just open up another "regular" socket @@ -370,7 +370,7 @@ const uint32 k_nCurrentProtocolVersion = 12; /// when we introduce wire breaking protocol changes and do not wish to be /// backward compatible. This has been fine before the first major release, /// but once we make a big public release, we probably won't ever be able to -/// do this again, and we'll need to have more sophisticated mechanisms. +/// do this again, and we'll need to have more sophisticated mechanisms. const uint32 k_nMinRequiredProtocolVersion = 8; /// SteamNetworkingMessages is built on top of SteamNetworkingSockets. We use a reserved @@ -469,19 +469,21 @@ inline int VarIntSerializedSize( uint64 x ) // De-serialize a var-int encoded quantity. Returns pointer to the next byte, // or NULL if there was a decoding error (we hit the end of stream.) -// https://developers.google.com/protocol-buffers/docs/encoding -// -// NOTE: We do not detect overflow. +// https://developers.google.com/protocol-buffers/docs/encoding/ template inline byte *DeserializeVarInt( byte *p, const byte *end, T &x ) { - if ( p >= end ) + if ( unlikely( p >= end ) ) return nullptr; + const byte *max_end = p + ( (sizeof(T)*8 + 6) / 7 ); + if ( end > max_end ) + end = max_end; + T nResult = *p & 0x7f; // use local variable for working, to make sure compiler doesn't try to worry about pointer aliasing unsigned nShift = 7; while ( *(p++) & 0x80 ) { - if ( p >= end ) + if ( unlikely( p >= end ) ) return nullptr; nResult |= ( T( *p & 0x7f ) << nShift ); nShift += 7; @@ -1611,7 +1613,7 @@ namespace vstd { // We need dynamic memory. If we're not exactly sized already, // just nuke everyhing we have. - if ( n != capacity_ ) + if ( n != capacity_ ) { clear(); reserve( n );