diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.cpp b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.cpp index 9acd653..1bdc8f4 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.cpp +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.cpp @@ -904,6 +904,14 @@ bool ParseRFC5245CandidateAttribute( const char *pszAttr, RFC5245CandidateAttr * } // namespace +// Compare IP addresses, ignoring the port. +// Should we promotet this to a more public header? Or perhaps +// make it a member of SteamNetworkingIPAddr? +inline bool IPAddrEqualIgnoringPort( const SteamNetworkingIPAddr &a, const SteamNetworkingIPAddr &b ) +{ + return memcmp( a.m_ipv6, b.m_ipv6, sizeof(a.m_ipv6) ) == 0; +} + ///////////////////////////////////////////////////////////////////////////// // @@ -1242,7 +1250,7 @@ void CSteamNetworkingICESession::GatherInterfaces() bool bFound = false; for ( int j = 0; j < vecAddrs.Count(); ++j ) { - if ( vecAddrs[j].m_addr == intf.m_localaddr ) + if ( IPAddrEqualIgnoringPort( vecAddrs[j].m_addr, intf.m_pSocket->m_boundAddr ) ) { vecAddrs.FastRemove( j ); bFound = true; @@ -1284,7 +1292,7 @@ void CSteamNetworkingICESession::GatherInterfaces() continue; } - m_vecInterfaces.emplace_back( std::make_unique( addr.m_addr, uNextPriority, addr.m_nPrefixLen, pSock ) ); + m_vecInterfaces.emplace_back( std::make_unique( uNextPriority, addr.m_nPrefixLen, pSock ) ); if ( uNextPriority > 0 ) --uNextPriority; } @@ -1292,13 +1300,9 @@ void CSteamNetworkingICESession::GatherInterfaces() int CSteamNetworkingICESession::GetLocalCandidatePrefixLen( const SteamNetworkingIPAddr &addr ) const { - // m_localaddr entries have port=0 (from getifaddrs); candidate bases carry the bound port. - // Strip the port before comparing so the lookup succeeds. - SteamNetworkingIPAddr addrNoPort = addr; - addrNoPort.m_port = 0; for ( const auto &pIntf : m_vecInterfaces ) { - if ( pIntf->m_localaddr == addrNoPort ) + if ( IPAddrEqualIgnoringPort( pIntf->m_pSocket->m_boundAddr, addr ) ) return pIntf->m_nPrefixLen; } return 0; @@ -1685,7 +1689,7 @@ void CSteamNetworkingICESession::STUNRequestCallback_ServerReflexiveCandidate( c uint32 uLocalPriority = 0; for ( const std::unique_ptr &pIface : m_vecInterfaces ) { - if ( pIface->m_localaddr == localAddr ) + if ( pIface->m_pSocket->m_boundAddr == localAddr ) { uLocalPriority = pIface->m_nPriority; break; diff --git a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.h b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.h index 0df992b..a0a5f87 100644 --- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.h +++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.h @@ -196,10 +196,6 @@ namespace SteamNetworkingSocketsLib { private: struct Interface { - // Local IP address of this network interface. Port is always 0; - // the actual bound port lives on the socket. - SteamNetworkingIPAddr m_localaddr; - // 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 @@ -213,10 +209,11 @@ namespace SteamNetworkingSocketsLib { // Raw UDP socket bound to this interface for sending and receiving // ICE traffic. Always non-NULL, owned by this object. + // m_pSocket->m_boundAddr is the local IP:port for this interface. IRawUDPSocket * const m_pSocket; - Interface( const SteamNetworkingIPAddr& ipAddr, uint32 p, int nPrefixLen, IRawUDPSocket *pSocket ) - : m_localaddr( ipAddr ), m_nPriority( p ), m_nPrefixLen( nPrefixLen ), m_pSocket( pSocket ) {} + Interface( uint32 p, int nPrefixLen, IRawUDPSocket *pSocket ) + : m_nPriority( p ), m_nPrefixLen( nPrefixLen ), m_pSocket( pSocket ) {} ~Interface() {