@ -15,6 +15,9 @@
static const unsigned char pchIPv4 [ 12 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0xff , 0xff } ;
static const unsigned char pchIPv4 [ 12 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0xff , 0xff } ;
static const unsigned char pchOnionCat [ ] = { 0xFD , 0x87 , 0xD8 , 0x7E , 0xEB , 0x43 } ;
static const unsigned char pchOnionCat [ ] = { 0xFD , 0x87 , 0xD8 , 0x7E , 0xEB , 0x43 } ;
// 0xFD + sha256("bitcoin")[0:5]
static const unsigned char g_internal_prefix [ ] = { 0xFD , 0x6B , 0x88 , 0xC0 , 0x87 , 0x24 } ;
void CNetAddr : : Init ( )
void CNetAddr : : Init ( )
{
{
memset ( ip , 0 , sizeof ( ip ) ) ;
memset ( ip , 0 , sizeof ( ip ) ) ;
@ -42,6 +45,18 @@ void CNetAddr::SetRaw(Network network, const uint8_t *ip_in)
}
}
}
}
bool CNetAddr : : SetInternal ( const std : : string & name )
{
if ( name . empty ( ) ) {
return false ;
}
unsigned char hash [ 32 ] = { } ;
CSHA256 ( ) . Write ( ( const unsigned char * ) name . data ( ) , name . size ( ) ) . Finalize ( hash ) ;
memcpy ( ip , g_internal_prefix , sizeof ( g_internal_prefix ) ) ;
memcpy ( ip + sizeof ( g_internal_prefix ) , hash , sizeof ( ip ) - sizeof ( g_internal_prefix ) ) ;
return true ;
}
bool CNetAddr : : SetSpecial ( const std : : string & strName )
bool CNetAddr : : SetSpecial ( const std : : string & strName )
{
{
if ( strName . size ( ) > 6 & & strName . substr ( strName . size ( ) - 6 , 6 ) = = " .onion " ) {
if ( strName . size ( ) > 6 & & strName . substr ( strName . size ( ) - 6 , 6 ) = = " .onion " ) {
@ -84,7 +99,7 @@ bool CNetAddr::IsIPv4() const
bool CNetAddr : : IsIPv6 ( ) const
bool CNetAddr : : IsIPv6 ( ) const
{
{
return ( ! IsIPv4 ( ) & & ! IsTor ( ) ) ;
return ( ! IsIPv4 ( ) & & ! IsTor ( ) & & ! IsInternal ( ) ) ;
}
}
bool CNetAddr : : IsRFC1918 ( ) const
bool CNetAddr : : IsRFC1918 ( ) const
@ -199,6 +214,9 @@ bool CNetAddr::IsValid() const
if ( IsRFC3849 ( ) )
if ( IsRFC3849 ( ) )
return false ;
return false ;
if ( IsInternal ( ) )
return false ;
if ( IsIPv4 ( ) )
if ( IsIPv4 ( ) )
{
{
// INADDR_NONE
// INADDR_NONE
@ -217,11 +235,19 @@ bool CNetAddr::IsValid() const
bool CNetAddr : : IsRoutable ( ) const
bool CNetAddr : : IsRoutable ( ) const
{
{
return IsValid ( ) & & ! ( IsRFC1918 ( ) | | IsRFC2544 ( ) | | IsRFC3927 ( ) | | IsRFC4862 ( ) | | IsRFC6598 ( ) | | IsRFC5737 ( ) | | ( IsRFC4193 ( ) & & ! IsTor ( ) ) | | IsRFC4843 ( ) | | IsLocal ( ) ) ;
return IsValid ( ) & & ! ( IsRFC1918 ( ) | | IsRFC2544 ( ) | | IsRFC3927 ( ) | | IsRFC4862 ( ) | | IsRFC6598 ( ) | | IsRFC5737 ( ) | | ( IsRFC4193 ( ) & & ! IsTor ( ) ) | | IsRFC4843 ( ) | | IsLocal ( ) | | IsInternal ( ) ) ;
}
bool CNetAddr : : IsInternal ( ) const
{
return memcmp ( ip , g_internal_prefix , sizeof ( g_internal_prefix ) ) = = 0 ;
}
}
enum Network CNetAddr : : GetNetwork ( ) const
enum Network CNetAddr : : GetNetwork ( ) const
{
{
if ( IsInternal ( ) )
return NET_INTERNAL ;
if ( ! IsRoutable ( ) )
if ( ! IsRoutable ( ) )
return NET_UNROUTABLE ;
return NET_UNROUTABLE ;
@ -238,6 +264,8 @@ std::string CNetAddr::ToStringIP() const
{
{
if ( IsTor ( ) )
if ( IsTor ( ) )
return EncodeBase32 ( & ip [ 6 ] , 10 ) + " .onion " ;
return EncodeBase32 ( & ip [ 6 ] , 10 ) + " .onion " ;
if ( IsInternal ( ) )
return EncodeBase32 ( ip + sizeof ( g_internal_prefix ) , sizeof ( ip ) - sizeof ( g_internal_prefix ) ) + " .internal " ;
CService serv ( * this , 0 ) ;
CService serv ( * this , 0 ) ;
struct sockaddr_storage sockaddr ;
struct sockaddr_storage sockaddr ;
socklen_t socklen = sizeof ( sockaddr ) ;
socklen_t socklen = sizeof ( sockaddr ) ;
@ -305,9 +333,15 @@ std::vector<unsigned char> CNetAddr::GetGroup() const
nClass = 255 ;
nClass = 255 ;
nBits = 0 ;
nBits = 0 ;
}
}
// all internal-usage addresses get their own group
// all unroutable addresses belong to the same group
if ( IsInternal ( ) )
if ( ! IsRoutable ( ) )
{
nClass = NET_INTERNAL ;
nStartByte = sizeof ( g_internal_prefix ) ;
nBits = ( sizeof ( ip ) - sizeof ( g_internal_prefix ) ) * 8 ;
}
// all other unroutable addresses belong to the same group
else if ( ! IsRoutable ( ) )
{
{
nClass = NET_UNROUTABLE ;
nClass = NET_UNROUTABLE ;
nBits = 0 ;
nBits = 0 ;
@ -393,7 +427,7 @@ int CNetAddr::GetReachabilityFrom(const CNetAddr *paddrPartner) const
REACH_PRIVATE
REACH_PRIVATE
} ;
} ;
if ( ! IsRoutable ( ) )
if ( ! IsRoutable ( ) | | IsInternal ( ) )
return REACH_UNREACHABLE ;
return REACH_UNREACHABLE ;
int ourNet = GetExtNetwork ( this ) ;
int ourNet = GetExtNetwork ( this ) ;
@ -552,7 +586,7 @@ std::string CService::ToStringPort() const
std : : string CService : : ToStringIPPort ( ) const
std : : string CService : : ToStringIPPort ( ) const
{
{
if ( IsIPv4 ( ) | | IsTor ( ) ) {
if ( IsIPv4 ( ) | | IsTor ( ) | | IsInternal ( ) ) {
return ToStringIP ( ) + " : " + ToStringPort ( ) ;
return ToStringIP ( ) + " : " + ToStringPort ( ) ;
} else {
} else {
return " [ " + ToStringIP ( ) + " ]: " + ToStringPort ( ) ;
return " [ " + ToStringIP ( ) + " ]: " + ToStringPort ( ) ;