pub mod blackhole;
pub mod dns;
pub mod freedom;
#[cfg(feature = "inbound-http")]
pub mod http;
pub mod net_manager;
pub mod shadowsocks;
pub mod socks;
#[cfg(feature = "outbound-trojan")]
pub mod trojan;
#[cfg(feature = "inbound-tun")]
pub mod tun;
pub mod vless;
use crate::app::config::OutboundProtocolOption;
use crate::app::dns::DnsManager;
use crate::app::Context as AppContext;
use crate::common::Address;
use async_trait::async_trait;
use bytes::BufMut;
use futures::ready;
use std::io::{ErrorKind, Result};
use std::net::SocketAddr;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use tokio::sync::mpsc;
pub trait AsAny: 'static {
fn as_any(&self) -> &dyn std::any::Any;
fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any>;
}
impl<T: 'static> AsAny for T {
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
self
}
}
pub trait LocalAddr {
fn local_addr(&self) -> Result<SocketAddr>;
}
pub trait ProxyStream: AsyncRead + AsyncWrite + Send + Sync + Unpin + AsAny + LocalAddr {
fn poll_read_exact(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize>>;
}
impl<T: AsyncRead + AsyncWrite + Send + Sync + Unpin + AsAny + LocalAddr> ProxyStream for T {
fn poll_read_exact(&mut self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize>> {
let size = buf.len();
if size == 0 {
return Err(ErrorKind::InvalidInput.into()).into();
}
let mut read_size = 0;
let mut buf = ReadBuf::new(buf);
while read_size < size {
let remaining = size - read_size;
let buffer = &mut buf.chunk_mut()[..remaining];
let mut read_buf = ReadBuf::uninit(unsafe {
std::slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut _, remaining)
});
ready!(Pin::new(&mut *self).poll_read(cx, &mut read_buf))?;
let n = read_buf.filled().len();
if n == 0 {
if read_size > 0 {
return Err(ErrorKind::UnexpectedEof.into()).into();
} else {
return Ok(0).into();
}
}
read_size += n;
unsafe {
buf.advance_mut(n);
}
}
Ok(size).into()
}
}
pub trait ProxySocket: Send + Sync + Unpin {
fn poll_recv_from(&self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<Result<Address>>;
fn poll_send_to(
&self,
cx: &mut Context<'_>,
buf: &[u8],
target: Address,
) -> Poll<Result<usize>>;
}
#[async_trait]
pub trait Inbound: Send + Sync {
fn clone_box(&self) -> Box<dyn Inbound>;
async fn run(&self, context: AppContext, channel: Option<mpsc::Sender<String>>) -> Result<()>;
}
impl Clone for Box<dyn Inbound> {
fn clone(&self) -> Self {
self.clone_box()
}
}
#[async_trait]
pub trait Outbound: Send + Sync {
fn protocol(&self) -> OutboundProtocolOption;
async fn pre_connect(&self, dns: &DnsManager) -> Result<Option<Box<dyn Outbound>>>;
async fn connect_tcp(&self, addr: Address) -> Result<Box<dyn ProxyStream>>;
async fn bind(&self, peer: SocketAddr, target: Address) -> Result<Box<dyn ProxySocket>>;
}
pub mod request_command {
pub const TCP: u8 = 1;
pub const UDP: u8 = 2;
pub const MUX: u8 = 3;
}
pub mod address_type {
pub const IPV4: u8 = 1;
pub const DOMAIN: u8 = 2;
pub const IPV6: u8 = 3;
}
pub mod mux_command {
pub const NEW: u8 = 1;
pub const KEEP: u8 = 2;
pub const END: u8 = 3;
pub const KEEP_ALIVE: u8 = 4;
}