termivar_proxy/lib.rs
1//! Experimental fixed-upstream TCP relay boundary for Termivar.
2//!
3//! ## Runtime scope
4//!
5//! - **Build:** separate workspace crate (`termivar-proxy`).
6//! - **Execution:** explicit optional CLI adapter (`termivar-cli/proxy-adapter`).
7//! - **Default `termivar scan`:** no.
8//! - **Support:** experimental fixed-upstream bidirectional TCP relay — not a TLS
9//! MITM implementation and not an HTTP interceptor (see [`relay`]).
10//!
11//! See `docs/internals/runtime-map.md`.
12//!
13//! [`ProxyServer`] is the process-level adapter around
14//! [`FixedUpstreamTcpRelay`]. Both listener and upstream are explicit typed
15//! socket addresses. TLS and HTTP interception are not implemented; use only
16//! for explicitly authorized traffic.
17
18#![forbid(unsafe_code)]
19#![deny(rustdoc::broken_intra_doc_links)]
20
21use std::net::SocketAddr;
22
23pub mod relay;
24
25pub use relay::FixedUpstreamTcpRelay;
26
27type Result<T> = std::io::Result<T>;
28
29/// Configures the listening address for the experimental proxy adapter.
30pub struct ProxyServer {
31 listen_addr: SocketAddr,
32 upstream_addr: SocketAddr,
33}
34
35impl ProxyServer {
36 /// Creates a relay server with explicit listener and upstream addresses.
37 #[must_use]
38 pub fn new(listen_addr: SocketAddr, upstream_addr: SocketAddr) -> Self {
39 Self {
40 listen_addr,
41 upstream_addr,
42 }
43 }
44
45 /// Binds the listener and starts relaying to the configured upstream.
46 pub async fn start(&self) -> Result<()> {
47 FixedUpstreamTcpRelay::bind(self.listen_addr, self.upstream_addr)
48 .await?
49 .run()
50 .await
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn constructor_preserves_explicit_ipv6_endpoints() {
60 let listen_addr = "[::1]:8081".parse().unwrap();
61 let upstream_addr = "[::1]:9081".parse().unwrap();
62 let server = ProxyServer::new(listen_addr, upstream_addr);
63 assert_eq!(server.listen_addr, listen_addr);
64 assert_eq!(server.upstream_addr, upstream_addr);
65 }
66}