Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4363e3f76a | ||
![]() |
ee9d0685b3 | ||
![]() |
421ad8c979 |
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -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",
|
||||||
|
@@ -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"
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
[](https://crates.io/crates/fourth) [](https://github.com/KernelErr/fourth/actions/workflows/rust.yml)
|
[](https://crates.io/crates/fourth) [](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
|
||||||
|
@@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
内置两个的upstream:ban(立即中断连接)、echo(返回读到的数据)。
|
内置两个的upstream:ban(立即中断连接)、echo(返回读到的数据)。
|
||||||
|
@@ -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
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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();
|
||||||
|
@@ -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"
|
||||||
|
Reference in New Issue
Block a user