enif_select() shenanigans
This commit is contained in:
parent
d94f20d042
commit
2446dcf05d
4 changed files with 47 additions and 9 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
|
@ -28,9 +28,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.5.0"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
|
|
@ -490,10 +490,10 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustler"
|
name = "rustler"
|
||||||
version = "0.37.4"
|
version = "0.37.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/lilioid/rustler.git?branch=master#fca9102702b878e7d8f05cf905552288206fa310"
|
||||||
checksum = "875c8fe88089b9bbc0977385e107d35bfae740c6b0734e60a1e9cc82d0017f49"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"inventory",
|
"inventory",
|
||||||
|
"libc",
|
||||||
"libloading",
|
"libloading",
|
||||||
"regex-lite",
|
"regex-lite",
|
||||||
"rustler_codegen",
|
"rustler_codegen",
|
||||||
|
|
@ -502,8 +502,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustler_codegen"
|
name = "rustler_codegen"
|
||||||
version = "0.37.4"
|
version = "0.37.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/lilioid/rustler.git?branch=master#fca9102702b878e7d8f05cf905552288206fa310"
|
||||||
checksum = "afb5848e9c4cf3796f190d9b4516523af27f3444a3af1771f20465f6586d40b2"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"inventory",
|
"inventory",
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,7 @@
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
members = ["native/p2pchat_transport_prim_tun"]
|
members = ["native/p2pchat_transport_prim_tun"]
|
||||||
|
|
||||||
|
[workspace.dependencies]
|
||||||
|
rustler = { version = "0.37.4", git = "https://github.com/lilioid/rustler.git", branch="master" }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,6 @@ edition = "2021"
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustler = "0.37.4"
|
rustler = { workspace = true }
|
||||||
tun-rs = { version = "2.8.3", default-features = false, features = ["blocking", "experimental"] }
|
tun-rs = { version = "2.8.3", default-features = false, features = ["blocking", "experimental"] }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::os::fd::AsRawFd;
|
||||||
|
|
||||||
|
use rustler::sys::{ErlNifEvent, ERL_NIF_SELECT_STOP};
|
||||||
use rustler::types::tuple::{get_tuple, make_tuple};
|
use rustler::types::tuple::{get_tuple, make_tuple};
|
||||||
use rustler::{
|
use rustler::{
|
||||||
resource_impl, Binary, Decoder, Encoder, NifResult, OwnedBinary, Resource, ResourceArc, Term,
|
resource_impl, Binary, Decoder, Encoder, NifResult, OwnedBinary, Resource, ResourceArc, Term,
|
||||||
|
|
@ -11,6 +13,7 @@ use tun_rs::{DeviceBuilder, SyncDevice};
|
||||||
mod atoms {
|
mod atoms {
|
||||||
rustler::atoms! {
|
rustler::atoms! {
|
||||||
ok,
|
ok,
|
||||||
|
undefined,
|
||||||
resource_busy,
|
resource_busy,
|
||||||
permission_denied,
|
permission_denied,
|
||||||
would_block,
|
would_block,
|
||||||
|
|
@ -92,7 +95,12 @@ impl<'a> Decoder<'a> for WrappedIpAddr {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[resource_impl]
|
#[resource_impl]
|
||||||
impl Resource for TunHandle {}
|
impl Resource for TunHandle {
|
||||||
|
fn stop<'a>(&'a self, _env: rustler::Env<'a>, event: ErlNifEvent, is_direct_call: bool) {
|
||||||
|
println!("event: {event:?}");
|
||||||
|
println!("is_direct_call: {is_direct_call:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[rustler::nif]
|
#[rustler::nif]
|
||||||
fn make_tun_device(env: rustler::Env, packet_info: bool) -> NifResult<Term> {
|
fn make_tun_device(env: rustler::Env, packet_info: bool) -> NifResult<Term> {
|
||||||
|
|
@ -101,9 +109,10 @@ fn make_tun_device(env: rustler::Env, packet_info: bool) -> NifResult<Term> {
|
||||||
.packet_information(packet_info)
|
.packet_information(packet_info)
|
||||||
.build_sync()
|
.build_sync()
|
||||||
.map_err(map_io_error)?;
|
.map_err(map_io_error)?;
|
||||||
device.set_nonblocking(true).map_err(map_io_error)?;
|
// device.set_nonblocking(true).map_err(map_io_error)?;
|
||||||
|
|
||||||
let handle = ResourceArc::new(TunHandle { device });
|
let handle = ResourceArc::new(TunHandle { device });
|
||||||
|
register_io(env, &handle);
|
||||||
Ok(make_ok_tuple(env, handle))
|
Ok(make_ok_tuple(env, handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,6 +207,32 @@ fn set_mtu(handle: ResourceArc<TunHandle>, mtu: u16) -> NifResult<()> {
|
||||||
handle.device.set_mtu(mtu).map_err(map_io_error)
|
handle.device.set_mtu(mtu).map_err(map_io_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Register pending IO with the erlang vm to later receive a callback when
|
||||||
|
/// something happened to the device and IO is available.
|
||||||
|
fn register_io(env: rustler::Env, handle: &ResourceArc<TunHandle>) {
|
||||||
|
// Safety: yolo! I have no idea what I'm doing
|
||||||
|
unsafe {
|
||||||
|
let enif_env = env.as_c_arg();
|
||||||
|
let enif_event: ErlNifEvent = handle.device.as_raw_fd();
|
||||||
|
let enif_flags = rustler::sys::ERL_NIF_SELECT_READ;
|
||||||
|
let enif_obj = handle.as_c_arg();
|
||||||
|
let enif_pid = std::ptr::null();
|
||||||
|
let enif_ref = atoms::undefined().to_term(env).as_c_arg();
|
||||||
|
rustler::sys::enif_select(
|
||||||
|
enif_env, enif_event, enif_flags, enif_obj, enif_pid, enif_ref,
|
||||||
|
);
|
||||||
|
|
||||||
|
rustler::sys::enif_select(
|
||||||
|
enif_env,
|
||||||
|
enif_event,
|
||||||
|
ERL_NIF_SELECT_STOP,
|
||||||
|
enif_obj,
|
||||||
|
enif_pid,
|
||||||
|
enif_ref,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn map_io_error(error: io::Error) -> rustler::Error {
|
fn map_io_error(error: io::Error) -> rustler::Error {
|
||||||
rustler::Error::Term(match error.kind() {
|
rustler::Error::Term(match error.kind() {
|
||||||
io::ErrorKind::ResourceBusy => Box::new(atoms::resource_busy()),
|
io::ErrorKind::ResourceBusy => Box::new(atoms::resource_busy()),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue