summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2019-03-25 11:19:27 +0100
committerLinus Färnstrand <linus@mullvad.net>2019-03-26 12:36:31 +0100
commit4b2841c9dfc75a513f99cd9695fc27977699cc91 (patch)
tree1cbda717667c2d569ebfea2bfb14f39e210131c2
parent0d95132e5ab6eb072ede73e901d783eaef12cad1 (diff)
downloadmullvadvpn-4b2841c9dfc75a513f99cd9695fc27977699cc91.tar.xz
mullvadvpn-4b2841c9dfc75a513f99cd9695fc27977699cc91.zip
Send two GeoIP lookups, one over each IPv
-rw-r--r--Cargo.lock1
-rw-r--r--mullvad-cli/src/cmds/status.rs14
-rw-r--r--mullvad-daemon/src/geoip.rs35
-rw-r--r--mullvad-daemon/src/lib.rs6
-rw-r--r--mullvad-rpc/Cargo.toml1
-rw-r--r--mullvad-rpc/src/lib.rs9
-rw-r--r--mullvad-types/src/location.rs37
7 files changed, 83 insertions, 20 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b2b0bae84d..9478ab7cea 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1196,7 +1196,6 @@ dependencies = [
"hyper-openssl 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-client-core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-client-http 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"mullvad-types 0.1.0",
"serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/mullvad-cli/src/cmds/status.rs b/mullvad-cli/src/cmds/status.rs
index b1fb696b7f..29ce0d2c6d 100644
--- a/mullvad-cli/src/cmds/status.rs
+++ b/mullvad-cli/src/cmds/status.rs
@@ -78,14 +78,20 @@ fn print_location(rpc: &mut DaemonRpcClient) -> Result<()> {
return Ok(());
}
};
+ if let Some(hostname) = location.hostname {
+ println!("Relay: {}", hostname);
+ }
+ if let Some(ipv4) = location.ipv4 {
+ println!("IPv4: {}", ipv4);
+ }
+ if let Some(ipv6) = location.ipv6 {
+ println!("IPv6: {}", ipv6);
+ }
let city_and_country = if let Some(city) = location.city {
format!("{}, {}", city, location.country)
} else {
- format!("{}", location.country)
+ location.country.clone()
};
- if let Some(hostname) = location.hostname {
- println!("Relay: {}", hostname);
- }
println!("Location: {}", city_and_country);
println!(
"Position: {:.5}°N, {:.5}°W",
diff --git a/mullvad-daemon/src/geoip.rs b/mullvad-daemon/src/geoip.rs
index 2faed344a6..ffd805739b 100644
--- a/mullvad-daemon/src/geoip.rs
+++ b/mullvad-daemon/src/geoip.rs
@@ -1,10 +1,11 @@
use futures::{self, Future};
use mullvad_rpc;
-use mullvad_types::location::GeoIpLocation;
+use mullvad_types::location::{AmIMullvad, GeoIpLocation};
use serde_json;
-const URI: &str = "https://am.i.mullvad.net/json";
+const URI_V4: &str = "https://ipv4.am.i.mullvad.net/json";
+const URI_V6: &str = "https://ipv6.am.i.mullvad.net/json";
error_chain! {
errors {
@@ -22,8 +23,36 @@ error_chain! {
pub fn send_location_request(
request_sender: mullvad_rpc::rest::RequestSender,
) -> impl Future<Item = GeoIpLocation, Error = Error> {
+ let v4_future =
+ send_location_request_internal(URI_V4, request_sender.clone()).map(GeoIpLocation::from);
+ let v6_future = send_location_request_internal(URI_V6, request_sender).map(GeoIpLocation::from);
+
+ v4_future.then(|v4_result| {
+ v6_future.then(|v6_result| match (v4_result, v6_result) {
+ (Ok(mut v4), Ok(v6)) => {
+ v4.ipv6 = v6.ipv6;
+ v4.mullvad_exit_ip = v4.mullvad_exit_ip && v6.mullvad_exit_ip;
+ Ok(v4)
+ }
+ (Ok(v4), Err(e)) => {
+ log::debug!("Unable to fetch IPv6 GeoIP location: {}", e);
+ Ok(v4)
+ }
+ (Err(e), Ok(v6)) => {
+ log::debug!("Unable to fetch IPv4 GeoIP location: {}", e);
+ Ok(v6)
+ }
+ (Err(e_v4), Err(_)) => Err(e_v4),
+ })
+ })
+}
+
+fn send_location_request_internal(
+ uri: &'static str,
+ request_sender: mullvad_rpc::rest::RequestSender,
+) -> impl Future<Item = AmIMullvad, Error = Error> {
let (response_tx, response_rx) = futures::sync::oneshot::channel();
- let request = mullvad_rpc::rest::create_get_request(URI.parse().unwrap());
+ let request = mullvad_rpc::rest::create_get_request(uri.parse().unwrap());
futures::Sink::send(request_sender, (request, response_tx))
.map_err(|e| Error::with_chain(e, ErrorKind::NoResponse))
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index bc7e32dcbc..7a4e4b9943 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -512,7 +512,8 @@ impl Daemon {
Some(location_from_relay) => Box::new(
self.get_geo_location()
.map(|fetched_location| GeoIpLocation {
- ip: fetched_location.ip,
+ ipv4: fetched_location.ipv4,
+ ipv6: fetched_location.ipv6,
..location_from_relay
})
.map(Some),
@@ -545,7 +546,8 @@ impl Daemon {
let hostname = relay.hostname.clone();
Some(GeoIpLocation {
- ip: None,
+ ipv4: None,
+ ipv6: None,
country: location.country,
city: Some(location.city),
latitude: location.latitude,
diff --git a/mullvad-rpc/Cargo.toml b/mullvad-rpc/Cargo.toml
index 2f21283c58..a2449842a7 100644
--- a/mullvad-rpc/Cargo.toml
+++ b/mullvad-rpc/Cargo.toml
@@ -12,7 +12,6 @@ error-chain = "0.12"
futures = "0.1.15"
jsonrpc-client-core = "0.5"
jsonrpc-client-http = "0.5"
-lazy_static = "1.0"
serde_json = "1.0"
tokio-core = "0.1"
hyper = "0.11"
diff --git a/mullvad-rpc/src/lib.rs b/mullvad-rpc/src/lib.rs
index 58fa07440f..6d32d0dea0 100644
--- a/mullvad-rpc/src/lib.rs
+++ b/mullvad-rpc/src/lib.rs
@@ -13,7 +13,6 @@ extern crate error_chain;
use chrono::{offset::Utc, DateTime};
use jsonrpc_client_core::{expand_params, jsonrpc_client};
use jsonrpc_client_http::{header::Host, HttpTransport, HttpTransportBuilder};
-use lazy_static::lazy_static;
use mullvad_types::{account::AccountToken, relay_list::RelayList, version};
use std::{
collections::HashMap,
@@ -43,9 +42,7 @@ const DNS_THREADS: usize = 2;
const API_HOST: &str = "api.mullvad.net";
const RPC_TIMEOUT: Duration = Duration::from_secs(10);
pub const API_IP_CACHE_FILENAME: &str = "api-ip-address.txt";
-lazy_static! {
- static ref API_IP: IpAddr = IpAddr::V4(Ipv4Addr::new(193, 138, 218, 73));
-}
+const API_IP: IpAddr = IpAddr::V4(Ipv4Addr::new(193, 138, 218, 73));
/// A type that helps with the creation of RPC connections.
@@ -58,7 +55,7 @@ impl MullvadRpcFactory {
/// Create a new `MullvadRpcFactory`.
pub fn new<P: Into<PathBuf>>(ca_path: P) -> Self {
MullvadRpcFactory {
- cached_dns_resolver: CachedDnsResolver::new(API_HOST.to_owned(), None, *API_IP),
+ cached_dns_resolver: CachedDnsResolver::new(API_HOST.to_owned(), None, API_IP),
ca_path: ca_path.into(),
}
}
@@ -67,7 +64,7 @@ impl MullvadRpcFactory {
pub fn with_cache_dir<P: Into<PathBuf>>(cache_dir: &Path, ca_path: P) -> Self {
let cache_file = cache_dir.join(API_IP_CACHE_FILENAME);
let cached_dns_resolver =
- CachedDnsResolver::new(API_HOST.to_owned(), Some(cache_file), *API_IP);
+ CachedDnsResolver::new(API_HOST.to_owned(), Some(cache_file), API_IP);
MullvadRpcFactory {
cached_dns_resolver,
diff --git a/mullvad-types/src/location.rs b/mullvad-types/src/location.rs
index 7f326ead42..1c59c0d416 100644
--- a/mullvad-types/src/location.rs
+++ b/mullvad-types/src/location.rs
@@ -1,5 +1,5 @@
use serde::{Deserialize, Serialize};
-use std::net::IpAddr;
+use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
pub type CountryCode = String;
pub type CityCode = String;
@@ -15,14 +15,45 @@ pub struct Location {
pub longitude: f64,
}
+/// The response from the am.i.mullvad.net location service.
+#[derive(Debug, Deserialize)]
+pub struct AmIMullvad {
+ pub ip: IpAddr,
+ pub country: String,
+ pub city: Option<String>,
+ pub latitude: f64,
+ pub longitude: f64,
+ pub mullvad_exit_ip: bool,
+}
+
+/// GeoIP information exposed from the daemon to frontends.
#[derive(Debug, Serialize, Deserialize)]
pub struct GeoIpLocation {
- pub ip: Option<IpAddr>,
+ pub ipv4: Option<Ipv4Addr>,
+ pub ipv6: Option<Ipv6Addr>,
pub country: String,
pub city: Option<String>,
pub latitude: f64,
pub longitude: f64,
pub mullvad_exit_ip: bool,
- #[serde(default)]
pub hostname: Option<String>,
}
+
+impl From<AmIMullvad> for GeoIpLocation {
+ fn from(location: AmIMullvad) -> GeoIpLocation {
+ let (ipv4, ipv6) = match location.ip {
+ IpAddr::V4(v4) => (Some(v4), None),
+ IpAddr::V6(v6) => (None, Some(v6)),
+ };
+ GeoIpLocation {
+ ipv4,
+ ipv6,
+ country: location.country,
+ city: location.city,
+ latitude: location.latitude,
+ longitude: location.longitude,
+ mullvad_exit_ip: location.mullvad_exit_ip,
+ hostname: None,
+ }
+ }
+}