Skip to content

Commit 49e78d6

Browse files
Add tun.unavailable_reason() (mitmproxy#199)
* Add tun.unavailable_reason() * [autofix.ci] apply automated fixes * make tun module public across all platforms * fixup * nits --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 0cc1a35 commit 49e78d6

File tree

7 files changed

+35
-6
lines changed

7 files changed

+35
-6
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mitmproxy-rs/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ boringtun = "0.6"
3030
tar = "0.4.43"
3131
console-subscriber = { version = "0.4.1", optional = true }
3232

33+
[target.'cfg(target_os = "linux")'.dependencies]
34+
nix = { version = "0.29.0", features = ["user"] }
3335

3436
[dev-dependencies]
3537
env_logger = "0.11"
@@ -40,4 +42,4 @@ tracing = ["console-subscriber"]
4042
[[test]]
4143
name = "test_task"
4244
path = "pytests/test_task.rs"
43-
harness = false
45+
harness = false

mitmproxy-rs/mitmproxy_rs/tun.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ from collections.abc import Awaitable, Callable
44
from typing import final
55
from . import Stream
66

7+
def unavailable_reason() -> str | None: ...
78
async def create_tun_interface(
89
handle_tcp_stream: Callable[[Stream], Awaitable[None]],
910
handle_udp_stream: Callable[[Stream], Awaitable[None]],

mitmproxy-rs/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ mod mitmproxy_rs {
6262
#[pymodule]
6363
mod tun {
6464
#[pymodule_export]
65-
use crate::server::{create_tun_interface, TunInterface};
65+
use crate::server::{create_tun_interface, unavailable_reason, TunInterface};
6666
}
6767

6868
#[pymodule]

mitmproxy-rs/src/server/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ mod udp;
55
mod wireguard;
66

77
pub use local_redirector::{start_local_redirector, LocalRedirector};
8-
pub use tun::{create_tun_interface, TunInterface};
8+
pub use tun::{create_tun_interface, unavailable_reason, TunInterface};
99
pub use udp::{start_udp_server, UdpServer};
1010
pub use wireguard::{start_wireguard_server, WireGuardServer};

mitmproxy-rs/src/server/tun.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use crate::server::base::Server;
22
use pyo3::prelude::*;
33

4+
#[cfg(target_os = "linux")]
5+
use nix::unistd;
6+
47
/// An open TUN interface.
58
///
69
/// A new tun interface can be created by calling `create_tun_interface`.
@@ -59,6 +62,22 @@ pub fn create_tun_interface(
5962
}
6063
#[cfg(not(target_os = "linux"))]
6164
Err(pyo3::exceptions::PyNotImplementedError::new_err(
62-
"TUN proxy mode is only available on Linux",
65+
unavailable_reason(),
6366
))
6467
}
68+
69+
/// Returns a `str` describing why tun mode is unavailable, or `None` if TUN mode is available.
70+
///
71+
/// Reasons for unavailability may be an unsupported platform, or missing privileges.
72+
#[pyfunction]
73+
pub fn unavailable_reason() -> Option<String> {
74+
#[cfg(target_os = "linux")]
75+
if !unistd::geteuid().is_root() {
76+
Some(String::from("mitmproxy is not running as root"))
77+
} else {
78+
None
79+
}
80+
81+
#[cfg(not(target_os = "linux"))]
82+
Some(String::from("OS not supported for TUN proxy mode"))
83+
}

src/network/virtual_device.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,14 @@ impl VirtualDevice {
2929
}
3030

3131
impl Device for VirtualDevice {
32-
type RxToken<'a> = VirtualRxToken where Self: 'a;
33-
type TxToken<'a> = VirtualTxToken<'a> where Self: 'a;
32+
type RxToken<'a>
33+
= VirtualRxToken
34+
where
35+
Self: 'a;
36+
type TxToken<'a>
37+
= VirtualTxToken<'a>
38+
where
39+
Self: 'a;
3440

3541
fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
3642
if self.rx_buffer.is_empty() {

0 commit comments

Comments
 (0)