Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
radicle/node: Do not error on IPv6 without `[]`
Merged fintohaps opened 1 month ago

IPv6 addresses are already persisted in config.json files. The parsing of these old addresses, e.g. FE80::0202:B3FF:FE1E:8329:5976 should remain valid. Emit a warning when they are found. The output of the address will still enclose the host in [].

3 files changed +46 -6 c237a3fe d01ff2e7
modified CHANGELOG.md
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

+
## Fixed Bugs
+

+
- The fix to ambiguous IPv6 addresses, e.g. `::1:8776` and `[::1]:8776`,
+
  resulted in backward incompatibility for existing addresses that were
+
  persisted, for example in `config.json`. Keep the compatibility and emit a log
+
  warning for when these cases are found.
+

+
## 1.7.0
+

## Release Highlights

- The "Signed References" feature was reimplemented. The commits in
modified crates/radicle/src/node.rs
@@ -548,10 +548,13 @@ impl FromStr for Address {
        {
            HostName::Ip(host.parse::<Ipv6Addr>()?.into())
        } else {
-
            // Require IPv6 addresses to always be enclosed in `[` and `]`.
-
            host.parse().and_then(|host| match host {
-
                HostName::Ip(IpAddr::V6(_)) => Err(AddrParseError::UnknownAddressFormat),
-
                host => Ok(host),
+
            // Warn on IPv6 addresses that are not enclosed in `[` and `]`.
+
            host.parse().map(|host| match host {
+
                HostName::Ip(IpAddr::V6(_)) => {
+
                    log::warn!("IPv6 address host {host} is not enclosed in `[]`. These addresses are deprecated, and must be updated");
+
                    host
+
                },
+
                host => host,
            })?
        };

@@ -1525,6 +1528,7 @@ mod test {
        assert!(Address::from_str("[::1]:8776").is_ok());
        assert!(Address::from_str("[::ffff:127.0.0.1]:8776").is_ok());
        assert!(Address::from_str("localhost:8776").is_ok());
+
        assert!(Address::from_str("::1:8776").is_ok()); // Backwards-compatibility

        assert!(Address::from_str("").is_err());
        assert!(Address::from_str(":").is_err());
@@ -1532,7 +1536,6 @@ mod test {
        assert!(Address::from_str("127.0.0.1:xyz").is_err());
        assert!(Address::from_str("[invalid]:8776").is_err());
        assert!(Address::from_str("[127.0.0.1]:8776").is_err());
-
        assert!(Address::from_str("::1:8776").is_err());
    }

    #[test]
modified crates/radicle/src/node/config.rs
@@ -712,7 +712,7 @@ wrapper!(
#[allow(clippy::unwrap_used)]
mod test {
    use super::{DefaultSeedingPolicy, Scope};
-
    use crate::node::policy;
+
    use crate::node::{policy, Alias};
    use serde_json::json;

    #[test]
@@ -833,4 +833,32 @@ mod test {
            .unwrap()
        );
    }
+

+
    #[test]
+
    fn regression_ipv6_address_brackets() {
+
        let address = "[FE80::0202:B3FF:FE1E:8329]:5976".to_string();
+
        let config = json!({
+
            "alias": "radicle",
+
            "externalAddresses": [address],
+
        });
+
        let got: super::Config = serde_json::from_value(config).unwrap();
+
        let mut expected = super::Config::new(Alias::new("radicle"));
+
        expected.external_addresses = vec![address.parse().unwrap()];
+
        assert_eq!(got.alias, expected.alias);
+
        assert_eq!(got.external_addresses, expected.external_addresses);
+
    }
+

+
    #[test]
+
    fn regression_ipv6_address_no_brackets() {
+
        let address = "FE80::0202:B3FF:FE1E:8329:5976".to_string();
+
        let config = json!({
+
            "alias": "radicle",
+
            "externalAddresses": [address],
+
        });
+
        let got: super::Config = serde_json::from_value(config).unwrap();
+
        let mut expected = super::Config::new(Alias::new("radicle"));
+
        expected.external_addresses = vec![address.parse().unwrap()];
+
        assert_eq!(got.alias, expected.alias);
+
        assert_eq!(got.external_addresses, expected.external_addresses);
+
    }
}