shadow_tls/
lib.rs

1#![feature(impl_trait_in_assoc_type)]
2
3mod client;
4mod helper_v2;
5mod server;
6pub mod sip003;
7mod util;
8
9use std::{fmt::Display, thread::JoinHandle};
10
11pub use crate::{
12    client::{ShadowTlsClient, TlsExtConfig, TlsNames},
13    server::{ShadowTlsServer, TlsAddrs},
14    util::{V3Mode, WildcardSNI},
15};
16
17pub enum RunningArgs {
18    Client {
19        listen_addr: String,
20        target_addr: String,
21        tls_names: TlsNames,
22        tls_ext: TlsExtConfig,
23        password: String,
24        nodelay: bool,
25        v3: V3Mode,
26    },
27    Server {
28        listen_addr: String,
29        target_addr: String,
30        tls_addr: TlsAddrs,
31        password: String,
32        nodelay: bool,
33        v3: V3Mode,
34    },
35}
36
37impl RunningArgs {
38    #[inline]
39    pub fn build(self) -> anyhow::Result<Runnable<String, String>> {
40        match self {
41            RunningArgs::Client {
42                listen_addr,
43                target_addr,
44                tls_names,
45                tls_ext,
46                password,
47                nodelay,
48                v3,
49            } => Ok(Runnable::Client(ShadowTlsClient::new(
50                listen_addr,
51                target_addr,
52                tls_names,
53                tls_ext,
54                password,
55                nodelay,
56                v3,
57            )?)),
58            RunningArgs::Server {
59                listen_addr,
60                target_addr,
61                tls_addr,
62                password,
63                nodelay,
64                v3,
65            } => Ok(Runnable::Server(ShadowTlsServer::new(
66                listen_addr,
67                target_addr,
68                tls_addr,
69                password,
70                nodelay,
71                v3,
72            ))),
73        }
74    }
75}
76
77impl Display for RunningArgs {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        match self {
80            Self::Client {
81                listen_addr,
82                target_addr,
83                tls_names,
84                tls_ext,
85                nodelay,
86                v3,
87                ..
88            } => {
89                write!(f, "Client with:\nListen address: {listen_addr}\nTarget address: {target_addr}\nTLS server names: {tls_names}\nTLS Extension: {tls_ext}\nTCP_NODELAY: {nodelay}\nV3 Protocol: {v3}")
90            }
91            Self::Server {
92                listen_addr,
93                target_addr,
94                tls_addr,
95                nodelay,
96                v3,
97                ..
98            } => {
99                write!(f, "Server with:\nListen address: {listen_addr}\nTarget address: {target_addr}\nTLS server address: {tls_addr}\nTCP_NODELAY: {nodelay}\nV3 Protocol: {v3}")
100            }
101        }
102    }
103}
104
105#[derive(Clone)]
106pub enum Runnable<A, B> {
107    Client(ShadowTlsClient<A, B>),
108    Server(ShadowTlsServer<A, B>),
109}
110
111impl<A, B> Runnable<A, B>
112where
113    A: std::net::ToSocketAddrs + 'static,
114    B: std::net::ToSocketAddrs + 'static,
115{
116    async fn serve(self) -> anyhow::Result<()> {
117        match self {
118            Runnable::Client(c) => c.serve().await,
119            Runnable::Server(s) => s.serve().await,
120        }
121    }
122
123    pub fn start(&self, parallelism: usize) -> Vec<JoinHandle<anyhow::Result<()>>>
124    where
125        A: Clone + Send + Sync,
126        B: Clone + Send + Sync,
127    {
128        let mut threads = Vec::new();
129        for _ in 0..parallelism {
130            let runnable_clone = self.clone();
131            let t = std::thread::spawn(move || {
132                let mut rt = monoio::RuntimeBuilder::<monoio::FusionDriver>::new()
133                .enable_timer()
134                .build()
135                .expect("unable to build monoio runtime(please refer to: https://github.com/ihciah/shadow-tls/wiki/How-to-Run#common-issues)");
136                rt.block_on(runnable_clone.serve())
137            });
138            threads.push(t);
139        }
140        threads
141    }
142}