From 889e2b8f8c438d2939273a8570208b7b2130537c Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Wed, 24 Jun 2020 21:23:03 +0200 Subject: [PATCH] Refactor Windows IPC to use named pipes instead of localhost --- Cargo.lock | 10 +++++++++ Cargo.toml | 3 +++ src/protocol/mod.rs | 8 +++---- src/protocol/windows.rs | 49 +++++++++++++++++++++++------------------ 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81fdede..9a891de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,6 +384,7 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "log-panics 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "named_pipe 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -802,6 +803,14 @@ dependencies = [ "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "named_pipe" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "native-tls" version = "0.2.3" @@ -1911,6 +1920,7 @@ dependencies = [ "checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" "checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +"checksum named_pipe 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad9c443cce91fc3e12f017290db75dde490d685cdaaf508d7159d7cf41f0eb2b" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" diff --git a/Cargo.toml b/Cargo.toml index 0ed1f99..6e49975 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,9 @@ notify = "4.0.13" libc = "0.2.62" signal-hook = "0.1.15" +[target.'cfg(windows)'.dependencies] +named_pipe = "0.4.1" + [build-dependencies] cmake = "0.1.31" diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index d719dac..563e560 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -214,13 +214,13 @@ pub fn get_ipc_client(service: Service, _: Configs) -> impl IPCClient { #[cfg(target_os = "windows")] pub fn get_ipc_server( service: Service, - config: Configs, + _: Configs, event_channel: Sender, ) -> impl IPCServer { - windows::WindowsIPCServer::new(service, config, event_channel) + windows::WindowsIPCServer::new(service, event_channel) } #[cfg(target_os = "windows")] -pub fn get_ipc_client(service: Service, config: Configs) -> impl IPCClient { - windows::WindowsIPCClient::new(service, config) +pub fn get_ipc_client(service: Service, _: Configs) -> impl IPCClient { + windows::WindowsIPCClient::new(service) } diff --git a/src/protocol/windows.rs b/src/protocol/windows.rs index 67b2125..9cf239c 100644 --- a/src/protocol/windows.rs +++ b/src/protocol/windows.rs @@ -25,30 +25,35 @@ use std::sync::mpsc::Sender; use crate::config::Configs; use crate::event::*; use crate::protocol::{process_event, send_command, Service}; +use named_pipe::{PipeOptions, PipeServer, PipeClient}; +use crate::context; +use std::io::Error; +use std::path::PathBuf; + +const DAEMON_WIN_PIPE_NAME: &str = "\\\\.\\pipe\\espansodaemon"; +const WORKER_WIN_PIPE_NAME: &str = "\\\\.\\pipe\\espansoworker"; +const CLIENT_TIMEOUT: u32 = 2000; pub struct WindowsIPCServer { service: Service, - config: Configs, event_channel: Sender, } -fn to_port(config: &Configs, service: &Service) -> u16 { - let port = match service { - Service::Daemon => config.ipc_server_port, - Service::Worker => config.worker_ipc_server_port, - }; - port as u16 +fn get_pipe_name(service: &Service) -> String { + match service { + Service::Daemon => DAEMON_WIN_PIPE_NAME.to_owned(), + Service::Worker => WORKER_WIN_PIPE_NAME.to_owned(), + } } + impl WindowsIPCServer { pub fn new( service: Service, - config: Configs, event_channel: Sender, ) -> WindowsIPCServer { WindowsIPCServer { service, - config, event_channel, } } @@ -57,20 +62,21 @@ impl WindowsIPCServer { impl super::IPCServer for WindowsIPCServer { fn start(&self) { let event_channel = self.event_channel.clone(); - let server_port = to_port(&self.config, &self.service); + let pipe_name = get_pipe_name(&self.service); std::thread::Builder::new() .name("ipc_server".to_string()) .spawn(move || { - let listener = TcpListener::bind(format!("127.0.0.1:{}", server_port)) - .expect("Error binding to IPC server port"); + let options = PipeOptions::new(&pipe_name); info!( - "Binded to IPC tcp socket: {}", - listener.local_addr().unwrap().to_string() + "Binding to named pipe: {}", + pipe_name ); - for stream in listener.incoming() { - process_event(&event_channel, stream); + loop { + let server = options.single().expect("unable to initialize IPC named pipe"); + let pipe_server = server.wait(); + process_event(&event_channel, pipe_server); } }) .expect("Unable to spawn IPC server thread"); @@ -79,20 +85,19 @@ impl super::IPCServer for WindowsIPCServer { pub struct WindowsIPCClient { service: Service, - config: Configs, } impl WindowsIPCClient { - pub fn new(service: Service, config: Configs) -> WindowsIPCClient { - WindowsIPCClient { service, config } + pub fn new(service: Service) -> WindowsIPCClient { + WindowsIPCClient { service } } } impl super::IPCClient for WindowsIPCClient { fn send_command(&self, command: IPCCommand) -> Result<(), String> { - let port = to_port(&self.config, &self.service); - let stream = TcpStream::connect(("127.0.0.1", port)); + let pipe_name = get_pipe_name(&self.service); + let client = PipeClient::connect_ms(pipe_name, CLIENT_TIMEOUT); - send_command(command, stream) + send_command(command, client) } }