diff options
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 13 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 8 | ||||
| -rw-r--r-- | mullvad-rpc/Cargo.toml | 1 | ||||
| -rw-r--r-- | mullvad-rpc/src/lib.rs | 17 | ||||
| -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 |
10 files changed, 127 insertions, 87 deletions
diff --git a/Cargo.lock b/Cargo.lock index d54055a31e..717f93bddc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,6 +702,7 @@ dependencies = [ "jsonrpc-client-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-client-http 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "mullvad-types 0.1.0", + "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index d4de632817..1619205669 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -48,10 +48,10 @@ use futures::Future; use jsonrpc_core::futures::sync::oneshot::Sender as OneshotSender; use management_interface::{BoxFuture, ManagementInterfaceServer, TunnelCommand}; use mullvad_rpc::{AccountsProxy, HttpHandle}; +use mullvad_types::CustomTunnelEndpoint; use mullvad_types::account::{AccountData, AccountToken}; use mullvad_types::relay_constraints::{Constraint, OpenVpnConstraints, RelayConstraints, RelayConstraintsUpdate, TunnelConstraints}; -use mullvad_types::relay_endpoint::RelayEndpoint; use mullvad_types::states::{DaemonState, SecurityState, TargetState}; use rand::Rng; @@ -561,16 +561,11 @@ impl Daemon { Constraint::Only(port) => port, }; - let endpoint = RelayEndpoint { + CustomTunnelEndpoint { host, - port, - protocol, - }.to_endpoint() - .chain_err(|| "Unable to construct a valid relay")?; - Ok(TunnelEndpoint { - address: endpoint.address.ip(), tunnel: TunnelParameters::OpenVpn(OpenVpnParameters { port, protocol }), - }) + }.to_tunnel_endpoint() + .chain_err(|| "Unable to construct a valid relay") } fn spawn_tunnel_monitor( diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index 28b905390d..a71dddfb35 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -449,9 +449,11 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem fn get_location(&self) -> Result<Location, Error> { trace!("get_location"); Ok(Location { - latlong: [1.0, 2.0], - country: "narnia".to_owned(), - city: "Le city".to_owned(), + country: String::from("narnia"), + country_code: String::from("na"), + city: String::from("Le city"), + city_code: String::from("le"), + position: [1.0, 2.0], }) } diff --git a/mullvad-rpc/Cargo.toml b/mullvad-rpc/Cargo.toml index 41f7fccb2d..d49557cb96 100644 --- a/mullvad-rpc/Cargo.toml +++ b/mullvad-rpc/Cargo.toml @@ -9,5 +9,6 @@ license = "GPL-3.0" chrono = { version = "0.4", features = ["serde"] } jsonrpc-client-core = "0.2.1" jsonrpc-client-http = "0.2.1" +serde_json = "1.0" mullvad-types = { path = "../mullvad-types" } diff --git a/mullvad-rpc/src/lib.rs b/mullvad-rpc/src/lib.rs index 9174f1e684..f0d32ad9ee 100644 --- a/mullvad-rpc/src/lib.rs +++ b/mullvad-rpc/src/lib.rs @@ -10,6 +10,7 @@ extern crate chrono; #[macro_use] extern crate jsonrpc_client_core; extern crate jsonrpc_client_http; +extern crate serde_json; extern crate mullvad_types; @@ -21,11 +22,16 @@ pub use jsonrpc_client_core::{Error, ErrorKind}; pub use jsonrpc_client_http::{Error as HttpError, HttpHandle}; use mullvad_types::account::AccountToken; +use mullvad_types::relay_list::RelayList; static MASTER_API_URI: &str = "https://api.mullvad.net/rpc/"; +pub fn connect() -> Result<HttpHandle, HttpError> { + HttpTransport::new()?.handle(MASTER_API_URI) +} + jsonrpc_client!(pub struct AccountsProxy { pub fn get_expiry(&mut self, account_token: AccountToken) -> RpcRequest<DateTime<Utc>>; }); @@ -47,3 +53,14 @@ impl ProblemReportProxy<HttpHandle> { Ok(ProblemReportProxy::new(transport)) } } + +jsonrpc_client!(pub struct RelayListProxy { + pub fn relay_list(&mut self) -> RpcRequest<RelayList>; +}); + +impl RelayListProxy<HttpHandle> { + pub fn connect() -> Result<Self, HttpError> { + let transport = HttpTransport::new()?.handle(MASTER_API_URI)?; + Ok(RelayListProxy::new(transport)) + } +} 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>, +} |
