radicle/node: Do not error on IPv6 without `[]`
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 `[]`.
This commit is contained in:
parent
c237a3fe47
commit
d01ff2e79d
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [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
|
## Release Highlights
|
||||||
|
|
||||||
- The "Signed References" feature was reimplemented. The commits in
|
- The "Signed References" feature was reimplemented. The commits in
|
||||||
|
|
|
||||||
|
|
@ -548,10 +548,13 @@ impl FromStr for Address {
|
||||||
{
|
{
|
||||||
HostName::Ip(host.parse::<Ipv6Addr>()?.into())
|
HostName::Ip(host.parse::<Ipv6Addr>()?.into())
|
||||||
} else {
|
} else {
|
||||||
// Require IPv6 addresses to always be enclosed in `[` and `]`.
|
// Warn on IPv6 addresses that are not enclosed in `[` and `]`.
|
||||||
host.parse().and_then(|host| match host {
|
host.parse().map(|host| match host {
|
||||||
HostName::Ip(IpAddr::V6(_)) => Err(AddrParseError::UnknownAddressFormat),
|
HostName::Ip(IpAddr::V6(addr)) => {
|
||||||
host => Ok(host),
|
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("[::1]:8776").is_ok());
|
||||||
assert!(Address::from_str("[::ffff:127.0.0.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("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());
|
||||||
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("127.0.0.1:xyz").is_err());
|
||||||
assert!(Address::from_str("[invalid]:8776").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("[127.0.0.1]:8776").is_err());
|
||||||
assert!(Address::from_str("::1:8776").is_err());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -712,7 +712,7 @@ wrapper!(
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{DefaultSeedingPolicy, Scope};
|
use super::{DefaultSeedingPolicy, Scope};
|
||||||
use crate::node::policy;
|
use crate::node::{policy, Alias};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -833,4 +833,32 @@ mod test {
|
||||||
.unwrap()
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue