added exclusive_tcp, and error_report
This commit is contained in:
parent
a3977ba52a
commit
7767096909
@ -6,7 +6,7 @@ Wants=network.target
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
WorkingDirectory=/usr/local/punchnet
|
WorkingDirectory=/usr/local/punchnet
|
||||||
ExecStart=/usr/local/punchnet/punchnet
|
ExecStart=/usr/local/punchnet/punchnet start
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@ -169,10 +169,23 @@ where T: Serialize + HMacCalculator,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// println!("status: {}", response.status());
|
// println!("status: {}", response.status());
|
||||||
let text = response.text().await.unwrap();
|
// let text = response.text().await.unwrap();
|
||||||
|
let text = match response.text().await {
|
||||||
|
Ok(text) => text,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(SDLanError::IOError(format!("failed to get response text: {}", e)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let data = match serde_json::from_str(&text) {
|
||||||
|
Ok(data) => data,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(SDLanError::IOError(format!("failed to deserialize text: {}", e)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// println!("got test: {}", text);
|
// println!("got test: {}", text);
|
||||||
let data = serde_json::from_str(&text).unwrap();
|
// let data = serde_json::from_str(&text).unwrap();
|
||||||
|
|
||||||
// println!("response: {}", response.text().await.unwrap());
|
// println!("response: {}", response.text().await.unwrap());
|
||||||
// let Ok(data) = response.json().await else {
|
// let Ok(data) = response.json().await else {
|
||||||
|
|||||||
@ -167,7 +167,7 @@ async fn daemonize_me(
|
|||||||
println!("hostname = {:?}", hostname);
|
println!("hostname = {:?}", hostname);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let _ = run_sdlan(
|
if let Err(e) = run_sdlan(
|
||||||
client_id,
|
client_id,
|
||||||
mac,
|
mac,
|
||||||
CommandLine {
|
CommandLine {
|
||||||
@ -196,8 +196,11 @@ async fn daemonize_me(
|
|||||||
server,
|
server,
|
||||||
Some(self_host_name),
|
Some(self_host_name),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
.await;
|
.await {
|
||||||
|
panic!("failed to run_sdlan: {}", e.as_str());
|
||||||
|
};
|
||||||
|
|
||||||
let _ = rx.recv();
|
let _ = rx.recv();
|
||||||
|
|
||||||
|
|||||||
30
src/lib.rs
30
src/lib.rs
@ -17,7 +17,7 @@ pub use network::{async_main, init_edge, NodeConfig, restore_dns};
|
|||||||
pub use network::{RouteInfo, set_route_from_net};
|
pub use network::{RouteInfo, set_route_from_net};
|
||||||
use sdlan_sn_rs::utils::{Mac, save_to_file};
|
use sdlan_sn_rs::utils::{Mac, save_to_file};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::{TcpListener, UdpSocket};
|
||||||
use tokio::sync::mpsc::{channel, Sender};
|
use tokio::sync::mpsc::{channel, Sender};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
@ -59,13 +59,15 @@ pub async fn run_sdlan(
|
|||||||
server_ip: String,
|
server_ip: String,
|
||||||
|
|
||||||
hostname: Option<String>,
|
hostname: Option<String>,
|
||||||
connecting_chan: Option<Sender<ConnectionInfo>>, // start_stop_sender: Sender<String>,
|
connecting_chan: Option<Sender<ConnectionInfo>>,
|
||||||
// start_stop_receiver: Receiver<String>,
|
// report error to
|
||||||
|
error_report_channel: Option<Sender<ErrorReport>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let (start_stop_sender, start_stop_chan) = channel(20);
|
let (start_stop_sender, start_stop_chan) = channel(20);
|
||||||
// let edge_uuid = create_or_load_uuid(&format!("{}/.id", get_base_dir()), None)?;
|
// let edge_uuid = create_or_load_uuid(&format!("{}/.id", get_base_dir()), None)?;
|
||||||
let node_conf = parse_config(edge_uuid, &args).await?;
|
let node_conf = parse_config(edge_uuid, &args).await?;
|
||||||
|
|
||||||
|
|
||||||
let hostfile = format!("{}/.host", get_base_dir());
|
let hostfile = format!("{}/.host", get_base_dir());
|
||||||
let host = create_or_load_uuid(&hostfile, Some(8))?;
|
let host = create_or_load_uuid(&hostfile, Some(8))?;
|
||||||
|
|
||||||
@ -76,7 +78,19 @@ pub async fn run_sdlan(
|
|||||||
let sock_dns = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
|
let sock_dns = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
|
||||||
let udp_sock_for_global_dns = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
|
let udp_sock_for_global_dns = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
|
||||||
|
|
||||||
if let Err(e) = init_edge(
|
let exclusive_tcp = match TcpListener::bind("127.0.0.1:7653").await {
|
||||||
|
Ok(tcp) => tcp,
|
||||||
|
Err(e) => {
|
||||||
|
if let Some(ref chan) = error_report_channel {
|
||||||
|
chan.send(ErrorReport { severity: ErrorSeverity::Panic, message: "bind tcp failed, is process already running?".to_string() }).await;
|
||||||
|
return Err(e.into());
|
||||||
|
} else {
|
||||||
|
panic!("new iface failed: {}", e.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
init_edge(
|
||||||
// &args.token,
|
// &args.token,
|
||||||
// &args.network_code,
|
// &args.network_code,
|
||||||
&args,
|
&args,
|
||||||
@ -91,11 +105,11 @@ pub async fn run_sdlan(
|
|||||||
hostname,
|
hostname,
|
||||||
server_ip,
|
server_ip,
|
||||||
install_channel.to_owned(),
|
install_channel.to_owned(),
|
||||||
|
error_report_channel,
|
||||||
|
exclusive_tcp,
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
{
|
|
||||||
panic!("failed to init edge: {:?}", e);
|
|
||||||
}
|
|
||||||
let _ = sender.send(true);
|
let _ = sender.send(true);
|
||||||
debug!("edge inited");
|
debug!("edge inited");
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, AtomicU8, Ordering};
|
|||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
use tokio::net::UdpSocket;
|
use tokio::net::{TcpListener, UdpSocket};
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error, warn};
|
||||||
|
|
||||||
@ -25,8 +25,7 @@ use crate::quic::quic_init;
|
|||||||
use crate::tcp::{get_quic_write_conn, NatType, PacketType, StunProbeAttr};
|
use crate::tcp::{get_quic_write_conn, NatType, PacketType, StunProbeAttr};
|
||||||
use crate::utils::Socket;
|
use crate::utils::Socket;
|
||||||
use crate::{
|
use crate::{
|
||||||
get_base_dir, get_default_interface, CommandLine, ConnectionInfo, DNSMatcher, MyEncryptor,
|
CommandLine, ConnectionInfo, DNSMatcher, ErrorReport, ErrorSeverity, MyEncryptor, RuleCache, get_base_dir, get_default_interface
|
||||||
RuleCache,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use sdlan_sn_rs::peer::{IpSubnet, V6Info};
|
use sdlan_sn_rs::peer::{IpSubnet, V6Info};
|
||||||
@ -57,6 +56,8 @@ pub async fn init_edge(
|
|||||||
hostname: String,
|
hostname: String,
|
||||||
server_ip: String,
|
server_ip: String,
|
||||||
install_channel: String,
|
install_channel: String,
|
||||||
|
error_report_channel: Option<Sender<ErrorReport>>,
|
||||||
|
exclusive_tcp: TcpListener,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// gen public key
|
// gen public key
|
||||||
let rsa_path = format!("{}/.client", get_base_dir());
|
let rsa_path = format!("{}/.client", get_base_dir());
|
||||||
@ -108,6 +109,27 @@ pub async fn init_edge(
|
|||||||
// TODO: set the sn's tcp socket
|
// TODO: set the sn's tcp socket
|
||||||
// let tcpsock = TCPSocket::build("121.4.79.234:1234").await?;
|
// let tcpsock = TCPSocket::build("121.4.79.234:1234").await?;
|
||||||
let tcp_pong = Arc::new(AtomicU64::new(0));
|
let tcp_pong = Arc::new(AtomicU64::new(0));
|
||||||
|
|
||||||
|
|
||||||
|
let mode = if cfg!(not(feature = "tun")) {
|
||||||
|
Mode::Tap
|
||||||
|
} else {
|
||||||
|
Mode::Tun
|
||||||
|
};
|
||||||
|
|
||||||
|
let iface = match new_iface("dev", mode) {
|
||||||
|
Ok(iface) => iface,
|
||||||
|
Err(e) => {
|
||||||
|
if let Some(ref chan) = error_report_channel {
|
||||||
|
chan.send(ErrorReport { severity: ErrorSeverity::Panic, message: e.to_string() }).await;
|
||||||
|
return Err(e.into());
|
||||||
|
} else {
|
||||||
|
panic!("new iface failed: {}", e.to_string());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
let edge = Node::new(
|
let edge = Node::new(
|
||||||
mac,
|
mac,
|
||||||
pubkey,
|
pubkey,
|
||||||
@ -128,6 +150,9 @@ pub async fn init_edge(
|
|||||||
server_ip,
|
server_ip,
|
||||||
install_channel,
|
install_channel,
|
||||||
args.take_dns,
|
args.take_dns,
|
||||||
|
error_report_channel,
|
||||||
|
iface,
|
||||||
|
exclusive_tcp,
|
||||||
);
|
);
|
||||||
|
|
||||||
edge.route_table
|
edge.route_table
|
||||||
@ -288,9 +313,13 @@ pub struct Node {
|
|||||||
|
|
||||||
nat_cookie: AtomicU32,
|
nat_cookie: AtomicU32,
|
||||||
|
|
||||||
|
error_report_channel: Option<Sender<ErrorReport>>,
|
||||||
|
|
||||||
//cookie_match: DashMap<u32, oneshot::Sender<SdlStunProbeReply>>,
|
//cookie_match: DashMap<u32, oneshot::Sender<SdlStunProbeReply>>,
|
||||||
pub cookie_match: Queryer,
|
pub cookie_match: Queryer,
|
||||||
// packet_id_match: DashMap<u32, oneshot::Sender<RegisterSuperFeedback>>,
|
// packet_id_match: DashMap<u32, oneshot::Sender<RegisterSuperFeedback>>,
|
||||||
|
|
||||||
|
exclusive_tcp: TcpListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Sync for Node {}
|
unsafe impl Sync for Node {}
|
||||||
@ -442,12 +471,11 @@ impl Node {
|
|||||||
server_ip: String,
|
server_ip: String,
|
||||||
install_channel: String,
|
install_channel: String,
|
||||||
take_over_dns: bool,
|
take_over_dns: bool,
|
||||||
|
// 是否需要上报错误信息
|
||||||
|
error_report_info: Option<Sender<ErrorReport>>,
|
||||||
|
virtual_iface: Iface,
|
||||||
|
tcp_listener: TcpListener,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mode = if cfg!(not(feature = "tun")) {
|
|
||||||
Mode::Tap
|
|
||||||
} else {
|
|
||||||
Mode::Tun
|
|
||||||
};
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
#[cfg(any(feature = "tun", target_os = "windows"))]
|
#[cfg(any(feature = "tun", target_os = "windows"))]
|
||||||
@ -485,7 +513,7 @@ impl Node {
|
|||||||
nat_type: Mutex::new(NatType::Blocked),
|
nat_type: Mutex::new(NatType::Blocked),
|
||||||
|
|
||||||
device_config: DeviceConfig::new(mac, mtu),
|
device_config: DeviceConfig::new(mac, mtu),
|
||||||
device: new_iface("dev", mode),
|
device: virtual_iface,
|
||||||
|
|
||||||
authorized: AtomicBool::new(false),
|
authorized: AtomicBool::new(false),
|
||||||
// encrypt_key: RwLock::new(Arc::new(Vec::new())),
|
// encrypt_key: RwLock::new(Arc::new(Vec::new())),
|
||||||
@ -519,9 +547,11 @@ impl Node {
|
|||||||
// packet_id_match: DashMap::new(),
|
// packet_id_match: DashMap::new(),
|
||||||
nat_cookie: AtomicU32::new(1),
|
nat_cookie: AtomicU32::new(1),
|
||||||
cookie_match: Queryer::new(),
|
cookie_match: Queryer::new(),
|
||||||
|
error_report_channel: error_report_info,
|
||||||
server_ip,
|
server_ip,
|
||||||
install_channel,
|
install_channel,
|
||||||
take_over_dns,
|
take_over_dns,
|
||||||
|
exclusive_tcp: tcp_listener,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ use std::ptr::null_mut;
|
|||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
use sdlan_sn_rs::utils::Result;
|
use sdlan_sn_rs::utils::Result;
|
||||||
use std::io::{BufRead, BufReader, Read, Write};
|
use std::io::{BufRead, BufReader, ErrorKind, Read, Write};
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::AsRawFd;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
@ -66,12 +66,13 @@ pub struct Iface {
|
|||||||
has_resolvectl: bool,
|
has_resolvectl: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_iface(tunname: &str, mode: Mode) -> Iface {
|
pub fn new_iface(tunname: &str, mode: Mode) -> std::io::Result<Iface> {
|
||||||
match Iface::without_packet_info(tunname, mode) {
|
match Iface::without_packet_info(tunname, mode) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
panic!("failed to create tun: {}", e.as_str());
|
error!("failed to create tun: {}", e.as_str());
|
||||||
|
Err(std::io::Error::new(ErrorKind::Other, "failed to create virtial device, is run with root?"))
|
||||||
}
|
}
|
||||||
Ok(iface) => iface,
|
Ok(iface) => Ok(iface),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -55,10 +55,12 @@ impl Iface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(&self, content: &[u8]) -> std::io::Result<usize> {
|
pub fn send(&self, content: &[u8]) -> std::io::Result<usize> {
|
||||||
let mut pkt = self
|
let Ok(mut pkt) = self
|
||||||
.session
|
.session
|
||||||
.allocate_send_packet(content.len() as u16)
|
.allocate_send_packet(content.len() as u16) else {
|
||||||
.unwrap();
|
error!("failed to allocate send packet");
|
||||||
|
return Err(std::io::Error::new(std::io::ErrorKind::Other, "failed to allocate send packet"));
|
||||||
|
};
|
||||||
let buf: &mut [u8] = pkt.bytes_mut();
|
let buf: &mut [u8] = pkt.bytes_mut();
|
||||||
buf.copy_from_slice(content);
|
buf.copy_from_slice(content);
|
||||||
self.session.send_packet(pkt);
|
self.session.send_packet(pkt);
|
||||||
@ -727,28 +729,35 @@ impl TunTapPacketHandler for Iface {
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_wintun(path: &str, name: &str) -> Iface {
|
fn create_wintun(path: &str, name: &str) -> std::io::Result<Iface> {
|
||||||
let wt = unsafe { wintun::load_from_path(path) }.expect("failed to load wintun");
|
let wt = unsafe { wintun::load_from_path(path) }.expect("failed to load wintun");
|
||||||
|
|
||||||
let adapter = match wintun::Adapter::open(&wt, name) {
|
let adapter = match wintun::Adapter::open(&wt, name) {
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
Err(_e) => wintun::Adapter::create(&wt, name, "Example", None)
|
Err(_e) => {
|
||||||
.expect("failed to create tun adapter"),
|
let Ok(adapt) = wintun::Adapter::create(&wt, name, "Punchnet", None) else {
|
||||||
|
return Err(std::io::Error::new(std::io::ErrorKind::Other, "failed to create Punch adapter"));
|
||||||
|
};
|
||||||
|
adapt
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let idx = adapter
|
let idx = adapter
|
||||||
.get_adapter_index()
|
.get_adapter_index()
|
||||||
.expect("failed to get adapter index");
|
.expect("failed to get adapter index");
|
||||||
// println!("idx = {}", idx);
|
// println!("idx = {}", idx);
|
||||||
let session = Arc::new(adapter.start_session(wintun::MAX_RING_CAPACITY).unwrap());
|
let Ok(sess) = adapter.start_session(wintun::MAX_RING_CAPACITY) else {
|
||||||
Iface {
|
return Err(std::io::Error::new(std::io::ErrorKind::Other, "failed to start session, maybe one process is running, or not running with admin?"));
|
||||||
|
};
|
||||||
|
let session = Arc::new(sess);
|
||||||
|
Ok(Iface {
|
||||||
if_idx: idx,
|
if_idx: idx,
|
||||||
_adapter: adapter,
|
_adapter: adapter,
|
||||||
session,
|
session,
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_iface(name: &str, _mode: Mode) -> Iface {
|
pub fn new_iface(name: &str, _mode: Mode) -> std::io::Result<Iface> {
|
||||||
create_wintun("./wintun.dll", name)
|
create_wintun("./wintun.dll", name)
|
||||||
// Ok(Box::new(create_wintun("/path/to/file")))
|
// Ok(Box::new(create_wintun("/path/to/file")))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -147,6 +147,8 @@ pub fn load_private_key_from_pem(path: impl AsRef<Path>) -> Option<PrivateKeyDer
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let mut reader = BufReader::new(file);
|
let mut reader = BufReader::new(file);
|
||||||
let key = private_key(&mut reader).unwrap();
|
if let Ok(key) = private_key(&mut reader) {
|
||||||
key
|
return key
|
||||||
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/utils/error_report.rs
Normal file
17
src/utils/error_report.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum ErrorSeverity {
|
||||||
|
Panic,
|
||||||
|
Error,
|
||||||
|
Warning,
|
||||||
|
Info,
|
||||||
|
Log,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub struct ErrorReport {
|
||||||
|
pub severity: ErrorSeverity,
|
||||||
|
pub message: String,
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ mod encrypter;
|
|||||||
mod system_action;
|
mod system_action;
|
||||||
mod file_configuration;
|
mod file_configuration;
|
||||||
mod dns;
|
mod dns;
|
||||||
|
mod error_report;
|
||||||
|
|
||||||
use std::{fs::OpenOptions, io::Write, net::Ipv4Addr, path::Path};
|
use std::{fs::OpenOptions, io::Write, net::Ipv4Addr, path::Path};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
@ -13,6 +14,7 @@ pub use command::*;
|
|||||||
pub use acl_session::*;
|
pub use acl_session::*;
|
||||||
pub use system_action::*;
|
pub use system_action::*;
|
||||||
pub use dns::*;
|
pub use dns::*;
|
||||||
|
pub use error_report::*;
|
||||||
|
|
||||||
mod socks;
|
mod socks;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
@ -52,7 +54,9 @@ pub fn ip_string_to_u32(ip: &str) -> Result<u32> {
|
|||||||
pub fn get_access_token() -> Option<CachedLoginInfo> {
|
pub fn get_access_token() -> Option<CachedLoginInfo> {
|
||||||
let path = format!("{}/.access_token", get_base_dir());
|
let path = format!("{}/.access_token", get_base_dir());
|
||||||
if let Ok(content) = std::fs::read(&path) {
|
if let Ok(content) = std::fs::read(&path) {
|
||||||
let data = serde_json::from_slice(&content).unwrap();
|
let Ok(data) = serde_json::from_slice(&content) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
return Some(data);
|
return Some(data);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user