summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2017-11-14 19:04:20 +0100
committerLinus Färnstrand <linus@mullvad.net>2017-11-14 19:04:20 +0100
commit1fde81d2eb8487f338d8a394d844d337cf393381 (patch)
tree6dbe0bb5ce47d7a33df9860f7c696c749c5786be
parenta417d14469f104b1eac001318e900559299a8f1a (diff)
downloadmullvadvpn-1fde81d2eb8487f338d8a394d844d337cf393381.tar.xz
mullvadvpn-1fde81d2eb8487f338d8a394d844d337cf393381.zip
Add RelayList and adapt surrounding types
-rw-r--r--mullvad-types/src/custom_tunnel.rs46
-rw-r--r--mullvad-types/src/lib.rs7
-rw-r--r--mullvad-types/src/location.rs5
-rw-r--r--mullvad-types/src/relay_endpoint.rs72
-rw-r--r--mullvad-types/src/relay_list.rs44
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>,
+}