@@ -14,6 +14,11 @@ static const unsigned char pchOnionCat[] = {0xFD,0x87,0xD8,0x7E,0xEB,0x43};
14
14
// 0xFD + sha256("bitcoin")[0:5]
15
15
static const unsigned char g_internal_prefix[] = { 0xFD , 0x6B , 0x88 , 0xC0 , 0x87 , 0x24 };
16
16
17
+ /* *
18
+ * Construct an unspecified IPv6 network address (::/128).
19
+ *
20
+ * @note This address is considered invalid by CNetAddr::IsValid()
21
+ */
17
22
CNetAddr::CNetAddr ()
18
23
{
19
24
memset (ip, 0 , sizeof (ip));
@@ -40,6 +45,20 @@ void CNetAddr::SetRaw(Network network, const uint8_t *ip_in)
40
45
}
41
46
}
42
47
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
+ */
43
62
bool CNetAddr::SetInternal (const std::string &name)
44
63
{
45
64
if (name.empty ()) {
@@ -52,6 +71,16 @@ bool CNetAddr::SetInternal(const std::string &name)
52
71
return true ;
53
72
}
54
73
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
+ */
55
84
bool CNetAddr::SetSpecial (const std::string &strName)
56
85
{
57
86
if (strName.size ()>6 && strName.substr (strName.size () - 6 , 6 ) == " .onion" ) {
@@ -175,6 +204,12 @@ bool CNetAddr::IsRFC4843() const
175
204
return (GetByte (15 ) == 0x20 && GetByte (14 ) == 0x01 && GetByte (13 ) == 0x00 && (GetByte (12 ) & 0xF0 ) == 0x10 );
176
205
}
177
206
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
+ */
178
213
bool CNetAddr::IsTor () const
179
214
{
180
215
return (memcmp (ip, pchOnionCat, sizeof (pchOnionCat)) == 0 );
@@ -194,6 +229,16 @@ bool CNetAddr::IsLocal() const
194
229
return false ;
195
230
}
196
231
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
+ */
197
242
bool CNetAddr::IsValid () const
198
243
{
199
244
// Cleanup 3-byte shifted addresses caused by garbage in size field
@@ -233,11 +278,25 @@ bool CNetAddr::IsValid() const
233
278
return true ;
234
279
}
235
280
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
+ */
236
290
bool CNetAddr::IsRoutable () const
237
291
{
238
292
return IsValid () && !(IsRFC1918 () || IsRFC2544 () || IsRFC3927 () || IsRFC4862 () || IsRFC6598 () || IsRFC5737 () || (IsRFC4193 () && !IsTor ()) || IsRFC4843 () || IsLocal () || IsInternal ());
239
293
}
240
294
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
+ */
241
300
bool CNetAddr::IsInternal () const
242
301
{
243
302
return memcmp (ip, g_internal_prefix, sizeof (g_internal_prefix)) == 0 ;
@@ -299,6 +358,16 @@ bool operator<(const CNetAddr& a, const CNetAddr& b)
299
358
return (memcmp (a.ip , b.ip , 16 ) < 0 );
300
359
}
301
360
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
+ */
302
371
bool CNetAddr::GetInAddr (struct in_addr * pipv4Addr) const
303
372
{
304
373
if (!IsIPv4 ())
@@ -307,6 +376,16 @@ bool CNetAddr::GetInAddr(struct in_addr* pipv4Addr) const
307
376
return true ;
308
377
}
309
378
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
+ */
310
389
bool CNetAddr::GetIn6Addr (struct in6_addr * pipv6Addr) const
311
390
{
312
391
if (!IsIPv6 ()) {
@@ -316,8 +395,16 @@ bool CNetAddr::GetIn6Addr(struct in6_addr* pipv6Addr) const
316
395
return true ;
317
396
}
318
397
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
+ */
321
408
std::vector<unsigned char > CNetAddr::GetGroup () const
322
409
{
323
410
std::vector<unsigned char > vchRet;
@@ -379,12 +466,15 @@ std::vector<unsigned char> CNetAddr::GetGroup() const
379
466
nBits = 32 ;
380
467
381
468
vchRet.push_back (nClass);
469
+
470
+ // push our ip onto vchRet byte by byte...
382
471
while (nBits >= 8 )
383
472
{
384
473
vchRet.push_back (GetByte (15 - nStartByte));
385
474
nStartByte++;
386
475
nBits -= 8 ;
387
476
}
477
+ // ...for the last byte, push nBits and for the rest of the byte push 1's
388
478
if (nBits > 0 )
389
479
vchRet.push_back (GetByte (15 - nStartByte) | ((1 << (8 - nBits)) - 1 ));
390
480
@@ -526,6 +616,18 @@ bool operator<(const CService& a, const CService& b)
526
616
return static_cast <CNetAddr>(a) < static_cast <CNetAddr>(b) || (static_cast <CNetAddr>(a) == static_cast <CNetAddr>(b) && a.port < b.port );
527
617
}
528
618
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
+ */
529
631
bool CService::GetSockAddr (struct sockaddr * paddr, socklen_t *addrlen) const
530
632
{
531
633
if (IsIPv4 ()) {
@@ -556,13 +658,16 @@ bool CService::GetSockAddr(struct sockaddr* paddr, socklen_t *addrlen) const
556
658
return false ;
557
659
}
558
660
661
+ /* *
662
+ * @returns An identifier unique to this service's address and port number.
663
+ */
559
664
std::vector<unsigned char > CService::GetKey () const
560
665
{
561
666
std::vector<unsigned char > vKey;
562
667
vKey.resize (18 );
563
668
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
566
671
return vKey;
567
672
}
568
673
@@ -641,6 +746,10 @@ CSubNet::CSubNet(const CNetAddr &addr):
641
746
network = addr;
642
747
}
643
748
749
+ /* *
750
+ * @returns True if this subnet is valid, the specified address is valid, and
751
+ * the specified address belongs in this subnet.
752
+ */
644
753
bool CSubNet::Match (const CNetAddr &addr) const
645
754
{
646
755
if (!valid || !addr.IsValid ())
@@ -651,6 +760,10 @@ bool CSubNet::Match(const CNetAddr &addr) const
651
760
return true ;
652
761
}
653
762
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
+ */
654
767
static inline int NetmaskBits (uint8_t x)
655
768
{
656
769
switch (x) {
0 commit comments