@@ -1267,79 +1267,31 @@ impl Ipv6Addr {
1267
1267
( self . segments ( ) [ 0 ] & 0xfe00 ) == 0xfc00
1268
1268
}
1269
1269
1270
- /// Returns [`true`] if the address is a unicast link-local address (`fe80::/64`).
1270
+ /// Returns `true` if the address is a unicast address with link-local scope,
1271
+ /// as defined in [RFC 4291].
1271
1272
///
1272
- /// A common misconception is to think that "unicast link-local addresses start with
1273
- /// `fe80::`", but [IETF RFC 4291] actually defines a stricter format for these addresses:
1273
+ /// A unicast address has link-local scope if it has the prefix `fe80::/10`, as per [RFC 4291 section 2.4].
1274
+ /// Note that this encompasses more addresses than those defined in [RFC 4291 section 2.5.6],
1275
+ /// which describes "Link-Local IPv6 Unicast Addresses" as having the following stricter format:
1274
1276
///
1275
- /// ```no_rust
1276
- /// | 10 |
1277
- /// | bits | 54 bits | 64 bits |
1277
+ /// ```text
1278
+ /// | 10 bits | 54 bits | 64 bits |
1278
1279
/// +----------+-------------------------+----------------------------+
1279
1280
/// |1111111010| 0 | interface ID |
1280
1281
/// +----------+-------------------------+----------------------------+
1281
1282
/// ```
1283
+ /// So while currently the only addresses with link-local scope an application will encounter are all in `fe80::/64`,
1284
+ /// this might change in the future with the publication of new standards. More addresses in `fe80::/10` could be allocated,
1285
+ /// and those addresses will have link-local scope.
1282
1286
///
1283
- /// This method validates the format defined in the RFC and won't recognize addresses
1284
- /// like `fe80:0:0:1::` or `fe81::` as unicast link-local addresses.
1285
- /// If you need a less strict validation, use [`Ipv6Addr::is_unicast_link_local()`] instead.
1286
- ///
1287
- /// # Examples
1288
- ///
1289
- /// ```
1290
- /// #![feature(ip)]
1291
- ///
1292
- /// use std::net::Ipv6Addr;
1293
- ///
1294
- /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);
1295
- /// assert!(ip.is_unicast_link_local_strict());
1296
- ///
1297
- /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);
1298
- /// assert!(ip.is_unicast_link_local_strict());
1299
- ///
1300
- /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);
1301
- /// assert!(!ip.is_unicast_link_local_strict());
1302
- /// assert!(ip.is_unicast_link_local());
1303
- ///
1304
- /// let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);
1305
- /// assert!(!ip.is_unicast_link_local_strict());
1306
- /// assert!(ip.is_unicast_link_local());
1307
- /// ```
1308
- ///
1309
- /// # See also
1310
- ///
1311
- /// - [IETF RFC 4291 section 2.5.6]
1312
- /// - [RFC 4291 errata 4406] (which has been rejected but provides useful
1313
- /// insight)
1314
- /// - [`Ipv6Addr::is_unicast_link_local()`]
1315
- ///
1316
- /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
1317
- /// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6
1318
- /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
1319
- #[ rustc_const_unstable( feature = "const_ipv6" , issue = "76205" ) ]
1320
- #[ unstable( feature = "ip" , issue = "27709" ) ]
1321
- #[ inline]
1322
- pub const fn is_unicast_link_local_strict ( & self ) -> bool {
1323
- matches ! ( self . segments( ) , [ 0xfe80 , 0 , 0 , 0 , ..] )
1324
- }
1325
-
1326
- /// Returns [`true`] if the address is a unicast link-local address (`fe80::/10`).
1287
+ /// Also note that while [RFC 4291 section 2.5.3] mentions about the [loopback address] (`::1`) that "it is treated as having Link-Local scope",
1288
+ /// this does not mean that the loopback address actually has link-local scope and this method will return `false` on it.
1327
1289
///
1328
- /// This method returns [`true`] for addresses in the range reserved by [RFC 4291 section 2.4],
1329
- /// i.e. addresses with the following format:
1330
- ///
1331
- /// ```no_rust
1332
- /// | 10 |
1333
- /// | bits | 54 bits | 64 bits |
1334
- /// +----------+-------------------------+----------------------------+
1335
- /// |1111111010| arbitratry value | interface ID |
1336
- /// +----------+-------------------------+----------------------------+
1337
- /// ```
1338
- ///
1339
- /// As a result, this method considers addresses such as `fe80:0:0:1::` or `fe81::` to be
1340
- /// unicast link-local addresses, whereas [`Ipv6Addr::is_unicast_link_local_strict()`] does not.
1341
- /// If you need a strict validation fully compliant with the RFC, use
1342
- /// [`Ipv6Addr::is_unicast_link_local_strict()`] instead.
1290
+ /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
1291
+ /// [RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4
1292
+ /// [RFC 4291 section 2.5.3]: https://tools.ietf.org/html/rfc4291#section-2.5.3
1293
+ /// [RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6
1294
+ /// [loopback address]: Ipv6Addr::LOCALHOST
1343
1295
///
1344
1296
/// # Examples
1345
1297
///
@@ -1348,29 +1300,17 @@ impl Ipv6Addr {
1348
1300
///
1349
1301
/// use std::net::Ipv6Addr;
1350
1302
///
1351
- /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);
1352
- /// assert!(ip .is_unicast_link_local());
1303
+ /// // The loopback address (`::1`) does not actually have link-local scope.
1304
+ /// assert_eq!(Ipv6Addr::LOCALHOST .is_unicast_link_local(), false );
1353
1305
///
1354
- /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);
1355
- /// assert!(ip.is_unicast_link_local());
1306
+ /// // Only addresses in `fe80::/10` have link-local scope.
1307
+ /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), false);
1308
+ /// assert_eq!(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true);
1356
1309
///
1357
- /// let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);
1358
- /// assert!(ip.is_unicast_link_local());
1359
- /// assert!(!ip.is_unicast_link_local_strict());
1360
- ///
1361
- /// let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);
1362
- /// assert!(ip.is_unicast_link_local());
1363
- /// assert!(!ip.is_unicast_link_local_strict());
1310
+ /// // Addresses outside the stricter `fe80::/64` also have link-local scope.
1311
+ /// assert_eq!(Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0).is_unicast_link_local(), true);
1312
+ /// assert_eq!(Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true);
1364
1313
/// ```
1365
- ///
1366
- /// # See also
1367
- ///
1368
- /// - [IETF RFC 4291 section 2.4]
1369
- /// - [RFC 4291 errata 4406] (which has been rejected but provides useful
1370
- /// insight)
1371
- ///
1372
- /// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4
1373
- /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
1374
1314
#[ rustc_const_unstable( feature = "const_ipv6" , issue = "76205" ) ]
1375
1315
#[ unstable( feature = "ip" , issue = "27709" ) ]
1376
1316
#[ inline]
0 commit comments