mirror of
https://github.com/ValveSoftware/GameNetworkingSockets.git
synced 2026-05-29 16:20:34 +00:00
GetLocalAddresses now also returns the prefix length
(cherry picked from commit b63a9d606d)
This commit is contained in:
@@ -1216,7 +1216,7 @@ void CSteamNetworkingICESession::GatherInterfaces()
|
||||
SteamNetworkingGlobalLock::AssertHeldByCurrentThread( "CSteamNetworkingICESession::GatherInterfaces" );
|
||||
|
||||
m_vecInterfaces.clear();
|
||||
CUtlVector< SteamNetworkingIPAddr > vecAddrs;
|
||||
CUtlVector<LocalAddress_t> vecAddrs;
|
||||
if ( !GetLocalAddresses( &vecAddrs ) )
|
||||
return;
|
||||
|
||||
@@ -1226,7 +1226,7 @@ void CSteamNetworkingICESession::GatherInterfaces()
|
||||
m_vecInterfaces.reserve( vecAddrs.Count() );
|
||||
for ( int i = 0; i < vecAddrs.Count(); ++i )
|
||||
{
|
||||
m_vecInterfaces.push_back( Interface( vecAddrs[i], uPriority ) );
|
||||
m_vecInterfaces.push_back( Interface( vecAddrs[i].m_addr, uPriority, vecAddrs[i].m_nPrefixLen ) );
|
||||
--uPriority;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +196,8 @@ namespace SteamNetworkingSocketsLib {
|
||||
{
|
||||
SteamNetworkingIPAddr m_localaddr;
|
||||
uint32 m_nPriority;
|
||||
Interface( const SteamNetworkingIPAddr& ipAddr, uint32 p ) : m_localaddr( ipAddr ), m_nPriority( p ) {}
|
||||
int m_nPrefixLen; // Subnet prefix length from adapter enumeration; 0 if unavailable
|
||||
Interface( const SteamNetworkingIPAddr& ipAddr, uint32 p, int nPrefixLen ) : m_localaddr( ipAddr ), m_nPriority( p ), m_nPrefixLen( nPrefixLen ) {}
|
||||
};
|
||||
|
||||
struct ICEPeerCandidate : public ICECandidate
|
||||
|
||||
@@ -336,7 +336,13 @@ extern void WakeServiceThread();
|
||||
extern bool IsRouteToAddressProbablyLocal( netadr_t addr );
|
||||
|
||||
extern bool ResolveHostname( const char* pszHostname, CUtlVector< SteamNetworkingIPAddr > *pAddrs );
|
||||
extern bool GetLocalAddresses( CUtlVector< SteamNetworkingIPAddr >* pAddrs );
|
||||
|
||||
struct LocalAddress_t
|
||||
{
|
||||
SteamNetworkingIPAddr m_addr;
|
||||
int m_nPrefixLen; // Subnet prefix length, e.g. 24 for a /24. 0 if unavailable or bogus.
|
||||
};
|
||||
extern bool GetLocalAddresses( CUtlVector<LocalAddress_t> *pAddrs );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
@@ -3908,7 +3908,53 @@ inline bool GetLocalAddresses_IsReserved( const SteamNetworkingIPAddr &ipAddr )
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetLocalAddresses( CUtlVector< SteamNetworkingIPAddr >* pAddrs )
|
||||
// Convert an IPv4 netmask (host byte order) to a prefix length.
|
||||
// Returns 0 if the mask is zero, non-contiguous, or otherwise bogus.
|
||||
static int IPv4MaskToPrefixLen( uint32 mask )
|
||||
{
|
||||
if ( mask == 0 )
|
||||
return 0;
|
||||
// Count leading 1-bits
|
||||
int n = 0;
|
||||
while ( n < 32 && ( mask & ( 0x80000000u >> n ) ) )
|
||||
++n;
|
||||
// Validate: reconstruct expected mask and compare
|
||||
uint32 expected = ( n == 32 ) ? 0xFFFFFFFFu : ~( 0xFFFFFFFFu >> n );
|
||||
return ( mask == expected ) ? n : 0;
|
||||
}
|
||||
|
||||
// Convert a 16-byte IPv6 netmask to a prefix length.
|
||||
// Returns 0 if the mask is zero, non-contiguous, or otherwise bogus.
|
||||
static int IPv6MaskToPrefixLen( const uint8 *pMask )
|
||||
{
|
||||
int n = 0;
|
||||
for ( int i = 0; i < 16; ++i )
|
||||
{
|
||||
uint8 b = pMask[i];
|
||||
if ( b == 0xFF ) { n += 8; continue; }
|
||||
if ( b == 0 )
|
||||
{
|
||||
// All remaining bytes must be 0
|
||||
for ( int j = i + 1; j < 16; ++j )
|
||||
if ( pMask[j] != 0 ) return 0;
|
||||
break;
|
||||
}
|
||||
// Partial byte: count leading 1-bits, then validate the rest is 0
|
||||
int nBits = 0;
|
||||
for ( uint8 m = 0x80; m && ( b & m ); m >>= 1 )
|
||||
++nBits;
|
||||
uint8 expected = (uint8)( 0xFF << ( 8 - nBits ) );
|
||||
if ( b != expected ) return 0; // non-contiguous
|
||||
n += nBits;
|
||||
// All remaining bytes must be 0
|
||||
for ( int j = i + 1; j < 16; ++j )
|
||||
if ( pMask[j] != 0 ) return 0;
|
||||
break;
|
||||
}
|
||||
return n; // 0 means all-zero mask, which is bogus
|
||||
}
|
||||
|
||||
bool GetLocalAddresses( CUtlVector<LocalAddress_t> *pAddrs )
|
||||
{
|
||||
|
||||
#if STEAMNETWORKINGSOCKETS_ENABLE_MOCK
|
||||
@@ -3917,7 +3963,14 @@ bool GetLocalAddresses( CUtlVector< SteamNetworkingIPAddr >* pAddrs )
|
||||
for ( const TEST_mocknetwork_interface_t &iface : s_mockNetworkConfig.m_vecInterfaces )
|
||||
{
|
||||
if ( iface.m_bEnabled )
|
||||
pAddrs->AddToTail( iface.m_ip );
|
||||
{
|
||||
LocalAddress_t &entry = *pAddrs->AddToTailGetPtr();
|
||||
entry.m_addr = iface.m_ip;
|
||||
// All mock private LANs are /24s identified by the third octet.
|
||||
// The public "internet" range (third octet == 100) is not a local LAN.
|
||||
bool bPublic = iface.m_ip.IsIPv4() && ( ( iface.m_ip.GetIPv4() & 0xFF00 ) == k_nMockPublicIPv4Net );
|
||||
entry.m_nPrefixLen = bPublic ? 0 : 24;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -3991,7 +4044,9 @@ bool GetLocalAddresses( CUtlVector< SteamNetworkingIPAddr >* pAddrs )
|
||||
continue;
|
||||
|
||||
// Got a host address, record it!
|
||||
pAddrs->AddToTail( ipAddr );
|
||||
LocalAddress_t &entry = *pAddrs->AddToTailGetPtr();
|
||||
entry.m_addr = ipAddr;
|
||||
entry.m_nPrefixLen = pThisAddr->OnLinkPrefixLength; // UINT8; 0 is bogus for a unicast addr
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4032,7 +4087,21 @@ bool GetLocalAddresses( CUtlVector< SteamNetworkingIPAddr >* pAddrs )
|
||||
continue;
|
||||
|
||||
// Got a host address, record it!
|
||||
pAddrs->AddToTail( ipAddr );
|
||||
LocalAddress_t &entry = *pAddrs->AddToTailGetPtr();
|
||||
entry.m_addr = ipAddr;
|
||||
entry.m_nPrefixLen = 0;
|
||||
if ( pAddr->ifa_netmask )
|
||||
{
|
||||
if ( pAddr->ifa_netmask->sa_family == AF_INET )
|
||||
{
|
||||
uint32 mask = BigDWord( ((sockaddr_in *)pAddr->ifa_netmask)->sin_addr.s_addr );
|
||||
entry.m_nPrefixLen = IPv4MaskToPrefixLen( mask );
|
||||
}
|
||||
else if ( pAddr->ifa_netmask->sa_family == AF_INET6 )
|
||||
{
|
||||
entry.m_nPrefixLen = IPv6MaskToPrefixLen( ((sockaddr_in6 *)pAddr->ifa_netmask)->sin6_addr.s6_addr );
|
||||
}
|
||||
}
|
||||
}
|
||||
freeifaddrs( pMyAddrInfo );
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user