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}