1515#include < steam/steam_api.h>
1616#endif
1717
18- #define PORT_SERVER 27200 // Default server port, UDP/TCP
19-
2018// It's 2021 and the C language doesn't have a cross-platform way to
2119// compare strings in a case-insensitive way
2220#ifdef _MSC_VER
2321 #define strcasecmp (a,b ) stricmp(a,b)
2422#endif
2523
24+ enum class ETestConnectionMode
25+ {
26+ Cursory, // Very fast sanity check: 1 condition, short durations
27+ Normal, // Standard: 2 conditions, moderate durations
28+ Soak, // Exhaustive: all conditions, long durations
29+ };
2630
2731static std::default_random_engine g_rand;
2832static SteamNetworkingMicroseconds g_usecTestElapsed;
@@ -134,29 +138,29 @@ struct SFakePeer
134138 m_nSendInterval += cbSend;
135139
136140 EResult result = SteamNetworkingSockets ()->SendMessageToConnection (
137- m_hSteamNetConnection,
141+ m_hSteamNetConnection,
138142 &msg,
139143 cbSend,
140144 msg.m_bReliable ? k_nSteamNetworkingSend_Reliable : k_nSteamNetworkingSend_Unreliable, nullptr );
141145
142146 if ( result != k_EResultOK )
143147 {
144- TEST_Printf ( " ***ERROR ON Send: %s %.3f %s message %lld, %d bytes (pending %d bytes)\n " ,
145- m_sName.c_str (),
148+ TEST_Printf ( " ***ERROR ON Send: %s %.3f %s message %lld, %d bytes (pending %d bytes)\n " ,
149+ m_sName.c_str (),
146150 g_usecTestElapsed*1e-6 ,
147151 msg.m_bReliable ? " reliable" : " unreliable" ,
148- (long long )msg.m_nMsgNum ,
152+ (long long )msg.m_nMsgNum ,
149153 msg.m_cbSize ,
150154 GetQueuedSendBytes () );
151155 abort ();
152156 }
153157 #if 0
154158 else
155- TEST_Printf( "Send: %s %.3f %s message %lld, %d bytes (pending %d bytes)\n",
156- connection.m_sName.c_str(),
159+ TEST_Printf( "Send: %s %.3f %s message %lld, %d bytes (pending %d bytes)\n",
160+ connection.m_sName.c_str(),
157161 g_usecTestElapsed*1e-6,
158162 msg.m_bReliable ? "reliable" : "unreliable",
159- (long long)msg.m_nMsgNum,
163+ (long long)msg.m_nMsgNum,
160164 msg.m_cbSize,
161165 GetQueuedSendBytes() );
162166 #endif
@@ -359,7 +363,7 @@ static void ClearConfig()
359363 }
360364}
361365
362- static void TestNetworkConditions ( int rate, float loss, int lag, float reorderPct, int reorderLag, bool bActLikeGame, bool bQuickTest )
366+ static void TestNetworkConditions ( int rate, float loss, int lag, float reorderPct, int reorderLag, bool bActLikeGame, ETestConnectionMode eMode )
363367{
364368 ISteamNetworkingSockets *pSteamSocketNetworking = SteamNetworkingSockets ();
365369
@@ -384,14 +388,18 @@ static void TestNetworkConditions( int rate, float loss, int lag, float reorderP
384388
385389 SteamNetworkingMicroseconds usecWhenStarted = SteamNetworkingUtils ()->GetLocalTimestamp ();
386390
387- // Loop!
388-
389- // SteamNetworkingMicroseconds usecLastNow = usecWhenStarted;
391+ struct Timing { double flQuietSec; double flActiveSec; float flPrintIntervalSec; int nIterations; };
392+ static const Timing k_timing[] = {
393+ { 0.5 , 2.0 , 1 .0f , 1 }, // Cursory
394+ { 1.0 , 5.0 , 2 .0f , 2 }, // Normal
395+ { 8.0 , 25.0 , 5 .0f , 4 }, // Soak
396+ };
397+ const Timing &timing = k_timing[ (int )eMode ];
390398
391- SteamNetworkingMicroseconds usecQuietDuration = SteamNetworkingMicroseconds ( ( bQuickTest ? 1.0 : 8.0 ) * 1e6 );
392- SteamNetworkingMicroseconds usecActiveDuration = SteamNetworkingMicroseconds ( ( bQuickTest ? 5.0 : 25.0 ) * 1e6 );
393- float flWaitBetweenPrints = bQuickTest ? 2 . 0f : 5 . 0f ;
394- int nIterations = bQuickTest ? 2 : 4 ;
399+ SteamNetworkingMicroseconds usecQuietDuration = SteamNetworkingMicroseconds ( timing. flQuietSec * 1e6 );
400+ SteamNetworkingMicroseconds usecActiveDuration = SteamNetworkingMicroseconds ( timing. flActiveSec * 1e6 );
401+ float flWaitBetweenPrints = timing. flPrintIntervalSec ;
402+ int nIterations = timing. nIterations ;
395403
396404 bool bQuiet = true ;
397405 SteamNetworkingMicroseconds usecWhenStateEnd = 0 ;
@@ -415,7 +423,7 @@ static void TestNetworkConditions( int rate, float loss, int lag, float reorderP
415423 int nServerPending = g_peerServer.GetQueuedSendBytes ();
416424 int nClientPending = g_peerClient.GetQueuedSendBytes ();
417425
418- bool bCheckStateChange = ( usecWhenStateEnd == 0 );
426+ bool bCheckStateChange = ( usecWhenStateEnd == 0 );
419427 float flElapsedPrint = ( now - usecLastPrint ) * 1e-6f ;
420428 if ( flElapsedPrint > flWaitBetweenPrints )
421429 {
@@ -483,38 +491,24 @@ static void TestNetworkConditions( int rate, float loss, int lag, float reorderP
483491 }
484492}
485493
486- static void Test_Connection ( bool bQuickTest )
494+ static void Test_Connection ( ETestConnectionMode eMode, const SteamNetworkingIPAddr &addrServerBind, const SteamNetworkingIPAddr &addrClientConnect )
487495{
496+ static const char *const k_rgszModeName[] = { " Cursory" , " Normal" , " Soak" };
497+ TEST_Printf ( " ***************************************************\n " );
498+ TEST_Printf ( " Mode: %s\n " , k_rgszModeName[ (int )eMode ] );
499+ TEST_Printf ( " Server bind: %s\n " , SteamNetworkingIPAddrRender ( addrServerBind ).c_str () );
500+ TEST_Printf ( " Client connect: %s\n " , SteamNetworkingIPAddrRender ( addrClientConnect ).c_str () );
501+ TEST_Printf ( " ***************************************************\n " );
502+
488503 SteamNetworkingUtils ()->SetGlobalCallback_SteamNetConnectionStatusChanged ( OnSteamNetConnectionStatusChanged );
489504
490505 CloseConnections ();
491506
492507 ISteamNetworkingSockets *pSteamSocketNetworking = SteamNetworkingSockets ();
493508
494- // Command line options:
495- // -connect:ip -- don't create a server, just try to connect to the given ip
496- // -serveronly -- don't create a client only create a server and wait for connection
497- SteamNetworkingIPAddr bindServerAddress;
498- bindServerAddress.Clear ();
499- bindServerAddress.m_port = PORT_SERVER ;
500-
501- SteamNetworkingIPAddr connectToServerAddress;
502- connectToServerAddress.SetIPv4 ( 0x7f000001 , PORT_SERVER );
503-
504- // const char *s_pszConnectParm = "-connect:";
505- // for ( int i = 0; i < CommandLine()->ParmCount(); ++i )
506- // {
507- // if ( V_strnicmp( CommandLine()->GetParm( i ), s_pszConnectParm, V_strlen( s_pszConnectParm ) ) == 0 )
508- // {
509- // bClientOnly = true;
510- // connection_adr.SetFromString( CommandLine()->GetParm( i ) + V_strlen( s_pszConnectParm ) );
511- // break;
512- // }
513- // }
514-
515509 // Initiate connection
516- g_hSteamListenSocket = pSteamSocketNetworking->CreateListenSocketIP ( bindServerAddress , 0 , nullptr );
517- g_peerClient.m_hSteamNetConnection = pSteamSocketNetworking->ConnectByIPAddress ( connectToServerAddress , 0 , nullptr );
510+ g_hSteamListenSocket = pSteamSocketNetworking->CreateListenSocketIP ( addrServerBind , 0 , nullptr );
511+ g_peerClient.m_hSteamNetConnection = pSteamSocketNetworking->ConnectByIPAddress ( addrClientConnect , 0 , nullptr );
518512 pSteamSocketNetworking->SetConnectionName ( g_peerClient.m_hSteamNetConnection , " Client" );
519513
520514 g_peerClient.SetConnectionConfig ();
@@ -528,15 +522,18 @@ static void Test_Connection( bool bQuickTest )
528522 while ( !g_peerClient.m_bIsConnected || !g_peerServer.m_bIsConnected )
529523 TEST_PumpCallbacks ();
530524
531- auto Test = [bQuickTest ]( int rate, float loss, int lag, float reorderPct, int reorderLag )
525+ auto Test = [eMode ]( int rate, float loss, int lag, float reorderPct, int reorderLag )
532526 {
533- TestNetworkConditions ( rate, loss, lag, reorderPct, reorderLag, false , bQuickTest );
534- TestNetworkConditions ( rate, loss, lag, reorderPct, reorderLag, true , bQuickTest );
527+ TestNetworkConditions ( rate, loss, lag, reorderPct, reorderLag, false , eMode );
528+ TestNetworkConditions ( rate, loss, lag, reorderPct, reorderLag, true , eMode );
535529 };
536530
537- if ( bQuickTest )
531+ if ( eMode == ETestConnectionMode::Cursory )
532+ {
533+ Test ( 128000 , 10 , 50 , 2 , 50 ); // Low bandwidth, high packet loss
534+ }
535+ else if ( eMode == ETestConnectionMode::Normal )
538536 {
539- // Quick test, just do two situations
540537 Test ( 128000 , 10 , 50 , 2 , 50 ); // Low bandwidth, high packet loss
541538 Test ( 1000000 , 5 , 10 , 1 , 10 ); // Medium bandwidth, still pretty bad packet loss
542539 }
@@ -561,10 +558,59 @@ static void Test_Connection( bool bQuickTest )
561558 Test ( 64000 , 5 , 50 , 2 , 50 );
562559 Test ( 1000000 , 5 , 50 , 2 , 10 );
563560 }
561+
562+ CloseConnections ();
564563}
565564
566- static void Test_quick () { Test_Connection ( true ); }
567- static void Test_soak () { Test_Connection ( false ); }
565+ const int k_nStartingServerPort = 27200 ;
566+
567+ static void Test_quick ()
568+ {
569+ int nServerPort = k_nStartingServerPort;
570+ SteamNetworkingIPAddr bindAddr, connectAddr;
571+
572+ //
573+ // First, do some 'cursory' connection tests between various combiantions of IPv4, IPc6, and dual-stack.
574+ // This is really just to make sure we can connect and exchange packets.
575+ //
576+
577+ // IPv4-only server, IPv4 client
578+ bindAddr.SetIPv4 ( 0 , nServerPort );
579+ connectAddr.SetIPv4 ( 0x7f000001 , nServerPort );
580+ Test_Connection ( ETestConnectionMode::Cursory, bindAddr, connectAddr );
581+ ++nServerPort;
582+
583+ // IPv6-only server, IPv6 client
584+ bindAddr.SetIPv6LocalHost ( nServerPort );
585+ connectAddr.SetIPv6LocalHost ( nServerPort );
586+ Test_Connection ( ETestConnectionMode::Cursory, bindAddr, connectAddr );
587+ ++nServerPort;
588+
589+ // Dual-stack server, IPv6 client
590+ bindAddr.Clear (); bindAddr.m_port = nServerPort;
591+ connectAddr.SetIPv6LocalHost ( nServerPort );
592+ Test_Connection ( ETestConnectionMode::Cursory, bindAddr, connectAddr );
593+ ++nServerPort;
594+
595+ //
596+ // Now do a 'normal' test
597+ //
598+ // Dual-stack server, IPv4 client (IPv4-mapped path)
599+ bindAddr.Clear (); bindAddr.m_port = nServerPort;
600+ connectAddr.SetIPv4 ( 0x7f000001 , nServerPort );
601+ Test_Connection ( ETestConnectionMode::Normal, bindAddr, connectAddr );
602+ }
603+
604+ static void Test_soak ()
605+ {
606+ int nServerPort = k_nStartingServerPort;
607+ SteamNetworkingIPAddr bindAddr, connectAddr;
608+
609+ // Dual-stack server, IPv4 client (IPv4-mapped path)
610+ bindAddr.Clear (); bindAddr.m_port = nServerPort;
611+ connectAddr.SetIPv4 ( 0x7f000001 , nServerPort );
612+ Test_Connection ( ETestConnectionMode::Soak, bindAddr, connectAddr );
613+ }
568614
569615// Some tests for identity string handling. Doesn't really have anything to do with
570616// connectivity, this is just a conveinent place for this to live
@@ -1296,7 +1342,7 @@ int main( int argc, const char **argv )
12961342 }
12971343
12981344 // Shutdown library
1299- TEST_Kill ();
1345+ TEST_Kill ();
13001346 return 0 ;
13011347}
13021348
0 commit comments