Skip to content

Commit

Permalink
lazy static initiating config
Browse files Browse the repository at this point in the history
Signed-off-by: Uncle Jack <[email protected]>
  • Loading branch information
unclejacki committed Jul 13, 2024
1 parent a257134 commit 6fa687b
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 68 deletions.
5 changes: 2 additions & 3 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ path = "/trojan"
password = "test"

[outbound]
addresses = ["127.0.0.1"]
addresses = ["relay1.bepass.org"]
port = 6666
protocol = "vless"
uuid = "0fbf4f81-2598-4b6a-a623-0ead4cb9efa8"
protocol = "relay_v1"
match = [
"173.245.48.0/20",
"103.21.244.0/22",
Expand Down
2 changes: 0 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ pub struct Inbound {
#[serde(default)]
pub password: String,
pub path: String,
#[serde(skip)]
pub context: RequestContext,
}

#[derive(Default, Clone, Serialize, Deserialize, JsonSchema)]
Expand Down
32 changes: 19 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,55 @@ mod config;
mod link;
mod proxy;

use crate::config::{Config, Inbound};
use std::sync::Arc;

use crate::config::Config;
use crate::link::generate_link;
use crate::proxy::RequestContext;

use worker::*;

lazy_static::lazy_static! {
static ref CONFIG: &'static str = {
include_str!(env!("CONFIG_PATH"))
static ref CONFIG: Arc<Config> = {
let c = include_str!(env!("CONFIG_PATH"));
Arc::new(Config::new(c))
};
}

#[event(fetch)]
async fn main(req: Request, _: Env, _: Context) -> Result<Response> {
let config = Config::new(&CONFIG);

match req.path().as_str() {
"/link" => link(req, config),
path => match config.dispatch_inbound(path) {
Some(mut inbound) => {
inbound.context.request = Some(req);
tunnel(config, inbound).await
"/link" => link(req, CONFIG.clone()),
path => match CONFIG.dispatch_inbound(path) {
Some(inbound) => {
let context = RequestContext {
inbound,
request: Some(req),
..Default::default()
};
tunnel(CONFIG.clone(), context).await
}
None => Response::empty(),
},
}
}

async fn tunnel(config: Config, inbound: Inbound) -> Result<Response> {
async fn tunnel(config: Arc<Config>, context: RequestContext) -> Result<Response> {
let WebSocketPair { server, client } = WebSocketPair::new()?;

server.accept()?;
wasm_bindgen_futures::spawn_local(async move {
let events = server.events().unwrap();

if let Err(e) = proxy::process(config, inbound, &server, events).await {
if let Err(e) = proxy::process(config, context, &server, events).await {
console_log!("[tunnel]: {}", e);
}
});

Response::from_websocket(client)
}

fn link(req: Request, config: Config) -> Result<Response> {
fn link(req: Request, config: Arc<Config>) -> Result<Response> {
let host = req.url()?.host().map(|x| x.to_string()).unwrap_or_default();
Response::from_json(&generate_link(&config, &host))
}
28 changes: 12 additions & 16 deletions src/proxy/bepass/inbound.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::config::{Config, Inbound};
use crate::proxy::{bepass::encoding, Proxy};
use crate::config::Config;
use crate::proxy::{bepass::encoding, Proxy, RequestContext};

use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};

use async_trait::async_trait;
Expand All @@ -13,8 +14,8 @@ use worker::*;

pin_project! {
pub struct BepassStream<'a> {
pub config: Config,
pub inbound: Inbound,
pub config: Arc<Config>,
pub context: RequestContext,
pub ws: &'a WebSocket,
pub buffer: BytesMut,
#[pin]
Expand All @@ -26,16 +27,16 @@ unsafe impl<'a> Send for BepassStream<'a> {}

impl<'a> BepassStream<'a> {
pub fn new(
config: Config,
inbound: Inbound,
config: Arc<Config>,
context: RequestContext,
events: EventStream<'a>,
ws: &'a WebSocket,
) -> Self {
let buffer = BytesMut::new();

Self {
config,
inbound,
context,
ws,
buffer,
events,
Expand All @@ -46,17 +47,12 @@ impl<'a> BepassStream<'a> {
#[async_trait]
impl<'a> Proxy for BepassStream<'a> {
async fn process(&mut self) -> Result<()> {
let request = self
.inbound
.context
.request
.as_ref()
.ok_or(Error::RustError(
"failed to retrive request context".to_string(),
))?;
let request = self.context.request.as_ref().ok_or(Error::RustError(
"failed to retrive request context".to_string(),
))?;
let header = encoding::decode_request_header(request)?;

let mut context = self.inbound.context.clone();
let mut context = self.context.clone();
{
context.address = header.address.clone();
context.port = header.port;
Expand Down
19 changes: 12 additions & 7 deletions src/proxy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pub mod trojan;
pub mod vless;
pub mod vmess;

use std::sync::Arc;

use crate::config::*;

use async_trait::async_trait;
Expand Down Expand Up @@ -60,6 +62,7 @@ pub struct RequestContext {
pub address: String,
pub port: u16,
pub network: Network,
pub inbound: Inbound,
pub request: Option<Request>,
}

Expand All @@ -70,11 +73,13 @@ impl Clone for RequestContext {
let port = self.port;
let address = self.address.clone();
let network = self.network.clone();
let inbound = self.inbound.clone();

Self {
address,
port,
network,
inbound,
// to avoid unnecessary overheads of copying:
// context is getting filled during processing a request
// so no need to clone any data here
Expand Down Expand Up @@ -125,29 +130,29 @@ async fn connect_outbound(ctx: RequestContext, outbound: Outbound) -> Result<Box
}

pub async fn process(
config: Config,
inbound: Inbound,
config: Arc<Config>,
context: RequestContext,
ws: &WebSocket,
events: EventStream<'_>,
) -> Result<()> {
match inbound.protocol {
match context.inbound.protocol {
Protocol::Vmess => {
vmess::inbound::VmessStream::new(config, inbound, events, ws)
vmess::inbound::VmessStream::new(config, context, events, ws)
.process()
.await
}
Protocol::Vless => {
vless::inbound::VlessStream::new(config, inbound, events, ws)
vless::inbound::VlessStream::new(config, context, events, ws)
.process()
.await
}
Protocol::Trojan => {
trojan::inbound::TrojanStream::new(config, inbound, events, ws)
trojan::inbound::TrojanStream::new(config, context, events, ws)
.process()
.await
}
Protocol::Bepass => {
bepass::inbound::BepassStream::new(config, inbound, events, ws)
bepass::inbound::BepassStream::new(config, context, events, ws)
.process()
.await
}
Expand Down
19 changes: 10 additions & 9 deletions src/proxy/trojan/inbound.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::config::{Config, Inbound};
use crate::proxy::{trojan::encoding, Proxy};
use crate::config::Config;
use crate::proxy::{trojan::encoding, Proxy, RequestContext};

use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};

use async_trait::async_trait;
Expand All @@ -13,8 +14,8 @@ use worker::*;

pin_project! {
pub struct TrojanStream<'a> {
pub config: Config,
pub inbound: Inbound,
pub config: Arc<Config>,
pub context: RequestContext,
pub ws: &'a WebSocket,
pub buffer: BytesMut,
#[pin]
Expand All @@ -26,16 +27,16 @@ unsafe impl<'a> Send for TrojanStream<'a> {}

impl<'a> TrojanStream<'a> {
pub fn new(
config: Config,
inbound: Inbound,
config: Arc<Config>,
context: RequestContext,
events: EventStream<'a>,
ws: &'a WebSocket,
) -> Self {
let buffer = BytesMut::new();

Self {
config,
inbound,
context,
ws,
buffer,
events,
Expand All @@ -46,10 +47,10 @@ impl<'a> TrojanStream<'a> {
#[async_trait]
impl<'a> Proxy for TrojanStream<'a> {
async fn process(&mut self) -> Result<()> {
let password = self.inbound.password.clone();
let password = self.context.inbound.password.clone();
let header = encoding::decode_request_header(&mut self, &password).await?;

let mut context = self.inbound.context.clone();
let mut context = self.context.clone();
{
context.address = header.address;
context.port = header.port;
Expand Down
19 changes: 10 additions & 9 deletions src/proxy/vless/inbound.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::config::{Config, Inbound};
use crate::proxy::{vless::encoding, Proxy};
use crate::config::Config;
use crate::proxy::{vless::encoding, Proxy, RequestContext};

use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};

use async_trait::async_trait;
Expand All @@ -13,8 +14,8 @@ use worker::*;

pin_project! {
pub struct VlessStream<'a> {
pub config: Config,
pub inbound: Inbound,
pub config: Arc<Config>,
pub context: RequestContext,
pub ws: &'a WebSocket,
pub buffer: BytesMut,
#[pin]
Expand All @@ -26,16 +27,16 @@ unsafe impl<'a> Send for VlessStream<'a> {}

impl<'a> VlessStream<'a> {
pub fn new(
config: Config,
inbound: Inbound,
config: Arc<Config>,
context: RequestContext,
events: EventStream<'a>,
ws: &'a WebSocket,
) -> Self {
let buffer = BytesMut::new();

Self {
config,
inbound,
context,
ws,
buffer,
events,
Expand All @@ -46,10 +47,10 @@ impl<'a> VlessStream<'a> {
#[async_trait]
impl<'a> Proxy for VlessStream<'a> {
async fn process(&mut self) -> Result<()> {
let uuid = self.inbound.uuid;
let uuid = self.context.inbound.uuid;
let header = encoding::decode_request_header(&mut self, &uuid.into_bytes()).await?;

let mut context = self.inbound.context.clone();
let mut context = self.context.clone();
{
context.address = header.address;
context.port = header.port;
Expand Down
19 changes: 10 additions & 9 deletions src/proxy/vmess/inbound.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::config::{Config, Inbound};
use crate::proxy::{vmess::encoding, Proxy};
use crate::config::Config;
use crate::proxy::{vmess::encoding, Proxy, RequestContext};

use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};

use async_trait::async_trait;
Expand All @@ -13,8 +14,8 @@ use worker::*;

pin_project! {
pub struct VmessStream<'a> {
pub config: Config,
pub inbound: Inbound,
pub config: Arc<Config>,
pub context: RequestContext,
pub ws: &'a WebSocket,
pub buffer: BytesMut,
#[pin]
Expand All @@ -26,16 +27,16 @@ unsafe impl<'a> Send for VmessStream<'a> {}

impl<'a> VmessStream<'a> {
pub fn new(
config: Config,
inbound: Inbound,
config: Arc<Config>,
context: RequestContext,
events: EventStream<'a>,
ws: &'a WebSocket,
) -> Self {
let buffer = BytesMut::new();

Self {
config,
inbound,
context,
ws,
buffer,
events,
Expand All @@ -46,10 +47,10 @@ impl<'a> VmessStream<'a> {
#[async_trait]
impl<'a> Proxy for VmessStream<'a> {
async fn process(&mut self) -> Result<()> {
let uuid = self.inbound.uuid;
let uuid = self.context.inbound.uuid;
let header = encoding::decode_request_header(&mut self, &uuid.into_bytes()).await?;

let mut context = self.inbound.context.clone();
let mut context = self.context.clone();
{
context.address = header.address;
context.port = header.port;
Expand Down

0 comments on commit 6fa687b

Please sign in to comment.