Refactor Windows IPC to use named pipes instead of localhost

This commit is contained in:
Federico Terzi 2020-06-24 21:23:03 +02:00
parent 32d7dbc88e
commit 889e2b8f8c
4 changed files with 44 additions and 26 deletions

10
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -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<Event>,
) -> 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)
}

View File

@ -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<Event>,
}
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<Event>,
) -> 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)
}
}