Skip to content

Commit

Permalink
实现传输加密
Browse files Browse the repository at this point in the history
  • Loading branch information
editso committed Nov 30, 2021
1 parent a5f82aa commit 56edc13
Show file tree
Hide file tree
Showing 14 changed files with 713 additions and 140 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ A fast, stable, cross-platform and efficient intranet penetration and port forwa
| Name | <font color="green">✔(Achieved)</font> / <font color="red">❌(Unrealized)</font>) |
| ---------------------- | -------------------------------------------------------------------------------- |
| 基本转发 (Forward) | <font color="green">✔</font> |
| 传输加密 (Encrypt) | |
| Sock5代理 (Socks5) | <font color="green">✔(Achieved)</font> |
| 传输加密 (Encrypt) | <font color="green">✔</font> |
| Socks5代理 (Socks5) | <font color="green">✔</font> |
| UDP支持 (udp support) ||
| 多映射 ||
| 级联代理 ||
Expand Down
40 changes: 35 additions & 5 deletions fuso-api/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@ use std::io::Cursor;

use async_trait::async_trait;
use bytes::{Buf, BufMut, Bytes, BytesMut};
use futures::AsyncReadExt;
use futures::{AsyncReadExt, Future};
use smol::io::{AsyncRead, AsyncWrite, AsyncWriteExt};

use crate::error::{self, Result};

const MAGIC: u32 = 0xFA;
const MAGIC: u32 = 0xCC;

#[inline]
pub fn now_mills() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs()
}

#[derive(Debug, Clone)]
pub struct Packet {
Expand Down Expand Up @@ -50,6 +58,16 @@ pub trait Forward<To> {
fn spwan_forward(self, to: To) -> Result<()>;
}

#[async_trait]
pub trait Life<C> {
async fn start(&self, cx: C) -> Result<()>;
async fn stop(self) -> Result<()>;
}

pub trait Spwan {
fn detach(self);
}

impl Packet {
#[inline]
fn constructor(magic: u32, cmd: u8, data: Bytes) -> Self {
Expand Down Expand Up @@ -221,9 +239,20 @@ where
}
}

impl<T, A> Spwan for T
where
A: Send + 'static,
T: Future<Output = A> + Send + 'static,
{
fn detach(self) {
smol::spawn(self).detach();
}
}

#[async_trait]
impl<To> Forward<To> for To
impl<From, To> Forward<To> for From
where
From: AsyncRead + AsyncWrite + Unpin + Send + Sync + 'static,
To: AsyncRead + AsyncWrite + Unpin + Send + Sync + 'static,
{
#[inline]
Expand All @@ -243,14 +272,15 @@ where

#[inline]
fn spwan_forward(self, to: To) -> Result<()> {
smol::spawn(async move {
async move {
let ret = Self::forward(self, to).await;

if ret.is_err() {
log::debug!("[fuso] Forward failure {}", ret.unwrap_err());
}
})
}
.detach();

Ok(())
}
}
1 change: 1 addition & 0 deletions fuso-api/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub struct Error {
#[derive(Debug)]
pub enum ErrorKind {
BadPacket,

}

#[derive(Debug)]
Expand Down
10 changes: 9 additions & 1 deletion fuso-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,22 @@ pub use async_trait::*;

#[cfg(test)]
mod tests {
use crate::core::Packet;
use crate::{core::Packet, now_mills};

fn init_logger() {
env_logger::builder()
.filter_level(log::LevelFilter::Debug)
.init();
}

#[test]
fn test_time(){
// let time = std::time::SystemTime::now()
// .duration_since(std::time::SystemTime::UNIX_EPOCH).unwrap();

println!("{:?}", now_mills())
}

#[test]
fn test_packet() {
init_logger();
Expand Down
153 changes: 153 additions & 0 deletions fuso-core/src/buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
use std::{
collections::VecDeque,
io::{Cursor, Write},
sync::{Arc, Mutex},
task::Poll,
};

use futures::{AsyncRead, AsyncWrite};

use async_trait::async_trait;

#[derive(Debug, Clone)]
pub struct Buffer<T> {
len: usize,
buf: Arc<Mutex<VecDeque<Vec<T>>>>,
}

impl<T> Buffer<T>
where
T: Clone,
{
#[inline]
pub fn new() -> Self {
Self {
len: 0,
buf: Arc::new(Mutex::new(VecDeque::new())),
}
}

pub fn is_empty(&self) -> bool {
self.buf.lock().unwrap().is_empty()
}

pub fn len(&self) -> usize {
self.len
}

pub fn clear(&mut self) {
self.buf.lock().unwrap().clear();
self.len = 0;
}

pub fn push_back(&mut self, data: &[T]) {
self.buf.lock().unwrap().push_back(data.to_vec());
self.len += data.len();
}

pub fn push_front(&mut self, data: &[T]) {
self.buf.lock().unwrap().push_front(data.to_vec());
self.len += data.len();
}
}

impl Buffer<u8> {
pub fn read_to_buffer(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let mut remaining = buf.len();
let mut read_len = 0;
let mut io = Cursor::new(buf);
let mut buf = self.buf.lock().unwrap();

loop {
if remaining == 0 {
self.len -= read_len;
break Ok(read_len);
}

let data = buf.pop_front();

if data.is_none() {
self.len -= read_len;
break Ok(read_len);
}

let data = data.unwrap();

if data.len() >= remaining {
let n = io.write(&data[..remaining])?;
remaining -= n;
read_len += n;

if data.len() != n {
buf.push_front(data[n..].to_vec())
}
} else {
let n = io.write(&data)?;

read_len += n;
remaining -= n;
}
}
}
}

#[async_trait]
impl AsyncRead for Buffer<u8> {
fn poll_read(
mut self: std::pin::Pin<&mut Self>,
_: &mut std::task::Context<'_>,
buf: &mut [u8],
) -> std::task::Poll<std::io::Result<usize>> {
Poll::Ready(self.read_to_buffer(buf))
}
}

#[async_trait]
impl AsyncWrite for Buffer<u8> {
fn poll_write(
mut self: std::pin::Pin<&mut Self>,
_: &mut std::task::Context<'_>,
buf: &[u8],
) -> std::task::Poll<std::io::Result<usize>> {
self.push_back(buf);
Poll::Ready(Ok(buf.len()))
}

fn poll_flush(
self: std::pin::Pin<&mut Self>,
_: &mut std::task::Context<'_>,
) -> std::task::Poll<std::io::Result<()>> {
Poll::Ready(Ok(()))
}

fn poll_close(
mut self: std::pin::Pin<&mut Self>,
_: &mut std::task::Context<'_>,
) -> std::task::Poll<std::io::Result<()>> {
self.clear();
Poll::Ready(Ok(()))
}
}

#[test]
fn test_buffer() {
use smol::io::{AsyncReadExt, AsyncWriteExt};

smol::block_on(async move {
let mut buf: Buffer<u8> = Buffer::new();

buf.write(b"hello world").await.unwrap();
buf.write(b"123456").await.unwrap();

let mut buffer = Vec::new();
buffer.resize(11, 0);

let n = buf.read(&mut buffer).await.unwrap();

assert_eq!(11, n);
assert_eq!(6, buf.len());

println!("{:?}", buffer);
println!("{:?}", buf);
});
}
Loading

0 comments on commit 56edc13

Please sign in to comment.