diff --git a/include/steam/steamnetworkingtypes.h b/include/steam/steamnetworkingtypes.h index f105712..a332232 100644 --- a/include/steam/steamnetworkingtypes.h +++ b/include/steam/steamnetworkingtypes.h @@ -1444,6 +1444,9 @@ enum ESteamNetworkingConfigValue /// route ping time and is then adjusted.) k_ESteamNetworkingConfig_P2P_Transport_ICE_Penalty = 105, k_ESteamNetworkingConfig_P2P_Transport_SDR_Penalty = 106, + k_ESteamNetworkingConfig_P2P_TURN_ServerList = 107, + k_ESteamNetworkingConfig_P2P_TURN_UserList = 108, + k_ESteamNetworkingConfig_P2P_TURN_PassList = 109, //k_ESteamNetworkingConfig_P2P_Transport_LANBeacon_Penalty = 107, // diff --git a/src/external/steamwebrtc/ice_session.cpp b/src/external/steamwebrtc/ice_session.cpp index 6bd9082..4fedac2 100644 --- a/src/external/steamwebrtc/ice_session.cpp +++ b/src/external/steamwebrtc/ice_session.cpp @@ -313,6 +313,7 @@ bool CICESession::BInitializeOnSocketThread( const ICESessionConfig &cfg ) case k_EProtocolTypeTCP: case k_EProtocolTypeSSLTCP: case k_EProtocolTypeTLS: + break; default: m_pDelegate->Log( IICESessionDelegate::k_ELogPriorityError, "Invalid Turn server protocol type '%d'\n", (int) pTurn->m_protocolType ); return false; diff --git a/src/steamnetworkingsockets/clientlib/csteamnetworkingsockets.cpp b/src/steamnetworkingsockets/clientlib/csteamnetworkingsockets.cpp index ae49a7b..be68917 100644 --- a/src/steamnetworkingsockets/clientlib/csteamnetworkingsockets.cpp +++ b/src/steamnetworkingsockets/clientlib/csteamnetworkingsockets.cpp @@ -97,6 +97,9 @@ DEFINE_CONNECTON_DEFAULT_CONFIGVAL( int32, EnableDiagnosticsUI, 1, 0, 1 ); #ifdef STEAMNETWORKINGSOCKETS_ENABLE_ICE DEFINE_CONNECTON_DEFAULT_CONFIGVAL( std::string, P2P_STUN_ServerList, "" ); +DEFINE_CONNECTON_DEFAULT_CONFIGVAL( std::string, P2P_TURN_ServerList, "" ); +DEFINE_CONNECTON_DEFAULT_CONFIGVAL( std::string, P2P_TURN_UserList, "" ); +DEFINE_CONNECTON_DEFAULT_CONFIGVAL( std::string, P2P_TURN_PassList, "" ); COMPILE_TIME_ASSERT( k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Default == -1 ); COMPILE_TIME_ASSERT( k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Disable == 0 ); diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_p2p_ice.cpp b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_p2p_ice.cpp index 178b0fd..dc0c17a 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_p2p_ice.cpp +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_p2p_ice.cpp @@ -141,7 +141,7 @@ void CConnectionTransportP2PICE::Init() if ( P2P_Transport_ICE_Enable & k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Private ) m_nAllowedCandidateTypes |= k_EICECandidate_Any_HostPrivate; - // Get the STUN server list + // Get the STUN server list std_vector vecStunServers; std_vector vecStunServersPsz; if ( P2P_Transport_ICE_Enable & k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Public ) @@ -177,10 +177,79 @@ void CConnectionTransportP2PICE::Init() cfg.m_pStunServers = vecStunServersPsz.data(); // Get the TURN server list + std_vector vecTurnServers; + std_vector vecTurnUsers; + std_vector vecTurnPasses; + std_vector vecTurnServersPsz; if ( P2P_Transport_ICE_Enable & k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Relay ) { // FIXME //cfg.m_nCandidateTypes = m_nAllowedCandidateTypes; + + m_nAllowedCandidateTypes |= k_EICECandidate_Any_HostPublic | k_EICECandidate_Any_Reflexive; + + { + CUtlVectorAutoPurge tempTurnServers; + V_AllocAndSplitString(m_connection.m_connectionConfig.m_P2P_TURN_ServerList.Get().c_str(), ",", tempTurnServers); + for (const char* pszAddress : tempTurnServers) + { + std::string server; + + // Add prefix, unless they already supplied it + if (V_strnicmp(pszAddress, "turn:", 5) != 0) + server = "turn:"; + server.append(pszAddress); + + vecTurnServers.push_back(std::move(server)); + } + + // populate usernames + CUtlVectorAutoPurge tempTurnUsers; + V_AllocAndSplitString(m_connection.m_connectionConfig.m_P2P_TURN_UserList.Get().c_str(), ",", tempTurnUsers); + for (const char* user : tempTurnServers) + { + std::string server; + server.append(user); + vecTurnUsers.push_back(std::move(server)); + } + + // populate passwords + CUtlVectorAutoPurge tempTurnPasses; + V_AllocAndSplitString(m_connection.m_connectionConfig.m_P2P_TURN_PassList.Get().c_str(), ",", tempTurnPasses); + for (const char* pass : tempTurnPasses) + { + std::string server; + server.append(pass); + vecTurnPasses.push_back(std::move(server)); + } + } + if (vecTurnServers.empty()) + SpewWarningGroup(LogLevel_P2PRendezvous(), "[%s] Reflexive candidates enabled by P2P_Transport_ICE_Enable, but P2P_STUN_ServerList is empty\n", ConnectionDescription()); + else + SpewVerboseGroup(LogLevel_P2PRendezvous(), "[%s] Using STUN server list: %s\n", ConnectionDescription(), m_connection.m_connectionConfig.m_P2P_TURN_ServerList.Get().c_str()); + + Assert(vecTurnServers.size() == vecTurnUsers.size() == vecTurnPasses.size()); + } + else + { + SpewVerboseGroup(LogLevel_P2PRendezvous(), "[%s] Not using STUN servers as per P2P_Transport_ICE_Enable\n", ConnectionDescription()); + } + + // Populate TurnServers configs + for (int i = 0; i < vecTurnServers.size(); i++) + { + ICESessionConfig::TurnServer* turn = new ICESessionConfig::TurnServer(); + turn->m_pszHost = vecTurnServers[i].c_str(); + turn->m_pszPwd = vecTurnUsers[i].c_str(); + turn->m_pszUsername = vecTurnPasses[i].c_str(); + vecTurnServersPsz.push_back(turn); + } + + // If any Turn server config exists, set it + if (vecTurnServers.size() > 0) + { + cfg.m_nTurnServers = len(vecTurnServers); + cfg.m_pTurnServers = *vecTurnServersPsz.data(); } cfg.m_nCandidateTypes = m_nAllowedCandidateTypes; diff --git a/src/steamnetworkingsockets/steamnetworkingsockets_internal.h b/src/steamnetworkingsockets/steamnetworkingsockets_internal.h index d3f3185..344b24b 100644 --- a/src/steamnetworkingsockets/steamnetworkingsockets_internal.h +++ b/src/steamnetworkingsockets/steamnetworkingsockets_internal.h @@ -822,6 +822,9 @@ struct ConnectionConfig ConfigValue m_P2P_STUN_ServerList; ConfigValue m_P2P_Transport_ICE_Enable; ConfigValue m_P2P_Transport_ICE_Penalty; + ConfigValue m_P2P_TURN_ServerList; + ConfigValue m_P2P_TURN_UserList; + ConfigValue m_P2P_TURN_PassList; #endif #ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR diff --git a/tests/test_p2p.cpp b/tests/test_p2p.cpp index 0e78b91..ecbef9d 100644 --- a/tests/test_p2p.cpp +++ b/tests/test_p2p.cpp @@ -198,6 +198,16 @@ int main( int argc, const char **argv ) // Hardcode STUN servers SteamNetworkingUtils()->SetGlobalConfigValueString( k_ESteamNetworkingConfig_P2P_STUN_ServerList, "stun.l.google.com:19302" ); + // Hardcode TURN servers + // comma seperated setting lists + //const char* turnList = "turn:123.45.45:3478"; + //const char* userList = "username"; + //const char* passList = "pass"; + + //SteamNetworkingUtils()->SetGlobalConfigValueString(k_ESteamNetworkingConfig_P2P_TURN_ServerList, turnList); + //SteamNetworkingUtils()->SetGlobalConfigValueString(k_ESteamNetworkingConfig_P2P_TURN_UserList, userList); + //SteamNetworkingUtils()->SetGlobalConfigValueString(k_ESteamNetworkingConfig_P2P_TURN_PassList, passList); + // Allow sharing of any kind of ICE address. // We don't have any method of relaying (TURN) in this example, so we are essentially // forced to disclose our public address if we want to pierce NAT. But if we