mycrl_turn/
lib.rs

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