Skip to content

Commit 9e1a6e8

Browse files
ssrliveEnoch Carterkp-thomas-yau
authored
Enable tvOS support (#117)
* added tvos * store address and netmask for Android tun device * update ios asyc device * bump version * no message * update errors * mode logs * remove logs, bump version * some cleanup * fix clippy and format error * add ci to build on tvos * minor changes --------- Co-authored-by: Enoch Carter <[email protected]> Co-authored-by: Thomas Yau <[email protected]>
1 parent d7a538d commit 9e1a6e8

File tree

9 files changed

+53
-20
lines changed

9 files changed

+53
-20
lines changed

.cargo/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
protocol = "sparse"
33

44
[build]
5+
# target = ["aarch64-apple-tvos"]
56
# target = ["x86_64-unknown-linux-musl"]
67
# target = ["x86_64-unknown-linux-gnu"]
78
# target = ["aarch64-linux-android"] # arm64-v8a

.github/workflows/rust.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,29 @@ jobs:
8585
if: ${{ failure() }}
8686
run: echo "iOS build job failed" && false
8787

88+
build_n_test_tvos:
89+
strategy:
90+
matrix:
91+
target: [aarch64-apple-tvos, aarch64-apple-tvos-sim, x86_64-apple-tvos]
92+
fail-fast: false
93+
runs-on: macos-latest
94+
95+
steps:
96+
- uses: actions/checkout@v4
97+
- uses: dtolnay/rust-toolchain@nightly
98+
with:
99+
components: clippy, rust-src
100+
- name: clippy
101+
if: ${{ !cancelled() }}
102+
run: cargo +nightly clippy -Zbuild-std --target ${{matrix.target}} --all-features --features="async tokio/rt-multi-thread" -- -D warnings
103+
- name: Build
104+
if: ${{ !cancelled() }}
105+
run: |
106+
cargo +nightly build -Zbuild-std --verbose --target ${{matrix.target}} --all-features --features="async tokio/rt-multi-thread"
107+
- name: Abort on error
108+
if: ${{ failure() }}
109+
run: echo "tvOS build job failed" && false
110+
88111
build_n_test_openharmony:
89112
strategy:
90113
matrix:

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "tun"
3-
version = "0.7.13"
3+
version = "0.7.17"
44
edition = "2024"
55
authors = ["meh. <[email protected]>", "@ssrlive"]
66
license = "WTFPL"

src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl From<Error> for std::io::Error {
8080
fn from(value: Error) -> Self {
8181
match value {
8282
Error::Io(err) => err,
83-
_ => std::io::Error::new(std::io::ErrorKind::Other, value),
83+
_ => std::io::Error::other(value),
8484
}
8585
}
8686
}

src/platform/android/device.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,19 @@
1313
// 0. You just DO WHAT THE FUCK YOU WANT TO.
1414
#![allow(unused_variables)]
1515

16-
use std::io::{Read, Write};
17-
use std::net::IpAddr;
18-
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
19-
2016
use crate::configuration::Configuration;
2117
use crate::device::AbstractDevice;
2218
use crate::error::{Error, Result};
2319
use crate::platform::posix::{self, Fd, Tun};
20+
use std::io::{Read, Write};
21+
use std::net::IpAddr;
22+
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
2423

2524
/// A TUN device for Android.
2625
pub struct Device {
2726
pub(crate) tun: Tun,
27+
pub(crate) address: Option<IpAddr>,
28+
pub(crate) netmask: Option<IpAddr>,
2829
}
2930

3031
impl AsRef<dyn AbstractDevice + 'static> for Device {
@@ -53,6 +54,8 @@ impl Device {
5354

5455
Device {
5556
tun: Tun::new(tun, mtu, false),
57+
address: config.address,
58+
netmask: config.netmask,
5659
}
5760
};
5861

@@ -114,7 +117,7 @@ impl AbstractDevice for Device {
114117
}
115118

116119
fn address(&self) -> Result<IpAddr> {
117-
Err(Error::NotImplemented)
120+
self.address.ok_or(Error::NotImplemented)
118121
}
119122

120123
fn set_address(&mut self, _value: IpAddr) -> Result<()> {
@@ -138,7 +141,7 @@ impl AbstractDevice for Device {
138141
}
139142

140143
fn netmask(&self) -> Result<IpAddr> {
141-
Err(Error::NotImplemented)
144+
self.netmask.ok_or(Error::NotImplemented)
142145
}
143146

144147
fn set_netmask(&mut self, _value: IpAddr) -> Result<()> {

src/platform/ios/device.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ use std::{
2828
/// A TUN device for iOS.
2929
pub struct Device {
3030
pub(crate) tun: Tun,
31+
pub(crate) address: Option<IpAddr>,
32+
pub(crate) netmask: Option<IpAddr>,
33+
pub(crate) tun_name: Option<String>,
3134
}
3235

3336
impl AsRef<dyn AbstractDevice + 'static> for Device {
@@ -55,6 +58,9 @@ impl Device {
5558
let fd = Fd::new(fd, close_fd_on_drop).map_err(|_| std::io::Error::last_os_error())?;
5659
Device {
5760
tun: Tun::new(fd, mtu, config.platform_config.packet_information),
61+
address: config.address,
62+
netmask: config.netmask,
63+
tun_name: config.tun_name.clone(),
5864
}
5965
};
6066

@@ -108,47 +114,47 @@ impl Write for Device {
108114

109115
impl AbstractDevice for Device {
110116
fn tun_index(&self) -> Result<i32> {
111-
Err(Error::NotImplemented)
117+
Err("no tun_index".into())
112118
}
113119

114120
fn tun_name(&self) -> Result<String> {
115-
Ok("".to_string())
121+
Ok(self.tun_name.clone().unwrap_or("".to_string()))
116122
}
117123

118124
fn set_tun_name(&mut self, value: &str) -> Result<()> {
119-
Err(Error::NotImplemented)
125+
Err("set_tun_name".into())
120126
}
121127

122128
fn enabled(&mut self, value: bool) -> Result<()> {
123129
Ok(())
124130
}
125131

126132
fn address(&self) -> Result<IpAddr> {
127-
Err(Error::NotImplemented)
133+
self.address.ok_or("no address".into())
128134
}
129135

130136
fn set_address(&mut self, _value: IpAddr) -> Result<()> {
131137
Ok(())
132138
}
133139

134140
fn destination(&self) -> Result<IpAddr> {
135-
Err(Error::NotImplemented)
141+
Err("no destination".into())
136142
}
137143

138144
fn set_destination(&mut self, _value: IpAddr) -> Result<()> {
139145
Ok(())
140146
}
141147

142148
fn broadcast(&self) -> Result<IpAddr> {
143-
Err(Error::NotImplemented)
149+
Err("no broadcast".into())
144150
}
145151

146152
fn set_broadcast(&mut self, _value: IpAddr) -> Result<()> {
147153
Ok(())
148154
}
149155

150156
fn netmask(&self) -> Result<IpAddr> {
151-
Err(Error::NotImplemented)
157+
self.netmask.ok_or("no netmask".into())
152158
}
153159

154160
fn set_netmask(&mut self, _value: IpAddr) -> Result<()> {

src/platform/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ pub(crate) mod macos;
3434
#[cfg(target_os = "macos")]
3535
pub use self::macos::{Device, PlatformConfig, create};
3636

37-
#[cfg(target_os = "ios")]
37+
#[cfg(any(target_os = "ios", target_os = "tvos"))]
3838
pub(crate) mod ios;
39-
#[cfg(target_os = "ios")]
39+
#[cfg(any(target_os = "ios", target_os = "tvos"))]
4040
pub use self::ios::{Device, PlatformConfig, create};
4141

4242
#[cfg(target_os = "android")]

src/platform/posix/split.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ pub(crate) fn generate_packet_information(
4141
#[cfg(any(target_os = "linux", target_os = "android"))]
4242
const TUN_PROTO_IP4: [u8; PIL] = (libc::ETH_P_IP as u32).to_be_bytes();
4343

44-
#[cfg(any(target_os = "macos", target_os = "ios"))]
44+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))]
4545
const TUN_PROTO_IP6: [u8; PIL] = (libc::AF_INET6 as u32).to_be_bytes();
46-
#[cfg(any(target_os = "macos", target_os = "ios"))]
46+
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos"))]
4747
const TUN_PROTO_IP4: [u8; PIL] = (libc::AF_INET as u32).to_be_bytes();
4848

4949
// FIXME: Currently, the FreeBSD we test (FreeBSD-14.0-RELEASE) seems to have no PI. Here just a dummy.

src/run_command.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub fn run_command(command: &str, args: &[&str]) -> std::io::Result<Vec<u8>> {
1919
});
2020
let info = format!("Run command: \"{full_cmd}\" failed with {err}");
2121
log::error!("{}", info);
22-
return Err(std::io::Error::new(std::io::ErrorKind::Other, info));
22+
return Err(std::io::Error::other(info));
2323
}
2424
Ok(out.stdout)
2525
}

0 commit comments

Comments
 (0)