Skip to content

Commit f2659bd

Browse files
feat(client): add HttpConnector::set_mark for SO_MARK
1 parent 56cdd31 commit f2659bd

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

src/client/legacy/connect/http.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ struct Config {
8989
))]
9090
interface: Option<std::ffi::CString>,
9191
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
92+
mark: Option<u32>,
93+
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
9294
tcp_user_timeout: Option<Duration>,
9395
}
9496

@@ -246,6 +248,8 @@ impl<R> HttpConnector<R> {
246248
))]
247249
interface: None,
248250
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
251+
mark: None,
252+
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
249253
tcp_user_timeout: None,
250254
}),
251255
resolver,
@@ -422,6 +426,26 @@ impl<R> HttpConnector<R> {
422426
self
423427
}
424428

429+
/// Sets the mark on sockets produced by this connector.
430+
///
431+
/// This sets the `SO_MARK` option on the socket (see [`man 7 socket`]
432+
/// for details). The mark can be matched by policy routing rules and
433+
/// packet filters.
434+
///
435+
/// Setting the mark requires the binary to either have `CAP_NET_ADMIN`
436+
/// or to be run as root.
437+
///
438+
/// This function is only available on the following operating systems:
439+
/// - Linux, including Android
440+
/// - Fuchsia
441+
///
442+
/// [`man 7 socket`]: https://man7.org/linux/man-pages/man7/socket.7.html
443+
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
444+
#[inline]
445+
pub fn set_mark(&mut self, mark: Option<u32>) {
446+
self.config_mut().mark = mark;
447+
}
448+
425449
/// Sets the value of the TCP_USER_TIMEOUT option on the socket.
426450
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
427451
#[inline]
@@ -894,6 +918,14 @@ fn connect(
894918
}
895919
}
896920

921+
// On Linux-like systems, set the packet mark using `SO_MARK`.
922+
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
923+
if let Some(mark) = config.mark {
924+
socket
925+
.set_mark(mark)
926+
.map_err(ConnectError::m("tcp set_mark error"))?;
927+
}
928+
897929
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
898930
if let Some(tcp_user_timeout) = &config.tcp_user_timeout {
899931
if let Err(e) = socket.set_tcp_user_timeout(Some(*tcp_user_timeout)) {
@@ -1303,6 +1335,12 @@ mod tests {
13031335
target_os = "fuchsia",
13041336
target_os = "linux"
13051337
))]
1338+
mark: None,
1339+
#[cfg(any(
1340+
target_os = "android",
1341+
target_os = "fuchsia",
1342+
target_os = "linux"
1343+
))]
13061344
tcp_user_timeout: None,
13071345
};
13081346
let connecting_tcp = ConnectingTcp::new(dns::SocketAddrs::new(addrs), &cfg);

0 commit comments

Comments
 (0)