@@ -14,6 +14,11 @@ static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
1414// 0xFD + sha256("bitcoin")[0:5]
1515static const unsigned char g_internal_prefix[] = { 0xFD , 0x6B , 0x88 , 0xC0 , 0x87 , 0x24 };
1616
17+ /* *
18+ * Construct an unspecified IPv6 network address (::/128).
19+ *
20+ * @note This address is considered invalid by CNetAddr::IsValid()
21+ */
1722CNetAddr::CNetAddr ()
1823{
1924 memset (ip, 0 , sizeof (ip));
@@ -40,6 +45,20 @@ void CNetAddr::SetRaw(Network network, const uint8_t *ip_in)
4045 }
4146}
4247
48+ /* *
49+ * Try to make this a dummy address that maps the specified name into IPv6 like
50+ * so: (0xFD + %sha256("bitcoin")[0:5]) + %sha256(name)[0:10]. Such dummy
51+ * addresses have a prefix of fd6b:88c0:8724::/48 and are guaranteed to not be
52+ * publicly routable as it falls under RFC4193's fc00::/7 subnet allocated to
53+ * unique-local addresses.
54+ *
55+ * CAddrMan uses these fake addresses to keep track of which DNS seeds were
56+ * used.
57+ *
58+ * @returns Whether or not the operation was successful.
59+ *
60+ * @see CNetAddr::IsInternal(), CNetAddr::IsRFC4193()
61+ */
4362bool CNetAddr::SetInternal (const std::string &name)
4463{
4564 if (name.empty ()) {
@@ -52,6 +71,16 @@ bool CNetAddr::SetInternal(const std::string &name)
5271 return true ;
5372}
5473
74+ /* *
75+ * Try to make this a dummy address that maps the specified onion address into
76+ * IPv6 using OnionCat's range and encoding. Such dummy addresses have a prefix
77+ * of fd87:d87e:eb43::/48 and are guaranteed to not be publicly routable as they
78+ * fall under RFC4193's fc00::/7 subnet allocated to unique-local addresses.
79+ *
80+ * @returns Whether or not the operation was successful.
81+ *
82+ * @see CNetAddr::IsTor(), CNetAddr::IsRFC4193()
83+ */
5584bool CNetAddr::SetSpecial (const std::string &strName)
5685{
5786 if (strName.size ()>6 && strName.substr (strName.size () - 6 , 6 ) == " .onion" ) {
@@ -175,6 +204,12 @@ bool CNetAddr::IsRFC4843() const
175204 return (GetByte (15 ) == 0x20 && GetByte (14 ) == 0x01 && GetByte (13 ) == 0x00 && (GetByte (12 ) & 0xF0 ) == 0x10 );
176205}
177206
207+ /* *
208+ * @returns Whether or not this is a dummy address that maps an onion address
209+ * into IPv6.
210+ *
211+ * @see CNetAddr::SetSpecial(const std::string &)
212+ */
178213bool CNetAddr::IsTor () const
179214{
180215 return (memcmp (ip, pchOnionCat, sizeof (pchOnionCat)) == 0 );
@@ -194,6 +229,16 @@ bool CNetAddr::IsLocal() const
194229 return false ;
195230}
196231
232+ /* *
233+ * @returns Whether or not this network address is a valid address that @a could
234+ * be used to refer to an actual host.
235+ *
236+ * @note A valid address may or may not be publicly routable on the global
237+ * internet. As in, the set of valid addreses is a superset of the set of
238+ * publicly routable addresses.
239+ *
240+ * @see CNetAddr::IsRoutable()
241+ */
197242bool CNetAddr::IsValid () const
198243{
199244 // Cleanup 3-byte shifted addresses caused by garbage in size field
@@ -233,11 +278,25 @@ bool CNetAddr::IsValid() const
233278 return true ;
234279}
235280
281+ /* *
282+ * @returns Whether or not this network address is publicly routable on the
283+ * global internet.
284+ *
285+ * @note A routable address is always valid. As in, the set of routable addreses
286+ * is a subset of the set of valid addresses.
287+ *
288+ * @see CNetAddr::IsValid()
289+ */
236290bool CNetAddr::IsRoutable () const
237291{
238292 return IsValid () && !(IsRFC1918 () || IsRFC2544 () || IsRFC3927 () || IsRFC4862 () || IsRFC6598 () || IsRFC5737 () || (IsRFC4193 () && !IsTor ()) || IsRFC4843 () || IsLocal () || IsInternal ());
239293}
240294
295+ /* *
296+ * @returns Whether or not this is a dummy address that maps a name into IPv6.
297+ *
298+ * @see CNetAddr::SetInternal(const std::string &)
299+ */
241300bool CNetAddr::IsInternal () const
242301{
243302 return memcmp (ip, g_internal_prefix, sizeof (g_internal_prefix)) == 0 ;
@@ -299,6 +358,16 @@ bool operator<(const CNetAddr& a, const CNetAddr& b)
299358 return (memcmp (a.ip , b.ip , 16 ) < 0 );
300359}
301360
361+ /* *
362+ * Try to get our IPv4 address.
363+ *
364+ * @param[out] pipv4Addr The in_addr struct to which to copy.
365+ *
366+ * @returns Whether or not the operation was successful, in particular, whether
367+ * or not our address was an IPv4 address.
368+ *
369+ * @see CNetAddr::IsIPv4()
370+ */
302371bool CNetAddr::GetInAddr (struct in_addr * pipv4Addr) const
303372{
304373 if (!IsIPv4 ())
@@ -307,6 +376,16 @@ bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
307376 return true ;
308377}
309378
379+ /* *
380+ * Try to get our IPv6 address.
381+ *
382+ * @param[out] pipv6Addr The in6_addr struct to which to copy.
383+ *
384+ * @returns Whether or not the operation was successful, in particular, whether
385+ * or not our address was an IPv6 address.
386+ *
387+ * @see CNetAddr::IsIPv6()
388+ */
310389bool CNetAddr::GetIn6Addr (struct in6_addr * pipv6Addr) const
311390{
312391 if (!IsIPv6 ()) {
@@ -316,8 +395,16 @@ bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
316395 return true ;
317396}
318397
319- // get canonical identifier of an address' group
320- // no two connections will be attempted to addresses with the same group
398+ /* *
399+ * Get the canonical identifier of our network group
400+ *
401+ * The groups are assigned in a way where it should be costly for an attacker to
402+ * obtain addresses with many different group identifiers, even if it is cheap
403+ * to obtain addresses with the same identifier.
404+ *
405+ * @note No two connections will be attempted to addresses with the same network
406+ * group.
407+ */
321408std::vector<unsigned char > CNetAddr::GetGroup () const
322409{
323410 std::vector<unsigned char > vchRet;
@@ -379,12 +466,15 @@ std::vector<unsigned char> CNetAddr::GetGroup() const
379466 nBits = 32 ;
380467
381468 vchRet.push_back (nClass);
469+
470+ // push our ip onto vchRet byte by byte...
382471 while (nBits >= 8 )
383472 {
384473 vchRet.push_back (GetByte (15 - nStartByte));
385474 nStartByte++;
386475 nBits -= 8 ;
387476 }
477+ // ...for the last byte, push nBits and for the rest of the byte push 1's
388478 if (nBits > 0 )
389479 vchRet.push_back (GetByte (15 - nStartByte) | ((1 << (8 - nBits)) - 1 ));
390480
@@ -526,6 +616,18 @@ bool operator<(const CService& a, const CService& b)
526616 return static_cast <CNetAddr>(a) < static_cast <CNetAddr>(b) || (static_cast <CNetAddr>(a) == static_cast <CNetAddr>(b) && a.port < b.port );
527617}
528618
619+ /* *
620+ * Obtain the IPv4/6 socket address this represents.
621+ *
622+ * @param[out] paddr The obtained socket address.
623+ * @param[in,out] addrlen The size, in bytes, of the address structure pointed
624+ * to by paddr. The value that's pointed to by this
625+ * parameter might change after calling this function if
626+ * the size of the corresponding address structure
627+ * changed.
628+ *
629+ * @returns Whether or not the operation was successful.
630+ */
529631bool CService::GetSockAddr (struct sockaddr * paddr, socklen_t *addrlen) const
530632{
531633 if (IsIPv4 ()) {
@@ -556,13 +658,16 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
556658 return false ;
557659}
558660
661+ /* *
662+ * @returns An identifier unique to this service's address and port number.
663+ */
559664std::vector<unsigned char > CService::GetKey () const
560665{
561666 std::vector<unsigned char > vKey;
562667 vKey.resize (18 );
563668 memcpy (vKey.data (), ip, 16 );
564- vKey[16 ] = port / 0x100 ;
565- vKey[17 ] = port & 0x0FF ;
669+ vKey[16 ] = port / 0x100 ; // most significant byte of our port
670+ vKey[17 ] = port & 0x0FF ; // least significant byte of our port
566671 return vKey;
567672}
568673
@@ -641,6 +746,10 @@ CSubNet::CSubNet(const CNetAddr &addr):
641746 network = addr;
642747}
643748
749+ /* *
750+ * @returns True if this subnet is valid, the specified address is valid, and
751+ * the specified address belongs in this subnet.
752+ */
644753bool CSubNet::Match (const CNetAddr &addr) const
645754{
646755 if (!valid || !addr.IsValid ())
@@ -651,6 +760,10 @@ bool CSubNet::Match(const CNetAddr &addr) const
651760 return true ;
652761}
653762
763+ /* *
764+ * @returns The number of 1-bits in the prefix of the specified subnet mask. If
765+ * the specified subnet mask is not a valid one, -1.
766+ */
654767static inline int NetmaskBits (uint8_t x)
655768{
656769 switch (x) {
0 commit comments