summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorErik Larkö <erik@mullvad.net>2017-03-01 12:37:52 +0800
committerErik Larkö <erik@mullvad.net>2017-03-02 21:29:23 +0800
commit6e3ec931bcf1f0f3ca220c3a1baabf5b6197db80 (patch)
treea0ab22b915c719f66bfc2fb91c1b32826a5a5a51
parent9dacaac457282cb26311a1e030be73fe94d6bc76 (diff)
downloadmullvadvpn-6e3ec931bcf1f0f3ca220c3a1baabf5b6197db80.tar.xz
mullvadvpn-6e3ec931bcf1f0f3ca220c3a1baabf5b6197db80.zip
Try a bunch of ports when starting the IpcServer
-rw-r--r--Cargo.lock89
-rw-r--r--talpid_ipc/Cargo.toml2
-rw-r--r--talpid_ipc/src/zmq_ipc.rs33
-rw-r--r--talpid_ipc/tests/zmq_integration_tests.rs51
4 files changed, 131 insertions, 44 deletions
diff --git a/Cargo.lock b/Cargo.lock
index be0b367869..4eb4f53821 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8,6 +8,14 @@ dependencies = [
]
[[package]]
+name = "aho-corasick"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "ansi_term"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -125,6 +133,14 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "memchr"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "metadeps"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -140,6 +156,31 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "rand"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "regex"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "rustc-demangle"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -175,6 +216,8 @@ version = "0.1.0"
dependencies = [
"assert_matches 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"zmq 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -189,6 +232,24 @@ dependencies = [
]
[[package]]
+name = "thread-id"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "thread_local"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "toml"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -204,11 +265,29 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "unreachable"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "utf8-ranges"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "vec_map"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -238,6 +317,7 @@ dependencies = [
]
[metadata]
+"checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum assert_matches 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9aa85694f8820620d0df15526544e1c3fbbac7ba3874781d874d7d6499a53724"
"checksum backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f551bc2ddd53aea015d453ef0b635af89444afa5ed2405dd0b2062ad5d600d80"
@@ -254,15 +334,24 @@ dependencies = [
"checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b"
"checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5"
"checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
+"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
"checksum metadeps 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829fffe7ea1d747e23f64be972991bc516b2f1ac2ae4a3b33d8bea150c410151"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
+"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
+"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
+"checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
"checksum rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1430d286cadb237c17c885e25447c982c97113926bb579f4379c0eca8d9586dc"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum term_size 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "71662702fe5cd2cf95edd4ad655eea42f24a87a0e44059cbaa4e55260b7bc331"
+"checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"
+"checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"
"checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4"
"checksum unicode-segmentation 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7baebdc1df1363fa66161fca2fe047e4f4209011cc7e045948298996afdf85df"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
+"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
+"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
"checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f"
+"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum zmq 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9623581b345b8a85fb72cae9b2cb67116d73ccb141e6c02f689e311962b74f9c"
diff --git a/talpid_ipc/Cargo.toml b/talpid_ipc/Cargo.toml
index 6bacc0f9a7..fcefd2f9d6 100644
--- a/talpid_ipc/Cargo.toml
+++ b/talpid_ipc/Cargo.toml
@@ -6,9 +6,11 @@ description = "IPC client and server for talpid"
[dependencies]
error-chain = "0.8"
+rand = "0.3"
[target.'cfg(not(windows))'.dependencies]
zmq = "0.8"
[dev-dependencies]
assert_matches = "1.0"
+regex = "0.2"
diff --git a/talpid_ipc/src/zmq_ipc.rs b/talpid_ipc/src/zmq_ipc.rs
index 0afab082b2..a93e0e9808 100644
--- a/talpid_ipc/src/zmq_ipc.rs
+++ b/talpid_ipc/src/zmq_ipc.rs
@@ -1,18 +1,17 @@
extern crate zmq;
+extern crate rand;
+use self::rand::distributions::{IndependentSample, Range};
use super::{OnMessage, ErrorKind, Result, ResultExt};
use std::thread;
type IpcServerId = String;
/// The server end of our Inter-Process Communcation implementation.
-pub struct Server {
- port: u16,
-}
-
+pub struct Server;
impl Server {
- pub fn new(port: u16) -> Self {
- Server { port: port }
+ pub fn new() -> Self {
+ Server {}
}
/// Starts listening to incoming IPC connections on the specified port.
@@ -24,10 +23,24 @@ impl Server {
/// This function is non-blocking and thus spawns a thread where it
/// listens to messages.
pub fn start(self, on_message: Box<OnMessage<Vec<u8>>>) -> Result<IpcServerId> {
- let socket =
- Self::start_zmq_server(self.port).chain_err(|| ErrorKind::CouldNotStartServer)?;
- let _ = Self::start_receive_loop(socket, on_message);
- Ok(format!("localhost:{}", self.port))
+
+ let port_range = Range::new(1024, 65535); // Docs doesn't say if this is inclusive or exclusive...
+ let mut rng = rand::thread_rng();
+ for _ in 0..10 {
+
+ let port = port_range.ind_sample(&mut rng);
+ if let Ok(socket) = Self::attempt_to_start_on_port(port) {
+ let _ = Self::start_receive_loop(socket, on_message);
+ return Ok(format!("tcp://localhost:{}", port));
+ }
+ }
+
+ return Err(ErrorKind::CouldNotStartServer.into());
+ }
+
+ fn attempt_to_start_on_port(port: u16) -> Result<zmq::Socket> {
+ let socket = Self::start_zmq_server(port).chain_err(|| ErrorKind::CouldNotStartServer)?;
+ Ok(socket)
}
fn start_zmq_server(port: u16) -> zmq::Result<zmq::Socket> {
diff --git a/talpid_ipc/tests/zmq_integration_tests.rs b/talpid_ipc/tests/zmq_integration_tests.rs
index a076c6fd7a..a65a5e59c3 100644
--- a/talpid_ipc/tests/zmq_integration_tests.rs
+++ b/talpid_ipc/tests/zmq_integration_tests.rs
@@ -1,9 +1,11 @@
extern crate talpid_ipc;
extern crate zmq;
+extern crate regex;
#[macro_use]
extern crate assert_matches;
+use regex::Regex;
use std::result;
use std::sync::mpsc::{self, Receiver};
use std::time::Duration;
@@ -14,37 +16,19 @@ const AN_INVALID_MESSAGE: u8 = 2;
#[test]
fn returns_connection_string_when_started() {
- let port = 1341;
- let connection_string = talpid_ipc::Server::new(port)
+ let connection_string = talpid_ipc::Server::new()
.start(Box::new(|_| {}))
.expect("Unable to start server");
- assert!(connection_string.contains("localhost"),
- format!("'{}' did not contain 'localhost'", connection_string));
- assert!(connection_string.contains(&port.to_string()),
- format!("'{}' did not contain the port", connection_string));
-}
-
-#[test]
-fn gives_error_when_unable_to_start() {
- let port = 1340;
-
- let ipc_server1 = talpid_ipc::Server::new(port);
- let ipc_server2 = talpid_ipc::Server::new(port);
-
- ipc_server1.start(Box::new(|_| {}))
- .expect("Unable to start the first server. Results inconclusive");
- let start_res = ipc_server2.start(Box::new(|_| {}));
-
- assert!(start_res.is_err());
- let err = start_res.unwrap_err();
- assert_matches!(err.kind(), &ErrorKind::CouldNotStartServer);
- assert!(err.iter().count() > 1)
+ let re = Regex::new(r"^tcp://localhost:\d+$").unwrap();
+ assert!(re.is_match(&connection_string),
+ format!("'{}' does not match 'tcp://localhost:port'",
+ connection_string));
}
#[test]
fn publishes_incoming_messages_to_channel() {
- let new_messages_rx = connect_and_send(1337, A_VALID_MESSAGE);
+ let new_messages_rx = connect_and_send(A_VALID_MESSAGE);
let message = new_messages_rx.recv_timeout(Duration::from_millis(1000))
.expect("Did not receive a message");
@@ -53,7 +37,7 @@ fn publishes_incoming_messages_to_channel() {
#[test]
fn does_not_publish_unknown_messages() {
- let rx = connect_and_send(1338, AN_INVALID_MESSAGE);
+ let rx = connect_and_send(AN_INVALID_MESSAGE);
let message = rx.recv_timeout(Duration::from_millis(1000))
.expect("Did not receive message");
@@ -61,26 +45,25 @@ fn does_not_publish_unknown_messages() {
assert_matches!(message.unwrap_err().kind(), &ErrorKind::InvalidMessage(_));
}
-fn connect_and_send(port: u16, message: u8) -> Receiver<Result<TestMessage>> {
+fn connect_and_send(message: u8) -> Receiver<Result<TestMessage>> {
let (tx, rx) = mpsc::channel();
- let ipc_server = talpid_ipc::Server::new(port);
- ipc_server.start(Box::new(move |message| {
- let _ = tx.send(message.and_then(parse_to_test_enum));
- })).expect("Could not start the server");
+ let ipc_server = talpid_ipc::Server::new();
+ let connection_string = ipc_server.start(Box::new(move |message| {
+ let _ = tx.send(message.and_then(parse_to_test_enum));
+ })).expect("Could not start the server");
- let socket = connect_to_server(port).expect("Could not connect to the server");
+ let socket = connect_to_server(&connection_string).expect("Could not connect to the server");
socket.send(&[message], 0).expect("Could not send message");
rx
}
-fn connect_to_server(port: u16) -> result::Result<zmq::Socket, zmq::Error> {
+fn connect_to_server(connection_string: &str) -> result::Result<zmq::Socket, zmq::Error> {
let ctx = zmq::Context::new();
let socket = ctx.socket(zmq::PUSH)?;
- let connection_string: String = format!("tcp://127.0.0.1:{}", port);
- try!(socket.connect(connection_string.as_str()));
+ try!(socket.connect(connection_string));
Ok(socket)
}