Factor out same-ip-network checks in Linkdb.cpp

Implemented is_same_network_linkwise() and used that instead of having masking
with the magic constanct 0x0000ffff spread out all over the code.
This commit is contained in:
Ivan Skytte Jørgensen
2016-06-09 12:30:41 +02:00
parent 322acc3c96
commit 10467334ea
3 changed files with 52 additions and 8 deletions

@ -145,3 +145,43 @@ bool is_trusted_protocol_ip(uint32_t ip/*network-order*/)
//probably not an intranet host, so we err on the side of caution
return false;
}
//This is a replacement for the hardcoded checks on the /16 prefix of the ip addresses
//This is slightly more intelligent.
//The correct solution would be to have access to whois information and check the
//identity of the owner, and have special cases for all hosting providers.
bool is_same_network_linkwise(uint32_t ip_a/*network order*/, uint32_t ip_b/*network order*/)
{
if(ip_a==ip_b) {
//same IP - same network
//This is inaccurate for some hosting providers, apache with virtual
//domains and general frontends eg. cloudflare. It is widly inaccurate for CDNs
//but there are rarely permalinks to CNDs so it's not a major problem.
return true;
}
if((ip_a&0x000000ff)!=(ip_b&0x000000ff)) {
//Top 8 bit are different so they are not even on the same class-A network. So must be different.
//This fails if a company has a fragmented address space due to mergers. Eg. HP now owns Compaqs
//networks and Compaq owned DEC's networks, so ... quite messy and inexact. But better than nothing.
return false;
}
//make educated guesses for some of the known class-A owners
//from the test above we know that the top 8 bites are quals
if((ip_a&0xff)==3)
return true; //General Electric
if((ip_a&0xff)==6)
return true; //DoD
if((ip_a&0xff)==7)
return true; //DoD
if((ip_a&0xff)==9)
return true; //IBM
if((ip_a&0xff)==11)
return true; //DoD
if((ip_a&0xff)==15)
return true; //HP
//make a wild guess
if((ip_a&0x0000ffff)==(ip_b&0x0000ffff)) //same /16 net?
return true;
return false;
}

@ -19,5 +19,8 @@ bool is_internal_net_ip(uint32_t ip/*network-order*/);
//Is the IP an internal-like that we allow to use the udp protocol without being registered as part of the cluster?
bool is_trusted_protocol_ip(uint32_t ip/*network-order*/);
//Make a guess if the two IPs are on the same network / controlled by the same
//entity and links between them should be treated as internal links
bool is_same_network_linkwise(uint32_t ip_a/*network order*/, uint32_t ip_b/*network order*/);
#endif // GB_IPADDRESSCHECKS_H

@ -7,6 +7,7 @@
#include "Rebalance.h"
#include "Process.h"
#include "HashTable.h"
#include "IPAddressChecks.h"
#ifdef _VALGRIND_
#include <valgrind/memcheck.h>
#endif
@ -2537,9 +2538,9 @@ bool Msg25::gotLinkText ( Msg20Request *req ) { // LinkTextReply *linkText ) {
Msg20Reply *r = m_replyPtrs[i];
// are we internal
bool internal = false;
if ( (r->m_ip&0x0000ffff) == (m_ip&0x0000ffff) )
if ( is_same_network_linkwise(r->m_ip,m_ip) )
internal = true;
if ( (r->m_firstIp&0x0000ffff) == (m_ip&0x0000ffff))
if ( is_same_network_linkwise(r->m_firstIp,m_ip))
internal = true;
// the "external" string
//char *ext = "Y"; if ( internal ) ext = "N";
@ -3001,9 +3002,9 @@ static LinkInfo *makeLinkInfo ( const char *coll ,
if ( ! replies[i] ) continue;
//if ( texts[i]->m_errno ) continue;
bool internal = false;
if ( (replies[i]->m_ip&0x0000ffff) == (ip&0x0000ffff) )
if ( is_same_network_linkwise(replies[i]->m_ip,ip) )
internal = true;
if ( (replies[i]->m_firstIp&0x0000ffff) == (ip&0x0000ffff) )
if ( is_same_network_linkwise(replies[i]->m_firstIp,ip) )
internal = true;
if ( internal )
icount++;
@ -3041,9 +3042,9 @@ static LinkInfo *makeLinkInfo ( const char *coll ,
}
bool internal = false;
if ((r->m_ip&0x0000ffff) == (ip & 0x0000ffff))
if ( is_same_network_linkwise(r->m_ip,ip))
internal = true;
if ((r->m_firstIp&0x0000ffff) == (ip & 0x0000ffff))
if ( is_same_network_linkwise(r->m_firstIp,ip))
internal = true;
// if its internal do not count towards good, but do
@ -3136,9 +3137,9 @@ static LinkInfo *makeLinkInfo ( const char *coll ,
if ( r->m_isLinkSpam && onlyNeedGoodInlinks ) continue;
// are we internal?
bool internal = false;
if ( (r->m_ip&0x0000ffff) == (ip & 0x0000ffff) )
if ( is_same_network_linkwise(r->m_ip,ip) )
internal = true;
if ( (r->m_firstIp&0x0000ffff) == (ip & 0x0000ffff) )
if ( is_same_network_linkwise(r->m_firstIp,ip) )
internal = true;
if ( internal ) icount3++;
// set the Inlink