turn_rs/
lib.rs

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