mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-09 20:12:14 +10:00
feat(tailscale): Add wrapper around libtailscale with Tailscale struct
Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
5
src-tauri/Cargo.lock
generated
5
src-tauri/Cargo.lock
generated
@ -2825,9 +2825,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.169"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -5290,6 +5290,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"abs-file-macro",
|
||||
"bindgen",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
1
src-tauri/tailscale/Cargo.lock
generated
1
src-tauri/tailscale/Cargo.lock
generated
@ -220,6 +220,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"abs-file-macro",
|
||||
"bindgen",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@ -3,8 +3,9 @@ name = "tailscale"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "*"
|
||||
abs-file-macro = "0.1.2"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.172"
|
||||
|
||||
@ -6,27 +6,49 @@ pub struct __BindgenComplex<T> {
|
||||
pub re: T,
|
||||
pub im: T,
|
||||
}
|
||||
pub const __has_safe_buffers: u32 = 1;
|
||||
pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 1;
|
||||
pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1;
|
||||
pub const __DARWIN_ONLY_VERS_1050: u32 = 1;
|
||||
pub const __DARWIN_UNIX03: u32 = 1;
|
||||
pub const __DARWIN_64_BIT_INO_T: u32 = 1;
|
||||
pub const __DARWIN_VERS_1050: u32 = 1;
|
||||
pub const __DARWIN_NON_CANCELABLE: u32 = 0;
|
||||
pub const __DARWIN_SUF_EXTSN: &[u8; 14] = b"$DARWIN_EXTSN\0";
|
||||
pub const __DARWIN_C_ANSI: u32 = 4096;
|
||||
pub const __DARWIN_C_FULL: u32 = 900000;
|
||||
pub const __DARWIN_C_LEVEL: u32 = 900000;
|
||||
pub const __STDC_WANT_LIB_EXT1__: u32 = 1;
|
||||
pub const __DARWIN_NO_LONG_LONG: u32 = 0;
|
||||
pub const _DARWIN_FEATURE_64_BIT_INODE: u32 = 1;
|
||||
pub const _DARWIN_FEATURE_ONLY_64_BIT_INODE: u32 = 1;
|
||||
pub const _DARWIN_FEATURE_ONLY_VERS_1050: u32 = 1;
|
||||
pub const _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE: u32 = 1;
|
||||
pub const _DARWIN_FEATURE_UNIX_CONFORMANCE: u32 = 3;
|
||||
pub const __has_ptrcheck: u32 = 0;
|
||||
pub const __has_bounds_safety_attributes: u32 = 0;
|
||||
pub const _ERRNO_H: u32 = 1;
|
||||
pub const _FEATURES_H: u32 = 1;
|
||||
pub const _DEFAULT_SOURCE: u32 = 1;
|
||||
pub const __GLIBC_USE_ISOC2Y: u32 = 0;
|
||||
pub const __GLIBC_USE_ISOC23: u32 = 0;
|
||||
pub const __USE_ISOC11: u32 = 1;
|
||||
pub const __USE_ISOC99: u32 = 1;
|
||||
pub const __USE_ISOC95: u32 = 1;
|
||||
pub const __USE_POSIX_IMPLICITLY: u32 = 1;
|
||||
pub const _POSIX_SOURCE: u32 = 1;
|
||||
pub const _POSIX_C_SOURCE: u32 = 200809;
|
||||
pub const __USE_POSIX: u32 = 1;
|
||||
pub const __USE_POSIX2: u32 = 1;
|
||||
pub const __USE_POSIX199309: u32 = 1;
|
||||
pub const __USE_POSIX199506: u32 = 1;
|
||||
pub const __USE_XOPEN2K: u32 = 1;
|
||||
pub const __USE_XOPEN2K8: u32 = 1;
|
||||
pub const _ATFILE_SOURCE: u32 = 1;
|
||||
pub const __WORDSIZE: u32 = 64;
|
||||
pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1;
|
||||
pub const __SYSCALL_WORDSIZE: u32 = 64;
|
||||
pub const __TIMESIZE: u32 = 64;
|
||||
pub const __USE_TIME_BITS64: u32 = 1;
|
||||
pub const __USE_MISC: u32 = 1;
|
||||
pub const __USE_ATFILE: u32 = 1;
|
||||
pub const __USE_FORTIFY_LEVEL: u32 = 0;
|
||||
pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0;
|
||||
pub const __GLIBC_USE_DEPRECATED_SCANF: u32 = 0;
|
||||
pub const __GLIBC_USE_C23_STRTOL: u32 = 0;
|
||||
pub const _STDC_PREDEF_H: u32 = 1;
|
||||
pub const __STDC_IEC_559__: u32 = 1;
|
||||
pub const __STDC_IEC_60559_BFP__: u32 = 201404;
|
||||
pub const __STDC_IEC_559_COMPLEX__: u32 = 1;
|
||||
pub const __STDC_IEC_60559_COMPLEX__: u32 = 201404;
|
||||
pub const __STDC_ISO_10646__: u32 = 201706;
|
||||
pub const __GNU_LIBRARY__: u32 = 6;
|
||||
pub const __GLIBC__: u32 = 2;
|
||||
pub const __GLIBC_MINOR__: u32 = 41;
|
||||
pub const _SYS_CDEFS_H: u32 = 1;
|
||||
pub const __glibc_c99_flexarr_available: u32 = 1;
|
||||
pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI: u32 = 0;
|
||||
pub const __HAVE_GENERIC_SELECTION: u32 = 1;
|
||||
pub const _BITS_ERRNO_H: u32 = 1;
|
||||
pub const EPERM: u32 = 1;
|
||||
pub const ENOENT: u32 = 2;
|
||||
pub const ESRCH: u32 = 3;
|
||||
@ -37,7 +59,7 @@ pub const E2BIG: u32 = 7;
|
||||
pub const ENOEXEC: u32 = 8;
|
||||
pub const EBADF: u32 = 9;
|
||||
pub const ECHILD: u32 = 10;
|
||||
pub const EDEADLK: u32 = 11;
|
||||
pub const EAGAIN: u32 = 11;
|
||||
pub const ENOMEM: u32 = 12;
|
||||
pub const EACCES: u32 = 13;
|
||||
pub const EFAULT: u32 = 14;
|
||||
@ -61,82 +83,124 @@ pub const EMLINK: u32 = 31;
|
||||
pub const EPIPE: u32 = 32;
|
||||
pub const EDOM: u32 = 33;
|
||||
pub const ERANGE: u32 = 34;
|
||||
pub const EAGAIN: u32 = 35;
|
||||
pub const EWOULDBLOCK: u32 = 35;
|
||||
pub const EINPROGRESS: u32 = 36;
|
||||
pub const EALREADY: u32 = 37;
|
||||
pub const ENOTSOCK: u32 = 38;
|
||||
pub const EDESTADDRREQ: u32 = 39;
|
||||
pub const EMSGSIZE: u32 = 40;
|
||||
pub const EPROTOTYPE: u32 = 41;
|
||||
pub const ENOPROTOOPT: u32 = 42;
|
||||
pub const EPROTONOSUPPORT: u32 = 43;
|
||||
pub const ESOCKTNOSUPPORT: u32 = 44;
|
||||
pub const ENOTSUP: u32 = 45;
|
||||
pub const EPFNOSUPPORT: u32 = 46;
|
||||
pub const EAFNOSUPPORT: u32 = 47;
|
||||
pub const EADDRINUSE: u32 = 48;
|
||||
pub const EADDRNOTAVAIL: u32 = 49;
|
||||
pub const ENETDOWN: u32 = 50;
|
||||
pub const ENETUNREACH: u32 = 51;
|
||||
pub const ENETRESET: u32 = 52;
|
||||
pub const ECONNABORTED: u32 = 53;
|
||||
pub const ECONNRESET: u32 = 54;
|
||||
pub const ENOBUFS: u32 = 55;
|
||||
pub const EISCONN: u32 = 56;
|
||||
pub const ENOTCONN: u32 = 57;
|
||||
pub const ESHUTDOWN: u32 = 58;
|
||||
pub const ETOOMANYREFS: u32 = 59;
|
||||
pub const ETIMEDOUT: u32 = 60;
|
||||
pub const ECONNREFUSED: u32 = 61;
|
||||
pub const ELOOP: u32 = 62;
|
||||
pub const ENAMETOOLONG: u32 = 63;
|
||||
pub const EHOSTDOWN: u32 = 64;
|
||||
pub const EHOSTUNREACH: u32 = 65;
|
||||
pub const ENOTEMPTY: u32 = 66;
|
||||
pub const EPROCLIM: u32 = 67;
|
||||
pub const EUSERS: u32 = 68;
|
||||
pub const EDQUOT: u32 = 69;
|
||||
pub const ESTALE: u32 = 70;
|
||||
pub const EREMOTE: u32 = 71;
|
||||
pub const EBADRPC: u32 = 72;
|
||||
pub const ERPCMISMATCH: u32 = 73;
|
||||
pub const EPROGUNAVAIL: u32 = 74;
|
||||
pub const EPROGMISMATCH: u32 = 75;
|
||||
pub const EPROCUNAVAIL: u32 = 76;
|
||||
pub const ENOLCK: u32 = 77;
|
||||
pub const ENOSYS: u32 = 78;
|
||||
pub const EFTYPE: u32 = 79;
|
||||
pub const EAUTH: u32 = 80;
|
||||
pub const ENEEDAUTH: u32 = 81;
|
||||
pub const EPWROFF: u32 = 82;
|
||||
pub const EDEVERR: u32 = 83;
|
||||
pub const EOVERFLOW: u32 = 84;
|
||||
pub const EBADEXEC: u32 = 85;
|
||||
pub const EBADARCH: u32 = 86;
|
||||
pub const ESHLIBVERS: u32 = 87;
|
||||
pub const EBADMACHO: u32 = 88;
|
||||
pub const ECANCELED: u32 = 89;
|
||||
pub const EIDRM: u32 = 90;
|
||||
pub const ENOMSG: u32 = 91;
|
||||
pub const EILSEQ: u32 = 92;
|
||||
pub const ENOATTR: u32 = 93;
|
||||
pub const EBADMSG: u32 = 94;
|
||||
pub const EMULTIHOP: u32 = 95;
|
||||
pub const ENODATA: u32 = 96;
|
||||
pub const ENOLINK: u32 = 97;
|
||||
pub const ENOSR: u32 = 98;
|
||||
pub const ENOSTR: u32 = 99;
|
||||
pub const EPROTO: u32 = 100;
|
||||
pub const ETIME: u32 = 101;
|
||||
pub const EOPNOTSUPP: u32 = 102;
|
||||
pub const ENOPOLICY: u32 = 103;
|
||||
pub const ENOTRECOVERABLE: u32 = 104;
|
||||
pub const EOWNERDEAD: u32 = 105;
|
||||
pub const EQFULL: u32 = 106;
|
||||
pub const ELAST: u32 = 106;
|
||||
pub const EDEADLK: u32 = 35;
|
||||
pub const ENAMETOOLONG: u32 = 36;
|
||||
pub const ENOLCK: u32 = 37;
|
||||
pub const ENOSYS: u32 = 38;
|
||||
pub const ENOTEMPTY: u32 = 39;
|
||||
pub const ELOOP: u32 = 40;
|
||||
pub const EWOULDBLOCK: u32 = 11;
|
||||
pub const ENOMSG: u32 = 42;
|
||||
pub const EIDRM: u32 = 43;
|
||||
pub const ECHRNG: u32 = 44;
|
||||
pub const EL2NSYNC: u32 = 45;
|
||||
pub const EL3HLT: u32 = 46;
|
||||
pub const EL3RST: u32 = 47;
|
||||
pub const ELNRNG: u32 = 48;
|
||||
pub const EUNATCH: u32 = 49;
|
||||
pub const ENOCSI: u32 = 50;
|
||||
pub const EL2HLT: u32 = 51;
|
||||
pub const EBADE: u32 = 52;
|
||||
pub const EBADR: u32 = 53;
|
||||
pub const EXFULL: u32 = 54;
|
||||
pub const ENOANO: u32 = 55;
|
||||
pub const EBADRQC: u32 = 56;
|
||||
pub const EBADSLT: u32 = 57;
|
||||
pub const EDEADLOCK: u32 = 35;
|
||||
pub const EBFONT: u32 = 59;
|
||||
pub const ENOSTR: u32 = 60;
|
||||
pub const ENODATA: u32 = 61;
|
||||
pub const ETIME: u32 = 62;
|
||||
pub const ENOSR: u32 = 63;
|
||||
pub const ENONET: u32 = 64;
|
||||
pub const ENOPKG: u32 = 65;
|
||||
pub const EREMOTE: u32 = 66;
|
||||
pub const ENOLINK: u32 = 67;
|
||||
pub const EADV: u32 = 68;
|
||||
pub const ESRMNT: u32 = 69;
|
||||
pub const ECOMM: u32 = 70;
|
||||
pub const EPROTO: u32 = 71;
|
||||
pub const EMULTIHOP: u32 = 72;
|
||||
pub const EDOTDOT: u32 = 73;
|
||||
pub const EBADMSG: u32 = 74;
|
||||
pub const EOVERFLOW: u32 = 75;
|
||||
pub const ENOTUNIQ: u32 = 76;
|
||||
pub const EBADFD: u32 = 77;
|
||||
pub const EREMCHG: u32 = 78;
|
||||
pub const ELIBACC: u32 = 79;
|
||||
pub const ELIBBAD: u32 = 80;
|
||||
pub const ELIBSCN: u32 = 81;
|
||||
pub const ELIBMAX: u32 = 82;
|
||||
pub const ELIBEXEC: u32 = 83;
|
||||
pub const EILSEQ: u32 = 84;
|
||||
pub const ERESTART: u32 = 85;
|
||||
pub const ESTRPIPE: u32 = 86;
|
||||
pub const EUSERS: u32 = 87;
|
||||
pub const ENOTSOCK: u32 = 88;
|
||||
pub const EDESTADDRREQ: u32 = 89;
|
||||
pub const EMSGSIZE: u32 = 90;
|
||||
pub const EPROTOTYPE: u32 = 91;
|
||||
pub const ENOPROTOOPT: u32 = 92;
|
||||
pub const EPROTONOSUPPORT: u32 = 93;
|
||||
pub const ESOCKTNOSUPPORT: u32 = 94;
|
||||
pub const EOPNOTSUPP: u32 = 95;
|
||||
pub const EPFNOSUPPORT: u32 = 96;
|
||||
pub const EAFNOSUPPORT: u32 = 97;
|
||||
pub const EADDRINUSE: u32 = 98;
|
||||
pub const EADDRNOTAVAIL: u32 = 99;
|
||||
pub const ENETDOWN: u32 = 100;
|
||||
pub const ENETUNREACH: u32 = 101;
|
||||
pub const ENETRESET: u32 = 102;
|
||||
pub const ECONNABORTED: u32 = 103;
|
||||
pub const ECONNRESET: u32 = 104;
|
||||
pub const ENOBUFS: u32 = 105;
|
||||
pub const EISCONN: u32 = 106;
|
||||
pub const ENOTCONN: u32 = 107;
|
||||
pub const ESHUTDOWN: u32 = 108;
|
||||
pub const ETOOMANYREFS: u32 = 109;
|
||||
pub const ETIMEDOUT: u32 = 110;
|
||||
pub const ECONNREFUSED: u32 = 111;
|
||||
pub const EHOSTDOWN: u32 = 112;
|
||||
pub const EHOSTUNREACH: u32 = 113;
|
||||
pub const EALREADY: u32 = 114;
|
||||
pub const EINPROGRESS: u32 = 115;
|
||||
pub const ESTALE: u32 = 116;
|
||||
pub const EUCLEAN: u32 = 117;
|
||||
pub const ENOTNAM: u32 = 118;
|
||||
pub const ENAVAIL: u32 = 119;
|
||||
pub const EISNAM: u32 = 120;
|
||||
pub const EREMOTEIO: u32 = 121;
|
||||
pub const EDQUOT: u32 = 122;
|
||||
pub const ENOMEDIUM: u32 = 123;
|
||||
pub const EMEDIUMTYPE: u32 = 124;
|
||||
pub const ECANCELED: u32 = 125;
|
||||
pub const ENOKEY: u32 = 126;
|
||||
pub const EKEYEXPIRED: u32 = 127;
|
||||
pub const EKEYREVOKED: u32 = 128;
|
||||
pub const EKEYREJECTED: u32 = 129;
|
||||
pub const EOWNERDEAD: u32 = 130;
|
||||
pub const ENOTRECOVERABLE: u32 = 131;
|
||||
pub const ERFKILL: u32 = 132;
|
||||
pub const EHWPOISON: u32 = 133;
|
||||
pub const ENOTSUP: u32 = 95;
|
||||
pub type wchar_t = ::std::os::raw::c_int;
|
||||
pub type max_align_t = f64;
|
||||
#[repr(C)]
|
||||
#[repr(align(16))]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct max_align_t {
|
||||
pub __clang_max_align_nonce1: ::std::os::raw::c_longlong,
|
||||
pub __bindgen_padding_0: u64,
|
||||
pub __clang_max_align_nonce2: u128,
|
||||
}
|
||||
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
|
||||
const _: () = {
|
||||
["Size of max_align_t"][::std::mem::size_of::<max_align_t>() - 32usize];
|
||||
["Alignment of max_align_t"][::std::mem::align_of::<max_align_t>() - 16usize];
|
||||
["Offset of field: max_align_t::__clang_max_align_nonce1"]
|
||||
[::std::mem::offset_of!(max_align_t, __clang_max_align_nonce1) - 0usize];
|
||||
["Offset of field: max_align_t::__clang_max_align_nonce2"]
|
||||
[::std::mem::offset_of!(max_align_t, __clang_max_align_nonce2) - 16usize];
|
||||
};
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct _GoString_ {
|
||||
@ -150,9 +214,8 @@ const _: () = {
|
||||
["Offset of field: _GoString_::p"][::std::mem::offset_of!(_GoString_, p) - 0usize];
|
||||
["Offset of field: _GoString_::n"][::std::mem::offset_of!(_GoString_, n) - 8usize];
|
||||
};
|
||||
pub type errno_t = ::std::os::raw::c_int;
|
||||
unsafe extern "C" {
|
||||
pub fn __error() -> *mut ::std::os::raw::c_int;
|
||||
pub fn __errno_location() -> *mut ::std::os::raw::c_int;
|
||||
}
|
||||
pub type GoInt8 = ::std::os::raw::c_schar;
|
||||
pub type GoUint8 = ::std::os::raw::c_uchar;
|
||||
|
||||
@ -2,4 +2,207 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
pub mod bindings;
|
||||
use std::os::raw::{c_int, c_char};
|
||||
use std::ffi::{CStr, CString};
|
||||
mod bindings;
|
||||
|
||||
type GoInt = i64;
|
||||
|
||||
|
||||
use bindings::*;
|
||||
use libc;
|
||||
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TailscaleError {
|
||||
ApiError(c_int, String),
|
||||
BadFileDescriptor,
|
||||
BufferTooSmall,
|
||||
NulError(std::ffi::NulError),
|
||||
InvalidUtf8(std::str::Utf8Error),
|
||||
IoError(std::io::Error),
|
||||
InvalidHandle,
|
||||
}
|
||||
|
||||
impl From<std::ffi::NulError> for TailscaleError {
|
||||
fn from(err: std::ffi::NulError) -> Self {
|
||||
TailscaleError::NulError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::str::Utf8Error> for TailscaleError {
|
||||
fn from(err: std::str::Utf8Error) -> Self {
|
||||
TailscaleError::InvalidUtf8(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for TailscaleError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
TailscaleError::IoError(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Helper function to get error message from the server handle
|
||||
// This helper is needed because TsnetErrmsg requires the server handle (sd)
|
||||
fn get_tsnet_errmsg(sd: c_int) -> String {
|
||||
let mut buf = [0u8; 256]; // Choose a reasonable buffer size
|
||||
let message = unsafe { TsnetErrmsg(sd, buf.as_mut_ptr() as *mut c_char, buf.len()) };
|
||||
|
||||
if message == 0 {
|
||||
// Success, buf contains the null-terminated string
|
||||
let c_str = unsafe { CStr::from_ptr(buf.as_ptr() as *const c_char) };
|
||||
c_str.to_string_lossy().into_owned()
|
||||
} else {
|
||||
// If errmsg itself failed
|
||||
format!("(Failed to get error message, TsnetErrmsg returned {})", message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn parse_tsnet_result(sd: c_int, ret: c_int) -> Result<(), TailscaleError> {
|
||||
match ret {
|
||||
0 => Ok(()),
|
||||
code if code == libc::EBADF => Err(TailscaleError::BadFileDescriptor),
|
||||
code if code == libc::ERANGE => Err(TailscaleError::BufferTooSmall),
|
||||
_ => {
|
||||
let message = get_tsnet_errmsg(sd);
|
||||
Err(TailscaleError::ApiError(ret, message))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct Tailscale(c_int);
|
||||
|
||||
// NEEDS REVIEW. CANNOT BE BADLY DONE
|
||||
impl Drop for Tailscale {
|
||||
fn drop(&mut self) {
|
||||
let ret = unsafe { TsnetClose(self.0) };
|
||||
if ret != 0 && ret != libc::EBADF {
|
||||
eprintln!("Error closing Tailscale server {}: {}", self.0, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Tailscale {
|
||||
pub fn new() -> Self {
|
||||
Tailscale(unsafe { TsnetNewServer() })
|
||||
}
|
||||
|
||||
pub fn start(&self) -> Result<(), TailscaleError> {
|
||||
let ret = unsafe { TsnetStart(self.0) };
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn up(&self) -> Result<(), TailscaleError> {
|
||||
let ret = unsafe { TsnetUp(self.0) };
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn close(&self) -> Result<(), TailscaleError> {
|
||||
let ret = unsafe { TsnetClose(self.0) };
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn set_dir(&self, dir: &str) -> Result<(), TailscaleError> {
|
||||
let c_dir = CString::new(dir)?;
|
||||
let ret = unsafe { TsnetSetDir(self.0, c_dir.as_ptr() as *mut c_char) };
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn set_hostname<T: AsRef<str>>(&self, hostname: T) -> Result<(), TailscaleError> {
|
||||
let c_hostname = CString::new(hostname.as_ref())?;
|
||||
let ret = unsafe { TsnetSetHostname(self.0, c_hostname.as_ptr() as *mut c_char) };
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn set_authkey(&self, authkey: &str) -> Result<(), TailscaleError> {
|
||||
let c_authkey = CString::new(authkey)?;
|
||||
let ret = unsafe { TsnetSetAuthKey(self.0, c_authkey.as_ptr() as *mut c_char) };
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn set_control_url(&self, control_url: &str) -> Result<(), TailscaleError> {
|
||||
let c_control_url = CString::new(control_url)?;
|
||||
let ret = unsafe { TsnetSetControlURL(self.0, c_control_url.as_ptr() as *mut c_char) };
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn set_ephemeral(&self, ephemeral: bool) -> Result<(), TailscaleError> {
|
||||
let e: GoInt = if ephemeral { 1 } else { 0 };
|
||||
// Use GoInt (i64) based on bindgen output
|
||||
let ret = unsafe { TsnetSetEphemeral(self.0, e) };
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn set_log_fd(&self, fd: i32) -> Result<(), TailscaleError> {
|
||||
let ret = unsafe { TsnetSetLogFD(self.0, fd) };
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn get_ips<'a>(&self, buf: &'a mut [u8]) -> Result<&'a str, TailscaleError> {
|
||||
let ret = unsafe { TsnetGetIps(self.0, buf.as_mut_ptr() as *mut c_char, buf.len()) };
|
||||
match ret {
|
||||
0 => {
|
||||
let c_str = unsafe { CStr::from_ptr(buf.as_ptr() as *const c_char) };
|
||||
c_str.to_str().map_err(TailscaleError::from) // Convert Utf8Error
|
||||
},
|
||||
code if code == libc::EBADF => Err(TailscaleError::BadFileDescriptor),
|
||||
code if code == libc::ERANGE => Err(TailscaleError::BufferTooSmall),
|
||||
_ => {
|
||||
let err_msg = get_tsnet_errmsg(self.0);
|
||||
Err(TailscaleError::ApiError(ret, err_msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn loopback(
|
||||
&self,
|
||||
addr_buf: &mut [u8],
|
||||
proxy_buf: &mut [u8],
|
||||
local_buf: &mut [u8],
|
||||
) -> Result<(), TailscaleError> {
|
||||
// C header says proxy_cred_out and local_api_cred_out must hold 33 bytes.
|
||||
if proxy_buf.len() < 33 || local_buf.len() < 33 {
|
||||
return Err(TailscaleError::BufferTooSmall); // Custom check based on docs
|
||||
}
|
||||
|
||||
let ret = unsafe {
|
||||
TsnetLoopback(
|
||||
self.0,
|
||||
addr_buf.as_mut_ptr() as *mut c_char,
|
||||
addr_buf.len(),
|
||||
proxy_buf.as_mut_ptr() as *mut c_char,
|
||||
local_buf.as_mut_ptr() as *mut c_char,
|
||||
)
|
||||
};
|
||||
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
/// Configures Funnel to route requests from the public web to a local plaintext HTTP/1 server.
|
||||
pub fn enable_funnel_to_localhost_plaintext_http1(
|
||||
&self,
|
||||
localhost_port: i32,
|
||||
) -> Result<(), TailscaleError> {
|
||||
let ret = unsafe { TsnetEnableFunnelToLocalhostPlaintextHttp1(self.0, localhost_port as c_int) };
|
||||
// Returns 0 on success or -1 on error.
|
||||
parse_tsnet_result(self.0, ret)
|
||||
}
|
||||
|
||||
pub fn get_last_error_message<'a>(&self, buf: &'a mut [u8]) -> Result<&'a str, TailscaleError> {
|
||||
let ret = unsafe { TsnetErrmsg(self.0, buf.as_mut_ptr() as *mut c_char, buf.len()) };
|
||||
match ret {
|
||||
0 => {
|
||||
let c_str = unsafe { CStr::from_ptr(buf.as_ptr() as *const c_char) };
|
||||
c_str.to_str().map_err(TailscaleError::from) // Convert Utf8Error
|
||||
}
|
||||
code if code == libc::EBADF => Err(TailscaleError::BadFileDescriptor),
|
||||
code if code == libc::ERANGE => Err(TailscaleError::BufferTooSmall),
|
||||
// TsnetErrmsg should ideally not return other codes, but handle defensively
|
||||
_ => Err(TailscaleError::ApiError(ret, format!("TsnetErrmsg returned unknown code {}", ret))),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user