1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#[cfg(target_os = "android")]
use crate::tun_provider::imp::VpnServiceConfig;
use cfg_if::cfg_if;
use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
cfg_if! {
if #[cfg(target_os = "android")] {
#[path = "android/mod.rs"]
mod imp;
use self::imp::{AndroidTunProvider, VpnServiceTun};
pub use self::imp::Error;
pub type Tun = VpnServiceTun;
pub type TunProvider = AndroidTunProvider;
} else if #[cfg(all(unix, not(target_os = "android")))] {
#[path = "unix.rs"]
mod imp;
use self::imp::{UnixTun, UnixTunProvider};
pub use self::imp::Error;
pub type Tun = UnixTun;
pub type TunProvider = UnixTunProvider;
} else if #[cfg(all(windows, feature = "boringtun"))] {
#[path = "windows.rs"]
mod imp;
use self::imp::{WindowsTun, WindowsTunProvider};
pub use self::imp::Error;
pub type Tun = WindowsTun;
pub type TunProvider = WindowsTunProvider;
} else {
mod stub;
use self::stub::StubTunProvider;
pub use self::stub::Error;
pub type TunProvider = StubTunProvider;
}
}
/// Configuration for creating a tunnel device.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct TunConfig {
/// Interface name to use.
#[cfg(target_os = "linux")]
pub name: Option<String>,
/// Whether to enable the packet_information option on the tun device.
#[cfg(target_os = "linux")]
pub packet_information: bool,
/// IP addresses for the tunnel interface.
pub addresses: Vec<IpAddr>,
/// MTU of the tunnel interface.
pub mtu: u16,
/// IPv4 address of the VPN server, and the default IPv4 DNS resolver.
pub ipv4_gateway: Ipv4Addr,
/// IPv6 address of the VPN server, and the default IPv6 DNS resolver.
pub ipv6_gateway: Option<Ipv6Addr>,
/// Routes to configure for the tunnel.
pub routes: Vec<IpNetwork>,
/// Exclude private IPs from the tunnel
pub allow_lan: bool,
/// DNS servers to use for the tunnel config.
/// Unless specified, the gateways will be used for DNS
pub dns_servers: Option<Vec<IpAddr>>,
/// Applications to exclude from the tunnel.
pub excluded_packages: Vec<String>,
}
impl TunConfig {
/// Return a copy of all gateway addresses
pub fn gateways(&self) -> Vec<IpAddr> {
let mut servers = vec![self.ipv4_gateway.into()];
if let Some(gateway) = self.ipv6_gateway {
servers.push(gateway.into());
}
servers
}
/// Routes to configure for the tunnel.
#[cfg(target_os = "android")]
pub fn real_routes(&self) -> Vec<IpNetwork> {
VpnServiceConfig::new(self.clone())
.routes
.iter()
.map(IpNetwork::from)
.collect()
}
}
/// Return a tunnel configuration that routes all traffic inside the tunnel.
///
/// Most values except the routes are nonsensical. This is mostly used as a reasonable default on
/// Android to route all traffic inside the tunnel.
pub fn blocking_config() -> TunConfig {
TunConfig {
#[cfg(target_os = "linux")]
name: None,
#[cfg(target_os = "linux")]
packet_information: false,
addresses: vec![IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1))],
mtu: 1380,
ipv4_gateway: Ipv4Addr::new(10, 64, 0, 1),
ipv6_gateway: None,
routes: DEFAULT_ROUTES.to_vec(),
allow_lan: false,
dns_servers: None,
excluded_packages: vec![],
}
}
const DEFAULT_ROUTES: [IpNetwork; 2] = [
IpNetwork::V4(IPV4_DEFAULT_ROUTE),
IpNetwork::V6(IPV6_DEFAULT_ROUTE),
];
const IPV4_DEFAULT_ROUTE: Ipv4Network = Ipv4Network::new_checked(Ipv4Addr::UNSPECIFIED, 0).unwrap();
const IPV6_DEFAULT_ROUTE: Ipv6Network = Ipv6Network::new_checked(Ipv6Addr::UNSPECIFIED, 0).unwrap();
|