Skip to content

Commit

Permalink
jsonrpc: uds support for Windows
Browse files Browse the repository at this point in the history
I could not find a way to get mio 0.7 running with Windows' uds. So,
until tokio-rs/mio#880 (deprecrated/mio-uds#7)
is implemented in Mio we use a simple blocking event loop for Windows.

That's fine, it's just for the RPC. We could potentially see some load
on a server, but it'd be on UNIX so Everything Is Fine ™️.

Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
  • Loading branch information
darosior committed Nov 17, 2020
1 parent 333d7e8 commit 381c47b
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 32 deletions.
121 changes: 114 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@ rusqlite = { version = "0.24.1", features = ["bundled"] }
# For the JSONRPC API
jsonrpc-core = "15.1.0"
jsonrpc-derive = "15.1.0"
[target.'cfg(not(windows))'.dependencies]
mio = { version = "0.7.5", features = ["default", "os-poll", "os-util", "uds"] }
[target.'cfg(windows)'.dependencies]
uds_windows = "0.1.5"
62 changes: 43 additions & 19 deletions src/jsonrpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ use std::{
time::Duration,
};

use mio::{
net::{UnixListener, UnixStream},
Events, Interest, Poll, Token,
};
use mio::{Events, Interest, Poll, Token};

#[cfg(not(windows))]
use mio::net::{UnixListener, UnixStream};
#[cfg(windows)]
use uds_windows::{UnixListener, UnixStream};

const JSONRPC_SERVER: Token = Token(0);

Expand All @@ -23,17 +25,6 @@ impl RpcApi for RpcImpl {
}
}

/// Set up the poller used to listen on the Unix Domain Socket for JSONRPC messages
pub fn jsonrpcapi_setup(socket_path: PathBuf) -> Result<(Poll, UnixListener), io::Error> {
// FIXME: permissions! (umask before binding ?)
let mut listener = UnixListener::bind(&socket_path)?;
let poll = Poll::new()?;
poll.registry()
.register(&mut listener, JSONRPC_SERVER, Interest::READABLE)?;

Ok((poll, listener))
}

// Remove trailing newlines from utf-8 byte stream
fn trimmed(mut vec: Vec<u8>, bytes_read: usize) -> Vec<u8> {
vec.truncate(bytes_read);
Expand Down Expand Up @@ -109,11 +100,18 @@ fn handle_byte_stream(
Ok(())
}

/// The main event loop for the JSONRPC interface
pub fn jsonrpcapi_loop(mut poller: Poll, listener: UnixListener) -> Result<(), io::Error> {
// For all but Windows, we use Mio.
#[cfg(not(windows))]
fn mio_loop(
mut listener: UnixListener,
jsonrpc_io: jsonrpc_core::IoHandler,
) -> Result<(), io::Error> {
let mut poller = Poll::new()?;
let mut events = Events::with_capacity(16);
let mut jsonrpc_io = jsonrpc_core::IoHandler::new();
jsonrpc_io.extend_with(RpcImpl.to_delegate());

poller
.registry()
.register(&mut listener, JSONRPC_SERVER, Interest::READABLE)?;

loop {
poller.poll(&mut events, Some(Duration::from_millis(10000)))?;
Expand Down Expand Up @@ -146,3 +144,29 @@ pub fn jsonrpcapi_loop(mut poller: Poll, listener: UnixListener) -> Result<(), i
}
}
}

// For windows, we don't: Mio UDS support for Windows is not yet implemented.
#[cfg(windows)]
fn windows_loop(
listener: UnixListener,
jsonrpc_io: jsonrpc_core::IoHandler,
) -> Result<(), io::Error> {
for stream in listener.incoming() {
handle_byte_stream(&jsonrpc_io, stream?)?;
}

Ok(())
}

/// The main event loop for the JSONRPC interface, polling the UDS at `socket_path`
pub fn jsonrpcapi_loop(socket_path: PathBuf) -> Result<(), io::Error> {
// FIXME: permissions! (umask before binding ?)
let listener = UnixListener::bind(&socket_path)?;
let mut jsonrpc_io = jsonrpc_core::IoHandler::new();
jsonrpc_io.extend_with(RpcImpl.to_delegate());

#[cfg(not(windows))]
return mio_loop(listener, jsonrpc_io);
#[cfg(windows)]
return windows_loop(listener, jsonrpc_io);
}
9 changes: 3 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
bitcoind::actions::{bitcoind_main_loop, setup_bitcoind},
config::parse_config,
database::actions::setup_db,
jsonrpc::{jsonrpcapi_loop, jsonrpcapi_setup},
jsonrpc::jsonrpcapi_loop,
revaultd::RevaultD,
};

Expand Down Expand Up @@ -46,12 +46,9 @@ fn daemon_main(mut revaultd: RevaultD) {
revaultd.bitcoind_config.network
);

let (poller, listener) = jsonrpcapi_setup(revaultd.rpc_socket_file()).unwrap_or_else(|e| {
log::error!("Error setting up the JSONRPC server: {}", e.to_string());
process::exit(1)
});
let socket_path = revaultd.rpc_socket_file();
let _jsonrpc_thread = thread::spawn(move || {
jsonrpcapi_loop(poller, listener).unwrap_or_else(|e| {
jsonrpcapi_loop(socket_path).unwrap_or_else(|e| {
log::error!("Error in JSONRPC server event loop: {}", e.to_string());
process::exit(1)
})
Expand Down

0 comments on commit 381c47b

Please sign in to comment.