mirror of
https://github.com/ValveSoftware/GameNetworkingSockets.git
synced 2026-05-29 16:20:34 +00:00
ICE client refactor: Each Interface knows what session owns it
Socket callback will be the interface pointer, which gives us
a little bit more context and makes a few things simpler.
(cherry picked from commit 60314c1606)
This commit is contained in:
@@ -1303,43 +1303,23 @@ void CSteamNetworkingICESession::GatherInterfaces()
|
||||
// the list was empty).
|
||||
for ( const LocalAddress_t &addr: vecAddrs )
|
||||
{
|
||||
std::unique_ptr<ICESessionInterface> pIntf = std::make_unique<ICESessionInterface>( *this, uNextPriority, addr.m_nPrefixLen );
|
||||
SteamDatagramErrMsg errMsg;
|
||||
SteamNetworkingIPAddr bindAddr = addr.m_addr;
|
||||
IRawUDPSocket *pSock = OpenRawUDPSocket( CRecvPacketCallback( CSteamNetworkingICESession::StaticPacketReceived, this ), errMsg, &bindAddr, nullptr );
|
||||
if ( pSock == nullptr )
|
||||
pIntf->m_pSocket = OpenRawUDPSocket( CRecvPacketCallback( CSteamNetworkingICESession::StaticPacketReceived, pIntf.get() ), errMsg, &bindAddr, nullptr );
|
||||
if ( pIntf->m_pSocket == nullptr )
|
||||
{
|
||||
SpewWarning( "Could not bind to %s, skipping interface. %s\n", SteamNetworkingIPAddrRender( addr.m_addr ).c_str(), errMsg );
|
||||
continue;
|
||||
}
|
||||
|
||||
m_vecInterfaces.emplace_back( std::make_unique<ICESessionInterface>( uNextPriority, addr.m_nPrefixLen, pSock ) );
|
||||
m_vecInterfaces.emplace_back( std::move( pIntf ) );
|
||||
if ( uNextPriority > 0 )
|
||||
--uNextPriority;
|
||||
}
|
||||
}
|
||||
|
||||
CSteamNetworkingSocketsSTUNRequest *CSteamNetworkingICESession::FindPendingRequestByTransactionID( const uint32 nTransactionID[3] ) const
|
||||
{
|
||||
auto fnMatches = [nTransactionID]( const CSteamNetworkingSocketsSTUNRequest *pRequest )
|
||||
{
|
||||
return pRequest != nullptr
|
||||
&& pRequest->m_nTransactionID[0] == nTransactionID[0]
|
||||
&& pRequest->m_nTransactionID[1] == nTransactionID[1]
|
||||
&& pRequest->m_nTransactionID[2] == nTransactionID[2];
|
||||
};
|
||||
|
||||
for ( const auto &pIntf : m_vecInterfaces )
|
||||
if ( fnMatches( pIntf->m_pPendingSTUNRequest ) )
|
||||
return pIntf->m_pPendingSTUNRequest;
|
||||
|
||||
for ( CSteamNetworkingSocketsSTUNRequest *pRequest : m_vecPendingPeerRequests )
|
||||
if ( fnMatches( pRequest ) )
|
||||
return pRequest;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CSteamNetworkingICESession::OnPacketReceived( const RecvPktInfo_t &info )
|
||||
void CSteamNetworkingICESession::OnPacketReceived( const RecvPktInfo_t &info, ICESessionInterface *pInterface )
|
||||
{
|
||||
SteamNetworkingGlobalLock::AssertHeldByCurrentThread( "CSteamNetworkingICESession::OnPacketReceived" );
|
||||
|
||||
@@ -1351,7 +1331,27 @@ void CSteamNetworkingICESession::OnPacketReceived( const RecvPktInfo_t &info )
|
||||
UnpackSTUNHeader( reinterpret_cast<const uint32 *>( info.m_pPkt ), &quickHeader );
|
||||
if ( IsValidSTUNHeader( &quickHeader, info.m_cbPkt, nullptr ) && quickHeader.m_nMessageType != k_nSTUN_BindingRequest )
|
||||
{
|
||||
CSteamNetworkingSocketsSTUNRequest *pRequest = FindPendingRequestByTransactionID( quickHeader.m_nTransactionID );
|
||||
CSteamNetworkingSocketsSTUNRequest *pRequest = pInterface->m_pPendingSTUNRequest;
|
||||
if (
|
||||
pRequest == nullptr
|
||||
|| pRequest->m_nTransactionID[0] != quickHeader.m_nTransactionID[0]
|
||||
|| pRequest->m_nTransactionID[1] != quickHeader.m_nTransactionID[1]
|
||||
|| pRequest->m_nTransactionID[2] != quickHeader.m_nTransactionID[2]
|
||||
) {
|
||||
pRequest = nullptr;
|
||||
for ( CSteamNetworkingSocketsSTUNRequest *p : m_vecPendingPeerRequests )
|
||||
{
|
||||
if (
|
||||
p->m_pInterface == pInterface
|
||||
&& p->m_nTransactionID[0] == quickHeader.m_nTransactionID[0]
|
||||
&& p->m_nTransactionID[1] == quickHeader.m_nTransactionID[1]
|
||||
&& p->m_nTransactionID[2] == quickHeader.m_nTransactionID[2]
|
||||
) {
|
||||
pRequest = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( pRequest != nullptr )
|
||||
{
|
||||
pRequest->OnPacketReceived( info );
|
||||
@@ -1414,14 +1414,13 @@ void CSteamNetworkingICESession::OnPacketReceived( const RecvPktInfo_t &info )
|
||||
CUtlVector< STUNAttribute > outAttrs;
|
||||
|
||||
{
|
||||
const SteamNetworkingIPAddr localAddr = info.m_pSock->m_boundAddr;
|
||||
SpewMsg( "Incoming binding request from %s to %s.\n\n", SteamNetworkingIPAddrRender( fromAddr ).c_str(), SteamNetworkingIPAddrRender( localAddr ).c_str() );
|
||||
SpewMsg( "Incoming binding request from %s to %s.\n\n", SteamNetworkingIPAddrRender( fromAddr ).c_str(), SteamNetworkingIPAddrRender( pInterface->m_pSocket->m_boundAddr ).c_str() );
|
||||
|
||||
ICECandidatePair *pThisPair = nullptr;
|
||||
for ( ICECandidatePair *pPair : m_vecCandidatePairs )
|
||||
{
|
||||
if ( pPair->m_remoteCandidate.m_addr == fromAddr
|
||||
&& pPair->m_localCandidate.m_pInterface->m_pSocket == info.m_pSock )
|
||||
&& pPair->m_localCandidate.m_pInterface == pInterface )
|
||||
{
|
||||
pThisPair = pPair;
|
||||
break;
|
||||
@@ -1439,7 +1438,7 @@ void CSteamNetworkingICESession::OnPacketReceived( const RecvPktInfo_t &info )
|
||||
ICELocalCandidate *pLocalCandidate = nullptr;
|
||||
for ( ICELocalCandidate &c : m_vecCandidates )
|
||||
{
|
||||
if ( c.m_pInterface->m_pSocket == info.m_pSock )
|
||||
if ( c.m_pInterface == pInterface )
|
||||
{
|
||||
pLocalCandidate = &c;
|
||||
break;
|
||||
@@ -1521,10 +1520,9 @@ void CSteamNetworkingICESession::OnPacketReceived( const RecvPktInfo_t &info )
|
||||
}
|
||||
}
|
||||
|
||||
void CSteamNetworkingICESession::StaticPacketReceived( const RecvPktInfo_t &info, CSteamNetworkingICESession *pContext )
|
||||
void CSteamNetworkingICESession::StaticPacketReceived( const RecvPktInfo_t &info, ICESessionInterface *pContext )
|
||||
{
|
||||
if ( pContext != nullptr )
|
||||
pContext->OnPacketReceived( info );
|
||||
pContext->m_session.OnPacketReceived( info, pContext );
|
||||
}
|
||||
|
||||
void CSteamNetworkingICESession::Think( SteamNetworkingMicroseconds usecNow )
|
||||
|
||||
@@ -14,11 +14,15 @@
|
||||
namespace SteamNetworkingSocketsLib {
|
||||
class CSteamNetworkingSocketsSTUNRequest;
|
||||
class CSteamNetworkingICESessionCallbacks;
|
||||
class CSteamNetworkingICESession;
|
||||
|
||||
/// Represents one local network interface used for ICE candidate gathering.
|
||||
/// Owns its socket and tracks at most one in-flight server-reflexive STUN request.
|
||||
struct ICESessionInterface
|
||||
{
|
||||
// The session that owns this interface.
|
||||
CSteamNetworkingICESession &m_session;
|
||||
|
||||
// Local-preference component of the ICE priority formula
|
||||
// (RFC 8445 §5.1.2). Assigned as a countdown from 65535 in
|
||||
// enumeration order so the first adapter returned by the OS gets
|
||||
@@ -31,17 +35,18 @@ namespace SteamNetworkingSocketsLib {
|
||||
int m_nPrefixLen;
|
||||
|
||||
// Raw UDP socket bound to this interface for sending and receiving
|
||||
// ICE traffic. Always non-NULL, owned by this object.
|
||||
// ICE traffic. Null only transiently during construction before
|
||||
// the socket is successfully opened. Owned by this object;
|
||||
// m_pSocket->m_boundAddr is the local IP:port for this interface.
|
||||
IRawUDPSocket * const m_pSocket;
|
||||
IRawUDPSocket *m_pSocket;
|
||||
|
||||
// In-flight STUN bind request for server-reflexive discovery or
|
||||
// keepalive, or null if none is active. At most one per interface.
|
||||
CSteamNetworkingSocketsSTUNRequest *m_pPendingSTUNRequest = nullptr;
|
||||
|
||||
ICESessionInterface( uint32 p, int nPrefixLen, IRawUDPSocket *pSocket )
|
||||
: m_nPriority( p ), m_nPrefixLen( nPrefixLen ), m_pSocket( pSocket ) {}
|
||||
~ICESessionInterface() { m_pSocket->Close(); }
|
||||
ICESessionInterface( CSteamNetworkingICESession &session, uint32 nPriority, int nPrefixLen )
|
||||
: m_session( session ), m_nPriority( nPriority ), m_nPrefixLen( nPrefixLen ), m_pSocket( nullptr ) {}
|
||||
~ICESessionInterface() { if ( m_pSocket ) m_pSocket->Close(); }
|
||||
|
||||
ICESessionInterface( const ICESessionInterface& ) = delete;
|
||||
ICESessionInterface& operator=( const ICESessionInterface& ) = delete;
|
||||
@@ -372,7 +377,6 @@ namespace SteamNetworkingSocketsLib {
|
||||
// each Think() pass before the regular check list.
|
||||
std_vector< ICECandidatePair* > m_vecTriggeredCheckQueue;
|
||||
|
||||
CSteamNetworkingSocketsSTUNRequest *FindPendingRequestByTransactionID( const uint32 nTransactionID[3] ) const;
|
||||
void GatherInterfaces();
|
||||
void UpdateHostCandidates();
|
||||
void UpdateKeepalive( const ICELocalCandidate& c );
|
||||
@@ -399,8 +403,8 @@ namespace SteamNetworkingSocketsLib {
|
||||
void STUNRequestCallback_PeerConnectivityCheck( const RecvSTUNPktInfo_t &info );
|
||||
static void StaticSTUNRequestCallback_PeerConnectivityCheck( const RecvSTUNPktInfo_t &info, CSteamNetworkingICESession* pContext );
|
||||
|
||||
void OnPacketReceived( const RecvPktInfo_t &info );
|
||||
static void StaticPacketReceived( const RecvPktInfo_t &info, CSteamNetworkingICESession *pContext );
|
||||
void OnPacketReceived( const RecvPktInfo_t &info, ICESessionInterface *pInterface );
|
||||
static void StaticPacketReceived( const RecvPktInfo_t &info, ICESessionInterface *pContext );
|
||||
};
|
||||
|
||||
class CSteamNetworkingICESessionCallbacks
|
||||
|
||||
Reference in New Issue
Block a user