Skip to content

Commit

Permalink
feat: support openharmony platform
Browse files Browse the repository at this point in the history
  • Loading branch information
richerfu committed Nov 19, 2024
1 parent eed689c commit f12ae3b
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Platforms
- [x] FreeBSD
- [x] Android
- [x] iOS
- [x] OpenHarmony


Linux
Expand Down
2 changes: 1 addition & 1 deletion examples/dev-config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn main_entry(quit: Receiver<()>) -> Result<(), BoxError> {
.destination((10, 0, 0, 1))
.up();

#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
config.platform_config(|config| {
config.ensure_root_privileges(true);
});
Expand Down
2 changes: 1 addition & 1 deletion examples/ping-tun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async fn main_entry(mut quit: Receiver<()>) -> Result<(), BoxError> {
.destination((10, 0, 0, 1))
.up();

#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
config.platform_config(|config| {
#[allow(deprecated)]
config.packet_information(true);
Expand Down
2 changes: 1 addition & 1 deletion examples/read-async-codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ async fn main_entry(mut quit: Receiver<()>) -> Result<(), BoxError> {
.destination((10, 0, 0, 1))
.up();

#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
config.platform_config(|config| {
#[allow(deprecated)]
config.packet_information(true);
Expand Down
2 changes: 1 addition & 1 deletion examples/read-async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async fn main_entry(mut quit: Receiver<()>) -> Result<(), BoxError> {
.mtu(tun::DEFAULT_MTU)
.up();

#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
config.platform_config(|config| {
config.ensure_root_privileges(true);
});
Expand Down
2 changes: 1 addition & 1 deletion examples/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn main_entry(quit: Receiver<()>) -> Result<(), BoxError> {
.destination((10, 0, 0, 1))
.up();

#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
config.platform_config(|config| {
config.ensure_root_privileges(true);
});
Expand Down
2 changes: 1 addition & 1 deletion examples/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn main_entry(quit: Receiver<()>) -> Result<(), BoxError> {
.destination((10, 0, 0, 1))
.up();

#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
config.platform_config(|config| {
config.ensure_root_privileges(true);
});
Expand Down
2 changes: 1 addition & 1 deletion examples/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fn main_entry(quit: Receiver<()>) -> Result<(), BoxError> {
.destination((10, 0, 0, 1))
.up();

#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
config.platform_config(|config| {
config.ensure_root_privileges(true);
});
Expand Down
9 changes: 7 additions & 2 deletions src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
#[cfg(unix)]
pub(crate) mod posix;

#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
pub(crate) mod linux;
#[cfg(target_os = "linux")]
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
pub use self::linux::{create, Device, PlatformConfig};

#[cfg(target_os = "freebsd")]
Expand All @@ -42,6 +42,11 @@ pub(crate) mod android;
#[cfg(target_os = "android")]
pub use self::android::{create, Device, PlatformConfig};

#[cfg(target_env = "ohos")]
pub(crate) mod ohos;
#[cfg(target_env = "ohos")]
pub use self::ohos::{create, Device, PlatformConfig};

#[cfg(unix)]
pub use crate::platform::posix::Tun;

Expand Down
174 changes: 174 additions & 0 deletions src/platform/ohos/device.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <meh@schizofreni.co> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.
#![allow(unused_variables)]

use std::io::{Read, Write};
use std::net::IpAddr;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};

use crate::configuration::Configuration;
use crate::device::AbstractDevice;
use crate::error::{Error, Result};
use crate::platform::posix::{self, Fd, Tun};

/// A TUN device for Android.
pub struct Device {
tun: Tun,
}

impl AsRef<dyn AbstractDevice + 'static> for Device {
fn as_ref(&self) -> &(dyn AbstractDevice + 'static) {
self
}
}

impl AsMut<dyn AbstractDevice + 'static> for Device {
fn as_mut(&mut self) -> &mut (dyn AbstractDevice + 'static) {
self
}
}

impl Device {
/// Create a new `Device` for the given `Configuration`.
pub fn new(config: &Configuration) -> Result<Self> {
let close_fd_on_drop = config.close_fd_on_drop.unwrap_or(true);
let fd = match config.raw_fd {
Some(raw_fd) => raw_fd,
_ => return Err(Error::InvalidConfig),
};
let device = {
let mtu = config.mtu.unwrap_or(crate::DEFAULT_MTU);
let tun = Fd::new(fd, close_fd_on_drop).map_err(|_| std::io::Error::last_os_error())?;

Device {
tun: Tun::new(tun, mtu, false),
}
};

Ok(device)
}

/// Split the interface into a `Reader` and `Writer`.
pub fn split(self) -> (posix::Reader, posix::Writer) {
(self.tun.reader, self.tun.writer)
}

/// Set non-blocking mode
pub fn set_nonblock(&self) -> std::io::Result<()> {
self.tun.set_nonblock()
}

/// Recv a packet from tun device
pub fn recv(&self, buf: &mut [u8]) -> std::io::Result<usize> {
self.tun.recv(buf)
}

/// Send a packet to tun device
pub fn send(&self, buf: &[u8]) -> std::io::Result<usize> {
self.tun.send(buf)
}
}

impl Read for Device {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
self.tun.read(buf)
}
}

impl Write for Device {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.tun.write(buf)
}

fn flush(&mut self) -> std::io::Result<()> {
self.tun.flush()
}
}

impl AbstractDevice for Device {
fn tun_index(&self) -> Result<i32> {
Err(Error::NotImplemented)
}

fn tun_name(&self) -> Result<String> {
Ok("".to_string())
}

fn set_tun_name(&mut self, value: &str) -> Result<()> {
Err(Error::NotImplemented)
}

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

fn address(&self) -> Result<IpAddr> {
Err(Error::NotImplemented)
}

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

fn destination(&self) -> Result<IpAddr> {
Err(Error::NotImplemented)
}

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

fn broadcast(&self) -> Result<IpAddr> {
Err(Error::NotImplemented)
}

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

fn netmask(&self) -> Result<IpAddr> {
Err(Error::NotImplemented)
}

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

fn mtu(&self) -> Result<u16> {
// TODO: must get the mtu from the underlying device driver
Ok(self.tun.mtu())
}

fn set_mtu(&mut self, value: u16) -> Result<()> {
// TODO: must set the mtu to the underlying device driver
self.tun.set_mtu(value);
Ok(())
}

fn packet_information(&self) -> bool {
self.tun.packet_information()
}
}

impl AsRawFd for Device {
fn as_raw_fd(&self) -> RawFd {
self.tun.as_raw_fd()
}
}

impl IntoRawFd for Device {
fn into_raw_fd(self) -> RawFd {
self.tun.into_raw_fd()
}
}
30 changes: 30 additions & 0 deletions src/platform/ohos/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// Version 2, December 2004
//
// Copyleft (ↄ) meh. <meh@schizofreni.co> | http://meh.schizofreni.co
//
// Everyone is permitted to copy and distribute verbatim or modified
// copies of this license document, and changing it is allowed as long
// as the name is changed.
//
// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
//
// 0. You just DO WHAT THE FUCK YOU WANT TO.

//! OpenHarmony specific functionality.
mod device;
pub use self::device::Device;

use crate::configuration::Configuration;
use crate::error::Result;

/// Android-only interface configuration.
#[derive(Copy, Clone, Default, Debug)]
pub struct PlatformConfig;

/// Create a TUN device with the given name.
pub fn create(configuration: &Configuration) -> Result<Device> {
Device::new(configuration)
}

0 comments on commit f12ae3b

Please sign in to comment.