Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
radicle/node: Do not error on IPv6 without `[]`
Fintan Halpenny committed 1 month ago
commit d01ff2e79d7159fd96b5b580b59224562d66d840
parent c237a3f
3 files changed +47 -6
modified CHANGELOG.md
@@ -7,6 +7,16 @@ 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` vs. `[::1]:8776`,
+
  resulted in backward incompatibility. Configuration files containing addresses
+
  in the ambiguous format could not be parsed anymore. Partially undo this change
+
  to stay backward compatible, but log a warning in case ambiguous addresses are
+
  encountered.
+

+
## 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(addr)) => {
+
                    log::warn!("Address format will change in the future. '{s}' should be changed to '[{addr}]:{port}' to stay compatible. Refer to RFC 5926, Sec. 6 as well as RFC 3986, Sec. D.1. and RFC 2732, Sec. 2.");
+
                    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 = "[2001:db8::1]: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 = "2001:db8::1: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);
+
    }
}