added exclusive_tcp, and error_report
This commit is contained in:
parent
a3977ba52a
commit
7767096909
@ -6,7 +6,7 @@ Wants=network.target
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/usr/local/punchnet
|
||||
ExecStart=/usr/local/punchnet/punchnet
|
||||
ExecStart=/usr/local/punchnet/punchnet start
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@ -169,10 +169,23 @@ where T: Serialize + HMacCalculator,
|
||||
};
|
||||
|
||||
// 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);
|
||||
let data = serde_json::from_str(&text).unwrap();
|
||||
// let data = serde_json::from_str(&text).unwrap();
|
||||
|
||||
// println!("response: {}", response.text().await.unwrap());
|
||||
// let Ok(data) = response.json().await else {
|
||||
|
||||
@ -167,7 +167,7 @@ async fn daemonize_me(
|
||||
println!("hostname = {:?}", hostname);
|
||||
*/
|
||||
|
||||
let _ = run_sdlan(
|
||||
if let Err(e) = run_sdlan(
|
||||
client_id,
|
||||
mac,
|
||||
CommandLine {
|
||||
@ -196,8 +196,11 @@ async fn daemonize_me(
|
||||
server,
|
||||
Some(self_host_name),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
.await {
|
||||
panic!("failed to run_sdlan: {}", e.as_str());
|
||||
};
|
||||
|
||||
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};
|
||||
use sdlan_sn_rs::utils::{Mac, save_to_file};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::net::UdpSocket;
|
||||
use tokio::net::{TcpListener, UdpSocket};
|
||||
use tokio::sync::mpsc::{channel, Sender};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::{debug, error};
|
||||
@ -59,13 +59,15 @@ pub async fn run_sdlan(
|
||||
server_ip: String,
|
||||
|
||||
hostname: Option<String>,
|
||||
connecting_chan: Option<Sender<ConnectionInfo>>, // start_stop_sender: Sender<String>,
|
||||
// start_stop_receiver: Receiver<String>,
|
||||
connecting_chan: Option<Sender<ConnectionInfo>>,
|
||||
// report error to
|
||||
error_report_channel: Option<Sender<ErrorReport>>,
|
||||
) -> Result<()> {
|
||||
let (start_stop_sender, start_stop_chan) = channel(20);
|
||||
// let edge_uuid = create_or_load_uuid(&format!("{}/.id", get_base_dir()), None)?;
|
||||
let node_conf = parse_config(edge_uuid, &args).await?;
|
||||
|
||||
|
||||
let hostfile = format!("{}/.host", get_base_dir());
|
||||
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 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.network_code,
|
||||
&args,
|
||||
@ -91,11 +105,11 @@ pub async fn run_sdlan(
|
||||
hostname,
|
||||
server_ip,
|
||||
install_channel.to_owned(),
|
||||
error_report_channel,
|
||||
exclusive_tcp,
|
||||
)
|
||||
.await
|
||||
{
|
||||
panic!("failed to init edge: {:?}", e);
|
||||
}
|
||||
.await?;
|
||||
|
||||
let _ = sender.send(true);
|
||||
debug!("edge inited");
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, AtomicU8, Ordering};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::time::Duration;
|
||||
use tokio::io::AsyncReadExt;
|
||||
use tokio::net::UdpSocket;
|
||||
use tokio::net::{TcpListener, UdpSocket};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
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::utils::Socket;
|
||||
use crate::{
|
||||
get_base_dir, get_default_interface, CommandLine, ConnectionInfo, DNSMatcher, MyEncryptor,
|
||||
RuleCache,
|
||||
CommandLine, ConnectionInfo, DNSMatcher, ErrorReport, ErrorSeverity, MyEncryptor, RuleCache, get_base_dir, get_default_interface
|
||||
};
|
||||
|
||||
use sdlan_sn_rs::peer::{IpSubnet, V6Info};
|
||||
@ -57,6 +56,8 @@ pub async fn init_edge(
|
||||
hostname: String,
|
||||
server_ip: String,
|
||||
install_channel: String,
|
||||
error_report_channel: Option<Sender<ErrorReport>>,
|
||||
exclusive_tcp: TcpListener,
|
||||
) -> Result<()> {
|
||||
// gen public key
|
||||
let rsa_path = format!("{}/.client", get_base_dir());
|
||||
@ -108,6 +109,27 @@ pub async fn init_edge(
|
||||
// TODO: set the sn's tcp socket
|
||||
// let tcpsock = TCPSocket::build("121.4.79.234:1234").await?;
|
||||
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(
|
||||
mac,
|
||||
pubkey,
|
||||
@ -128,6 +150,9 @@ pub async fn init_edge(
|
||||
server_ip,
|
||||
install_channel,
|
||||
args.take_dns,
|
||||
error_report_channel,
|
||||
iface,
|
||||
exclusive_tcp,
|
||||
);
|
||||
|
||||
edge.route_table
|
||||
@ -288,9 +313,13 @@ pub struct Node {
|
||||
|
||||
nat_cookie: AtomicU32,
|
||||
|
||||
error_report_channel: Option<Sender<ErrorReport>>,
|
||||
|
||||
//cookie_match: DashMap<u32, oneshot::Sender<SdlStunProbeReply>>,
|
||||
pub cookie_match: Queryer,
|
||||
// packet_id_match: DashMap<u32, oneshot::Sender<RegisterSuperFeedback>>,
|
||||
|
||||
exclusive_tcp: TcpListener,
|
||||
}
|
||||
|
||||
unsafe impl Sync for Node {}
|
||||
@ -442,12 +471,11 @@ impl Node {
|
||||
server_ip: String,
|
||||
install_channel: String,
|
||||
take_over_dns: bool,
|
||||
// 是否需要上报错误信息
|
||||
error_report_info: Option<Sender<ErrorReport>>,
|
||||
virtual_iface: Iface,
|
||||
tcp_listener: TcpListener,
|
||||
) -> Self {
|
||||
let mode = if cfg!(not(feature = "tun")) {
|
||||
Mode::Tap
|
||||
} else {
|
||||
Mode::Tun
|
||||
};
|
||||
|
||||
Self {
|
||||
#[cfg(any(feature = "tun", target_os = "windows"))]
|
||||
@ -485,7 +513,7 @@ impl Node {
|
||||
nat_type: Mutex::new(NatType::Blocked),
|
||||
|
||||
device_config: DeviceConfig::new(mac, mtu),
|
||||
device: new_iface("dev", mode),
|
||||
device: virtual_iface,
|
||||
|
||||
authorized: AtomicBool::new(false),
|
||||
// encrypt_key: RwLock::new(Arc::new(Vec::new())),
|
||||
@ -519,9 +547,11 @@ impl Node {
|
||||
// packet_id_match: DashMap::new(),
|
||||
nat_cookie: AtomicU32::new(1),
|
||||
cookie_match: Queryer::new(),
|
||||
error_report_channel: error_report_info,
|
||||
server_ip,
|
||||
install_channel,
|
||||
take_over_dns,
|
||||
exclusive_tcp: tcp_listener,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ use std::ptr::null_mut;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
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::process::Command;
|
||||
|
||||
@ -66,12 +66,13 @@ pub struct Iface {
|
||||
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) {
|
||||
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> {
|
||||
let mut pkt = self
|
||||
let Ok(mut pkt) = self
|
||||
.session
|
||||
.allocate_send_packet(content.len() as u16)
|
||||
.unwrap();
|
||||
.allocate_send_packet(content.len() as u16) else {
|
||||
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();
|
||||
buf.copy_from_slice(content);
|
||||
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 adapter = match wintun::Adapter::open(&wt, name) {
|
||||
Ok(a) => a,
|
||||
Err(_e) => wintun::Adapter::create(&wt, name, "Example", None)
|
||||
.expect("failed to create tun adapter"),
|
||||
Err(_e) => {
|
||||
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
|
||||
.get_adapter_index()
|
||||
.expect("failed to get adapter index");
|
||||
// println!("idx = {}", idx);
|
||||
let session = Arc::new(adapter.start_session(wintun::MAX_RING_CAPACITY).unwrap());
|
||||
Iface {
|
||||
let Ok(sess) = adapter.start_session(wintun::MAX_RING_CAPACITY) else {
|
||||
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,
|
||||
_adapter: adapter,
|
||||
session,
|
||||
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)
|
||||
// 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;
|
||||
};
|
||||
let mut reader = BufReader::new(file);
|
||||
let key = private_key(&mut reader).unwrap();
|
||||
key
|
||||
if let Ok(key) = private_key(&mut reader) {
|
||||
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 file_configuration;
|
||||
mod dns;
|
||||
mod error_report;
|
||||
|
||||
use std::{fs::OpenOptions, io::Write, net::Ipv4Addr, path::Path};
|
||||
use tracing::error;
|
||||
@ -13,6 +14,7 @@ pub use command::*;
|
||||
pub use acl_session::*;
|
||||
pub use system_action::*;
|
||||
pub use dns::*;
|
||||
pub use error_report::*;
|
||||
|
||||
mod socks;
|
||||
use rand::Rng;
|
||||
@ -52,7 +54,9 @@ pub fn ip_string_to_u32(ip: &str) -> Result<u32> {
|
||||
pub fn get_access_token() -> Option<CachedLoginInfo> {
|
||||
let path = format!("{}/.access_token", get_base_dir());
|
||||
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);
|
||||
}
|
||||
None
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user