diff options
| author | Erik Larkö <erik@mullvad.net> | 2017-03-27 12:35:49 +0800 |
|---|---|---|
| committer | Erik Larkö <erik@mullvad.net> | 2017-04-07 13:08:25 +0800 |
| commit | f7b702c41da9ab31a80d1654b9b2c323e2a25ec5 (patch) | |
| tree | b22441036215270963e50d37dff7b60f2e88455d /talpid_ipc/src/http_ipc | |
| parent | 89723462dc879cb29fb917ff2f16ebb663217082 (diff) | |
| download | mullvadvpn-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.rs | 41 | ||||
| -rw-r--r-- | talpid_ipc/src/http_ipc/mod.rs | 73 |
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") + } + } +} |
