This commit is contained in:
sijie.sun
2024-05-03 07:55:00 +08:00
parent 1be6db661e
commit 873851e6d0
20 changed files with 373 additions and 530 deletions
-1
View File
@@ -13,7 +13,6 @@ pub mod global_ctx;
pub mod ifcfg;
pub mod netns;
pub mod network;
pub mod rkyv_util;
pub mod stun;
pub mod stun_codec_ext;
-72
View File
@@ -1,72 +0,0 @@
use rkyv::{
string::ArchivedString,
validation::{validators::DefaultValidator, CheckTypeError},
vec::ArchivedVec,
Archive, CheckBytes, Serialize,
};
use tokio_util::bytes::{Bytes, BytesMut};
pub fn decode_from_bytes_checked<'a, T: Archive>(
bytes: &'a [u8],
) -> Result<&'a T::Archived, CheckTypeError<T::Archived, DefaultValidator<'a>>>
where
T::Archived: CheckBytes<DefaultValidator<'a>>,
{
rkyv::check_archived_root::<T>(bytes)
}
pub fn decode_from_bytes<'a, T: Archive>(
bytes: &'a [u8],
) -> Result<&'a T::Archived, CheckTypeError<T::Archived, DefaultValidator<'a>>>
where
T::Archived: CheckBytes<DefaultValidator<'a>>,
{
// rkyv::check_archived_root::<T>(bytes)
unsafe { Ok(rkyv::archived_root::<T>(bytes)) }
}
// allow deseraial T to Bytes
pub fn encode_to_bytes<T, const N: usize>(val: &T) -> Bytes
where
T: Serialize<rkyv::ser::serializers::AllocSerializer<N>>,
{
let ret = rkyv::to_bytes::<_, N>(val).unwrap();
// let mut r = BytesMut::new();
// r.extend_from_slice(&ret);
// r.freeze()
ret.into_boxed_slice().into()
}
pub fn extract_bytes_from_archived_vec(raw_data: &Bytes, archived_data: &ArchivedVec<u8>) -> Bytes {
let ptr_range = archived_data.as_ptr_range();
let offset = ptr_range.start as usize - raw_data.as_ptr() as usize;
let len = ptr_range.end as usize - ptr_range.start as usize;
return raw_data.slice(offset..offset + len);
}
pub fn extract_bytes_from_archived_string(
raw_data: &Bytes,
archived_data: &ArchivedString,
) -> Bytes {
let offset = archived_data.as_ptr() as usize - raw_data.as_ptr() as usize;
let len = archived_data.len();
if offset + len > raw_data.len() {
return Bytes::new();
}
return raw_data.slice(offset..offset + archived_data.len());
}
pub fn extract_bytes_mut_from_archived_vec(
raw_data: &mut BytesMut,
archived_data: &ArchivedVec<u8>,
) -> BytesMut {
let ptr_range = archived_data.as_ptr_range();
let offset = ptr_range.start as usize - raw_data.as_ptr() as usize;
let len = ptr_range.end as usize - ptr_range.start as usize;
raw_data.split_off(offset).split_to(len)
}
pub fn vec_to_string(vec: Vec<u8>) -> String {
unsafe { String::from_utf8_unchecked(vec) }
}
+8 -7
View File
@@ -3,16 +3,15 @@ use std::{
sync::Arc,
};
#[cfg(feature = "quic")]
use crate::tunnel::quic::QUICTunnelConnector;
#[cfg(feature = "wireguard")]
use crate::tunnel::wireguard::{WgConfig, WgTunnelConnector};
use crate::{
common::{error::Error, global_ctx::ArcGlobalCtx, network::IPCollector},
tunnel::{
check_scheme_and_get_socket_addr,
quic::QUICTunnelConnector,
ring::RingTunnelConnector,
tcp::TcpTunnelConnector,
udp::UdpTunnelConnector,
wireguard::{WgConfig, WgTunnelConnector},
TunnelConnector,
check_scheme_and_get_socket_addr, ring::RingTunnelConnector, tcp::TcpTunnelConnector,
udp::UdpTunnelConnector, TunnelConnector,
},
};
@@ -77,6 +76,7 @@ pub async fn create_connector_by_url(
let connector = RingTunnelConnector::new(url);
return Ok(Box::new(connector));
}
#[cfg(feature = "quic")]
"quic" => {
let dst_addr = check_scheme_and_get_socket_addr::<SocketAddr>(&url, "quic")?;
let mut connector = QUICTunnelConnector::new(url);
@@ -88,6 +88,7 @@ pub async fn create_connector_by_url(
.await;
return Ok(Box::new(connector));
}
#[cfg(feature = "wireguard")]
"wg" => {
let dst_addr = check_scheme_and_get_socket_addr::<SocketAddr>(&url, "wg")?;
let nid = global_ctx.get_network_identity();
+2
View File
@@ -32,8 +32,10 @@ use crate::common::{
global_ctx::GlobalCtxEvent,
};
#[cfg(feature = "mimalloc")]
use mimalloc_rust::*;
#[cfg(feature = "mimalloc")]
#[global_allocator]
static GLOBAL_MIMALLOC: GlobalMiMalloc = GlobalMiMalloc;
+3
View File
@@ -130,7 +130,10 @@ impl Instance {
let peer_center = Arc::new(PeerCenterInstance::new(peer_manager.clone()));
#[cfg(feature = "wireguard")]
let vpn_portal_inst = vpn_portal::wireguard::WireGuard::default();
#[cfg(not(feature = "wireguard"))]
let vpn_portal_inst = vpn_portal::NullVpnPortal;
Instance {
inst_name: global_ctx.inst_name.clone(),
+10 -8
View File
@@ -4,6 +4,10 @@ use anyhow::Context;
use async_trait::async_trait;
use tokio::{sync::Mutex, task::JoinSet};
#[cfg(feature = "quic")]
use crate::tunnel::quic::QUICTunnelListener;
#[cfg(feature = "wireguard")]
use crate::tunnel::wireguard::{WgConfig, WgTunnelListener};
use crate::{
common::{
error::Error,
@@ -12,30 +16,28 @@ use crate::{
},
peers::peer_manager::PeerManager,
tunnel::{
quic::QUICTunnelListener,
ring::RingTunnelListener,
tcp::TcpTunnelListener,
udp::UdpTunnelListener,
wireguard::{WgConfig, WgTunnelListener},
Tunnel, TunnelListener,
ring::RingTunnelListener, tcp::TcpTunnelListener, udp::UdpTunnelListener, Tunnel,
TunnelListener,
},
};
pub fn get_listener_by_url(
l: &url::Url,
ctx: ArcGlobalCtx,
_ctx: ArcGlobalCtx,
) -> Result<Box<dyn TunnelListener>, Error> {
Ok(match l.scheme() {
"tcp" => Box::new(TcpTunnelListener::new(l.clone())),
"udp" => Box::new(UdpTunnelListener::new(l.clone())),
#[cfg(feature = "wireguard")]
"wg" => {
let nid = ctx.get_network_identity();
let nid = _ctx.get_network_identity();
let wg_config = WgConfig::new_from_network_identity(
&nid.network_name,
&nid.network_secret.unwrap_or_default(),
);
Box::new(WgTunnelListener::new(l.clone(), wg_config))
}
#[cfg(feature = "quic")]
"quic" => Box::new(QUICTunnelListener::new(l.clone())),
_ => {
unreachable!("unsupported listener uri");
+146
View File
@@ -0,0 +1,146 @@
use aes_gcm::aead::consts::{U12, U16};
use aes_gcm::aead::generic_array::GenericArray;
use aes_gcm::{AeadCore, AeadInPlace, Aes128Gcm, Aes256Gcm, Key, KeyInit, Nonce, Tag};
use rand::rngs::OsRng;
use zerocopy::{AsBytes, FromBytes};
use crate::tunnel::packet_def::{AesGcmTail, ZCPacket, AES_GCM_ENCRYPTION_RESERVED};
use super::{Encryptor, Error};
#[derive(Clone)]
pub struct AesGcmCipher {
pub(crate) cipher: AesGcmEnum,
}
#[derive(Clone)]
pub enum AesGcmEnum {
AES128GCM(Aes128Gcm),
AES256GCM(Aes256Gcm),
}
impl AesGcmCipher {
pub fn new_128(key: [u8; 16]) -> Self {
let key: &Key<Aes128Gcm> = &key.into();
Self {
cipher: AesGcmEnum::AES128GCM(Aes128Gcm::new(key)),
}
}
pub fn new_256(key: [u8; 32]) -> Self {
let key: &Key<Aes256Gcm> = &key.into();
Self {
cipher: AesGcmEnum::AES256GCM(Aes256Gcm::new(key)),
}
}
}
impl Encryptor for AesGcmCipher {
fn decrypt(&self, zc_packet: &mut ZCPacket) -> Result<(), Error> {
let pm_header = zc_packet.peer_manager_header().unwrap();
if !pm_header.is_encrypted() {
return Err(Error::NotEcrypted);
}
let payload_len = zc_packet.payload().len();
if payload_len < AES_GCM_ENCRYPTION_RESERVED {
return Err(Error::PacketTooShort(zc_packet.payload().len()));
}
let text_len = payload_len - AES_GCM_ENCRYPTION_RESERVED;
let aes_tail = AesGcmTail::ref_from_suffix(zc_packet.payload())
.unwrap()
.clone();
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&aes_tail.nonce);
let tag: GenericArray<u8, U16> = Tag::clone_from_slice(aes_tail.tag.as_slice());
let rs = match &self.cipher {
AesGcmEnum::AES128GCM(aes_gcm) => aes_gcm.decrypt_in_place_detached(
nonce,
&[],
&mut zc_packet.mut_payload()[..text_len],
&tag,
),
AesGcmEnum::AES256GCM(aes_gcm) => aes_gcm.decrypt_in_place_detached(
nonce,
&[],
&mut zc_packet.mut_payload()[..text_len],
&tag,
),
};
if let Err(e) = rs {
println!("error: {:?}", e.to_string());
return Err(Error::DecryptionFailed);
}
let pm_header = zc_packet.mut_peer_manager_header().unwrap();
pm_header.set_encrypted(false);
let old_len = zc_packet.buf_len();
zc_packet
.mut_inner()
.truncate(old_len - AES_GCM_ENCRYPTION_RESERVED);
return Ok(());
}
fn encrypt(&self, zc_packet: &mut ZCPacket) -> Result<(), Error> {
let pm_header = zc_packet.peer_manager_header().unwrap();
if pm_header.is_encrypted() {
tracing::warn!(?zc_packet, "packet is already encrypted");
return Ok(());
}
let mut tail = AesGcmTail::default();
let rs = match &self.cipher {
AesGcmEnum::AES128GCM(aes_gcm) => {
let nonce = Aes128Gcm::generate_nonce(&mut OsRng);
tail.nonce.copy_from_slice(nonce.as_slice());
aes_gcm.encrypt_in_place_detached(&nonce, &[], zc_packet.mut_payload())
}
AesGcmEnum::AES256GCM(aes_gcm) => {
let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
tail.nonce.copy_from_slice(nonce.as_slice());
aes_gcm.encrypt_in_place_detached(&nonce, &[], zc_packet.mut_payload())
}
};
return match rs {
Ok(tag) => {
tail.tag.copy_from_slice(tag.as_slice());
let pm_header = zc_packet.mut_peer_manager_header().unwrap();
pm_header.set_encrypted(true);
zc_packet.mut_inner().extend_from_slice(tail.as_bytes());
Ok(())
}
Err(_) => Err(Error::EncryptionFailed),
};
}
}
#[cfg(test)]
mod tests {
use crate::{
peers::encrypt::{aes_gcm::AesGcmCipher, Encryptor},
tunnel::packet_def::{ZCPacket, AES_GCM_ENCRYPTION_RESERVED},
};
#[test]
fn test_aes_gcm_cipher() {
let key = [0u8; 16];
let cipher = AesGcmCipher::new_128(key);
let text = b"1234567";
let mut packet = ZCPacket::new_with_payload(text);
packet.fill_peer_manager_hdr(0, 0, 0);
cipher.encrypt(&mut packet).unwrap();
assert_eq!(
packet.payload().len(),
text.len() + AES_GCM_ENCRYPTION_RESERVED
);
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), true);
cipher.decrypt(&mut packet).unwrap();
assert_eq!(packet.payload(), text);
assert_eq!(packet.peer_manager_header().unwrap().is_encrypted(), false);
}
}
+4
View File
@@ -1,7 +1,11 @@
use crate::tunnel::packet_def::ZCPacket;
#[cfg(feature = "wireguard")]
pub mod ring_aes_gcm;
#[cfg(feature = "aes-gcm")]
pub mod aes_gcm;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("packet is not encrypted")]
-1
View File
@@ -1,4 +1,3 @@
pub mod packet;
pub mod peer;
// pub mod peer_conn;
pub mod peer_conn;
-254
View File
@@ -1,254 +0,0 @@
use std::fmt::Debug;
use rkyv::{Archive, Deserialize, Serialize};
use tokio_util::bytes::Bytes;
use crate::common::{
global_ctx::NetworkIdentity,
rkyv_util::{decode_from_bytes, encode_to_bytes, vec_to_string},
PeerId,
};
const MAGIC: u32 = 0xd1e1a5e1;
const VERSION: u32 = 1;
#[derive(Archive, Deserialize, Serialize, PartialEq, Clone)]
#[archive(compare(PartialEq), check_bytes)]
// Derives can be passed through to the generated type:
#[archive_attr(derive(Debug))]
pub struct UUID(uuid::Bytes);
// impl Debug for UUID
impl std::fmt::Debug for UUID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let uuid = uuid::Uuid::from_bytes(self.0);
write!(f, "{}", uuid)
}
}
impl From<uuid::Uuid> for UUID {
fn from(uuid: uuid::Uuid) -> Self {
UUID(*uuid.as_bytes())
}
}
impl From<UUID> for uuid::Uuid {
fn from(uuid: UUID) -> Self {
uuid::Uuid::from_bytes(uuid.0)
}
}
impl ArchivedUUID {
pub fn to_uuid(&self) -> uuid::Uuid {
uuid::Uuid::from_bytes(self.0)
}
}
impl From<&ArchivedUUID> for UUID {
fn from(uuid: &ArchivedUUID) -> Self {
UUID(uuid.0)
}
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct HandShake {
pub magic: u32,
pub my_peer_id: PeerId,
pub version: u32,
pub features: Vec<String>,
pub network_identity: NetworkIdentity,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct RoutePacket {
pub route_id: u8,
pub body: Vec<u8>,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub enum CtrlPacketPayload {
HandShake(HandShake),
RoutePacket(RoutePacket),
Ping(u32),
Pong(u32),
TaRpc(u32, u32, bool, Vec<u8>), // u32: service_id, u32: transact_id, bool: is_req, Vec<u8>: rpc body
}
impl CtrlPacketPayload {
pub fn from_packet(p: &ArchivedPacket) -> CtrlPacketPayload {
assert_ne!(p.packet_type, PacketType::Data);
postcard::from_bytes(p.payload.as_bytes()).unwrap()
}
pub fn from_packet2(p: &Packet) -> CtrlPacketPayload {
postcard::from_bytes(p.payload.as_bytes()).unwrap()
}
}
#[repr(u8)]
#[derive(Archive, Deserialize, Serialize, Debug)]
#[archive(compare(PartialEq), check_bytes)]
// Derives can be passed through to the generated type:
#[archive_attr(derive(Debug))]
pub enum PacketType {
Data = 1,
HandShake = 2,
RoutePacket = 3,
Ping = 4,
Pong = 5,
TaRpc = 6,
}
#[derive(Archive, Deserialize, Serialize)]
#[archive(compare(PartialEq), check_bytes)]
// Derives can be passed through to the generated type:
pub struct Packet {
pub from_peer: PeerId,
pub to_peer: PeerId,
pub packet_type: PacketType,
pub payload: String,
}
impl std::fmt::Debug for Packet {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Packet {{ from_peer: {}, to_peer: {}, packet_type: {:?}, payload: {:?} }}",
self.from_peer,
self.to_peer,
self.packet_type,
&self.payload.as_bytes()
)
}
}
impl std::fmt::Debug for ArchivedPacket {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Packet {{ from_peer: {}, to_peer: {}, packet_type: {:?}, payload: {:?} }}",
self.from_peer,
self.to_peer,
self.packet_type,
&self.payload.as_bytes()
)
}
}
impl Packet {
pub fn decode(v: &[u8]) -> &ArchivedPacket {
decode_from_bytes::<Packet>(v).unwrap()
}
pub fn new(
from_peer: PeerId,
to_peer: PeerId,
packet_type: PacketType,
payload: Vec<u8>,
) -> Self {
Packet {
from_peer,
to_peer,
packet_type,
payload: vec_to_string(payload),
}
}
}
impl From<Packet> for Bytes {
fn from(val: Packet) -> Self {
encode_to_bytes::<_, 4096>(&val)
}
}
impl Packet {
pub fn new_handshake(from_peer: PeerId, network: &NetworkIdentity) -> Self {
let handshake = CtrlPacketPayload::HandShake(HandShake {
magic: MAGIC,
my_peer_id: from_peer,
version: VERSION,
features: Vec::new(),
network_identity: network.clone().into(),
});
Packet::new(
from_peer.into(),
0,
PacketType::HandShake,
postcard::to_allocvec(&handshake).unwrap(),
)
}
pub fn new_data_packet(from_peer: PeerId, to_peer: PeerId, data: &[u8]) -> Self {
Packet::new(from_peer, to_peer, PacketType::Data, data.to_vec())
}
pub fn new_route_packet(from_peer: PeerId, to_peer: PeerId, route_id: u8, data: &[u8]) -> Self {
let route = CtrlPacketPayload::RoutePacket(RoutePacket {
route_id,
body: data.to_vec(),
});
Packet::new(
from_peer,
to_peer,
PacketType::RoutePacket,
postcard::to_allocvec(&route).unwrap(),
)
}
pub fn new_ping_packet(from_peer: PeerId, to_peer: PeerId, seq: u32) -> Self {
let ping = CtrlPacketPayload::Ping(seq);
Packet::new(
from_peer,
to_peer,
PacketType::Ping,
postcard::to_allocvec(&ping).unwrap(),
)
}
pub fn new_pong_packet(from_peer: PeerId, to_peer: PeerId, seq: u32) -> Self {
let pong = CtrlPacketPayload::Pong(seq);
Packet::new(
from_peer,
to_peer,
PacketType::Pong,
postcard::to_allocvec(&pong).unwrap(),
)
}
pub fn new_tarpc_packet(
from_peer: PeerId,
to_peer: PeerId,
service_id: u32,
transact_id: u32,
is_req: bool,
body: Vec<u8>,
) -> Self {
let ta_rpc = CtrlPacketPayload::TaRpc(service_id, transact_id, is_req, body);
Packet::new(
from_peer,
to_peer,
PacketType::TaRpc,
postcard::to_allocvec(&ta_rpc).unwrap(),
)
}
}
#[cfg(test)]
mod tests {
use crate::common::new_peer_id;
use super::*;
#[tokio::test]
async fn serialize() {
let a = "abcde";
let out = Packet::new_data_packet(new_peer_id(), new_peer_id(), a.as_bytes());
// let out = T::new(a.as_bytes());
let out_bytes: Bytes = out.into();
println!("out str: {:?}", a.as_bytes());
println!("out bytes: {:?}", out_bytes);
let archived = Packet::decode(&out_bytes[..]);
println!("in packet: {:?}", archived);
}
}
+1 -1
View File
@@ -29,8 +29,8 @@ use crate::{
global_ctx::ArcGlobalCtx,
PeerId,
},
peers::packet::PacketType,
rpc::{HandshakeRequest, PeerConnInfo, PeerConnStats, TunnelInfo},
tunnel::packet_def::PacketType,
tunnel::{
filter::{StatsRecorderTunnelFilter, TunnelFilter, TunnelWithFilter},
mpsc::{MpscTunnel, MpscTunnelSender},
+28 -10
View File
@@ -22,17 +22,18 @@ use tokio_util::bytes::Bytes;
use crate::{
common::{error::Error, global_ctx::ArcGlobalCtx, PeerId},
peers::{
packet, peer_conn::PeerConn, peer_rpc::PeerRpcManagerTransport,
route_trait::RouteInterface, PeerPacketFilter,
peer_conn::PeerConn, peer_rpc::PeerRpcManagerTransport, route_trait::RouteInterface,
PeerPacketFilter,
},
tunnel::{
self,
packet_def::{PacketType, ZCPacket},
SinkItem, Tunnel, TunnelConnector,
},
};
use super::{
encrypt::{ring_aes_gcm::AesGcmCipher, Encryptor, NullCipher},
encrypt::{Encryptor, NullCipher},
foreign_network_client::ForeignNetworkClient,
foreign_network_manager::ForeignNetworkManager,
peer_conn::PeerConnId,
@@ -176,12 +177,25 @@ impl PeerManager {
my_peer_id,
));
let encryptor: Arc<Box<dyn Encryptor>> =
Arc::new(if global_ctx.get_flags().enable_encryption {
Box::new(AesGcmCipher::new_128(global_ctx.get_128_key()))
} else {
Box::new(NullCipher)
});
let mut encryptor: Arc<Box<dyn Encryptor>> = Arc::new(Box::new(NullCipher));
if global_ctx.get_flags().enable_encryption {
#[cfg(feature = "wireguard")]
{
use super::encrypt::ring_aes_gcm::AesGcmCipher;
encryptor = Arc::new(Box::new(AesGcmCipher::new_128(global_ctx.get_128_key())));
}
#[cfg(all(feature = "aes-gcm", not(feature = "wireguard")))]
{
use super::encrypt::aes_gcm::AesGcmCipher;
encryptor = Arc::new(Box::new(AesGcmCipher::new_128(global_ctx.get_128_key())));
}
#[cfg(all(not(feature = "wireguard"), not(feature = "aes-gcm")))]
{
compile_error!("wireguard or aes-gcm feature must be enabled for encryption");
}
}
// TODO: remove these because we have impl pipeline processor.
let (peer_rpc_tspt_sender, peer_rpc_tspt_recv) = mpsc::unbounded_channel();
@@ -536,7 +550,11 @@ impl PeerManager {
return Ok(());
}
msg.fill_peer_manager_hdr(self.my_peer_id, 0, packet::PacketType::Data as u8);
msg.fill_peer_manager_hdr(
self.my_peer_id,
0,
tunnel::packet_def::PacketType::Data as u8,
);
self.run_nic_packet_process_pipeline(&mut msg).await;
self.encryptor
.encrypt(&mut msg)
+3 -2
View File
@@ -3,7 +3,7 @@ use std::{
fmt::Debug,
net::Ipv4Addr,
sync::{
atomic::{AtomicBool, AtomicU32, AtomicU64, Ordering},
atomic::{AtomicBool, AtomicU32, Ordering},
Arc, Weak,
},
time::{Duration, SystemTime},
@@ -473,7 +473,8 @@ impl RouteTable {
}
type SessionId = u64;
type AtomicSessionId = AtomicU64;
type AtomicSessionId = atomic_shim::AtomicU64;
// if we need to sync route info with one peer, we create a SyncRouteSession with that peer.
#[derive(Debug)]
+11 -7
View File
@@ -9,17 +9,18 @@ use super::*;
use crate::{
common::{
config::{ConfigLoader, NetworkIdentity, TomlConfigLoader, VpnPortalConfig},
config::{ConfigLoader, NetworkIdentity, TomlConfigLoader},
netns::{NetNS, ROOT_NETNS_NAME},
},
instance::instance::Instance,
peers::tests::wait_for_condition,
tunnel::{
ring::RingTunnelConnector,
tcp::TcpTunnelConnector,
udp::UdpTunnelConnector,
wireguard::{WgConfig, WgTunnelConnector},
},
tunnel::{ring::RingTunnelConnector, tcp::TcpTunnelConnector, udp::UdpTunnelConnector},
};
#[cfg(feature = "wireguard")]
use crate::{
common::config::VpnPortalConfig,
tunnel::wireguard::{WgConfig, WgTunnelConnector},
vpn_portal::wireguard::get_wg_config_for_portal,
};
@@ -81,6 +82,7 @@ pub async fn init_three_node(proto: &str) -> Vec<Instance> {
"udp://10.1.1.1:11010".parse().unwrap(),
));
} else if proto == "wg" {
#[cfg(feature = "wireguard")]
inst2
.get_conn_manager()
.add_connector(WgTunnelConnector::new(
@@ -226,6 +228,7 @@ pub async fn icmp_proxy_three_node_test(#[values("tcp", "udp", "wg")] proto: &st
.await;
}
#[cfg(feature = "wireguard")]
#[rstest::rstest]
#[tokio::test]
#[serial_test::serial]
@@ -478,6 +481,7 @@ fn run_wireguard_client(
Ok(())
}
#[cfg(feature = "wireguard")]
#[tokio::test]
#[serial_test::serial]
pub async fn wireguard_vpn_portal() {
+5 -1
View File
@@ -17,13 +17,17 @@ pub mod common;
pub mod filter;
pub mod mpsc;
pub mod packet_def;
pub mod quic;
pub mod ring;
pub mod stats;
pub mod tcp;
pub mod udp;
#[cfg(feature = "wireguard")]
pub mod wireguard;
#[cfg(feature = "quic")]
pub mod quic;
#[derive(thiserror::Error, Debug)]
pub enum TunnelError {
#[error("io error")]
+26
View File
@@ -9,6 +9,7 @@ use std::sync::Arc;
use crate::{common::global_ctx::ArcGlobalCtx, peers::peer_manager::PeerManager};
#[cfg(feature = "wireguard")]
pub mod wireguard;
#[async_trait::async_trait]
@@ -22,3 +23,28 @@ pub trait VpnPortal: Send + Sync {
fn name(&self) -> String;
async fn list_clients(&self) -> Vec<String>;
}
pub struct NullVpnPortal;
#[async_trait::async_trait]
impl VpnPortal for NullVpnPortal {
async fn start(
&mut self,
_global_ctx: ArcGlobalCtx,
_peer_mgr: Arc<PeerManager>,
) -> anyhow::Result<()> {
Ok(())
}
async fn dump_client_config(&self, _peer_mgr: Arc<PeerManager>) -> String {
"".to_string()
}
fn name(&self) -> String {
"null".to_string()
}
async fn list_clients(&self) -> Vec<String> {
vec![]
}
}