Add Windows named-pipe local control
This commit is contained in:
parent
ce3e029b3d
commit
3c84713472
9 changed files with 338 additions and 72 deletions
|
|
@ -2,6 +2,7 @@ pub mod backup;
|
|||
mod daemon;
|
||||
pub mod doctor;
|
||||
mod local_control;
|
||||
mod local_transport;
|
||||
mod peer_client;
|
||||
mod peer_control;
|
||||
mod resource_contracts;
|
||||
|
|
@ -68,6 +69,7 @@ use geth_types::{
|
|||
use iroh::protocol::ProtocolHandler;
|
||||
use iroh_docs::api::protocol::{AddrInfoOptions, ShareMode};
|
||||
pub use local_control::handle_request_async;
|
||||
use local_transport::LocalStream;
|
||||
use peer_client::{request_overlay_wire, request_peer_control, request_pipe_wire};
|
||||
use peer_control::{
|
||||
IrohAlpnRoute, PeerControlCaller, authenticate_peer_control_caller, classify_iroh_alpn,
|
||||
|
|
@ -85,7 +87,9 @@ use sync::{
|
|||
KvDocsState, load_live_sync_cursor, store_live_sync_cursor, sync_now, sync_status_local,
|
||||
};
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||
use tokio::net::{TcpListener, TcpStream, UnixListener, UnixStream};
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
#[cfg(unix)]
|
||||
use tokio::net::{UnixListener, UnixStream};
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
use tun_rs::{DeviceBuilder, Layer};
|
||||
use wire::{
|
||||
|
|
@ -429,7 +433,7 @@ pub async fn send_control(
|
|||
paths: &GethPaths,
|
||||
request: ControlRequest,
|
||||
) -> Result<ControlResponse, NodeError> {
|
||||
let mut stream = UnixStream::connect(paths.socket_path()).await?;
|
||||
let mut stream = local_transport::connect(paths).await?;
|
||||
stream
|
||||
.write_all(geth_control::encode_request(&request)?.as_bytes())
|
||||
.await?;
|
||||
|
|
@ -445,7 +449,7 @@ pub async fn stream_ssh_proxy(
|
|||
peer_node: String,
|
||||
bearer_secret: Option<String>,
|
||||
) -> Result<(), NodeError> {
|
||||
let mut stream = UnixStream::connect(paths.socket_path()).await?;
|
||||
let mut stream = local_transport::connect(paths).await?;
|
||||
stream
|
||||
.write_all(
|
||||
geth_control::encode_request(&ControlRequest::SshProxyStream {
|
||||
|
|
@ -461,7 +465,7 @@ pub async fn stream_ssh_proxy(
|
|||
match geth_control::decode_response(&line)? {
|
||||
ControlResponse::SshProxyConnected { allowed: true, .. } => {
|
||||
let stream = reader.into_inner();
|
||||
let (mut local_read, mut local_write) = stream.into_split();
|
||||
let (mut local_read, mut local_write) = tokio::io::split(stream);
|
||||
let mut stdin = tokio::io::stdin();
|
||||
let mut stdout = tokio::io::stdout();
|
||||
let upload = async {
|
||||
|
|
@ -526,7 +530,7 @@ async fn stream_pipe_tcp(
|
|||
bearer_secret: Option<String>,
|
||||
client: TcpStream,
|
||||
) -> Result<(), NodeError> {
|
||||
let mut stream = UnixStream::connect(paths.socket_path()).await?;
|
||||
let mut stream = local_transport::connect(paths).await?;
|
||||
stream
|
||||
.write_all(
|
||||
geth_control::encode_request(&ControlRequest::PipeTcpStream {
|
||||
|
|
@ -543,7 +547,7 @@ async fn stream_pipe_tcp(
|
|||
match geth_control::decode_response(&line)? {
|
||||
ControlResponse::PipeRemoteConnected { allowed: true, .. } => {
|
||||
let daemon_stream = reader.into_inner();
|
||||
let (mut daemon_read, mut daemon_write) = daemon_stream.into_split();
|
||||
let (mut daemon_read, mut daemon_write) = tokio::io::split(daemon_stream);
|
||||
let (mut client_read, mut client_write) = client.into_split();
|
||||
let upload = async {
|
||||
tokio::io::copy(&mut client_read, &mut daemon_write).await?;
|
||||
|
|
@ -568,6 +572,7 @@ async fn stream_pipe_tcp(
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub async fn run_unix_forward(
|
||||
paths: &GethPaths,
|
||||
listen_path: PathBuf,
|
||||
|
|
@ -605,6 +610,20 @@ pub async fn run_unix_forward(
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
pub async fn run_unix_forward(
|
||||
_paths: &GethPaths,
|
||||
_listen_path: PathBuf,
|
||||
_peer_node: String,
|
||||
_target_path: PathBuf,
|
||||
_bearer_secret: Option<String>,
|
||||
) -> Result<(), NodeError> {
|
||||
Err(NodeError::UnsupportedPlatform(
|
||||
geth_pipe::unix_forward_unsupported_message().to_owned(),
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
async fn stream_pipe_unix(
|
||||
paths: &GethPaths,
|
||||
peer_node: String,
|
||||
|
|
@ -612,7 +631,7 @@ async fn stream_pipe_unix(
|
|||
bearer_secret: Option<String>,
|
||||
client: UnixStream,
|
||||
) -> Result<(), NodeError> {
|
||||
let mut stream = UnixStream::connect(paths.socket_path()).await?;
|
||||
let mut stream = local_transport::connect(paths).await?;
|
||||
stream
|
||||
.write_all(
|
||||
geth_control::encode_request(&ControlRequest::PipeUnixStream {
|
||||
|
|
@ -629,7 +648,7 @@ async fn stream_pipe_unix(
|
|||
match geth_control::decode_response(&line)? {
|
||||
ControlResponse::PipeRemoteConnected { allowed: true, .. } => {
|
||||
let daemon_stream = reader.into_inner();
|
||||
let (mut daemon_read, mut daemon_write) = daemon_stream.into_split();
|
||||
let (mut daemon_read, mut daemon_write) = tokio::io::split(daemon_stream);
|
||||
let (mut client_read, mut client_write) = client.into_split();
|
||||
let upload = async {
|
||||
tokio::io::copy(&mut client_read, &mut daemon_write).await?;
|
||||
|
|
@ -654,7 +673,7 @@ async fn stream_pipe_unix(
|
|||
}
|
||||
}
|
||||
|
||||
async fn handle_stream(node: LocalNode, stream: UnixStream) -> Result<(), NodeError> {
|
||||
async fn handle_stream(node: LocalNode, stream: LocalStream) -> Result<(), NodeError> {
|
||||
let mut reader = BufReader::new(stream);
|
||||
let mut line = String::new();
|
||||
reader.read_line(&mut line).await?;
|
||||
|
|
@ -737,6 +756,7 @@ async fn handle_stream(node: LocalNode, stream: UnixStream) -> Result<(), NodeEr
|
|||
}
|
||||
return result;
|
||||
}
|
||||
#[cfg(unix)]
|
||||
if let ControlRequest::PipeUnixStream {
|
||||
node: peer_node,
|
||||
target_path,
|
||||
|
|
@ -2661,7 +2681,7 @@ async fn handle_local_pipe_tcp_stream(
|
|||
peer_node: &str,
|
||||
target_addr: String,
|
||||
bearer_secret: Option<String>,
|
||||
local_stream: UnixStream,
|
||||
local_stream: LocalStream,
|
||||
) -> Result<(), NodeError> {
|
||||
geth_pipe::validate_tcp_forward_target_addr(&target_addr)?;
|
||||
let store = Store::open(&node.paths.metadata_db())?;
|
||||
|
|
@ -2753,7 +2773,7 @@ async fn handle_local_pipe_tcp_stream(
|
|||
let ControlResponse::PipeRemoteConnected { allowed: true, .. } = local_response else {
|
||||
return Ok(());
|
||||
};
|
||||
let (mut local_read, mut local_write) = local_stream.into_split();
|
||||
let (mut local_read, mut local_write) = tokio::io::split(local_stream);
|
||||
let upload = async {
|
||||
tokio::io::copy(&mut local_read, &mut remote_send)
|
||||
.await
|
||||
|
|
@ -2773,12 +2793,13 @@ async fn handle_local_pipe_tcp_stream(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
async fn handle_local_pipe_unix_stream(
|
||||
node: LocalNode,
|
||||
peer_node: &str,
|
||||
target_path: PathBuf,
|
||||
bearer_secret: Option<String>,
|
||||
local_stream: UnixStream,
|
||||
local_stream: LocalStream,
|
||||
) -> Result<(), NodeError> {
|
||||
let target_path = geth_pipe::validate_unix_forward_path(&target_path)?;
|
||||
let target_display = target_path.display().to_string();
|
||||
|
|
@ -2871,7 +2892,7 @@ async fn handle_local_pipe_unix_stream(
|
|||
let ControlResponse::PipeRemoteConnected { allowed: true, .. } = local_response else {
|
||||
return Ok(());
|
||||
};
|
||||
let (mut local_read, mut local_write) = local_stream.into_split();
|
||||
let (mut local_read, mut local_write) = tokio::io::split(local_stream);
|
||||
let upload = async {
|
||||
tokio::io::copy(&mut local_read, &mut remote_send)
|
||||
.await
|
||||
|
|
@ -2988,7 +3009,7 @@ async fn handle_local_ssh_proxy_stream(
|
|||
node: LocalNode,
|
||||
peer_node: &str,
|
||||
bearer_secret: Option<String>,
|
||||
local_stream: UnixStream,
|
||||
local_stream: LocalStream,
|
||||
) -> Result<(), NodeError> {
|
||||
let store = Store::open(&node.paths.metadata_db())?;
|
||||
let stored = store
|
||||
|
|
@ -3076,7 +3097,7 @@ async fn handle_local_ssh_proxy_stream(
|
|||
let ControlResponse::SshProxyConnected { allowed: true, .. } = local_response else {
|
||||
return Ok(());
|
||||
};
|
||||
let (mut local_read, mut local_write) = local_stream.into_split();
|
||||
let (mut local_read, mut local_write) = tokio::io::split(local_stream);
|
||||
let upload = async {
|
||||
tokio::io::copy(&mut local_read, &mut remote_send)
|
||||
.await
|
||||
|
|
@ -5519,6 +5540,7 @@ async fn handle_pipe_tcp_wire_connection(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
async fn handle_pipe_unix_wire_connection(
|
||||
node: LocalNode,
|
||||
remote_endpoint_id: &str,
|
||||
|
|
@ -5620,6 +5642,24 @@ async fn handle_pipe_unix_wire_connection(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
async fn handle_pipe_unix_wire_connection(
|
||||
_node: LocalNode,
|
||||
_remote_endpoint_id: &str,
|
||||
_request: PipeUnixConnectWire,
|
||||
mut send: iroh::endpoint::SendStream,
|
||||
_recv: iroh::endpoint::RecvStream,
|
||||
) -> Result<(), NodeError> {
|
||||
let response = PipeWireResponse::Error {
|
||||
message: geth_pipe::unix_forward_unsupported_message().to_owned(),
|
||||
};
|
||||
send.write_all(geth_control::encode_pipe_wire_response(&response)?.as_bytes())
|
||||
.await
|
||||
.map_err(|error| NodeError::IrohPeer(error.to_string()))?;
|
||||
send.finish()
|
||||
.map_err(|error| NodeError::IrohPeer(error.to_string()))
|
||||
}
|
||||
|
||||
fn peer_gossip_endpoint_id(
|
||||
node: &LocalNode,
|
||||
peer_node: &str,
|
||||
|
|
@ -12926,7 +12966,7 @@ mod tests {
|
|||
socket.write_all(b"pong").await.expect("write tcp echo");
|
||||
socket.shutdown().await.expect("shutdown tcp echo");
|
||||
});
|
||||
let (forward_client, forward_daemon) = UnixStream::pair().expect("unix stream pair");
|
||||
let (forward_client, forward_daemon) = tokio::io::duplex(64 * 1024);
|
||||
let right_node_id = right_card.node_id.to_string();
|
||||
let left_for_forward = left.clone();
|
||||
let tcp_target_for_forward = tcp_target.clone();
|
||||
|
|
@ -12936,7 +12976,7 @@ mod tests {
|
|||
&right_node_id,
|
||||
tcp_target_for_forward,
|
||||
None,
|
||||
forward_daemon,
|
||||
Box::new(forward_daemon),
|
||||
)
|
||||
.await
|
||||
});
|
||||
|
|
@ -12958,7 +12998,7 @@ mod tests {
|
|||
other => panic!("unexpected pipe TCP stream response: {other:?}"),
|
||||
}
|
||||
let stream = forward_reader.into_inner();
|
||||
let (mut forward_read, mut forward_write) = stream.into_split();
|
||||
let (mut forward_read, mut forward_write) = tokio::io::split(stream);
|
||||
forward_write
|
||||
.write_all(b"ping")
|
||||
.await
|
||||
|
|
@ -13015,7 +13055,7 @@ mod tests {
|
|||
&right_node_id,
|
||||
unix_target_for_forward,
|
||||
None,
|
||||
unix_forward_daemon,
|
||||
Box::new(unix_forward_daemon),
|
||||
)
|
||||
.await
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue