diff --git a/src/client.rs b/src/client.rs index cb8fa7b..812a21a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -8,7 +8,7 @@ use tracing::{error, info, info_span, warn, Instrument}; use uuid::Uuid; use crate::auth::Authenticator; -use crate::shared::{ClientMessage, Delimited, ServerMessage, CONTROL_PORT, NETWORK_TIMEOUT}; +use crate::shared::{ClientMessage, Delimited, ServerMessage, NETWORK_TIMEOUT}; /// State structure for the client. pub struct Client { @@ -29,6 +29,9 @@ pub struct Client { /// Optional secret used to authenticate clients. auth: Option, + + /// TCP port used for control connections with the server. + control_port: u16, } impl Client { @@ -39,8 +42,9 @@ impl Client { to: &str, port: u16, secret: Option<&str>, + control_port: u16, ) -> Result { - let mut stream = Delimited::new(connect_with_timeout(to, CONTROL_PORT).await?); + let mut stream = Delimited::new(connect_with_timeout(to, control_port).await?); let auth = secret.map(Authenticator::new); if let Some(auth) = &auth { auth.client_handshake(&mut stream).await?; @@ -66,6 +70,7 @@ impl Client { local_port, remote_port, auth, + control_port, }) } @@ -104,7 +109,7 @@ impl Client { async fn handle_connection(&self, id: Uuid) -> Result<()> { let mut remote_conn = - Delimited::new(connect_with_timeout(&self.to[..], CONTROL_PORT).await?); + Delimited::new(connect_with_timeout(&self.to[..], self.control_port).await?); if let Some(auth) = &self.auth { auth.client_handshake(&mut remote_conn).await?; } diff --git a/src/main.rs b/src/main.rs index 71429c4..b498675 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,10 @@ enum Command { /// Optional secret for authentication. #[clap(short, long, env = "BORE_SECRET", hide_env_values = true)] secret: Option, + + /// TCP port used for control connections with the server. + #[clap(long, default_value_t = 7835, env = "BORE_CONTROL_PORT")] + control_port: u16, }, /// Runs the remote proxy server. @@ -57,6 +61,10 @@ enum Command { /// IP address where tunnels will listen on, defaults to --bind-addr. #[clap(long)] bind_tunnels: Option, + + /// TCP port used for control connections with clients. + #[clap(long, default_value_t = 7835, env = "BORE_CONTROL_PORT")] + control_port: u16, }, } @@ -69,8 +77,9 @@ async fn run(command: Command) -> Result<()> { to, port, secret, + control_port, } => { - let client = Client::new(&local_host, local_port, &to, port, secret.as_deref()).await?; + let client = Client::new(&local_host, local_port, &to, port, secret.as_deref(), control_port).await?; client.listen().await?; } Command::Server { @@ -79,6 +88,7 @@ async fn run(command: Command) -> Result<()> { secret, bind_addr, bind_tunnels, + control_port, } => { let port_range = min_port..=max_port; if port_range.is_empty() { @@ -89,6 +99,7 @@ async fn run(command: Command) -> Result<()> { let mut server = Server::new(port_range, secret.as_deref()); server.set_bind_addr(bind_addr); server.set_bind_tunnels(bind_tunnels.unwrap_or(bind_addr)); + server.set_control_port(control_port); server.listen().await?; } } diff --git a/src/server.rs b/src/server.rs index f47d714..7421517 100644 --- a/src/server.rs +++ b/src/server.rs @@ -12,7 +12,7 @@ use tracing::{info, info_span, warn, Instrument}; use uuid::Uuid; use crate::auth::Authenticator; -use crate::shared::{ClientMessage, Delimited, ServerMessage, CONTROL_PORT}; +use crate::shared::{ClientMessage, Delimited, ServerMessage, DEFAULT_CONTROL_PORT}; /// State structure for the server. pub struct Server { @@ -30,6 +30,9 @@ pub struct Server { /// IP address where tunnels will listen on. bind_tunnels: IpAddr, + + /// TCP port used for control connections with clients. + control_port: u16, } impl Server { @@ -42,6 +45,7 @@ impl Server { auth: secret.map(Authenticator::new), bind_addr: IpAddr::V4(Ipv4Addr::UNSPECIFIED), bind_tunnels: IpAddr::V4(Ipv4Addr::UNSPECIFIED), + control_port: DEFAULT_CONTROL_PORT, } } @@ -55,11 +59,16 @@ impl Server { self.bind_tunnels = bind_tunnels; } + /// Set the TCP port used for control connections with clients. + pub fn set_control_port(&mut self, control_port: u16) { + self.control_port = control_port; + } + /// Start the server, listening for new connections. pub async fn listen(self) -> Result<()> { let this = Arc::new(self); - let listener = TcpListener::bind((this.bind_addr, CONTROL_PORT)).await?; - info!(addr = ?this.bind_addr, "server listening"); + let listener = TcpListener::bind((this.bind_addr, this.control_port)).await?; + info!(addr = ?this.bind_addr, port = this.control_port, "server listening"); loop { let (stream, addr) = listener.accept().await?; diff --git a/src/shared.rs b/src/shared.rs index d9c5d3b..79225db 100644 --- a/src/shared.rs +++ b/src/shared.rs @@ -11,8 +11,8 @@ use tokio_util::codec::{AnyDelimiterCodec, Framed, FramedParts}; use tracing::trace; use uuid::Uuid; -/// TCP port used for control connections with the server. -pub const CONTROL_PORT: u16 = 7835; +/// Default TCP port used for control connections with the server. +pub const DEFAULT_CONTROL_PORT: u16 = 7835; /// Maximum byte length for a JSON frame in the stream. pub const MAX_FRAME_LENGTH: usize = 256;