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}