3 Commits

Author SHA1 Message Date
4363e3f76a Publish 0.1.3 and update README 2021-10-26 23:58:00 +08:00
ee9d0685b3 Refactor TCP and KCP test 2021-10-26 23:52:07 +08:00
421ad8c979 Fix example config 2021-10-26 23:27:03 +08:00
8 changed files with 46 additions and 29 deletions

2
Cargo.lock generated
View File

@ -98,7 +98,7 @@ dependencies = [
[[package]] [[package]]
name = "fourth" name = "fourth"
version = "0.1.2" version = "0.1.3"
dependencies = [ dependencies = [
"byte_string", "byte_string",
"bytes 1.1.0", "bytes 1.1.0",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "fourth" name = "fourth"
version = "0.1.2" version = "0.1.3"
edition = "2021" edition = "2021"
authors = ["LI Rui <lr_cn@outlook.com>"] authors = ["LI Rui <lr_cn@outlook.com>"]
license = "Apache-2.0" license = "Apache-2.0"

View File

@ -4,6 +4,8 @@
[![](https://img.shields.io/crates/v/fourth)](https://crates.io/crates/fourth) [![CI](https://img.shields.io/github/workflow/status/kernelerr/fourth/Rust)](https://github.com/KernelErr/fourth/actions/workflows/rust.yml) [![](https://img.shields.io/crates/v/fourth)](https://crates.io/crates/fourth) [![CI](https://img.shields.io/github/workflow/status/kernelerr/fourth/Rust)](https://github.com/KernelErr/fourth/actions/workflows/rust.yml)
**Under heavy development, version 0.1 may update frequently**
Fourth is a layer 4 proxy implemented by Rust to listen on specific ports and transfer TCP/KCP data to remote addresses(only TCP) according to configuration. Fourth is a layer 4 proxy implemented by Rust to listen on specific ports and transfer TCP/KCP data to remote addresses(only TCP) according to configuration.
## Features ## Features
@ -55,7 +57,7 @@ servers:
upstream: upstream:
nginx: "127.0.0.1:8080" nginx: "127.0.0.1:8080"
proxy: "127.0.0.1:1024" proxy: "127.0.0.1:1024"
other: "www.remote.example.com:8082" # proxy to remote address remote: "www.remote.example.com:8082" # proxy to remote address
``` ```
Built-in two upstreams: ban(terminate connection immediately), echo Built-in two upstreams: ban(terminate connection immediately), echo

View File

@ -6,6 +6,8 @@
[English](/README-EN.md) [English](/README-EN.md)
**积极开发中0.1版本迭代可能较快**
Fourth是一个Rust实现的Layer 4代理用于监听指定端口TCP/KCP流量并根据规则转发到指定目标目前只支持TCP Fourth是一个Rust实现的Layer 4代理用于监听指定端口TCP/KCP流量并根据规则转发到指定目标目前只支持TCP
## 功能 ## 功能
@ -62,7 +64,7 @@ servers:
upstream: upstream:
nginx: "127.0.0.1:8080" nginx: "127.0.0.1:8080"
proxy: "127.0.0.1:1024" proxy: "127.0.0.1:1024"
other: "www.remote.example.com:8082" # proxy to remote address remote: "www.remote.example.com:8082" # proxy to remote address
``` ```
内置两个的upstreamban立即中断连接、echo返回读到的数据 内置两个的upstreamban立即中断连接、echo返回读到的数据

View File

@ -24,4 +24,4 @@ servers:
upstream: upstream:
nginx: "127.0.0.1:8080" nginx: "127.0.0.1:8080"
proxy: "127.0.0.1:1024" proxy: "127.0.0.1:1024"
other: "www.remote.example.com:8082" # proxy to remote address remote: "www.remote.example.com:8082" # proxy to remote address

View File

@ -87,7 +87,7 @@ mod tests {
let config = Config::new("tests/config.yaml").unwrap(); let config = Config::new("tests/config.yaml").unwrap();
assert_eq!(config.base.version, 1); assert_eq!(config.base.version, 1);
assert_eq!(config.base.log.unwrap(), "disable"); assert_eq!(config.base.log.unwrap(), "disable");
assert_eq!(config.base.servers.len(), 4); assert_eq!(config.base.servers.len(), 5);
assert_eq!(config.base.upstream.len(), 3); assert_eq!(config.base.upstream.len(), 3);
} }
} }

View File

@ -118,8 +118,11 @@ mod test {
let server_addr: SocketAddr = "127.0.0.1:54599".parse().unwrap(); let server_addr: SocketAddr = "127.0.0.1:54599".parse().unwrap();
let listener = TcpListener::bind(server_addr).await.unwrap(); let listener = TcpListener::bind(server_addr).await.unwrap();
let (mut stream, _) = listener.accept().await.unwrap(); let (mut stream, _) = listener.accept().await.unwrap();
stream.write(b"hello").await.unwrap(); let mut buf = [0u8; 1024];
stream.shutdown().await.unwrap(); let n = stream.read(&mut buf).await.unwrap();
if n > 0 {
stream.write(b"hello").await.unwrap();
}
} }
#[tokio::test] #[tokio::test]
@ -135,25 +138,19 @@ mod test {
let _ = server.run(); let _ = server.run();
}); });
sleep(Duration::from_secs(1)); // wait for server to start sleep(Duration::from_secs(1)); // wait for server to start
let mut conn = TcpStream::connect("127.0.0.1:54500").await.unwrap();
let mut buf = [0u8; 5];
conn.read(&mut buf).await.unwrap();
assert_eq!(&buf, b"hello");
conn.shutdown().await.unwrap();
}
#[tokio::test] // // test proxy
async fn test_tcp_echo_server() { // let mut conn = TcpStream::connect("127.0.0.1:54500").await.unwrap();
use crate::config::Config; // let mut buf = [0u8; 5];
let config = Config::new("tests/config.yaml").unwrap(); // conn.write(b"hi").await.unwrap();
let mut server = Server::new(config.base); // conn.read(&mut buf).await.unwrap();
thread::spawn(move || { // assert_eq!(&buf, b"hello");
let _ = server.run(); // conn.shutdown().await.unwrap();
});
sleep(Duration::from_secs(1)); // wait for server to start // test echo
let mut conn = TcpStream::connect("127.0.0.1:54956").await.unwrap(); let mut conn = TcpStream::connect("127.0.0.1:54956").await.unwrap();
let mut buf = [0u8; 1]; let mut buf = [0u8; 1];
for i in 0..=255u8 { for i in 0..=10u8 {
conn.write(&[i]).await.unwrap(); conn.write(&[i]).await.unwrap();
conn.read(&mut buf).await.unwrap(); conn.read(&mut buf).await.unwrap();
assert_eq!(&buf, &[i]); assert_eq!(&buf, &[i]);
@ -162,7 +159,7 @@ mod test {
} }
#[tokio::test] #[tokio::test]
async fn test_kcp_echo_server() { async fn test_kcp_proxy() {
use crate::config::Config; use crate::config::Config;
let config = Config::new("tests/config.yaml").unwrap(); let config = Config::new("tests/config.yaml").unwrap();
let mut server = Server::new(config.base); let mut server = Server::new(config.base);
@ -170,6 +167,17 @@ mod test {
let _ = server.run(); let _ = server.run();
}); });
sleep(Duration::from_secs(1)); // wait for server to start sleep(Duration::from_secs(1)); // wait for server to start
// test proxy
let kcp_config = KcpConfig::default();
let server_addr: SocketAddr = "127.0.0.1:54958".parse().unwrap();
let mut conn = KcpStream::connect(&kcp_config, server_addr).await.unwrap();
let mut buf = [0u8; 5];
conn.write(b"hi").await.unwrap();
conn.read(&mut buf).await.unwrap();
assert_eq!(&buf, b"hello");
// test echo
let kcp_config = KcpConfig::default(); let kcp_config = KcpConfig::default();
let server_addr: SocketAddr = "127.0.0.1:54959".parse().unwrap(); let server_addr: SocketAddr = "127.0.0.1:54959".parse().unwrap();
let mut conn = KcpStream::connect(&kcp_config, server_addr).await.unwrap(); let mut conn = KcpStream::connect(&kcp_config, server_addr).await.unwrap();

View File

@ -11,15 +11,20 @@ servers:
proxy.test.com: proxy proxy.test.com: proxy
www.test.com: web www.test.com: web
default: ban default: ban
echo_server:
listen:
- "0.0.0.0:54956"
default: echo
tcp_server: tcp_server:
listen: listen:
- "127.0.0.1:54500" - "127.0.0.1:54500"
default: tester default: tester
tcp_echo_server:
listen:
- "0.0.0.0:54956"
default: echo
kcp_server: kcp_server:
protocol: kcp
listen:
- "127.0.0.1:54958"
default: tester
kcp_echo_server:
protocol: kcp protocol: kcp
listen: listen:
- "127.0.0.1:54959" - "127.0.0.1:54959"