turn_server/service/mod.rs
1pub mod routing;
2pub mod session;
3
4use std::{net::SocketAddr, sync::Arc};
5
6use crate::codec::{crypto::Password, message::attributes::PasswordAlgorithm};
7
8use self::{
9 routing::Router,
10 session::{Identifier, SessionManager, SessionManagerOptions, ports::PortRange},
11};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub enum Transport {
15 Udp,
16 Tcp,
17}
18
19impl ToString for Transport {
20 fn to_string(&self) -> String {
21 match self {
22 Transport::Udp => "UDP".to_string(),
23 Transport::Tcp => "TCP".to_string(),
24 }
25 }
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29pub struct InterfaceAddr {
30 pub addr: SocketAddr,
31 pub external: SocketAddr,
32 pub transport: Transport,
33}
34
35pub trait ServiceHandler: Send + Sync + 'static {
36 fn get_password(
37 &self,
38 id: &Identifier,
39 username: &str,
40 algorithm: PasswordAlgorithm,
41 ) -> impl Future<Output = Option<Password>> + Send;
42
43 /// allocate request
44 ///
45 /// [rfc8489](https://tools.ietf.org/html/rfc8489)
46 ///
47 /// In all cases, the server SHOULD only allocate ports from the range
48 /// 49152 - 65535 (the Dynamic and/or Private Port range [PORT-NUMBERS]),
49 /// unless the TURN server application knows, through some means not
50 /// specified here, that other applications running on the same host as
51 /// the TURN server application will not be impacted by allocating ports
52 /// outside this range. This condition can often be satisfied by running
53 /// the TURN server application on a dedicated machine and/or by
54 /// arranging that any other applications on the machine allocate ports
55 /// before the TURN server application starts. In any case, the TURN
56 /// server SHOULD NOT allocate ports in the range 0 - 1023 (the Well-
57 /// Known Port range) to discourage clients from using TURN to run
58 /// standard services.
59 #[allow(unused_variables)]
60 fn on_allocated(&self, id: &Identifier, username: &str, port: u16) {}
61
62 /// channel binding request
63 ///
64 /// The server MAY impose restrictions on the IP address and port values
65 /// allowed in the XOR-PEER-ADDRESS attribute; if a value is not allowed,
66 /// the server rejects the request with a 403 (Forbidden) error.
67 ///
68 /// If the request is valid, but the server is unable to fulfill the
69 /// request due to some capacity limit or similar, the server replies
70 /// with a 508 (Insufficient Capacity) error.
71 ///
72 /// Otherwise, the server replies with a ChannelBind success response.
73 /// There are no required attributes in a successful ChannelBind
74 /// response.
75 ///
76 /// If the server can satisfy the request, then the server creates or
77 /// refreshes the channel binding using the channel number in the
78 /// CHANNEL-NUMBER attribute and the transport address in the XOR-PEER-
79 /// ADDRESS attribute. The server also installs or refreshes a
80 /// permission for the IP address in the XOR-PEER-ADDRESS attribute as
81 /// described in Section 9.
82 ///
83 /// NOTE: A server need not do anything special to implement
84 /// idempotency of ChannelBind requests over UDP using the
85 /// "stateless stack approach". Retransmitted ChannelBind requests
86 /// will simply refresh the channel binding and the corresponding
87 /// permission. Furthermore, the client must wait 5 minutes before
88 /// binding a previously bound channel number or peer address to a
89 /// different channel, eliminating the possibility that the
90 /// transaction would initially fail but succeed on a
91 /// retransmission.
92 #[allow(unused_variables)]
93 fn on_channel_bind(&self, id: &Identifier, username: &str, channel: u16) {}
94
95 /// create permission request
96 ///
97 /// [rfc8489](https://tools.ietf.org/html/rfc8489)
98 ///
99 /// When the server receives the CreatePermission request, it processes
100 /// as per [Section 5](https://tools.ietf.org/html/rfc8656#section-5)
101 /// plus the specific rules mentioned here.
102 ///
103 /// The message is checked for validity. The CreatePermission request
104 /// MUST contain at least one XOR-PEER-ADDRESS attribute and MAY contain
105 /// multiple such attributes. If no such attribute exists, or if any of
106 /// these attributes are invalid, then a 400 (Bad Request) error is
107 /// returned. If the request is valid, but the server is unable to
108 /// satisfy the request due to some capacity limit or similar, then a 508
109 /// (Insufficient Capacity) error is returned.
110 ///
111 /// If an XOR-PEER-ADDRESS attribute contains an address of an address
112 /// family that is not the same as that of a relayed transport address
113 /// for the allocation, the server MUST generate an error response with
114 /// the 443 (Peer Address Family Mismatch) response code.
115 ///
116 /// The server MAY impose restrictions on the IP address allowed in the
117 /// XOR-PEER-ADDRESS attribute; if a value is not allowed, the server
118 /// rejects the request with a 403 (Forbidden) error.
119 ///
120 /// If the message is valid and the server is capable of carrying out the
121 /// request, then the server installs or refreshes a permission for the
122 /// IP address contained in each XOR-PEER-ADDRESS attribute as described
123 /// in [Section 9](https://tools.ietf.org/html/rfc8656#section-9).
124 /// The port portion of each attribute is ignored and may be any arbitrary
125 /// value.
126 ///
127 /// The server then responds with a CreatePermission success response.
128 /// There are no mandatory attributes in the success response.
129 ///
130 /// NOTE: A server need not do anything special to implement
131 /// idempotency of CreatePermission requests over UDP using the
132 /// "stateless stack approach". Retransmitted CreatePermission
133 /// requests will simply refresh the permissions.
134 #[allow(unused_variables)]
135 fn on_create_permission(&self, id: &Identifier, username: &str, ports: &[u16]) {}
136
137 /// refresh request
138 ///
139 /// If the server receives a Refresh Request with a REQUESTED-ADDRESS-
140 /// FAMILY attribute and the attribute value does not match the address
141 /// family of the allocation, the server MUST reply with a 443 (Peer
142 /// Address Family Mismatch) Refresh error response.
143 ///
144 /// The server computes a value called the "desired lifetime" as follows:
145 /// if the request contains a LIFETIME attribute and the attribute value
146 /// is zero, then the "desired lifetime" is zero. Otherwise, if the
147 /// request contains a LIFETIME attribute, then the server computes the
148 /// minimum of the client's requested lifetime and the server's maximum
149 /// allowed lifetime. If this computed value is greater than the default
150 /// lifetime, then the "desired lifetime" is the computed value.
151 /// Otherwise, the "desired lifetime" is the default lifetime.
152 ///
153 /// Subsequent processing depends on the "desired lifetime" value:
154 ///
155 /// * If the "desired lifetime" is zero, then the request succeeds and
156 /// the allocation is deleted.
157 ///
158 /// * If the "desired lifetime" is non-zero, then the request succeeds
159 /// and the allocation's time-to-expiry is set to the "desired
160 /// lifetime".
161 ///
162 /// If the request succeeds, then the server sends a success response
163 /// containing:
164 ///
165 /// * A LIFETIME attribute containing the current value of the time-to-
166 /// expiry timer.
167 ///
168 /// NOTE: A server need not do anything special to implement
169 /// idempotency of Refresh requests over UDP using the "stateless
170 /// stack approach". Retransmitted Refresh requests with a non-
171 /// zero "desired lifetime" will simply refresh the allocation. A
172 /// retransmitted Refresh request with a zero "desired lifetime"
173 /// will cause a 437 (Allocation Mismatch) response if the
174 /// allocation has already been deleted, but the client will treat
175 /// this as equivalent to a success response (see below).
176 #[allow(unused_variables)]
177 fn on_refresh(&self, id: &Identifier, username: &str, lifetime: u32) {}
178
179 /// session destroy
180 ///
181 /// Triggered when the session leaves from the turn. Possible reasons: the
182 /// session life cycle has expired, external active deletion, or active
183 /// exit of the session.
184 #[allow(unused_variables)]
185 fn on_destroy(&self, id: &Identifier, username: &str) {}
186}
187
188pub struct ServiceOptions<T> {
189 pub port_range: PortRange,
190 pub realm: String,
191 pub interfaces: Vec<InterfaceAddr>,
192 pub handler: T,
193}
194
195/// Turn service.
196#[derive(Clone)]
197pub struct Service<T> {
198 interfaces: Arc<Vec<InterfaceAddr>>,
199 manager: Arc<SessionManager<T>>,
200 software: String,
201 realm: String,
202 handler: T,
203}
204
205impl<T> Service<T>
206where
207 T: ServiceHandler + Clone,
208{
209 /// Create turn service.
210 pub fn new(options: ServiceOptions<T>) -> Self {
211 Self {
212 manager: SessionManager::new(SessionManagerOptions {
213 port_range: options.port_range,
214 handler: options.handler.clone(),
215 }),
216 interfaces: Arc::new(options.interfaces),
217 software: crate::SOFTWARE.to_string(),
218 handler: options.handler,
219 realm: options.realm,
220 }
221 }
222
223 /// create a router.
224 pub fn make_router(&self, id: Identifier) -> Router<T> {
225 Router::new(self, id)
226 }
227
228 pub fn get_session_manager(&self) -> &SessionManager<T> {
229 &self.manager
230 }
231}