fix: fix conditional code for windows builds (#334)

This commit is contained in:
Santiago Carmuega 2023-11-16 13:36:49 -03:00 committed by GitHub
parent 43fefc8176
commit cc2f295fb2
3 changed files with 61 additions and 55 deletions

View file

@ -58,7 +58,7 @@ async fn do_chainsync(client: &mut NodeClient) {
// environment // environment
const SOCKET_PATH: &str = "/tmp/node.socket"; const SOCKET_PATH: &str = "/tmp/node.socket";
#[cfg(target_family = "unix")] #[cfg(unix)]
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
tracing::subscriber::set_global_default( tracing::subscriber::set_global_default(

View file

@ -5,15 +5,10 @@ use tokio::net::TcpListener;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use tracing::{debug, error}; use tracing::{debug, error};
#[cfg(not(target_os = "windows"))] #[cfg(unix)]
use tokio::net::UnixListener; use tokio::net::UnixListener;
use crate::miniprotocols::handshake::{ use crate::miniprotocols::handshake::{n2c, n2n, Confirmation, VersionNumber, VersionTable};
n2c::VersionData,
n2n, VersionTable,
Confirmation,
VersionNumber
};
use crate::miniprotocols::PROTOCOL_N2N_HANDSHAKE; use crate::miniprotocols::PROTOCOL_N2N_HANDSHAKE;
use crate::{ use crate::{
@ -160,9 +155,10 @@ pub struct NodeClient {
} }
impl NodeClient { impl NodeClient {
async fn connect_bearer(
async fn connect_bearer(bearer:Bearer,versions: VersionTable<VersionData>) -> Result<Self, Error> { bearer: Bearer,
versions: VersionTable<n2c::VersionData>,
) -> Result<Self, Error> {
let mut plexer = multiplexer::Plexer::new(bearer); let mut plexer = multiplexer::Plexer::new(bearer);
let hs_channel = plexer.subscribe_client(PROTOCOL_N2C_HANDSHAKE); let hs_channel = plexer.subscribe_client(PROTOCOL_N2C_HANDSHAKE);
@ -191,8 +187,7 @@ impl NodeClient {
}) })
} }
#[cfg(unix)]
#[cfg(not(target_os = "windows"))]
pub async fn connect(path: impl AsRef<Path>, magic: u64) -> Result<Self, Error> { pub async fn connect(path: impl AsRef<Path>, magic: u64) -> Result<Self, Error> {
debug!("connecting"); debug!("connecting");
@ -202,25 +197,26 @@ impl NodeClient {
let versions = handshake::n2c::VersionTable::v10_and_above(magic); let versions = handshake::n2c::VersionTable::v10_and_above(magic);
Self::connect_bearer(bearer,versions).await Self::connect_bearer(bearer, versions).await
} }
#[cfg(target_os = "windows")] #[cfg(windows)]
pub async fn connect(pipe_name: impl AsRef<std::ffi::OsStr>, magic: u64) -> Result<Self, Error> { pub async fn connect(
pipe_name: impl AsRef<std::ffi::OsStr>,
magic: u64,
) -> Result<Self, Error> {
debug!("connecting"); debug!("connecting");
let bearer = Bearer::connect_named_pipe(pipe_name) let bearer = Bearer::connect_named_pipe(pipe_name)
.await .await
.map_err(Error::ConnectFailure)?; .map_err(Error::ConnectFailure)?;
let versions =
handshake::n2c::VersionTable::only_v10(magic);
Self::connect_bearer(bearer,versions).await let versions = handshake::n2c::VersionTable::v10_and_above(magic);
Self::connect_bearer(bearer, versions).await
} }
#[cfg(not(target_os = "windows"))] #[cfg(unix)]
pub async fn handshake_query( pub async fn handshake_query(
path: impl AsRef<Path>, path: impl AsRef<Path>,
magic: u64, magic: u64,
@ -275,7 +271,7 @@ impl NodeClient {
} }
/// Server of N2C Ouroboros. /// Server of N2C Ouroboros.
#[cfg(not(target_os = "windows"))] #[cfg(unix)]
pub struct NodeServer { pub struct NodeServer {
pub plexer_handle: JoinHandle<Result<(), crate::multiplexer::Error>>, pub plexer_handle: JoinHandle<Result<(), crate::multiplexer::Error>>,
pub version: (VersionNumber, n2c::VersionData), pub version: (VersionNumber, n2c::VersionData),
@ -283,7 +279,7 @@ pub struct NodeServer {
pub statequery: localstate::Server, pub statequery: localstate::Server,
} }
#[cfg(not(target_os = "windows"))] #[cfg(unix)]
impl NodeServer { impl NodeServer {
pub async fn accept(listener: &UnixListener, magic: u64) -> Result<Self, Error> { pub async fn accept(listener: &UnixListener, magic: u64) -> Result<Self, Error> {
let (bearer, _) = Bearer::accept_unix(listener) let (bearer, _) = Bearer::accept_unix(listener)

View file

@ -11,12 +11,9 @@ use tokio::sync::mpsc::error::SendError;
use tokio::time::Instant; use tokio::time::Instant;
use tracing::{debug, error, trace}; use tracing::{debug, error, trace};
#[cfg(not(target_os = "windows"))] #[cfg(unix)]
use tokio::net::{UnixListener, UnixStream}; use tokio::net::{UnixListener, UnixStream};
#[cfg(not(target_os = "windows"))]
use tokio::net::UnixListener;
#[cfg(windows)] #[cfg(windows)]
use tokio::net::windows::named_pipe::NamedPipeClient; use tokio::net::windows::named_pipe::NamedPipeClient;
@ -65,16 +62,14 @@ pub struct Segment {
pub payload: Payload, pub payload: Payload,
} }
#[cfg(target_os = "windows")]
pub enum Bearer { pub enum Bearer {
Tcp(TcpStream), Tcp(TcpStream),
NamedPipe(NamedPipeClient)
}
#[cfg(not(target_os = "windows"))] #[cfg(unix)]
pub enum Bearer {
Tcp(TcpStream),
Unix(UnixStream), Unix(UnixStream),
#[cfg(windows)]
NamedPipe(NamedPipeClient),
} }
const BUFFER_LEN: usize = 1024 * 10; const BUFFER_LEN: usize = 1024 * 10;
@ -90,7 +85,13 @@ impl Bearer {
Ok((Self::Tcp(stream), addr)) Ok((Self::Tcp(stream), addr))
} }
#[cfg(not(target_os = "windows"))] #[cfg(unix)]
pub async fn connect_unix(path: impl AsRef<std::path::Path>) -> Result<Self, tokio::io::Error> {
let stream = UnixStream::connect(path).await?;
Ok(Self::Unix(stream))
}
#[cfg(unix)]
pub async fn accept_unix( pub async fn accept_unix(
listener: &UnixListener, listener: &UnixListener,
) -> tokio::io::Result<(Self, tokio::net::unix::SocketAddr)> { ) -> tokio::io::Result<(Self, tokio::net::unix::SocketAddr)> {
@ -99,53 +100,60 @@ impl Bearer {
} }
#[cfg(windows)] #[cfg(windows)]
pub async fn connect_named_pipe(pipe_name: impl AsRef<std::ffi::OsStr>) -> Result<Self, tokio::io::Error>{ pub async fn connect_named_pipe(
pipe_name: impl AsRef<std::ffi::OsStr>,
) -> Result<Self, tokio::io::Error> {
// TODO: revisit if busy wait logic is required
let client = loop { let client = loop {
match tokio::net::windows::named_pipe::ClientOptions::new().open(&pipe_name) { match tokio::net::windows::named_pipe::ClientOptions::new().open(&pipe_name) {
Ok(client) => break client, Ok(client) => break client,
Err(e) if e.raw_os_error() == Some(windows_sys::Win32::Foundation::ERROR_PIPE_BUSY as i32) => (), Err(e)
if e.raw_os_error()
== Some(windows_sys::Win32::Foundation::ERROR_PIPE_BUSY as i32) =>
{
()
}
Err(e) => return Err(e), Err(e) => return Err(e),
} }
tokio::time::sleep(std::time::Duration::from_millis(50)).await; tokio::time::sleep(std::time::Duration::from_millis(50)).await;
}; };
Ok(Self::NamedPipe(client))
}
#[cfg(not(target_os = "windows"))] Ok(Self::NamedPipe(client))
pub async fn connect_unix(path: impl AsRef<std::path::Path>) -> Result<Self, tokio::io::Error> {
let stream = UnixStream::connect(path).await?;
Ok(Self::Unix(stream))
} }
pub async fn readable(&mut self) -> tokio::io::Result<()> { pub async fn readable(&mut self) -> tokio::io::Result<()> {
match self { match self {
Bearer::Tcp(x) => x.readable().await, Bearer::Tcp(x) => x.readable().await,
#[cfg(not(target_os = "windows"))]
#[cfg(unix)]
Bearer::Unix(x) => x.readable().await, Bearer::Unix(x) => x.readable().await,
#[cfg(target_os = "windows")] #[cfg(windows)]
Bearer::NamedPipe(x) => x.readable().await Bearer::NamedPipe(x) => x.readable().await,
} }
} }
fn try_read(&mut self, buf: &mut [u8]) -> tokio::io::Result<usize> { fn try_read(&mut self, buf: &mut [u8]) -> tokio::io::Result<usize> {
match self { match self {
Bearer::Tcp(x) => x.try_read(buf), Bearer::Tcp(x) => x.try_read(buf),
#[cfg(not(target_os = "windows"))]
#[cfg(unix)]
Bearer::Unix(x) => x.try_read(buf), Bearer::Unix(x) => x.try_read(buf),
#[cfg(target_os = "windows")]
Bearer::NamedPipe(x) => x.try_read(buf) #[cfg(windows)]
Bearer::NamedPipe(x) => x.try_read(buf),
} }
} }
async fn write_all(&mut self, buf: &[u8]) -> tokio::io::Result<()> { async fn write_all(&mut self, buf: &[u8]) -> tokio::io::Result<()> {
match self { match self {
Bearer::Tcp(x) => x.write_all(buf).await, Bearer::Tcp(x) => x.write_all(buf).await,
#[cfg(not(target_os = "windows"))]
#[cfg(unix)]
Bearer::Unix(x) => x.write_all(buf).await, Bearer::Unix(x) => x.write_all(buf).await,
#[cfg(target_os = "windows")]
#[cfg(windows)]
Bearer::NamedPipe(x) => x.write_all(buf).await, Bearer::NamedPipe(x) => x.write_all(buf).await,
} }
} }
@ -153,9 +161,11 @@ impl Bearer {
async fn flush(&mut self) -> tokio::io::Result<()> { async fn flush(&mut self) -> tokio::io::Result<()> {
match self { match self {
Bearer::Tcp(x) => x.flush().await, Bearer::Tcp(x) => x.flush().await,
#[cfg(not(target_os = "windows"))]
#[cfg(unix)]
Bearer::Unix(x) => x.flush().await, Bearer::Unix(x) => x.flush().await,
#[cfg(target_os = "windows")]
#[cfg(windows)]
Bearer::NamedPipe(x) => x.flush().await, Bearer::NamedPipe(x) => x.flush().await,
} }
} }
@ -203,7 +213,7 @@ impl SegmentBuffer {
let remaining = required - self.1.len(); let remaining = required - self.1.len();
let mut buf = vec![0u8; remaining]; let mut buf = vec![0u8; remaining];
match self.0.try_read(&mut buf) { match self.0.try_read(&mut buf) {
Ok(0) => { Ok(0) => {
error!("empty bearer"); error!("empty bearer");