Make guest side forwarder agent buildable
Bug: 340126051
Test: cd build/debian/forwarder_guest && cargo build
Change-Id: I13eec2c3daf59412de679258142de66f0f60002d
diff --git a/build/debian/forwarder_guest/Cargo.toml b/build/debian/forwarder_guest/Cargo.toml
new file mode 100644
index 0000000..e70dcd4
--- /dev/null
+++ b/build/debian/forwarder_guest/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "forwarder_guest"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+clap = { version = "4.5.19", features = ["derive"] }
+forwarder = { path = "../../../libs/libforwarder" }
+poll_token_derive = "0.1.0"
+remain = "0.2.14"
+vmm-sys-util = "0.12.1"
diff --git a/build/debian/forwarder_guest/src/main.rs b/build/debian/forwarder_guest/src/main.rs
index 1bcbed4..6ebd4ef 100644
--- a/build/debian/forwarder_guest/src/main.rs
+++ b/build/debian/forwarder_guest/src/main.rs
@@ -15,34 +15,26 @@
// Copied from ChromiumOS with relicensing:
// src/platform2/vm_tools/chunnel/src/bin/chunnel.rs
-use std::env;
+//! Guest-side stream socket forwarder
+
use std::fmt;
-use std::process;
use std::result;
-use chunnel::forwarder::{ForwarderError, ForwarderSession};
-use chunnel::stream::{StreamSocket, StreamSocketError};
-use getopts::Options;
-use libchromeos::deprecated::{PollContext, PollToken};
-use libchromeos::panic_handler::install_memfd_handler;
-use libchromeos::signal::block_signal;
-use libchromeos::syslog;
-use log::warn;
-use nix::sys::signal::Signal;
-
-// Program name.
-const IDENT: &str = "chunnel";
+use clap::Parser;
+use forwarder::forwarder::{ForwarderError, ForwarderSession};
+use forwarder::stream::{StreamSocket, StreamSocketError};
+use poll_token_derive::PollToken;
+use vmm_sys_util::poll::{PollContext, PollToken};
#[remain::sorted]
#[derive(Debug)]
enum Error {
- BlockSigpipe(nix::Error),
ConnectSocket(StreamSocketError),
Forward(ForwarderError),
- PollContextDelete(nix::Error),
- PollContextNew(nix::Error),
- PollWait(nix::Error),
- Syslog(libchromeos::syslog::Error),
+ PollContextAdd(vmm_sys_util::errno::Error),
+ PollContextDelete(vmm_sys_util::errno::Error),
+ PollContextNew(vmm_sys_util::errno::Error),
+ PollWait(vmm_sys_util::errno::Error),
}
type Result<T> = result::Result<T, Error>;
@@ -54,35 +46,25 @@
#[remain::sorted]
match self {
- BlockSigpipe(e) => write!(f, "failed to block SIGPIPE: {}", e),
- ConnectSocket(e) => write!(f, "failed to connnect socket: {}", e),
+ ConnectSocket(e) => write!(f, "failed to connect socket: {}", e),
Forward(e) => write!(f, "failed to forward traffic: {}", e),
+ PollContextAdd(e) => write!(f, "failed to add fd to poll context: {}", e),
PollContextDelete(e) => write!(f, "failed to delete fd from poll context: {}", e),
PollContextNew(e) => write!(f, "failed to create poll context: {}", e),
PollWait(e) => write!(f, "failed to wait for poll: {}", e),
- Syslog(e) => write!(f, "failed to initialize syslog: {}", e),
}
}
}
-fn print_usage(program: &str, opts: &Options) {
- let brief = format!("Usage: {} [options]", program);
- print!("{}", opts.usage(&brief));
-}
-
fn run_forwarder(local_stream: StreamSocket, remote_stream: StreamSocket) -> Result<()> {
- block_signal(Signal::SIGPIPE).map_err(Error::BlockSigpipe)?;
-
#[derive(PollToken)]
enum Token {
LocalStreamReadable,
RemoteStreamReadable,
}
- let poll_ctx: PollContext<Token> = PollContext::build_with(&[
- (&local_stream, Token::LocalStreamReadable),
- (&remote_stream, Token::RemoteStreamReadable),
- ])
- .map_err(Error::PollContextNew)?;
+ let poll_ctx: PollContext<Token> = PollContext::new().map_err(Error::PollContextNew)?;
+ poll_ctx.add(&local_stream, Token::LocalStreamReadable).map_err(Error::PollContextAdd)?;
+ poll_ctx.add(&remote_stream, Token::RemoteStreamReadable).map_err(Error::PollContextAdd)?;
let mut forwarder = ForwarderSession::new(local_stream, remote_stream);
@@ -115,69 +97,27 @@
}
}
+#[derive(Parser)]
+/// Flags for running command
+pub struct Args {
+ /// Local socket address
+ #[arg(long)]
+ #[arg(alias = "local")]
+ local_sockaddr: String,
+
+ /// Remote socket address
+ #[arg(long)]
+ #[arg(alias = "remote")]
+ remote_sockaddr: String,
+}
+
+// TODO(b/370897694): Support forwarding for datagram socket
fn main() -> Result<()> {
- install_memfd_handler();
- let args: Vec<String> = env::args().collect();
- let program = args[0].clone();
+ let args = Args::parse();
- let mut opts = Options::new();
- opts.optflag("h", "help", "print this help menu");
- opts.reqopt("l", "local", "local socket to forward", "SOCKADDR");
- opts.reqopt("r", "remote", "remote socket to forward to", "SOCKADDR");
- opts.optopt("t", "type", "type of traffic to forward", "stream|datagram");
-
- let matches = match opts.parse(&args[1..]) {
- Ok(m) => m,
- Err(e) => {
- warn!("failed to parse arg: {}", e);
- print_usage(&program, &opts);
- process::exit(1);
- }
- };
- if matches.opt_present("h") {
- print_usage(&program, &opts);
- return Ok(());
- }
-
- syslog::init(IDENT.to_string(), false /* log_to_stderr */).map_err(Error::Syslog)?;
-
- let local_sockaddr = match matches.opt_str("l") {
- Some(sockaddr) => sockaddr,
- None => {
- warn!("local socket must be defined");
- print_usage(&program, &opts);
- process::exit(1);
- }
- };
-
- let remote_sockaddr = match matches.opt_str("r") {
- Some(sockaddr) => sockaddr,
- None => {
- warn!("remote socket must be defined");
- print_usage(&program, &opts);
- process::exit(1);
- }
- };
-
- // Default to "stream" if traffic type is not defined.
- let traffic_type = matches.opt_str("t");
- if let Some(t) = traffic_type {
- match t.as_ref() {
- "stream" => {}
- "datagram" => {
- warn!("datagram sockets are not yet supported");
- process::exit(1);
- }
- s => {
- warn!("not a valid type of traffic: {}", s);
- print_usage(&program, &opts);
- process::exit(1);
- }
- }
- }
-
- let local_stream = StreamSocket::connect(&local_sockaddr).map_err(Error::ConnectSocket)?;
- let remote_stream = StreamSocket::connect(&remote_sockaddr).map_err(Error::ConnectSocket)?;
+ let local_stream = StreamSocket::connect(&args.local_sockaddr).map_err(Error::ConnectSocket)?;
+ let remote_stream =
+ StreamSocket::connect(&args.remote_sockaddr).map_err(Error::ConnectSocket)?;
run_forwarder(local_stream, remote_stream)
}
diff --git a/libs/libforwarder/Cargo.toml b/libs/libforwarder/Cargo.toml
new file mode 100644
index 0000000..9f3f341
--- /dev/null
+++ b/libs/libforwarder/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "forwarder"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+libc = "0.2.159"
+remain = "0.2.14"
+vsock = "0.5.1"