Skip to content

Commit 6df989c

Browse files
committed
Use ip -6 addr command for setting ipv6 addr on linux
Using tun throws strange I/O errors. There may be a bug related to ipv6 in tun 0.7.10
1 parent f008ce5 commit 6df989c

File tree

1 file changed

+25
-25
lines changed
  • talpid-tunnel/src/tun_provider

1 file changed

+25
-25
lines changed

talpid-tunnel/src/tun_provider/unix.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
11
use super::TunConfig;
2-
#[cfg(target_os = "macos")]
3-
use std::io;
42
use std::{
53
net::IpAddr,
64
ops::Deref,
75
os::unix::io::{AsRawFd, RawFd},
6+
process::Command,
87
};
98
use tun::{AbstractDevice, Configuration};
109

1110
/// Errors that can occur while setting up a tunnel device.
1211
#[derive(Debug, thiserror::Error)]
1312
pub enum Error {
14-
/// Failed to set IP address on tunnel device
15-
#[cfg(target_os = "linux")]
16-
#[error("Failed to set IP address on tunnel device")]
17-
SetIp(#[source] tun::Error),
18-
1913
/// Failed to set IPv4 address on tunnel device
20-
#[cfg(target_os = "macos")]
2114
#[error("Failed to set IPv4 address")]
2215
SetIpv4(#[source] tun::Error),
2316

2417
/// Failed to set IPv6 address on tunnel device
25-
#[cfg(target_os = "macos")]
2618
#[error("Failed to set IPv6 address")]
27-
SetIpv6(#[source] io::Error),
19+
SetIpv6(#[source] std::io::Error),
2820

2921
/// Unable to open a tunnel device
3022
#[error("Unable to open a tunnel device")]
@@ -148,29 +140,37 @@ impl AsRawFd for TunnelDevice {
148140
}
149141

150142
impl TunnelDevice {
151-
#[cfg(target_os = "linux")]
152-
fn set_ip(&mut self, ip: IpAddr) -> Result<(), Error> {
153-
self.dev.set_address(ip).map_err(Error::SetIp)?;
154-
Ok(())
155-
}
156-
157-
#[cfg(target_os = "macos")]
158143
fn set_ip(&mut self, ip: IpAddr) -> Result<(), Error> {
159144
match ip {
160-
// NOTE: As of `tun 0.7`, `Device::set_address` accepts an `IpAddr` but
161-
// only supports the `IpAddr::V4` address kind and panics if you pass it an
162-
// `IpAddr::V6` value..
163145
IpAddr::V4(ipv4) => {
164146
self.dev.set_address(ipv4.into()).map_err(Error::SetIpv4)?;
165147
}
148+
149+
// NOTE: On MacOs, As of `tun 0.7`, `Device::set_address` accepts an `IpAddr` but
150+
// only supports the `IpAddr::V4` address kind and panics if you pass it an
151+
// `IpAddr::V6` value.
152+
#[cfg(target_os = "macos")]
166153
IpAddr::V6(ipv6) => {
167-
use std::process::Command;
168154
// ifconfig <device> inet6 <ipv6 address> alias
169-
let address = ipv6.to_string();
155+
let ipv6 = ipv6.to_string();
156+
let device = self.dev.tun_name().unwrap(); // TODO: Do not unwrap!
157+
Command::new("ifconfig")
158+
.args([&device, "inet6", &ipv6, "alias"])
159+
.output()
160+
.map_err(Error::SetIpv6)?;
161+
}
162+
163+
// NOTE: On Linux, As of `tun 0.7`, `Device::set_address` throws an I/O error if you
164+
// pass it an IPv6-address.
165+
#[cfg(target_os = "linux")]
166+
IpAddr::V6(ipv6) => {
167+
// ip -6 addr add <ipv6 address> dev <device>
168+
let ipv6 = ipv6.to_string();
170169
let device = self.dev.tun_name().unwrap(); // TODO: Do not unwrap!
171-
let mut ifconfig = Command::new("ifconfig");
172-
ifconfig.args([&device, "inet6", &address, "alias"]);
173-
ifconfig.output().map_err(Error::SetIpv6)?;
170+
Command::new("ip")
171+
.args(["-6", "addr", "add", &ipv6, "dev", &device])
172+
.output()
173+
.map_err(Error::SetIpv6)?;
174174
}
175175
}
176176
Ok(())

0 commit comments

Comments
 (0)