summaryrefslogtreecommitdiffhomepage
path: root/talpid_ipc/src/http_ipc
diff options
context:
space:
mode:
authorErik Larkö <erik@mullvad.net>2017-03-27 12:35:49 +0800
committerErik Larkö <erik@mullvad.net>2017-04-07 13:08:25 +0800
commitf7b702c41da9ab31a80d1654b9b2c323e2a25ec5 (patch)
treeb22441036215270963e50d37dff7b60f2e88455d /talpid_ipc/src/http_ipc
parent89723462dc879cb29fb917ff2f16ebb663217082 (diff)
downloadmullvadvpn-f7b702c41da9ab31a80d1654b9b2c323e2a25ec5.tar.xz
mullvadvpn-f7b702c41da9ab31a80d1654b9b2c323e2a25ec5.zip
Created the talpid_daemon crate and put the frontend IPC stuff there
Diffstat (limited to 'talpid_ipc/src/http_ipc')
-rw-r--r--talpid_ipc/src/http_ipc/connection_info.rs41
-rw-r--r--talpid_ipc/src/http_ipc/mod.rs73
2 files changed, 114 insertions, 0 deletions
diff --git a/talpid_ipc/src/http_ipc/connection_info.rs b/talpid_ipc/src/http_ipc/connection_info.rs
new file mode 100644
index 0000000000..99d87c0603
--- /dev/null
+++ b/talpid_ipc/src/http_ipc/connection_info.rs
@@ -0,0 +1,41 @@
+use std::fs::{File, OpenOptions};
+use std::io::Write;
+use std::path::PathBuf;
+
+/// The path to the file where we write the connection infp
+const IPC_CONNECTION_INFO_FILE: &'static str = "./.ipc_connection_info";
+
+error_chain! {
+ errors {
+ OpenFileFailed(file_name: PathBuf) {
+ description("Could not open file")
+ display("Could not open {}", file_name.to_string_lossy())
+ }
+ WriteConnectionInfoFailed(file_name: PathBuf) {
+ description("Could not write connection info file")
+ display("Could not write to {}", file_name.to_string_lossy())
+ }
+ }
+}
+
+pub fn write(connection_info: &str) -> Result<()> {
+ let file_location = PathBuf::from(IPC_CONNECTION_INFO_FILE);
+ let mut file = open_file(&file_location)?;
+ let res = file.write_all(connection_info.as_bytes())
+ .chain_err(|| ErrorKind::WriteConnectionInfoFailed(file_location.clone()));
+
+ debug!("Wrote IPC connection info ({}) to {}",
+ connection_info,
+ file_location.to_string_lossy());
+
+ res
+}
+
+fn open_file(file_name: &PathBuf) -> Result<File> {
+ OpenOptions::new()
+ .write(true)
+ .truncate(true)
+ .create(true)
+ .open(file_name)
+ .chain_err(|| ErrorKind::OpenFileFailed(file_name.to_owned()))
+}
diff --git a/talpid_ipc/src/http_ipc/mod.rs b/talpid_ipc/src/http_ipc/mod.rs
new file mode 100644
index 0000000000..24e177a755
--- /dev/null
+++ b/talpid_ipc/src/http_ipc/mod.rs
@@ -0,0 +1,73 @@
+extern crate jsonrpc_core;
+extern crate jsonrpc_http_server;
+
+use self::jsonrpc_http_server::{ServerBuilder, Server};
+use std::net::{SocketAddr, IpAddr, Ipv4Addr};
+
+mod connection_info;
+
+pub struct ServerHandle {
+ pub address: String,
+ server: Server,
+}
+
+impl ServerHandle {
+ pub fn stop(self) {
+ self.server.close();
+ }
+}
+
+pub fn start(build_router: fn() -> jsonrpc_core::IoHandler) -> Result<ServerHandle> {
+ let server = start_server(build_router)?;
+
+ let write_res = connection_info::write(&server.address)
+ .chain_err(|| ErrorKind::FailedToWriteConnectionInfo);
+ if let Err(e) = write_res {
+ debug!("Could not write the connection info, killing the IPC server");
+ server.stop();
+
+ return Err(e);
+ }
+
+ info!("Started Ipc server on: {:?}", server.address);
+ Ok(server)
+}
+
+fn start_server(build_router: fn() -> jsonrpc_core::IoHandler) -> Result<ServerHandle> {
+
+ let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
+ for port in 5000..5010 {
+ let server_config = ServerBuilder::new(build_router()).allow_only_bind_host();
+
+ let socket_addr = SocketAddr::new(ip, port);
+ let start_res = attempt_to_start(server_config, &socket_addr);
+
+ match start_res {
+ Ok(server) => {
+ return Ok(ServerHandle {
+ address: format!("http://{}", socket_addr),
+ server: server,
+ });
+ }
+ Err(Error(ErrorKind::UnableToStartServer, _)) => (),
+ Err(e) => return Err(e),
+ }
+ }
+ bail!(ErrorKind::UnableToStartServer)
+}
+
+fn attempt_to_start(server_config: ServerBuilder, address: &SocketAddr) -> Result<Server> {
+ server_config.start_http(&address)
+ .chain_err(|| ErrorKind::UnableToStartServer)
+}
+
+error_chain! {
+ errors {
+ FailedToWriteConnectionInfo {
+ description("Unable to write IPC connection info")
+ }
+ UnableToStartServer {
+ description("Failed to start the server")
+ }
+ }
+}