diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2017-11-14 19:04:20 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2017-11-14 19:04:20 +0100 |
| commit | 1fde81d2eb8487f338d8a394d844d337cf393381 (patch) | |
| tree | 6dbe0bb5ce47d7a33df9860f7c696c749c5786be | |
| parent | a417d14469f104b1eac001318e900559299a8f1a (diff) | |
| download | mullvadvpn-1fde81d2eb8487f338d8a394d844d337cf393381.tar.xz mullvadvpn-1fde81d2eb8487f338d8a394d844d337cf393381.zip | |
Add RelayList and adapt surrounding types
| -rw-r--r-- | mullvad-types/src/custom_tunnel.rs | 46 | ||||
| -rw-r--r-- | mullvad-types/src/lib.rs | 7 | ||||
| -rw-r--r-- | mullvad-types/src/location.rs | 5 | ||||
| -rw-r--r-- | mullvad-types/src/relay_endpoint.rs | 72 | ||||
| -rw-r--r-- | mullvad-types/src/relay_list.rs | 44 |
5 files changed, 99 insertions, 75 deletions
diff --git a/mullvad-types/src/custom_tunnel.rs b/mullvad-types/src/custom_tunnel.rs new file mode 100644 index 0000000000..788587568b --- /dev/null +++ b/mullvad-types/src/custom_tunnel.rs @@ -0,0 +1,46 @@ +use std::net::{IpAddr, ToSocketAddrs}; + +use talpid_types::net::{TunnelEndpoint, TunnelParameters}; + +error_chain!{ + errors { + InvalidHost(host: String) { + display("Invalid host: {}", host) + } + } +} + + +#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] +pub struct CustomTunnelEndpoint { + pub host: String, + pub tunnel: TunnelParameters, +} + +impl CustomTunnelEndpoint { + pub fn to_tunnel_endpoint(&self) -> Result<TunnelEndpoint> { + Ok(TunnelEndpoint { + address: resolve_to_ip(&self.host)?, + tunnel: self.tunnel, + }) + } +} + +/// Does a DNS lookup if the host isn't an IP. +/// Returns the first IPv4 address if one exists, otherwise the first IPv6 address. +/// Rust only provides means to resolve a socket addr, not just a host, for some reason. So +/// because of this we do the resolving with port zero and then pick out the IPs. +fn resolve_to_ip(host: &str) -> Result<IpAddr> { + let (mut ipv4, mut ipv6): (Vec<IpAddr>, Vec<IpAddr>) = (host, 0) + .to_socket_addrs() + .chain_err(|| ErrorKind::InvalidHost(host.to_owned()))? + .map(|addr| addr.ip()) + .partition(|addr| addr.is_ipv4()); + + ipv4.pop() + .or_else(|| { + info!("No IPv4 for host {}", host); + ipv6.pop() + }) + .ok_or(ErrorKind::InvalidHost(host.to_owned()).into()) +} diff --git a/mullvad-types/src/lib.rs b/mullvad-types/src/lib.rs index 82022bbf9a..cd3a3bcb97 100644 --- a/mullvad-types/src/lib.rs +++ b/mullvad-types/src/lib.rs @@ -21,6 +21,9 @@ extern crate error_chain; pub mod account; pub mod location; -pub mod states; -pub mod relay_endpoint; pub mod relay_constraints; +pub mod relay_list; +pub mod states; + +mod custom_tunnel; +pub use custom_tunnel::*; diff --git a/mullvad-types/src/location.rs b/mullvad-types/src/location.rs index 72146998b3..6789e77ead 100644 --- a/mullvad-types/src/location.rs +++ b/mullvad-types/src/location.rs @@ -1,8 +1,11 @@ pub type CountryCode = String; +pub type CityCode = String; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Location { - pub latlong: [f64; 2], pub country: String, + pub country_code: CountryCode, pub city: String, + pub city_code: CityCode, + pub position: [f64; 2], } diff --git a/mullvad-types/src/relay_endpoint.rs b/mullvad-types/src/relay_endpoint.rs deleted file mode 100644 index 8a53d16393..0000000000 --- a/mullvad-types/src/relay_endpoint.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::fmt; -use std::net::{SocketAddr, ToSocketAddrs}; -use talpid_types; -use talpid_types::net::TransportProtocol; - -error_chain!{ - errors { - InvalidHost(host: String) { - display("Invalid host: {}", host) - } - } -} - -#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] -pub struct RelayEndpoint { - pub host: String, - pub port: u16, - pub protocol: TransportProtocol, -} - -impl RelayEndpoint { - pub fn to_endpoint(&self) -> Result<talpid_types::net::Endpoint> { - let socket_addrs = to_socket_addrs(self.host.as_str(), self.port)?; - ensure!( - socket_addrs.len() > 0, - ErrorKind::InvalidHost(self.host.clone()) - ); - - let socket_addr = choose_ip(&socket_addrs).unwrap(); - - if socket_addrs.len() > 1 { - info!( - "{} resolved to more than one IP, ignoring all but {}", - self.host, - socket_addr.ip() - ) - } - - Ok(talpid_types::net::Endpoint::new( - socket_addr.ip(), - socket_addr.port(), - self.protocol, - )) - } -} - -/// Does a DNS lookup if the host isn't an IP. -fn to_socket_addrs(host: &str, port: u16) -> Result<Vec<SocketAddr>> { - Ok( - (host, port) - .to_socket_addrs() - .chain_err(|| ErrorKind::InvalidHost(host.to_owned()))? - .collect(), - ) -} - -fn choose_ip(socket_addrs: &Vec<SocketAddr>) -> Option<SocketAddr> { - // We prefer IPv4 addresses, so we split the addresses into - // IPv4 ad IPv6s and take form the IPv4 pile if any. - - let (mut ipv4, mut ipv6): (Vec<SocketAddr>, Vec<SocketAddr>) = - socket_addrs.into_iter().partition(|addr| addr.is_ipv4()); - - // If there are many IP:s, we simply ignore the rest - ipv4.pop().or(ipv6.pop()) -} - -impl fmt::Display for RelayEndpoint { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}:{} - {}", self.host, self.port, self.protocol) - } -} diff --git a/mullvad-types/src/relay_list.rs b/mullvad-types/src/relay_list.rs new file mode 100644 index 0000000000..829665efa3 --- /dev/null +++ b/mullvad-types/src/relay_list.rs @@ -0,0 +1,44 @@ +use location::{CityCode, CountryCode, Location}; + +use std::net::Ipv4Addr; + +use talpid_types::net::{OpenVpnParameters, WireguardParameters}; + + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct RelayList { + pub countries: Vec<RelayListCountry>, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct RelayListCountry { + pub name: String, + pub code: CountryCode, + pub cities: Vec<RelayListCity>, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct RelayListCity { + pub name: String, + pub code: CityCode, + pub position: [f64; 2], + #[serde(skip_serializing_if = "Vec::is_empty", default)] pub relays: Vec<Relay>, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Relay { + pub hostname: String, + pub ipv4_addr_in: Ipv4Addr, + pub ipv4_addr_exit: Ipv4Addr, + pub include_in_country: bool, + pub weight: u64, + pub tunnels: RelayTunnels, + #[serde(skip)] pub location: Option<Location>, +} + +#[derive(Debug, Default, Clone, Deserialize, Serialize)] +#[serde(default)] +pub struct RelayTunnels { + pub openvpn: Vec<OpenVpnParameters>, + pub wireguard: Vec<WireguardParameters>, +} |
