Skip to content

Commit e7fc4c8

Browse files
committed
Change Ipv6Addr::is_unicast_global to check if an address has unicast global scope
1 parent d192c80 commit e7fc4c8

File tree

2 files changed

+56
-22
lines changed

2 files changed

+56
-22
lines changed

library/std/src/net/ip.rs

+49-19
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,9 @@ impl Ipv6Addr {
12391239
pub const fn is_global(&self) -> bool {
12401240
match self.multicast_scope() {
12411241
Some(Ipv6MulticastScope::Global) => true,
1242-
None => self.is_unicast_global(),
1242+
None => {
1243+
self.is_unicast_global() && !(self.is_unique_local() || self.is_documentation())
1244+
}
12431245
_ => false,
12441246
}
12451247
}
@@ -1370,25 +1372,38 @@ impl Ipv6Addr {
13701372
(self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
13711373
}
13721374

1373-
/// Returns [`true`] if the address is a globally routable unicast address.
1375+
/// Returns `true` if the address is a unicast address with global scope,
1376+
/// as defined in [RFC 4291].
13741377
///
1375-
/// The following return false:
1378+
/// Any unicast address has global scope if it is not:
1379+
/// - the [unspecified address] (`::`)
1380+
/// - the [loopback address] (`::1`)
1381+
/// - a [link-local address] (`fe80::/10`)
13761382
///
1377-
/// - the loopback address
1378-
/// - the link-local addresses
1379-
/// - unique local addresses
1380-
/// - the unspecified address
1381-
/// - the address range reserved for documentation
1383+
/// Note that an address that has global scope may still not be globally reachable.
1384+
/// If you want to check if an address appears to be globally reachable, use [`is_global`](Ipv6Addr::is_global).
13821385
///
1383-
/// This method returns [`true`] for site-local addresses as per [RFC 4291 section 2.5.7]
1386+
/// # Deprecation of Site-Local Addresses
13841387
///
1385-
/// ```no_rust
1386-
/// The special behavior of [the site-local unicast] prefix defined in [RFC3513] must no longer
1387-
/// be supported in new implementations (i.e., new implementations must treat this prefix as
1388-
/// Global Unicast).
1389-
/// ```
1388+
/// Site-local addresses have been officially deprecated, see [RFC 4291 section 2.5.7].
1389+
/// It is stated that the special behaviour of site-local unicast addresses must no longer be
1390+
/// supported, and that implementations must treat these addresses as having global scope.
1391+
///
1392+
/// This method therefore returns [`true`] for any address that had the deprecated site-local scope (`fec0::/10`).
13901393
///
1391-
/// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7
1394+
/// # Stability Guarantees
1395+
///
1396+
/// Note that this method's behavior may be subject to changes in the future,
1397+
/// as new IETF RFCs are published. Specifically [RFC 4291 section 2.4] mentions:
1398+
///
1399+
/// > "Future specifications may redefine one or more sub-ranges of the Global Unicast space for other purposes"
1400+
///
1401+
/// [RFC 4291]: https://tools.ietf.org/html/rfc4291
1402+
/// [RFC 4291 section 2.4]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
1403+
/// [RFC 4291 section 2.5.7]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.7
1404+
/// [unspecified address]: Ipv6Addr::is_unspecified
1405+
/// [loopback address]: Ipv6Addr::is_loopback
1406+
/// [link-local address]: Ipv6Addr::is_unicast_link_local
13921407
///
13931408
/// # Examples
13941409
///
@@ -1397,19 +1412,34 @@ impl Ipv6Addr {
13971412
///
13981413
/// use std::net::Ipv6Addr;
13991414
///
1400-
/// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
1415+
/// // The unspecified address (`::`) does not have unicast global scope
1416+
/// assert_eq!(Ipv6Addr::UNSPECIFIED.is_unicast_global(), false);
1417+
///
1418+
/// // The loopback address (`::1`) does not have unicast global scope.
1419+
/// assert_eq!(Ipv6Addr::LOCALHOST.is_unicast_global(), false);
1420+
///
1421+
/// // A unicast address with link-local scope (`fe80::/10`) does not have global scope.
1422+
/// assert_eq!(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
1423+
///
1424+
/// // A unicast address that had the deprecated site-local scope (`fec0::/10`) now has global scope.
1425+
/// assert_eq!(Ipv6Addr::new(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_global(), true);
1426+
///
1427+
/// // Any multicast address (`ff00::/8`) does not have unicast global scope;
1428+
/// // there is a difference between unicast global scope and multicast global scope.
1429+
/// assert_eq!(Ipv6Addr::new(0xff03, 0, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
1430+
/// assert_eq!(Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 0).is_unicast_global(), false);
1431+
///
1432+
/// // Any other address is defined as having unicast global scope.
14011433
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true);
14021434
/// ```
14031435
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
14041436
#[unstable(feature = "ip", issue = "27709")]
14051437
#[inline]
14061438
pub const fn is_unicast_global(&self) -> bool {
14071439
self.is_unicast()
1440+
&& !self.is_unspecified()
14081441
&& !self.is_loopback()
14091442
&& !self.is_unicast_link_local()
1410-
&& !self.is_unique_local()
1411-
&& !self.is_unspecified()
1412-
&& !self.is_documentation()
14131443
}
14141444

14151445
/// Returns the address's multicast scope if the address is multicast.

library/std/src/net/ip/tests.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -593,12 +593,16 @@ fn ipv6_properties() {
593593

594594
check!("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global);
595595

596-
check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local);
596+
check!(
597+
"fc00::",
598+
&[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
599+
unique_local | unicast_global
600+
);
597601

598602
check!(
599603
"fdff:ffff::",
600604
&[0xfd, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
601-
unique_local
605+
unique_local | unicast_global
602606
);
603607

604608
check!(
@@ -676,7 +680,7 @@ fn ipv6_properties() {
676680
check!(
677681
"2001:db8:85a3::8a2e:370:7334",
678682
&[0x20, 1, 0xd, 0xb8, 0x85, 0xa3, 0, 0, 0, 0, 0x8a, 0x2e, 3, 0x70, 0x73, 0x34],
679-
documentation
683+
documentation | unicast_global
680684
);
681685

682686
check!(

0 commit comments

Comments
 (0)