xref: /webrtc/turn/src/server/request.rs (revision ffe74184)
1*ffe74184SMartin Algesten #[cfg(test)]
2*ffe74184SMartin Algesten mod request_test;
3*ffe74184SMartin Algesten 
4*ffe74184SMartin Algesten use crate::allocation::allocation_manager::*;
5*ffe74184SMartin Algesten use crate::allocation::channel_bind::ChannelBind;
6*ffe74184SMartin Algesten use crate::allocation::five_tuple::*;
7*ffe74184SMartin Algesten use crate::allocation::permission::Permission;
8*ffe74184SMartin Algesten use crate::auth::*;
9*ffe74184SMartin Algesten use crate::error::*;
10*ffe74184SMartin Algesten use crate::proto::chandata::ChannelData;
11*ffe74184SMartin Algesten use crate::proto::channum::ChannelNumber;
12*ffe74184SMartin Algesten use crate::proto::data::Data;
13*ffe74184SMartin Algesten use crate::proto::evenport::EvenPort;
14*ffe74184SMartin Algesten use crate::proto::lifetime::*;
15*ffe74184SMartin Algesten use crate::proto::peeraddr::PeerAddress;
16*ffe74184SMartin Algesten use crate::proto::relayaddr::RelayedAddress;
17*ffe74184SMartin Algesten use crate::proto::reqtrans::RequestedTransport;
18*ffe74184SMartin Algesten use crate::proto::rsrvtoken::ReservationToken;
19*ffe74184SMartin Algesten use crate::proto::*;
20*ffe74184SMartin Algesten 
21*ffe74184SMartin Algesten use stun::agent::*;
22*ffe74184SMartin Algesten use stun::attributes::*;
23*ffe74184SMartin Algesten use stun::error_code::*;
24*ffe74184SMartin Algesten use stun::fingerprint::*;
25*ffe74184SMartin Algesten use stun::integrity::*;
26*ffe74184SMartin Algesten use stun::message::*;
27*ffe74184SMartin Algesten use stun::textattrs::*;
28*ffe74184SMartin Algesten use stun::uattrs::*;
29*ffe74184SMartin Algesten use stun::xoraddr::*;
30*ffe74184SMartin Algesten 
31*ffe74184SMartin Algesten use util::Conn;
32*ffe74184SMartin Algesten 
33*ffe74184SMartin Algesten use std::collections::HashMap;
34*ffe74184SMartin Algesten use std::marker::{Send, Sync};
35*ffe74184SMartin Algesten use std::net::SocketAddr;
36*ffe74184SMartin Algesten use std::sync::Arc;
37*ffe74184SMartin Algesten use std::time::SystemTime;
38*ffe74184SMartin Algesten use tokio::sync::Mutex;
39*ffe74184SMartin Algesten use tokio::time::{Duration, Instant};
40*ffe74184SMartin Algesten 
41*ffe74184SMartin Algesten use md5::{Digest, Md5};
42*ffe74184SMartin Algesten 
43*ffe74184SMartin Algesten pub(crate) const MAXIMUM_ALLOCATION_LIFETIME: Duration = Duration::from_secs(3600); // https://tools.ietf.org/html/rfc5766#section-6.2 defines 3600 seconds recommendation
44*ffe74184SMartin Algesten pub(crate) const NONCE_LIFETIME: Duration = Duration::from_secs(3600); // https://tools.ietf.org/html/rfc5766#section-4
45*ffe74184SMartin Algesten 
46*ffe74184SMartin Algesten // Request contains all the state needed to process a single incoming datagram
47*ffe74184SMartin Algesten pub struct Request {
48*ffe74184SMartin Algesten     // Current Request State
49*ffe74184SMartin Algesten     pub conn: Arc<dyn Conn + Send + Sync>,
50*ffe74184SMartin Algesten     pub src_addr: SocketAddr,
51*ffe74184SMartin Algesten     pub buff: Vec<u8>,
52*ffe74184SMartin Algesten 
53*ffe74184SMartin Algesten     // Server State
54*ffe74184SMartin Algesten     pub allocation_manager: Arc<Manager>,
55*ffe74184SMartin Algesten     pub nonces: Arc<Mutex<HashMap<String, Instant>>>,
56*ffe74184SMartin Algesten 
57*ffe74184SMartin Algesten     // User Configuration
58*ffe74184SMartin Algesten     pub auth_handler: Arc<dyn AuthHandler + Send + Sync>,
59*ffe74184SMartin Algesten     pub realm: String,
60*ffe74184SMartin Algesten     pub channel_bind_timeout: Duration,
61*ffe74184SMartin Algesten }
62*ffe74184SMartin Algesten 
63*ffe74184SMartin Algesten impl Request {
64*ffe74184SMartin Algesten     pub fn new(
65*ffe74184SMartin Algesten         conn: Arc<dyn Conn + Send + Sync>,
66*ffe74184SMartin Algesten         src_addr: SocketAddr,
67*ffe74184SMartin Algesten         allocation_manager: Arc<Manager>,
68*ffe74184SMartin Algesten         auth_handler: Arc<dyn AuthHandler + Send + Sync>,
69*ffe74184SMartin Algesten     ) -> Self {
70*ffe74184SMartin Algesten         Request {
71*ffe74184SMartin Algesten             conn,
72*ffe74184SMartin Algesten             src_addr,
73*ffe74184SMartin Algesten             buff: vec![],
74*ffe74184SMartin Algesten             allocation_manager,
75*ffe74184SMartin Algesten             nonces: Arc::new(Mutex::new(HashMap::new())),
76*ffe74184SMartin Algesten             auth_handler,
77*ffe74184SMartin Algesten             realm: String::new(),
78*ffe74184SMartin Algesten             channel_bind_timeout: Duration::from_secs(0),
79*ffe74184SMartin Algesten         }
80*ffe74184SMartin Algesten     }
81*ffe74184SMartin Algesten 
82*ffe74184SMartin Algesten     // handle_request processes the give Request
83*ffe74184SMartin Algesten     pub async fn handle_request(&mut self) -> Result<()> {
84*ffe74184SMartin Algesten         /*log::debug!(
85*ffe74184SMartin Algesten             "received {} bytes of udp from {} on {}",
86*ffe74184SMartin Algesten             self.buff.len(),
87*ffe74184SMartin Algesten             self.src_addr,
88*ffe74184SMartin Algesten             self.conn.local_addr().await?
89*ffe74184SMartin Algesten         );*/
90*ffe74184SMartin Algesten 
91*ffe74184SMartin Algesten         if ChannelData::is_channel_data(&self.buff) {
92*ffe74184SMartin Algesten             self.handle_data_packet().await
93*ffe74184SMartin Algesten         } else {
94*ffe74184SMartin Algesten             self.handle_turn_packet().await
95*ffe74184SMartin Algesten         }
96*ffe74184SMartin Algesten     }
97*ffe74184SMartin Algesten 
98*ffe74184SMartin Algesten     async fn handle_data_packet(&mut self) -> Result<()> {
99*ffe74184SMartin Algesten         log::debug!("received DataPacket from {}", self.src_addr);
100*ffe74184SMartin Algesten         let mut c = ChannelData {
101*ffe74184SMartin Algesten             raw: self.buff.clone(),
102*ffe74184SMartin Algesten             ..Default::default()
103*ffe74184SMartin Algesten         };
104*ffe74184SMartin Algesten         c.decode()?;
105*ffe74184SMartin Algesten         self.handle_channel_data(&c).await
106*ffe74184SMartin Algesten     }
107*ffe74184SMartin Algesten 
108*ffe74184SMartin Algesten     async fn handle_turn_packet(&mut self) -> Result<()> {
109*ffe74184SMartin Algesten         log::debug!("handle_turn_packet");
110*ffe74184SMartin Algesten         let mut m = Message {
111*ffe74184SMartin Algesten             raw: self.buff.clone(),
112*ffe74184SMartin Algesten             ..Default::default()
113*ffe74184SMartin Algesten         };
114*ffe74184SMartin Algesten         m.decode()?;
115*ffe74184SMartin Algesten 
116*ffe74184SMartin Algesten         self.process_message_handler(&m).await
117*ffe74184SMartin Algesten     }
118*ffe74184SMartin Algesten 
119*ffe74184SMartin Algesten     async fn process_message_handler(&mut self, m: &Message) -> Result<()> {
120*ffe74184SMartin Algesten         if m.typ.class == CLASS_INDICATION {
121*ffe74184SMartin Algesten             match m.typ.method {
122*ffe74184SMartin Algesten                 METHOD_SEND => self.handle_send_indication(m).await,
123*ffe74184SMartin Algesten                 _ => Err(Error::ErrUnexpectedClass),
124*ffe74184SMartin Algesten             }
125*ffe74184SMartin Algesten         } else if m.typ.class == CLASS_REQUEST {
126*ffe74184SMartin Algesten             match m.typ.method {
127*ffe74184SMartin Algesten                 METHOD_ALLOCATE => self.handle_allocate_request(m).await,
128*ffe74184SMartin Algesten                 METHOD_REFRESH => self.handle_refresh_request(m).await,
129*ffe74184SMartin Algesten                 METHOD_CREATE_PERMISSION => self.handle_create_permission_request(m).await,
130*ffe74184SMartin Algesten                 METHOD_CHANNEL_BIND => self.handle_channel_bind_request(m).await,
131*ffe74184SMartin Algesten                 METHOD_BINDING => self.handle_binding_request(m).await,
132*ffe74184SMartin Algesten                 _ => Err(Error::ErrUnexpectedClass),
133*ffe74184SMartin Algesten             }
134*ffe74184SMartin Algesten         } else {
135*ffe74184SMartin Algesten             Err(Error::ErrUnexpectedClass)
136*ffe74184SMartin Algesten         }
137*ffe74184SMartin Algesten     }
138*ffe74184SMartin Algesten 
139*ffe74184SMartin Algesten     pub(crate) async fn authenticate_request(
140*ffe74184SMartin Algesten         &mut self,
141*ffe74184SMartin Algesten         m: &Message,
142*ffe74184SMartin Algesten         calling_method: Method,
143*ffe74184SMartin Algesten     ) -> Result<Option<MessageIntegrity>> {
144*ffe74184SMartin Algesten         if !m.contains(ATTR_MESSAGE_INTEGRITY) {
145*ffe74184SMartin Algesten             self.respond_with_nonce(m, calling_method, CODE_UNAUTHORIZED)
146*ffe74184SMartin Algesten                 .await?;
147*ffe74184SMartin Algesten             return Ok(None);
148*ffe74184SMartin Algesten         }
149*ffe74184SMartin Algesten 
150*ffe74184SMartin Algesten         let mut nonce_attr = Nonce::new(ATTR_NONCE, String::new());
151*ffe74184SMartin Algesten         let mut username_attr = Username::new(ATTR_USERNAME, String::new());
152*ffe74184SMartin Algesten         let mut realm_attr = Realm::new(ATTR_REALM, String::new());
153*ffe74184SMartin Algesten         let bad_request_msg = build_msg(
154*ffe74184SMartin Algesten             m.transaction_id,
155*ffe74184SMartin Algesten             MessageType::new(calling_method, CLASS_ERROR_RESPONSE),
156*ffe74184SMartin Algesten             vec![Box::new(ErrorCodeAttribute {
157*ffe74184SMartin Algesten                 code: CODE_BAD_REQUEST,
158*ffe74184SMartin Algesten                 reason: vec![],
159*ffe74184SMartin Algesten             })],
160*ffe74184SMartin Algesten         )?;
161*ffe74184SMartin Algesten 
162*ffe74184SMartin Algesten         if let Err(err) = nonce_attr.get_from(m) {
163*ffe74184SMartin Algesten             build_and_send_err(&self.conn, self.src_addr, bad_request_msg, err.into()).await?;
164*ffe74184SMartin Algesten             return Ok(None);
165*ffe74184SMartin Algesten         }
166*ffe74184SMartin Algesten 
167*ffe74184SMartin Algesten         let to_be_deleted = {
168*ffe74184SMartin Algesten             // Assert Nonce exists and is not expired
169*ffe74184SMartin Algesten             let mut nonces = self.nonces.lock().await;
170*ffe74184SMartin Algesten 
171*ffe74184SMartin Algesten             let to_be_deleted = if let Some(nonce_creation_time) = nonces.get(&nonce_attr.text) {
172*ffe74184SMartin Algesten                 Instant::now()
173*ffe74184SMartin Algesten                     .checked_duration_since(*nonce_creation_time)
174*ffe74184SMartin Algesten                     .unwrap_or_else(|| Duration::from_secs(0))
175*ffe74184SMartin Algesten                     >= NONCE_LIFETIME
176*ffe74184SMartin Algesten             } else {
177*ffe74184SMartin Algesten                 true
178*ffe74184SMartin Algesten             };
179*ffe74184SMartin Algesten 
180*ffe74184SMartin Algesten             if to_be_deleted {
181*ffe74184SMartin Algesten                 nonces.remove(&nonce_attr.text);
182*ffe74184SMartin Algesten             }
183*ffe74184SMartin Algesten             to_be_deleted
184*ffe74184SMartin Algesten         };
185*ffe74184SMartin Algesten 
186*ffe74184SMartin Algesten         if to_be_deleted {
187*ffe74184SMartin Algesten             self.respond_with_nonce(m, calling_method, CODE_STALE_NONCE)
188*ffe74184SMartin Algesten                 .await?;
189*ffe74184SMartin Algesten             return Ok(None);
190*ffe74184SMartin Algesten         }
191*ffe74184SMartin Algesten 
192*ffe74184SMartin Algesten         if let Err(err) = realm_attr.get_from(m) {
193*ffe74184SMartin Algesten             build_and_send_err(&self.conn, self.src_addr, bad_request_msg, err.into()).await?;
194*ffe74184SMartin Algesten             return Ok(None);
195*ffe74184SMartin Algesten         }
196*ffe74184SMartin Algesten         if let Err(err) = username_attr.get_from(m) {
197*ffe74184SMartin Algesten             build_and_send_err(&self.conn, self.src_addr, bad_request_msg, err.into()).await?;
198*ffe74184SMartin Algesten             return Ok(None);
199*ffe74184SMartin Algesten         }
200*ffe74184SMartin Algesten 
201*ffe74184SMartin Algesten         let our_key = match self.auth_handler.auth_handle(
202*ffe74184SMartin Algesten             &username_attr.to_string(),
203*ffe74184SMartin Algesten             &realm_attr.to_string(),
204*ffe74184SMartin Algesten             self.src_addr,
205*ffe74184SMartin Algesten         ) {
206*ffe74184SMartin Algesten             Ok(key) => key,
207*ffe74184SMartin Algesten             Err(_) => {
208*ffe74184SMartin Algesten                 build_and_send_err(
209*ffe74184SMartin Algesten                     &self.conn,
210*ffe74184SMartin Algesten                     self.src_addr,
211*ffe74184SMartin Algesten                     bad_request_msg,
212*ffe74184SMartin Algesten                     Error::ErrNoSuchUser,
213*ffe74184SMartin Algesten                 )
214*ffe74184SMartin Algesten                 .await?;
215*ffe74184SMartin Algesten                 return Ok(None);
216*ffe74184SMartin Algesten             }
217*ffe74184SMartin Algesten         };
218*ffe74184SMartin Algesten 
219*ffe74184SMartin Algesten         let mi = MessageIntegrity(our_key);
220*ffe74184SMartin Algesten         if let Err(err) = mi.check(&mut m.clone()) {
221*ffe74184SMartin Algesten             build_and_send_err(&self.conn, self.src_addr, bad_request_msg, err.into()).await?;
222*ffe74184SMartin Algesten             Ok(None)
223*ffe74184SMartin Algesten         } else {
224*ffe74184SMartin Algesten             Ok(Some(mi))
225*ffe74184SMartin Algesten         }
226*ffe74184SMartin Algesten     }
227*ffe74184SMartin Algesten 
228*ffe74184SMartin Algesten     async fn respond_with_nonce(
229*ffe74184SMartin Algesten         &mut self,
230*ffe74184SMartin Algesten         m: &Message,
231*ffe74184SMartin Algesten         calling_method: Method,
232*ffe74184SMartin Algesten         response_code: ErrorCode,
233*ffe74184SMartin Algesten     ) -> Result<()> {
234*ffe74184SMartin Algesten         let nonce = build_nonce()?;
235*ffe74184SMartin Algesten 
236*ffe74184SMartin Algesten         {
237*ffe74184SMartin Algesten             // Nonce has already been taken
238*ffe74184SMartin Algesten             let mut nonces = self.nonces.lock().await;
239*ffe74184SMartin Algesten             if nonces.contains_key(&nonce) {
240*ffe74184SMartin Algesten                 return Err(Error::ErrDuplicatedNonce);
241*ffe74184SMartin Algesten             }
242*ffe74184SMartin Algesten             nonces.insert(nonce.clone(), Instant::now());
243*ffe74184SMartin Algesten         }
244*ffe74184SMartin Algesten 
245*ffe74184SMartin Algesten         let msg = build_msg(
246*ffe74184SMartin Algesten             m.transaction_id,
247*ffe74184SMartin Algesten             MessageType::new(calling_method, CLASS_ERROR_RESPONSE),
248*ffe74184SMartin Algesten             vec![
249*ffe74184SMartin Algesten                 Box::new(ErrorCodeAttribute {
250*ffe74184SMartin Algesten                     code: response_code,
251*ffe74184SMartin Algesten                     reason: vec![],
252*ffe74184SMartin Algesten                 }),
253*ffe74184SMartin Algesten                 Box::new(Nonce::new(ATTR_NONCE, nonce)),
254*ffe74184SMartin Algesten                 Box::new(Realm::new(ATTR_REALM, self.realm.clone())),
255*ffe74184SMartin Algesten             ],
256*ffe74184SMartin Algesten         )?;
257*ffe74184SMartin Algesten 
258*ffe74184SMartin Algesten         build_and_send(&self.conn, self.src_addr, msg).await
259*ffe74184SMartin Algesten     }
260*ffe74184SMartin Algesten 
261*ffe74184SMartin Algesten     pub(crate) async fn handle_binding_request(&mut self, m: &Message) -> Result<()> {
262*ffe74184SMartin Algesten         log::debug!("received BindingRequest from {}", self.src_addr);
263*ffe74184SMartin Algesten 
264*ffe74184SMartin Algesten         let (ip, port) = (self.src_addr.ip(), self.src_addr.port());
265*ffe74184SMartin Algesten 
266*ffe74184SMartin Algesten         let msg = build_msg(
267*ffe74184SMartin Algesten             m.transaction_id,
268*ffe74184SMartin Algesten             BINDING_SUCCESS,
269*ffe74184SMartin Algesten             vec![
270*ffe74184SMartin Algesten                 Box::new(XorMappedAddress { ip, port }),
271*ffe74184SMartin Algesten                 Box::new(FINGERPRINT),
272*ffe74184SMartin Algesten             ],
273*ffe74184SMartin Algesten         )?;
274*ffe74184SMartin Algesten 
275*ffe74184SMartin Algesten         build_and_send(&self.conn, self.src_addr, msg).await
276*ffe74184SMartin Algesten     }
277*ffe74184SMartin Algesten 
278*ffe74184SMartin Algesten     // // https://tools.ietf.org/html/rfc5766#section-6.2
279*ffe74184SMartin Algesten     pub(crate) async fn handle_allocate_request(&mut self, m: &Message) -> Result<()> {
280*ffe74184SMartin Algesten         log::debug!("received AllocateRequest from {}", self.src_addr);
281*ffe74184SMartin Algesten 
282*ffe74184SMartin Algesten         // 1. The server MUST require that the request be authenticated.  This
283*ffe74184SMartin Algesten         //    authentication MUST be done using the long-term credential
284*ffe74184SMartin Algesten         //    mechanism of [https://tools.ietf.org/html/rfc5389#section-10.2.2]
285*ffe74184SMartin Algesten         //    unless the client and server agree to use another mechanism through
286*ffe74184SMartin Algesten         //    some procedure outside the scope of this document.
287*ffe74184SMartin Algesten         let message_integrity =
288*ffe74184SMartin Algesten             if let Some(mi) = self.authenticate_request(m, METHOD_ALLOCATE).await? {
289*ffe74184SMartin Algesten                 mi
290*ffe74184SMartin Algesten             } else {
291*ffe74184SMartin Algesten                 log::debug!("no MessageIntegrity");
292*ffe74184SMartin Algesten                 return Ok(());
293*ffe74184SMartin Algesten             };
294*ffe74184SMartin Algesten 
295*ffe74184SMartin Algesten         let five_tuple = FiveTuple {
296*ffe74184SMartin Algesten             src_addr: self.src_addr,
297*ffe74184SMartin Algesten             dst_addr: self.conn.local_addr().await?,
298*ffe74184SMartin Algesten             protocol: PROTO_UDP,
299*ffe74184SMartin Algesten         };
300*ffe74184SMartin Algesten         let mut requested_port = 0;
301*ffe74184SMartin Algesten         let mut reservation_token = "".to_owned();
302*ffe74184SMartin Algesten 
303*ffe74184SMartin Algesten         // 2. The server checks if the 5-tuple is currently in use by an
304*ffe74184SMartin Algesten         //    existing allocation.  If yes, the server rejects the request with
305*ffe74184SMartin Algesten         //    a 437 (Allocation Mismatch) error.
306*ffe74184SMartin Algesten         if self
307*ffe74184SMartin Algesten             .allocation_manager
308*ffe74184SMartin Algesten             .get_allocation(&five_tuple)
309*ffe74184SMartin Algesten             .await
310*ffe74184SMartin Algesten             .is_some()
311*ffe74184SMartin Algesten         {
312*ffe74184SMartin Algesten             let msg = build_msg(
313*ffe74184SMartin Algesten                 m.transaction_id,
314*ffe74184SMartin Algesten                 MessageType::new(METHOD_ALLOCATE, CLASS_ERROR_RESPONSE),
315*ffe74184SMartin Algesten                 vec![Box::new(ErrorCodeAttribute {
316*ffe74184SMartin Algesten                     code: CODE_ALLOC_MISMATCH,
317*ffe74184SMartin Algesten                     reason: vec![],
318*ffe74184SMartin Algesten                 })],
319*ffe74184SMartin Algesten             )?;
320*ffe74184SMartin Algesten             return build_and_send_err(
321*ffe74184SMartin Algesten                 &self.conn,
322*ffe74184SMartin Algesten                 self.src_addr,
323*ffe74184SMartin Algesten                 msg,
324*ffe74184SMartin Algesten                 Error::ErrRelayAlreadyAllocatedForFiveTuple,
325*ffe74184SMartin Algesten             )
326*ffe74184SMartin Algesten             .await;
327*ffe74184SMartin Algesten         }
328*ffe74184SMartin Algesten 
329*ffe74184SMartin Algesten         // 3. The server checks if the request contains a REQUESTED-TRANSPORT
330*ffe74184SMartin Algesten         //    attribute.  If the REQUESTED-TRANSPORT attribute is not included
331*ffe74184SMartin Algesten         //    or is malformed, the server rejects the request with a 400 (Bad
332*ffe74184SMartin Algesten         //    Request) error.  Otherwise, if the attribute is included but
333*ffe74184SMartin Algesten         //    specifies a protocol other that UDP, the server rejects the
334*ffe74184SMartin Algesten         //    request with a 442 (Unsupported Transport Protocol) error.
335*ffe74184SMartin Algesten         let mut requested_transport = RequestedTransport::default();
336*ffe74184SMartin Algesten         if let Err(err) = requested_transport.get_from(m) {
337*ffe74184SMartin Algesten             let bad_request_msg = build_msg(
338*ffe74184SMartin Algesten                 m.transaction_id,
339*ffe74184SMartin Algesten                 MessageType::new(METHOD_ALLOCATE, CLASS_ERROR_RESPONSE),
340*ffe74184SMartin Algesten                 vec![Box::new(ErrorCodeAttribute {
341*ffe74184SMartin Algesten                     code: CODE_BAD_REQUEST,
342*ffe74184SMartin Algesten                     reason: vec![],
343*ffe74184SMartin Algesten                 })],
344*ffe74184SMartin Algesten             )?;
345*ffe74184SMartin Algesten             return build_and_send_err(&self.conn, self.src_addr, bad_request_msg, err.into())
346*ffe74184SMartin Algesten                 .await;
347*ffe74184SMartin Algesten         } else if requested_transport.protocol != PROTO_UDP {
348*ffe74184SMartin Algesten             let msg = build_msg(
349*ffe74184SMartin Algesten                 m.transaction_id,
350*ffe74184SMartin Algesten                 MessageType::new(METHOD_ALLOCATE, CLASS_ERROR_RESPONSE),
351*ffe74184SMartin Algesten                 vec![Box::new(ErrorCodeAttribute {
352*ffe74184SMartin Algesten                     code: CODE_UNSUPPORTED_TRANS_PROTO,
353*ffe74184SMartin Algesten                     reason: vec![],
354*ffe74184SMartin Algesten                 })],
355*ffe74184SMartin Algesten             )?;
356*ffe74184SMartin Algesten             return build_and_send_err(
357*ffe74184SMartin Algesten                 &self.conn,
358*ffe74184SMartin Algesten                 self.src_addr,
359*ffe74184SMartin Algesten                 msg,
360*ffe74184SMartin Algesten                 Error::ErrRequestedTransportMustBeUdp,
361*ffe74184SMartin Algesten             )
362*ffe74184SMartin Algesten             .await;
363*ffe74184SMartin Algesten         }
364*ffe74184SMartin Algesten 
365*ffe74184SMartin Algesten         // 4. The request may contain a DONT-FRAGMENT attribute.  If it does,
366*ffe74184SMartin Algesten         //    but the server does not support sending UDP datagrams with the DF
367*ffe74184SMartin Algesten         //    bit set to 1 (see Section 12), then the server treats the DONT-
368*ffe74184SMartin Algesten         //    FRAGMENT attribute in the Allocate request as an unknown
369*ffe74184SMartin Algesten         //    comprehension-required attribute.
370*ffe74184SMartin Algesten         if m.contains(ATTR_DONT_FRAGMENT) {
371*ffe74184SMartin Algesten             let msg = build_msg(
372*ffe74184SMartin Algesten                 m.transaction_id,
373*ffe74184SMartin Algesten                 MessageType::new(METHOD_ALLOCATE, CLASS_ERROR_RESPONSE),
374*ffe74184SMartin Algesten                 vec![
375*ffe74184SMartin Algesten                     Box::new(ErrorCodeAttribute {
376*ffe74184SMartin Algesten                         code: CODE_UNKNOWN_ATTRIBUTE,
377*ffe74184SMartin Algesten                         reason: vec![],
378*ffe74184SMartin Algesten                     }),
379*ffe74184SMartin Algesten                     Box::new(UnknownAttributes(vec![ATTR_DONT_FRAGMENT])),
380*ffe74184SMartin Algesten                 ],
381*ffe74184SMartin Algesten             )?;
382*ffe74184SMartin Algesten             return build_and_send_err(
383*ffe74184SMartin Algesten                 &self.conn,
384*ffe74184SMartin Algesten                 self.src_addr,
385*ffe74184SMartin Algesten                 msg,
386*ffe74184SMartin Algesten                 Error::ErrNoDontFragmentSupport,
387*ffe74184SMartin Algesten             )
388*ffe74184SMartin Algesten             .await;
389*ffe74184SMartin Algesten         }
390*ffe74184SMartin Algesten 
391*ffe74184SMartin Algesten         // 5.  The server checks if the request contains a RESERVATION-TOKEN
392*ffe74184SMartin Algesten         //     attribute.  If yes, and the request also contains an EVEN-PORT
393*ffe74184SMartin Algesten         //     attribute, then the server rejects the request with a 400 (Bad
394*ffe74184SMartin Algesten         //     Request) error.  Otherwise, it checks to see if the token is
395*ffe74184SMartin Algesten         //     valid (i.e., the token is in range and has not expired and the
396*ffe74184SMartin Algesten         //     corresponding relayed transport address is still available).  If
397*ffe74184SMartin Algesten         //     the token is not valid for some reason, the server rejects the
398*ffe74184SMartin Algesten         //     request with a 508 (Insufficient Capacity) error.
399*ffe74184SMartin Algesten         let mut reservation_token_attr = ReservationToken::default();
400*ffe74184SMartin Algesten         if reservation_token_attr.get_from(m).is_ok() {
401*ffe74184SMartin Algesten             let mut even_port = EvenPort::default();
402*ffe74184SMartin Algesten             if even_port.get_from(m).is_ok() {
403*ffe74184SMartin Algesten                 let bad_request_msg = build_msg(
404*ffe74184SMartin Algesten                     m.transaction_id,
405*ffe74184SMartin Algesten                     MessageType::new(METHOD_ALLOCATE, CLASS_ERROR_RESPONSE),
406*ffe74184SMartin Algesten                     vec![Box::new(ErrorCodeAttribute {
407*ffe74184SMartin Algesten                         code: CODE_BAD_REQUEST,
408*ffe74184SMartin Algesten                         reason: vec![],
409*ffe74184SMartin Algesten                     })],
410*ffe74184SMartin Algesten                 )?;
411*ffe74184SMartin Algesten                 return build_and_send_err(
412*ffe74184SMartin Algesten                     &self.conn,
413*ffe74184SMartin Algesten                     self.src_addr,
414*ffe74184SMartin Algesten                     bad_request_msg,
415*ffe74184SMartin Algesten                     Error::ErrRequestWithReservationTokenAndEvenPort,
416*ffe74184SMartin Algesten                 )
417*ffe74184SMartin Algesten                 .await;
418*ffe74184SMartin Algesten             }
419*ffe74184SMartin Algesten         }
420*ffe74184SMartin Algesten 
421*ffe74184SMartin Algesten         // 6. The server checks if the request contains an EVEN-PORT attribute.
422*ffe74184SMartin Algesten         //    If yes, then the server checks that it can satisfy the request
423*ffe74184SMartin Algesten         //    (i.e., can allocate a relayed transport address as described
424*ffe74184SMartin Algesten         //    below).  If the server cannot satisfy the request, then the
425*ffe74184SMartin Algesten         //    server rejects the request with a 508 (Insufficient Capacity)
426*ffe74184SMartin Algesten         //    error.
427*ffe74184SMartin Algesten         let mut even_port = EvenPort::default();
428*ffe74184SMartin Algesten         if even_port.get_from(m).is_ok() {
429*ffe74184SMartin Algesten             let mut random_port = 1;
430*ffe74184SMartin Algesten 
431*ffe74184SMartin Algesten             while random_port % 2 != 0 {
432*ffe74184SMartin Algesten                 random_port = match self.allocation_manager.get_random_even_port().await {
433*ffe74184SMartin Algesten                     Ok(port) => port,
434*ffe74184SMartin Algesten                     Err(err) => {
435*ffe74184SMartin Algesten                         let insufficent_capacity_msg = build_msg(
436*ffe74184SMartin Algesten                             m.transaction_id,
437*ffe74184SMartin Algesten                             MessageType::new(METHOD_ALLOCATE, CLASS_ERROR_RESPONSE),
438*ffe74184SMartin Algesten                             vec![Box::new(ErrorCodeAttribute {
439*ffe74184SMartin Algesten                                 code: CODE_INSUFFICIENT_CAPACITY,
440*ffe74184SMartin Algesten                                 reason: vec![],
441*ffe74184SMartin Algesten                             })],
442*ffe74184SMartin Algesten                         )?;
443*ffe74184SMartin Algesten                         return build_and_send_err(
444*ffe74184SMartin Algesten                             &self.conn,
445*ffe74184SMartin Algesten                             self.src_addr,
446*ffe74184SMartin Algesten                             insufficent_capacity_msg,
447*ffe74184SMartin Algesten                             err,
448*ffe74184SMartin Algesten                         )
449*ffe74184SMartin Algesten                         .await;
450*ffe74184SMartin Algesten                     }
451*ffe74184SMartin Algesten                 };
452*ffe74184SMartin Algesten             }
453*ffe74184SMartin Algesten 
454*ffe74184SMartin Algesten             requested_port = random_port;
455*ffe74184SMartin Algesten             reservation_token = rand_seq(8);
456*ffe74184SMartin Algesten         }
457*ffe74184SMartin Algesten 
458*ffe74184SMartin Algesten         // 7. At any point, the server MAY choose to reject the request with a
459*ffe74184SMartin Algesten         //    486 (Allocation Quota Reached) error if it feels the client is
460*ffe74184SMartin Algesten         //    trying to exceed some locally defined allocation quota.  The
461*ffe74184SMartin Algesten         //    server is free to define this allocation quota any way it wishes,
462*ffe74184SMartin Algesten         //    but SHOULD define it based on the username used to authenticate
463*ffe74184SMartin Algesten         //    the request, and not on the client's transport address.
464*ffe74184SMartin Algesten 
465*ffe74184SMartin Algesten         // 8. Also at any point, the server MAY choose to reject the request
466*ffe74184SMartin Algesten         //    with a 300 (Try Alternate) error if it wishes to redirect the
467*ffe74184SMartin Algesten         //    client to a different server.  The use of this error code and
468*ffe74184SMartin Algesten         //    attribute follow the specification in [RFC5389].
469*ffe74184SMartin Algesten         let lifetime_duration = allocation_lifetime(m);
470*ffe74184SMartin Algesten         let a = match self
471*ffe74184SMartin Algesten             .allocation_manager
472*ffe74184SMartin Algesten             .create_allocation(
473*ffe74184SMartin Algesten                 five_tuple,
474*ffe74184SMartin Algesten                 Arc::clone(&self.conn),
475*ffe74184SMartin Algesten                 requested_port,
476*ffe74184SMartin Algesten                 lifetime_duration,
477*ffe74184SMartin Algesten             )
478*ffe74184SMartin Algesten             .await
479*ffe74184SMartin Algesten         {
480*ffe74184SMartin Algesten             Ok(a) => a,
481*ffe74184SMartin Algesten             Err(err) => {
482*ffe74184SMartin Algesten                 let insufficent_capacity_msg = build_msg(
483*ffe74184SMartin Algesten                     m.transaction_id,
484*ffe74184SMartin Algesten                     MessageType::new(METHOD_ALLOCATE, CLASS_ERROR_RESPONSE),
485*ffe74184SMartin Algesten                     vec![Box::new(ErrorCodeAttribute {
486*ffe74184SMartin Algesten                         code: CODE_INSUFFICIENT_CAPACITY,
487*ffe74184SMartin Algesten                         reason: vec![],
488*ffe74184SMartin Algesten                     })],
489*ffe74184SMartin Algesten                 )?;
490*ffe74184SMartin Algesten                 return build_and_send_err(
491*ffe74184SMartin Algesten                     &self.conn,
492*ffe74184SMartin Algesten                     self.src_addr,
493*ffe74184SMartin Algesten                     insufficent_capacity_msg,
494*ffe74184SMartin Algesten                     err,
495*ffe74184SMartin Algesten                 )
496*ffe74184SMartin Algesten                 .await;
497*ffe74184SMartin Algesten             }
498*ffe74184SMartin Algesten         };
499*ffe74184SMartin Algesten 
500*ffe74184SMartin Algesten         // Once the allocation is created, the server replies with a success
501*ffe74184SMartin Algesten         // response.  The success response contains:
502*ffe74184SMartin Algesten         //   * An XOR-RELAYED-ADDRESS attribute containing the relayed transport
503*ffe74184SMartin Algesten         //     address.
504*ffe74184SMartin Algesten         //   * A LIFETIME attribute containing the current value of the time-to-
505*ffe74184SMartin Algesten         //     expiry timer.
506*ffe74184SMartin Algesten         //   * A RESERVATION-TOKEN attribute (if a second relayed transport
507*ffe74184SMartin Algesten         //     address was reserved).
508*ffe74184SMartin Algesten         //   * An XOR-MAPPED-ADDRESS attribute containing the client's IP address
509*ffe74184SMartin Algesten         //     and port (from the 5-tuple).
510*ffe74184SMartin Algesten 
511*ffe74184SMartin Algesten         let (src_ip, src_port) = (self.src_addr.ip(), self.src_addr.port());
512*ffe74184SMartin Algesten         let (relay_ip, relay_port) = {
513*ffe74184SMartin Algesten             let a = a.lock().await;
514*ffe74184SMartin Algesten             (a.relay_addr.ip(), a.relay_addr.port())
515*ffe74184SMartin Algesten         };
516*ffe74184SMartin Algesten 
517*ffe74184SMartin Algesten         let msg = {
518*ffe74184SMartin Algesten             if !reservation_token.is_empty() {
519*ffe74184SMartin Algesten                 self.allocation_manager
520*ffe74184SMartin Algesten                     .create_reservation(reservation_token.clone(), relay_port)
521*ffe74184SMartin Algesten                     .await;
522*ffe74184SMartin Algesten             }
523*ffe74184SMartin Algesten 
524*ffe74184SMartin Algesten             let mut response_attrs: Vec<Box<dyn Setter>> = vec![
525*ffe74184SMartin Algesten                 Box::new(RelayedAddress {
526*ffe74184SMartin Algesten                     ip: relay_ip,
527*ffe74184SMartin Algesten                     port: relay_port,
528*ffe74184SMartin Algesten                 }),
529*ffe74184SMartin Algesten                 Box::new(Lifetime(lifetime_duration)),
530*ffe74184SMartin Algesten                 Box::new(XorMappedAddress {
531*ffe74184SMartin Algesten                     ip: src_ip,
532*ffe74184SMartin Algesten                     port: src_port,
533*ffe74184SMartin Algesten                 }),
534*ffe74184SMartin Algesten             ];
535*ffe74184SMartin Algesten 
536*ffe74184SMartin Algesten             if !reservation_token.is_empty() {
537*ffe74184SMartin Algesten                 response_attrs.push(Box::new(ReservationToken(
538*ffe74184SMartin Algesten                     reservation_token.as_bytes().to_vec(),
539*ffe74184SMartin Algesten                 )));
540*ffe74184SMartin Algesten             }
541*ffe74184SMartin Algesten 
542*ffe74184SMartin Algesten             response_attrs.push(Box::new(message_integrity));
543*ffe74184SMartin Algesten             build_msg(
544*ffe74184SMartin Algesten                 m.transaction_id,
545*ffe74184SMartin Algesten                 MessageType::new(METHOD_ALLOCATE, CLASS_SUCCESS_RESPONSE),
546*ffe74184SMartin Algesten                 response_attrs,
547*ffe74184SMartin Algesten             )?
548*ffe74184SMartin Algesten         };
549*ffe74184SMartin Algesten 
550*ffe74184SMartin Algesten         build_and_send(&self.conn, self.src_addr, msg).await
551*ffe74184SMartin Algesten     }
552*ffe74184SMartin Algesten 
553*ffe74184SMartin Algesten     pub(crate) async fn handle_refresh_request(&mut self, m: &Message) -> Result<()> {
554*ffe74184SMartin Algesten         log::debug!("received RefreshRequest from {}", self.src_addr);
555*ffe74184SMartin Algesten 
556*ffe74184SMartin Algesten         let message_integrity =
557*ffe74184SMartin Algesten             if let Some(mi) = self.authenticate_request(m, METHOD_REFRESH).await? {
558*ffe74184SMartin Algesten                 mi
559*ffe74184SMartin Algesten             } else {
560*ffe74184SMartin Algesten                 log::debug!("no MessageIntegrity");
561*ffe74184SMartin Algesten                 return Ok(());
562*ffe74184SMartin Algesten             };
563*ffe74184SMartin Algesten 
564*ffe74184SMartin Algesten         let lifetime_duration = allocation_lifetime(m);
565*ffe74184SMartin Algesten         let five_tuple = FiveTuple {
566*ffe74184SMartin Algesten             src_addr: self.src_addr,
567*ffe74184SMartin Algesten             dst_addr: self.conn.local_addr().await?,
568*ffe74184SMartin Algesten             protocol: PROTO_UDP,
569*ffe74184SMartin Algesten         };
570*ffe74184SMartin Algesten 
571*ffe74184SMartin Algesten         if lifetime_duration != Duration::from_secs(0) {
572*ffe74184SMartin Algesten             let a = self.allocation_manager.get_allocation(&five_tuple).await;
573*ffe74184SMartin Algesten             if let Some(a) = a {
574*ffe74184SMartin Algesten                 let a = a.lock().await;
575*ffe74184SMartin Algesten                 a.refresh(lifetime_duration).await;
576*ffe74184SMartin Algesten             } else {
577*ffe74184SMartin Algesten                 return Err(Error::ErrNoAllocationFound);
578*ffe74184SMartin Algesten             }
579*ffe74184SMartin Algesten         } else {
580*ffe74184SMartin Algesten             self.allocation_manager.delete_allocation(&five_tuple).await;
581*ffe74184SMartin Algesten         }
582*ffe74184SMartin Algesten 
583*ffe74184SMartin Algesten         let msg = build_msg(
584*ffe74184SMartin Algesten             m.transaction_id,
585*ffe74184SMartin Algesten             MessageType::new(METHOD_REFRESH, CLASS_SUCCESS_RESPONSE),
586*ffe74184SMartin Algesten             vec![
587*ffe74184SMartin Algesten                 Box::new(Lifetime(lifetime_duration)),
588*ffe74184SMartin Algesten                 Box::new(message_integrity),
589*ffe74184SMartin Algesten             ],
590*ffe74184SMartin Algesten         )?;
591*ffe74184SMartin Algesten 
592*ffe74184SMartin Algesten         build_and_send(&self.conn, self.src_addr, msg).await
593*ffe74184SMartin Algesten     }
594*ffe74184SMartin Algesten 
595*ffe74184SMartin Algesten     pub(crate) async fn handle_create_permission_request(&mut self, m: &Message) -> Result<()> {
596*ffe74184SMartin Algesten         log::debug!("received CreatePermission from {}", self.src_addr);
597*ffe74184SMartin Algesten 
598*ffe74184SMartin Algesten         let a = self
599*ffe74184SMartin Algesten             .allocation_manager
600*ffe74184SMartin Algesten             .get_allocation(&FiveTuple {
601*ffe74184SMartin Algesten                 src_addr: self.src_addr,
602*ffe74184SMartin Algesten                 dst_addr: self.conn.local_addr().await?,
603*ffe74184SMartin Algesten                 protocol: PROTO_UDP,
604*ffe74184SMartin Algesten             })
605*ffe74184SMartin Algesten             .await;
606*ffe74184SMartin Algesten 
607*ffe74184SMartin Algesten         if let Some(a) = a {
608*ffe74184SMartin Algesten             let message_integrity = if let Some(mi) = self
609*ffe74184SMartin Algesten                 .authenticate_request(m, METHOD_CREATE_PERMISSION)
610*ffe74184SMartin Algesten                 .await?
611*ffe74184SMartin Algesten             {
612*ffe74184SMartin Algesten                 mi
613*ffe74184SMartin Algesten             } else {
614*ffe74184SMartin Algesten                 log::debug!("no MessageIntegrity");
615*ffe74184SMartin Algesten                 return Ok(());
616*ffe74184SMartin Algesten             };
617*ffe74184SMartin Algesten             let mut add_count = 0;
618*ffe74184SMartin Algesten 
619*ffe74184SMartin Algesten             {
620*ffe74184SMartin Algesten                 let a = a.lock().await;
621*ffe74184SMartin Algesten                 for attr in &m.attributes.0 {
622*ffe74184SMartin Algesten                     if attr.typ != ATTR_XOR_PEER_ADDRESS {
623*ffe74184SMartin Algesten                         continue;
624*ffe74184SMartin Algesten                     }
625*ffe74184SMartin Algesten 
626*ffe74184SMartin Algesten                     let mut peer_address = PeerAddress::default();
627*ffe74184SMartin Algesten                     if peer_address.get_from(m).is_err() {
628*ffe74184SMartin Algesten                         add_count = 0;
629*ffe74184SMartin Algesten                         break;
630*ffe74184SMartin Algesten                     }
631*ffe74184SMartin Algesten 
632*ffe74184SMartin Algesten                     log::debug!(
633*ffe74184SMartin Algesten                         "adding permission for {}",
634*ffe74184SMartin Algesten                         format!("{}:{}", peer_address.ip, peer_address.port)
635*ffe74184SMartin Algesten                     );
636*ffe74184SMartin Algesten 
637*ffe74184SMartin Algesten                     a.add_permission(Permission::new(SocketAddr::new(
638*ffe74184SMartin Algesten                         peer_address.ip,
639*ffe74184SMartin Algesten                         peer_address.port,
640*ffe74184SMartin Algesten                     )))
641*ffe74184SMartin Algesten                     .await;
642*ffe74184SMartin Algesten                     add_count += 1;
643*ffe74184SMartin Algesten                 }
644*ffe74184SMartin Algesten             }
645*ffe74184SMartin Algesten 
646*ffe74184SMartin Algesten             let mut resp_class = CLASS_SUCCESS_RESPONSE;
647*ffe74184SMartin Algesten             if add_count == 0 {
648*ffe74184SMartin Algesten                 resp_class = CLASS_ERROR_RESPONSE;
649*ffe74184SMartin Algesten             }
650*ffe74184SMartin Algesten 
651*ffe74184SMartin Algesten             let msg = build_msg(
652*ffe74184SMartin Algesten                 m.transaction_id,
653*ffe74184SMartin Algesten                 MessageType::new(METHOD_CREATE_PERMISSION, resp_class),
654*ffe74184SMartin Algesten                 vec![Box::new(message_integrity)],
655*ffe74184SMartin Algesten             )?;
656*ffe74184SMartin Algesten 
657*ffe74184SMartin Algesten             build_and_send(&self.conn, self.src_addr, msg).await
658*ffe74184SMartin Algesten         } else {
659*ffe74184SMartin Algesten             Err(Error::ErrNoAllocationFound)
660*ffe74184SMartin Algesten         }
661*ffe74184SMartin Algesten     }
662*ffe74184SMartin Algesten 
663*ffe74184SMartin Algesten     pub(crate) async fn handle_send_indication(&mut self, m: &Message) -> Result<()> {
664*ffe74184SMartin Algesten         log::debug!("received SendIndication from {}", self.src_addr);
665*ffe74184SMartin Algesten 
666*ffe74184SMartin Algesten         let a = self
667*ffe74184SMartin Algesten             .allocation_manager
668*ffe74184SMartin Algesten             .get_allocation(&FiveTuple {
669*ffe74184SMartin Algesten                 src_addr: self.src_addr,
670*ffe74184SMartin Algesten                 dst_addr: self.conn.local_addr().await?,
671*ffe74184SMartin Algesten                 protocol: PROTO_UDP,
672*ffe74184SMartin Algesten             })
673*ffe74184SMartin Algesten             .await;
674*ffe74184SMartin Algesten 
675*ffe74184SMartin Algesten         if let Some(a) = a {
676*ffe74184SMartin Algesten             let mut data_attr = Data::default();
677*ffe74184SMartin Algesten             data_attr.get_from(m)?;
678*ffe74184SMartin Algesten 
679*ffe74184SMartin Algesten             let mut peer_address = PeerAddress::default();
680*ffe74184SMartin Algesten             peer_address.get_from(m)?;
681*ffe74184SMartin Algesten 
682*ffe74184SMartin Algesten             let msg_dst = SocketAddr::new(peer_address.ip, peer_address.port);
683*ffe74184SMartin Algesten 
684*ffe74184SMartin Algesten             let has_perm = {
685*ffe74184SMartin Algesten                 let a = a.lock().await;
686*ffe74184SMartin Algesten                 a.has_permission(&msg_dst).await
687*ffe74184SMartin Algesten             };
688*ffe74184SMartin Algesten             if !has_perm {
689*ffe74184SMartin Algesten                 return Err(Error::ErrNoPermission);
690*ffe74184SMartin Algesten             }
691*ffe74184SMartin Algesten 
692*ffe74184SMartin Algesten             let a = a.lock().await;
693*ffe74184SMartin Algesten             let l = a.relay_socket.send_to(&data_attr.0, msg_dst).await?;
694*ffe74184SMartin Algesten             if l != data_attr.0.len() {
695*ffe74184SMartin Algesten                 Err(Error::ErrShortWrite)
696*ffe74184SMartin Algesten             } else {
697*ffe74184SMartin Algesten                 Ok(())
698*ffe74184SMartin Algesten             }
699*ffe74184SMartin Algesten         } else {
700*ffe74184SMartin Algesten             Err(Error::ErrNoAllocationFound)
701*ffe74184SMartin Algesten         }
702*ffe74184SMartin Algesten     }
703*ffe74184SMartin Algesten 
704*ffe74184SMartin Algesten     pub(crate) async fn handle_channel_bind_request(&mut self, m: &Message) -> Result<()> {
705*ffe74184SMartin Algesten         log::debug!("received ChannelBindRequest from {}", self.src_addr);
706*ffe74184SMartin Algesten 
707*ffe74184SMartin Algesten         let a = self
708*ffe74184SMartin Algesten             .allocation_manager
709*ffe74184SMartin Algesten             .get_allocation(&FiveTuple {
710*ffe74184SMartin Algesten                 src_addr: self.src_addr,
711*ffe74184SMartin Algesten                 dst_addr: self.conn.local_addr().await?,
712*ffe74184SMartin Algesten                 protocol: PROTO_UDP,
713*ffe74184SMartin Algesten             })
714*ffe74184SMartin Algesten             .await;
715*ffe74184SMartin Algesten 
716*ffe74184SMartin Algesten         if let Some(a) = a {
717*ffe74184SMartin Algesten             let bad_request_msg = build_msg(
718*ffe74184SMartin Algesten                 m.transaction_id,
719*ffe74184SMartin Algesten                 MessageType::new(METHOD_CHANNEL_BIND, CLASS_ERROR_RESPONSE),
720*ffe74184SMartin Algesten                 vec![Box::new(ErrorCodeAttribute {
721*ffe74184SMartin Algesten                     code: CODE_BAD_REQUEST,
722*ffe74184SMartin Algesten                     reason: vec![],
723*ffe74184SMartin Algesten                 })],
724*ffe74184SMartin Algesten             )?;
725*ffe74184SMartin Algesten 
726*ffe74184SMartin Algesten             let message_integrity =
727*ffe74184SMartin Algesten                 if let Some(mi) = self.authenticate_request(m, METHOD_CHANNEL_BIND).await? {
728*ffe74184SMartin Algesten                     mi
729*ffe74184SMartin Algesten                 } else {
730*ffe74184SMartin Algesten                     log::debug!("no MessageIntegrity");
731*ffe74184SMartin Algesten                     return Ok(());
732*ffe74184SMartin Algesten                 };
733*ffe74184SMartin Algesten             let mut channel = ChannelNumber::default();
734*ffe74184SMartin Algesten             if let Err(err) = channel.get_from(m) {
735*ffe74184SMartin Algesten                 return build_and_send_err(&self.conn, self.src_addr, bad_request_msg, err.into())
736*ffe74184SMartin Algesten                     .await;
737*ffe74184SMartin Algesten             }
738*ffe74184SMartin Algesten 
739*ffe74184SMartin Algesten             let mut peer_addr = PeerAddress::default();
740*ffe74184SMartin Algesten             if let Err(err) = peer_addr.get_from(m) {
741*ffe74184SMartin Algesten                 return build_and_send_err(&self.conn, self.src_addr, bad_request_msg, err.into())
742*ffe74184SMartin Algesten                     .await;
743*ffe74184SMartin Algesten             }
744*ffe74184SMartin Algesten 
745*ffe74184SMartin Algesten             log::debug!(
746*ffe74184SMartin Algesten                 "binding channel {} to {}",
747*ffe74184SMartin Algesten                 channel,
748*ffe74184SMartin Algesten                 format!("{}:{}", peer_addr.ip, peer_addr.port)
749*ffe74184SMartin Algesten             );
750*ffe74184SMartin Algesten 
751*ffe74184SMartin Algesten             let result = {
752*ffe74184SMartin Algesten                 let a = a.lock().await;
753*ffe74184SMartin Algesten                 a.add_channel_bind(
754*ffe74184SMartin Algesten                     ChannelBind::new(channel, SocketAddr::new(peer_addr.ip, peer_addr.port)),
755*ffe74184SMartin Algesten                     self.channel_bind_timeout,
756*ffe74184SMartin Algesten                 )
757*ffe74184SMartin Algesten                 .await
758*ffe74184SMartin Algesten             };
759*ffe74184SMartin Algesten             if let Err(err) = result {
760*ffe74184SMartin Algesten                 return build_and_send_err(&self.conn, self.src_addr, bad_request_msg, err).await;
761*ffe74184SMartin Algesten             }
762*ffe74184SMartin Algesten 
763*ffe74184SMartin Algesten             let msg = build_msg(
764*ffe74184SMartin Algesten                 m.transaction_id,
765*ffe74184SMartin Algesten                 MessageType::new(METHOD_CHANNEL_BIND, CLASS_SUCCESS_RESPONSE),
766*ffe74184SMartin Algesten                 vec![Box::new(message_integrity)],
767*ffe74184SMartin Algesten             )?;
768*ffe74184SMartin Algesten             build_and_send(&self.conn, self.src_addr, msg).await
769*ffe74184SMartin Algesten         } else {
770*ffe74184SMartin Algesten             Err(Error::ErrNoAllocationFound)
771*ffe74184SMartin Algesten         }
772*ffe74184SMartin Algesten     }
773*ffe74184SMartin Algesten 
774*ffe74184SMartin Algesten     pub(crate) async fn handle_channel_data(&mut self, c: &ChannelData) -> Result<()> {
775*ffe74184SMartin Algesten         log::debug!("received ChannelData from {}", self.src_addr);
776*ffe74184SMartin Algesten 
777*ffe74184SMartin Algesten         let a = self
778*ffe74184SMartin Algesten             .allocation_manager
779*ffe74184SMartin Algesten             .get_allocation(&FiveTuple {
780*ffe74184SMartin Algesten                 src_addr: self.src_addr,
781*ffe74184SMartin Algesten                 dst_addr: self.conn.local_addr().await?,
782*ffe74184SMartin Algesten                 protocol: PROTO_UDP,
783*ffe74184SMartin Algesten             })
784*ffe74184SMartin Algesten             .await;
785*ffe74184SMartin Algesten 
786*ffe74184SMartin Algesten         if let Some(a) = a {
787*ffe74184SMartin Algesten             let a = a.lock().await;
788*ffe74184SMartin Algesten             let channel = a.get_channel_addr(&c.number).await;
789*ffe74184SMartin Algesten             if let Some(peer) = channel {
790*ffe74184SMartin Algesten                 let l = a.relay_socket.send_to(&c.data, peer).await?;
791*ffe74184SMartin Algesten                 if l != c.data.len() {
792*ffe74184SMartin Algesten                     Err(Error::ErrShortWrite)
793*ffe74184SMartin Algesten                 } else {
794*ffe74184SMartin Algesten                     Ok(())
795*ffe74184SMartin Algesten                 }
796*ffe74184SMartin Algesten             } else {
797*ffe74184SMartin Algesten                 Err(Error::ErrNoSuchChannelBind)
798*ffe74184SMartin Algesten             }
799*ffe74184SMartin Algesten         } else {
800*ffe74184SMartin Algesten             Err(Error::ErrNoAllocationFound)
801*ffe74184SMartin Algesten         }
802*ffe74184SMartin Algesten     }
803*ffe74184SMartin Algesten }
804*ffe74184SMartin Algesten 
805*ffe74184SMartin Algesten pub(crate) fn rand_seq(n: usize) -> String {
806*ffe74184SMartin Algesten     let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".as_bytes();
807*ffe74184SMartin Algesten     let mut buf = vec![0u8; n];
808*ffe74184SMartin Algesten     for b in &mut buf {
809*ffe74184SMartin Algesten         *b = letters[rand::random::<usize>() % letters.len()];
810*ffe74184SMartin Algesten     }
811*ffe74184SMartin Algesten     if let Ok(s) = String::from_utf8(buf) {
812*ffe74184SMartin Algesten         s
813*ffe74184SMartin Algesten     } else {
814*ffe74184SMartin Algesten         String::new()
815*ffe74184SMartin Algesten     }
816*ffe74184SMartin Algesten }
817*ffe74184SMartin Algesten 
818*ffe74184SMartin Algesten pub(crate) fn build_nonce() -> Result<String> {
819*ffe74184SMartin Algesten     /* #nosec */
820*ffe74184SMartin Algesten     let mut s = String::new();
821*ffe74184SMartin Algesten     s.push_str(
822*ffe74184SMartin Algesten         format!(
823*ffe74184SMartin Algesten             "{}",
824*ffe74184SMartin Algesten             SystemTime::now()
825*ffe74184SMartin Algesten                 .duration_since(SystemTime::UNIX_EPOCH)?
826*ffe74184SMartin Algesten                 .as_nanos()
827*ffe74184SMartin Algesten         )
828*ffe74184SMartin Algesten         .as_str(),
829*ffe74184SMartin Algesten     );
830*ffe74184SMartin Algesten     s.push_str(format!("{}", rand::random::<u64>()).as_str());
831*ffe74184SMartin Algesten 
832*ffe74184SMartin Algesten     let mut h = Md5::new();
833*ffe74184SMartin Algesten     h.update(s.as_bytes());
834*ffe74184SMartin Algesten     Ok(format!("{:x}", h.finalize()))
835*ffe74184SMartin Algesten }
836*ffe74184SMartin Algesten 
837*ffe74184SMartin Algesten pub(crate) async fn build_and_send(
838*ffe74184SMartin Algesten     conn: &Arc<dyn Conn + Send + Sync>,
839*ffe74184SMartin Algesten     dst: SocketAddr,
840*ffe74184SMartin Algesten     msg: Message,
841*ffe74184SMartin Algesten ) -> Result<()> {
842*ffe74184SMartin Algesten     let _ = conn.send_to(&msg.raw, dst).await?;
843*ffe74184SMartin Algesten     Ok(())
844*ffe74184SMartin Algesten }
845*ffe74184SMartin Algesten 
846*ffe74184SMartin Algesten // Send a STUN packet and return the original error to the caller
847*ffe74184SMartin Algesten pub(crate) async fn build_and_send_err(
848*ffe74184SMartin Algesten     conn: &Arc<dyn Conn + Send + Sync>,
849*ffe74184SMartin Algesten     dst: SocketAddr,
850*ffe74184SMartin Algesten     msg: Message,
851*ffe74184SMartin Algesten     err: Error,
852*ffe74184SMartin Algesten ) -> Result<()> {
853*ffe74184SMartin Algesten     if let Err(send_err) = build_and_send(conn, dst, msg).await {
854*ffe74184SMartin Algesten         Err(send_err)
855*ffe74184SMartin Algesten     } else {
856*ffe74184SMartin Algesten         Err(err)
857*ffe74184SMartin Algesten     }
858*ffe74184SMartin Algesten }
859*ffe74184SMartin Algesten 
860*ffe74184SMartin Algesten pub(crate) fn build_msg(
861*ffe74184SMartin Algesten     transaction_id: TransactionId,
862*ffe74184SMartin Algesten     msg_type: MessageType,
863*ffe74184SMartin Algesten     mut additional: Vec<Box<dyn Setter>>,
864*ffe74184SMartin Algesten ) -> Result<Message> {
865*ffe74184SMartin Algesten     let mut attrs: Vec<Box<dyn Setter>> = vec![
866*ffe74184SMartin Algesten         Box::new(Message {
867*ffe74184SMartin Algesten             transaction_id,
868*ffe74184SMartin Algesten             ..Default::default()
869*ffe74184SMartin Algesten         }),
870*ffe74184SMartin Algesten         Box::new(msg_type),
871*ffe74184SMartin Algesten     ];
872*ffe74184SMartin Algesten 
873*ffe74184SMartin Algesten     attrs.append(&mut additional);
874*ffe74184SMartin Algesten 
875*ffe74184SMartin Algesten     let mut msg = Message::new();
876*ffe74184SMartin Algesten     msg.build(&attrs)?;
877*ffe74184SMartin Algesten     Ok(msg)
878*ffe74184SMartin Algesten }
879*ffe74184SMartin Algesten 
880*ffe74184SMartin Algesten pub(crate) fn allocation_lifetime(m: &Message) -> Duration {
881*ffe74184SMartin Algesten     let mut lifetime_duration = DEFAULT_LIFETIME;
882*ffe74184SMartin Algesten 
883*ffe74184SMartin Algesten     let mut lifetime = Lifetime::default();
884*ffe74184SMartin Algesten     if lifetime.get_from(m).is_ok() && lifetime.0 < MAXIMUM_ALLOCATION_LIFETIME {
885*ffe74184SMartin Algesten         lifetime_duration = lifetime.0;
886*ffe74184SMartin Algesten     }
887*ffe74184SMartin Algesten 
888*ffe74184SMartin Algesten     lifetime_duration
889*ffe74184SMartin Algesten }
890