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