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