openssh/
port_forwarding.rs
1#[cfg(feature = "native-mux")]
2use super::native_mux_impl;
3
4#[cfg(feature = "process-mux")]
5use std::ffi::OsStr;
6
7use std::borrow::Cow;
8use std::fmt;
9use std::net::{self, SocketAddr};
10use std::path::{Path, PathBuf};
11
12#[derive(Copy, Clone, Debug, Eq, PartialEq)]
14pub enum ForwardType {
15 Local,
17
18 Remote,
20}
21
22#[cfg(feature = "native-mux")]
23impl From<ForwardType> for native_mux_impl::ForwardType {
24 fn from(fwd_type: ForwardType) -> Self {
25 use native_mux_impl::ForwardType::*;
26
27 match fwd_type {
28 ForwardType::Local => Local,
29 ForwardType::Remote => Remote,
30 }
31 }
32}
33
34#[derive(Clone, Debug, Eq, PartialEq, Hash)]
36pub enum Socket<'a> {
37 #[cfg(unix)]
39 #[cfg_attr(docsrs, doc(cfg(unix)))]
40 UnixSocket {
41 path: Cow<'a, Path>,
43 },
44
45 TcpSocket {
47 host: Cow<'a, str>,
49 port: u16,
51 },
52}
53
54impl From<SocketAddr> for Socket<'static> {
55 fn from(addr: SocketAddr) -> Self {
56 Socket::TcpSocket {
57 host: addr.ip().to_string().into(),
58 port: addr.port(),
59 }
60 }
61}
62
63macro_rules! impl_from_addr {
64 ($ip:ty) => {
65 impl From<($ip, u16)> for Socket<'static> {
66 fn from((ip, port): ($ip, u16)) -> Self {
67 SocketAddr::new(ip.into(), port).into()
68 }
69 }
70 };
71}
72
73impl_from_addr!(net::IpAddr);
74impl_from_addr!(net::Ipv4Addr);
75impl_from_addr!(net::Ipv6Addr);
76
77impl<'a> From<Cow<'a, Path>> for Socket<'a> {
78 fn from(path: Cow<'a, Path>) -> Self {
79 Socket::UnixSocket { path }
80 }
81}
82
83impl<'a> From<&'a Path> for Socket<'a> {
84 fn from(path: &'a Path) -> Self {
85 Socket::UnixSocket {
86 path: Cow::Borrowed(path),
87 }
88 }
89}
90
91impl From<PathBuf> for Socket<'static> {
92 fn from(path: PathBuf) -> Self {
93 Socket::UnixSocket {
94 path: Cow::Owned(path),
95 }
96 }
97}
98
99impl From<Box<Path>> for Socket<'static> {
100 fn from(path: Box<Path>) -> Self {
101 Socket::UnixSocket {
102 path: Cow::Owned(path.into()),
103 }
104 }
105}
106
107impl Socket<'_> {
108 pub fn new<'a, S>(host: S, port: u16) -> Socket<'a>
110 where
111 S: Into<Cow<'a, str>>,
112 {
113 Socket::TcpSocket {
114 host: host.into(),
115 port,
116 }
117 }
118
119 #[cfg(feature = "process-mux")]
120 pub(crate) fn as_os_str(&self) -> Cow<'_, OsStr> {
121 match self {
122 #[cfg(unix)]
123 Socket::UnixSocket { path } => Cow::Borrowed(path.as_os_str()),
124 Socket::TcpSocket { host, port } => Cow::Owned(format!("{host}:{port}").into()),
125 }
126 }
127}
128
129#[cfg(feature = "native-mux")]
130impl<'a> From<Socket<'a>> for native_mux_impl::Socket<'a> {
131 fn from(socket: Socket<'a>) -> Self {
132 use native_mux_impl::Socket::*;
133
134 match socket {
135 #[cfg(unix)]
136 Socket::UnixSocket { path } => UnixSocket { path },
137 Socket::TcpSocket { host, port } => TcpSocket {
138 host,
139 port: port as u32,
140 },
141 }
142 }
143}
144
145impl<'a> fmt::Display for Socket<'a> {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 match self {
148 #[cfg(unix)]
149 Socket::UnixSocket { path } => {
150 write!(f, "{}", path.display())
151 }
152 Socket::TcpSocket { host, port } => write!(f, "{host}:{port}"),
153 }
154 }
155}