mirror of
https://github.com/htrefil/rkvm.git
synced 2024-12-27 09:58:13 +01:00
Fix IPv6 socket address parsing
This commit is contained in:
parent
29e357da5e
commit
e401fee01c
1 changed files with 72 additions and 1 deletions
|
@ -1,7 +1,9 @@
|
||||||
use serde::de::{self, Visitor};
|
use serde::de::{self, Visitor};
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
use std::fmt::{self, Formatter};
|
use std::fmt::{self, Formatter};
|
||||||
|
use std::net::SocketAddr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::str::FromStr;
|
||||||
use tokio_rustls::rustls::ServerName;
|
use tokio_rustls::rustls::ServerName;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -39,8 +41,16 @@ impl<'de> Visitor<'de> for ServerVisitor {
|
||||||
where
|
where
|
||||||
E: de::Error,
|
E: de::Error,
|
||||||
{
|
{
|
||||||
|
// Parsing IPv6 socket addresses can get quite hairy, so let the SocketAddr parser do it for us.
|
||||||
|
if let Ok(socket_addr) = SocketAddr::from_str(data) {
|
||||||
|
return Ok(Server {
|
||||||
|
hostname: ServerName::IpAddress(socket_addr.ip()),
|
||||||
|
port: socket_addr.port(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let (hostname, port) = data
|
let (hostname, port) = data
|
||||||
.rsplit_once(':')
|
.split_once(':')
|
||||||
.ok_or_else(|| E::custom("No port provided"))?;
|
.ok_or_else(|| E::custom("No port provided"))?;
|
||||||
|
|
||||||
let hostname = hostname.try_into().map_err(E::custom)?;
|
let hostname = hostname.try_into().map_err(E::custom)?;
|
||||||
|
@ -49,3 +59,64 @@ impl<'de> Visitor<'de> for ServerVisitor {
|
||||||
Ok(Server { hostname, port })
|
Ok(Server { hostname, port })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::net::Ipv6Addr;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Data {
|
||||||
|
server: Server,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn server_dns() {
|
||||||
|
let parsed = toml::from_str::<Data>(r#"server = "example.com:8523""#)
|
||||||
|
.unwrap()
|
||||||
|
.server;
|
||||||
|
let expected = Server {
|
||||||
|
hostname: "example.com".try_into().unwrap(),
|
||||||
|
port: 8523,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(parsed.hostname, expected.hostname);
|
||||||
|
assert_eq!(parsed.port, expected.port);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn server_ipv4() {
|
||||||
|
let parsed = toml::from_str::<Data>(r#"server = "127.0.0.1:8523""#)
|
||||||
|
.unwrap()
|
||||||
|
.server;
|
||||||
|
let expected = Server {
|
||||||
|
hostname: "127.0.0.1".try_into().unwrap(),
|
||||||
|
port: 8523,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(parsed.hostname, expected.hostname);
|
||||||
|
assert_eq!(parsed.port, expected.port);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn server_ipv6() {
|
||||||
|
let parsed = toml::from_str::<Data>(r#"server = "[::1]:8523""#)
|
||||||
|
.unwrap()
|
||||||
|
.server;
|
||||||
|
let expected = Server {
|
||||||
|
hostname: "::1".try_into().unwrap(),
|
||||||
|
port: 8523,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(parsed.hostname, expected.hostname);
|
||||||
|
assert_eq!(parsed.port, expected.port);
|
||||||
|
|
||||||
|
let parsed_ip = match parsed.hostname {
|
||||||
|
ServerName::IpAddress(parsed_ip) => parsed_ip,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(parsed_ip, Ipv6Addr::from_str("::1").unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue