Skip to main content

rtc_turn/client/
mod.rs

1//! The Sans-I/O TURN client.
2//!
3//! Using a relay takes three steps: Allocate to obtain a public address, CreatePermission for
4//! each peer you intend to exchange data with, and then Send/Data indications (or a bound channel)
5//! to move bytes. Each step is a STUN transaction, so every [`Event`](crate::client::Event) carries the
6//! transaction id of the request it answers.
7//!
8//! The three address kinds are easy to confuse: [`RelayedAddr`](crate::client::RelayedAddr) is what peers send to,
9//! [`ReflexiveAddr`](crate::client::ReflexiveAddr) is how the server sees this client, and [`PeerAddr`](crate::client::PeerAddr) is the far end.
10#[cfg(test)]
11mod client_test;
12
13/// Channel bindings, which replace the 36-byte Data indication header with a 4-byte one.
14pub mod binding;
15/// Per-peer send permissions, which a relay requires before it will forward to an address.
16pub mod permission;
17mod proto;
18/// A live allocation on the server, and sending or receiving through it.
19pub mod relay;
20/// Outstanding request tracking, with the RFC's retransmission schedule.
21pub mod transaction;
22
23use bytes::BytesMut;
24use log::{debug, trace};
25use std::collections::{HashMap, VecDeque};
26use std::net::SocketAddr;
27use std::time::{Duration, Instant};
28
29use stun::attributes::*;
30use stun::integrity::*;
31use stun::message::*;
32use stun::textattrs::*;
33use stun::xoraddr::*;
34
35use binding::*;
36use transaction::*;
37
38use crate::client::relay::{Relay, RelayState};
39use crate::proto::chandata::*;
40use crate::proto::channum::ChannelNumber;
41use crate::proto::data::*;
42use crate::proto::lifetime::Lifetime;
43use crate::proto::peeraddr::*;
44use crate::proto::relayaddr::RelayedAddress;
45use crate::proto::reqtrans::RequestedTransport;
46use crate::proto::{PROTO_TCP, PROTO_UDP};
47use shared::error::{Error, Result};
48use shared::util::lookup_host;
49use shared::{TransportContext, TransportMessage, TransportProtocol};
50use stun::error_code::ErrorCodeAttribute;
51use stun::fingerprint::FINGERPRINT;
52
53const DEFAULT_RTO_IN_MS: u64 = 200;
54const MAX_DATA_BUFFER_SIZE: usize = u16::MAX as usize; // message size limit for Chromium
55const MAX_READ_QUEUE_SIZE: usize = 1024;
56
57/// The public address the TURN server allocated on this client's behalf.
58///
59/// Peers send here; the server forwards to the client.
60pub type RelayedAddr = SocketAddr;
61/// The client's own address as seen by the server — its server-reflexive address.
62pub type ReflexiveAddr = SocketAddr;
63/// The address of a remote peer the client exchanges data with through the relay.
64pub type PeerAddr = SocketAddr;
65
66#[derive(Debug)]
67/// What the client produces in response to inbound datagrams and elapsed time.
68///
69/// Every variant carries the [`TransactionId`] of the request it answers, so a caller can
70/// match responses to the requests it issued.
71pub enum Event {
72    /// A request exhausted its retransmissions without a response.
73    TransactionTimeout(TransactionId),
74
75    /// A STUN Binding succeeded, reporting this client's server-reflexive address.
76    BindingResponse(TransactionId, ReflexiveAddr),
77    /// A STUN Binding failed.
78    BindingError(TransactionId, Error),
79
80    /// An Allocate succeeded; the relayed address is now usable.
81    AllocateResponse(TransactionId, RelayedAddr),
82    /// An Allocate failed — commonly authentication, or the server being out of ports.
83    AllocateError(TransactionId, Error),
84
85    /// A CreatePermission succeeded; the relay will now forward to and from this peer.
86    CreatePermissionResponse(TransactionId, PeerAddr),
87    /// A CreatePermission failed.
88    CreatePermissionError(TransactionId, Error),
89
90    /// Data arrived from a peer through the relay.
91    ///
92    /// The channel number is `Some` when it came as ChannelData and `None` when it came as a
93    /// Data indication.
94    DataIndicationOrChannelData(Option<ChannelNumber>, PeerAddr, BytesMut),
95}
96
97enum AllocateState {
98    Attempting,
99    Requesting(TextAttribute),
100}
101
102//              interval [msec]
103// 0: 0 ms      +500
104// 1: 500 ms	+1000
105// 2: 1500 ms   +2000
106// 3: 3500 ms   +4000
107// 4: 7500 ms   +8000
108// 5: 15500 ms  +16000
109// 6: 31500 ms  +32000
110// -: 63500 ms  failed
111
112/// ClientConfig is a bag of config parameters for Client.
113pub struct ClientConfig {
114    /// The STUN server to use for Binding requests, as `host:port`. May be empty.
115    pub stun_serv_addr: String, // STUN server address (e.g. "stun.abc.com:3478")
116    /// The TURN server to allocate from, as `host:port`.
117    pub turn_serv_addr: String, // TURN server address (e.g. "turn.abc.com:3478")
118    /// The local address the client sends from.
119    pub local_addr: SocketAddr,
120    /// Whether to reach the server over UDP or TCP.
121    pub transport_protocol: TransportProtocol,
122    /// The long-term credential username for the TURN server.
123    pub username: String,
124    /// The long-term credential password.
125    pub password: String,
126    /// The authentication realm, used in the `MESSAGE-INTEGRITY` computation.
127    pub realm: String,
128    /// An optional `SOFTWARE` attribute value, sent for diagnostics.
129    pub software: String,
130    /// The initial retransmission timeout in milliseconds; each retry doubles it.
131    pub rto_in_ms: u64,
132}
133
134/// Client is a STUN client
135pub struct Client {
136    stun_serv_addr: Option<SocketAddr>,
137    turn_serv_addr: Option<SocketAddr>,
138    local_addr: SocketAddr,
139    transport_protocol: TransportProtocol,
140    username: Username,
141    password: String,
142    realm: Realm,
143    integrity: MessageIntegrity,
144    software: Software,
145    tr_map: TransactionMap,
146    binding_mgr: BindingManager,
147    rto_in_ms: u64,
148
149    relays: HashMap<RelayedAddr, RelayState>,
150    transmits: VecDeque<TransportMessage<BytesMut>>,
151    events: VecDeque<Event>,
152}
153
154impl Client {
155    /// new returns a new Client instance. listeningAddress is the address and port to listen on, default "0.0.0.0:0"
156    pub fn new(config: ClientConfig) -> Result<Self> {
157        let stun_serv_addr = if config.stun_serv_addr.is_empty() {
158            None
159        } else {
160            Some(lookup_host(
161                config.local_addr.is_ipv4(),
162                config.stun_serv_addr.as_str(),
163            )?)
164        };
165
166        let turn_serv_addr = if config.turn_serv_addr.is_empty() {
167            None
168        } else {
169            Some(lookup_host(
170                config.local_addr.is_ipv4(),
171                config.turn_serv_addr.as_str(),
172            )?)
173        };
174
175        Ok(Client {
176            stun_serv_addr,
177            turn_serv_addr,
178            local_addr: config.local_addr,
179            transport_protocol: config.transport_protocol,
180            username: Username::new(ATTR_USERNAME, config.username),
181            password: config.password,
182            realm: Realm::new(ATTR_REALM, config.realm),
183            software: Software::new(ATTR_SOFTWARE, config.software),
184            tr_map: TransactionMap::new(),
185            binding_mgr: BindingManager::new(),
186            rto_in_ms: if config.rto_in_ms != 0 {
187                config.rto_in_ms
188            } else {
189                DEFAULT_RTO_IN_MS
190            },
191            integrity: MessageIntegrity::new_short_term_integrity(String::new()),
192
193            relays: HashMap::new(),
194            transmits: VecDeque::new(),
195            events: VecDeque::new(),
196        })
197    }
198
199    // handle_inbound handles data received.
200    // This method handles incoming packet demultiplex it by the source address
201    // and the types of the message.
202    // This return Ok(handled or not) and if there was an error.
203    // Caller should check if the packet was handled by this client or not.
204    // If not handled, it is assumed that the packet is application data.
205    // If an error is returned, the caller should discard the packet regardless.
206    fn handle_inbound(&mut self, data: &[u8], from: SocketAddr) -> Result<()> {
207        // +-------------------+-------------------------------+
208        // |   Return Values   |                               |
209        // +-------------------+       Meaning / Action        |
210        // | handled |  error  |                               |
211        // |=========+=========+===============================+
212        // |  false  |   nil   | Handle the packet as app data |
213        // |---------+---------+-------------------------------+
214        // |  true   |   nil   |        Nothing to do          |
215        // |---------+---------+-------------------------------+
216        // |  false  |  error  |     (shouldn't happen)        |
217        // |---------+---------+-------------------------------+
218        // |  true   |  error  | Error occurred while handling |
219        // +---------+---------+-------------------------------+
220        // Possible causes of the error:
221        //  - Malformed packet (parse error)
222        //  - STUN message was a request
223        //  - Non-STUN message from the STUN server
224
225        if is_stun_message(data) {
226            self.handle_stun_message(data)
227        } else if ChannelData::is_channel_data(data) {
228            self.handle_channel_data(data)
229        } else if self.stun_serv_addr.is_some() && &from == self.stun_serv_addr.as_ref().unwrap() {
230            // received from STUN server, but it is not a STUN message
231            Err(Error::ErrNonStunmessage)
232        } else {
233            // assume, this is an application data
234            trace!("non-STUN/TURN packet, unhandled");
235            Ok(())
236        }
237    }
238
239    fn handle_stun_message(&mut self, data: &[u8]) -> Result<()> {
240        let mut msg = Message::new();
241        msg.raw = data.to_vec();
242        msg.decode()?;
243
244        if msg.typ.class == CLASS_REQUEST {
245            return Err(Error::Other(format!(
246                "{:?} : {}",
247                Error::ErrUnexpectedStunrequestMessage,
248                msg
249            )));
250        }
251
252        if msg.typ.class == CLASS_INDICATION {
253            if msg.typ.method == METHOD_DATA {
254                let mut peer_addr = PeerAddress::default();
255                peer_addr.get_from(&msg)?;
256                let from = SocketAddr::new(peer_addr.ip, peer_addr.port);
257
258                let mut data = Data::default();
259                data.get_from(&msg)?;
260
261                debug!("data indication received from {}", from);
262
263                self.events.push_back(Event::DataIndicationOrChannelData(
264                    None,
265                    from,
266                    BytesMut::from(&data.0[..]),
267                ))
268            }
269
270            return Ok(());
271        }
272
273        // This is a STUN response message (transactional)
274        // The type is either:
275        // - stun.ClassSuccessResponse
276        // - stun.ClassErrorResponse
277
278        if self.tr_map.find(&msg.transaction_id).is_none() {
279            // silently discard
280            debug!("no transaction for {}", msg);
281            return Ok(());
282        }
283
284        if let Some(tr) = self.tr_map.delete(&msg.transaction_id) {
285            match msg.typ.method {
286                METHOD_BINDING => {
287                    if msg.typ.class == CLASS_ERROR_RESPONSE {
288                        let mut code = ErrorCodeAttribute::default();
289                        let err = if code.get_from(&msg).is_err() {
290                            Error::Other(format!("{}", msg.typ))
291                        } else {
292                            Error::Other(format!("{} (error {})", msg.typ, code))
293                        };
294                        self.events
295                            .push_back(Event::BindingError(tr.transaction_id, err));
296                    } else {
297                        let mut refl_addr = XorMappedAddress::default();
298                        match refl_addr.get_from(&msg) {
299                            Ok(_) => {
300                                self.events.push_back(Event::BindingResponse(
301                                    tr.transaction_id,
302                                    ReflexiveAddr::new(refl_addr.ip, refl_addr.port),
303                                ));
304                            }
305                            Err(err) => {
306                                self.events
307                                    .push_back(Event::BindingError(tr.transaction_id, err));
308                            }
309                        }
310                    }
311                }
312                METHOD_ALLOCATE => {
313                    self.handle_allocate_response(msg, tr.transaction_type)?;
314                }
315                METHOD_CREATE_PERMISSION => {
316                    if let TransactionType::CreatePermissionRequest(relayed_addr, peer_addr) =
317                        tr.transaction_type
318                    {
319                        let mut relay = Relay {
320                            relayed_addr,
321                            client: self,
322                        };
323                        relay.handle_create_permission_response(msg, peer_addr)?;
324                    }
325                }
326                METHOD_REFRESH => {
327                    if let TransactionType::RefreshRequest(relayed_addr) = tr.transaction_type {
328                        let mut relay = Relay {
329                            relayed_addr,
330                            client: self,
331                        };
332                        relay.handle_refresh_allocation_response(msg)?;
333                    }
334                }
335                METHOD_CHANNEL_BIND => {
336                    if let TransactionType::ChannelBindRequest(relayed_addr, bind_addr) =
337                        tr.transaction_type
338                    {
339                        let mut relay = Relay {
340                            relayed_addr,
341                            client: self,
342                        };
343                        relay.handle_channel_bind_response(msg, bind_addr)?;
344                    }
345                }
346                _ => {}
347            }
348        }
349
350        Ok(())
351    }
352
353    fn handle_channel_data(&mut self, data: &[u8]) -> Result<()> {
354        let mut ch_data = ChannelData {
355            raw: data.to_vec(),
356            ..Default::default()
357        };
358        ch_data.decode()?;
359
360        let addr = self
361            .find_addr_by_channel_number(ch_data.number.0)
362            .ok_or(Error::ErrChannelBindNotFound)?;
363
364        trace!(
365            "channel data received from {} (ch={})",
366            addr, ch_data.number.0
367        );
368
369        self.events.push_back(Event::DataIndicationOrChannelData(
370            Some(ch_data.number),
371            addr,
372            BytesMut::from(&ch_data.data[..]),
373        ));
374
375        Ok(())
376    }
377
378    /// Borrows the allocation for `relayed_addr` so data can be sent or permissions created.
379    ///
380    /// # Errors
381    ///
382    /// Fails if this client has no allocation for that address — it was never allocated, or has
383    /// already been closed.
384    pub fn relay(&mut self, relayed_addr: SocketAddr) -> Result<Relay<'_>> {
385        if !self.relays.contains_key(&relayed_addr) {
386            Err(Error::ErrStreamNotExisted)
387        } else {
388            Ok(Relay {
389                relayed_addr,
390                client: self,
391            })
392        }
393    }
394
395    /// send_binding_request_to sends a new STUN request to the given transport address
396    /// return key to find out corresponding Event either BindingResponse or BindingRequestTimeout
397    pub fn send_binding_request_to(&mut self, to: SocketAddr) -> Result<TransactionId> {
398        let msg = {
399            let attrs: Vec<Box<dyn Setter>> = if !self.software.text.is_empty() {
400                vec![
401                    Box::new(TransactionId::new()),
402                    Box::new(BINDING_REQUEST),
403                    Box::new(self.software.clone()),
404                ]
405            } else {
406                vec![Box::new(TransactionId::new()), Box::new(BINDING_REQUEST)]
407            };
408
409            let mut msg = Message::new();
410            msg.build(&attrs)?;
411            msg
412        };
413
414        debug!("client.SendBindingRequestTo call PerformTransaction 1");
415        Ok(self.perform_transaction(&msg, to, TransactionType::BindingRequest))
416    }
417
418    /// send_binding_request sends a new STUN request to the STUN server
419    /// return key to find out corresponding Event either BindingResponse or BindingRequestTimeout
420    pub fn send_binding_request(&mut self) -> Result<TransactionId> {
421        if let Some(stun_serv_addr) = &self.stun_serv_addr {
422            self.send_binding_request_to(*stun_serv_addr)
423        } else {
424            Err(Error::ErrStunserverAddressNotSet)
425        }
426    }
427
428    // find_addr_by_channel_number returns a peer address associated with the
429    // channel number on this UDPConn
430    fn find_addr_by_channel_number(&self, ch_num: u16) -> Option<SocketAddr> {
431        self.binding_mgr.find_by_number(ch_num).map(|b| b.addr)
432    }
433
434    // stun_server_addr return the STUN server address
435    fn stun_server_addr(&self) -> Option<SocketAddr> {
436        self.stun_serv_addr
437    }
438
439    /* https://datatracker.ietf.org/doc/html/rfc8656#section-20
440    TURN                                 TURN          Peer         Peer
441    client                               server         A            B
442      |                                    |            |            |
443      |--- Allocate request -------------->|            |            |
444      |    Transaction-Id=0xA56250D3F17ABE679422DE85    |            |
445      |    SOFTWARE="Example client, version 1.03"      |            |
446      |    LIFETIME=3600 (1 hour)          |            |            |
447      |    REQUESTED-TRANSPORT=17 (UDP)    |            |            |
448      |    DONT-FRAGMENT                   |            |            |
449      |                                    |            |            |
450      |<-- Allocate error response --------|            |            |
451      |    Transaction-Id=0xA56250D3F17ABE679422DE85    |            |
452      |    SOFTWARE="Example server, version 1.17"      |            |
453      |    ERROR-CODE=401 (Unauthorized)   |            |            |
454      |    REALM="example.com"             |            |            |
455      |    NONCE="obMatJos2gAAAadl7W7PeDU4hKE72jda"     |            |
456      |    PASSWORD-ALGORITHMS=MD5 and SHA256           |            |
457      |                                    |            |            |
458      |--- Allocate request -------------->|            |            |
459      |    Transaction-Id=0xC271E932AD7446A32C234492    |            |
460      |    SOFTWARE="Example client 1.03"  |            |            |
461      |    LIFETIME=3600 (1 hour)          |            |            |
462      |    REQUESTED-TRANSPORT=17 (UDP)    |            |            |
463      |    DONT-FRAGMENT                   |            |            |
464      |    USERNAME="George"               |            |            |
465      |    REALM="example.com"             |            |            |
466      |    NONCE="obMatJos2gAAAadl7W7PeDU4hKE72jda"     |            |
467      |    PASSWORD-ALGORITHMS=MD5 and SHA256           |            |
468      |    PASSWORD-ALGORITHM=SHA256       |            |            |
469      |    MESSAGE-INTEGRITY=...           |            |            |
470      |    MESSAGE-INTEGRITY-SHA256=...    |            |            |
471      |                                    |            |            |
472      |<-- Allocate success response ------|            |            |
473      |    Transaction-Id=0xC271E932AD7446A32C234492    |            |
474      |    SOFTWARE="Example server, version 1.17"      |            |
475      |    LIFETIME=1200 (20 minutes)      |            |            |
476      |    XOR-RELAYED-ADDRESS=192.0.2.15:50000         |            |
477      |    XOR-MAPPED-ADDRESS=192.0.2.1:7000            |            |
478      |    MESSAGE-INTEGRITY-SHA256=...    |            |            |
479    */
480    /// Replaces the long-term credential used to sign subsequent requests, **keeping any
481    /// existing allocation**.
482    ///
483    /// A TURN allocation is a property of the 5-tuple, not of the credential that created
484    /// it: [RFC 5766 §6.2] identifies an allocation by 5-tuple, and a server's
485    /// `Refresh` handling looks it up the same way. So when credentials are rotated on the
486    /// same server there is no need to give up the allocation and re-`Allocate` — which
487    /// would in fact be rejected with **437 (Allocation Mismatch)**, since the server still
488    /// holds the previous allocation for that 5-tuple. Re-signing the existing allocation is
489    /// both correct and seamless: permissions and channel bindings survive.
490    ///
491    /// The realm is *not* re-negotiated. It was learned from the server's 401 during the
492    /// first `Allocate`, and a credential rotation keeps the same server, so it still
493    /// applies. Follow this with [`Relay::refresh`] so the server sees the new credential
494    /// before the allocation would otherwise expire.
495    ///
496    /// [RFC 5766 §6.2]: https://datatracker.ietf.org/doc/html/rfc5766#section-6.2
497    pub fn update_credentials(&mut self, username: String, password: String) {
498        self.username = Username::new(ATTR_USERNAME, username);
499        self.password = password;
500        self.integrity = MessageIntegrity::new_long_term_integrity(
501            self.username.text.clone(),
502            self.realm.text.clone(),
503            self.password.clone(),
504        );
505
506        // Each allocation carries the integrity it will sign its own Refresh /
507        // CreatePermission / ChannelBind with, so they have to be re-signed too — otherwise
508        // the next refresh would still present the retired credential.
509        for relay in self.relays.values_mut() {
510            relay.integrity = self.integrity.clone();
511        }
512    }
513
514    /// Refreshes every live allocation, re-signing each with the current credential.
515    ///
516    /// Each allocation is refreshed with its own current lifetime, so this extends rather
517    /// than changes it. Intended to follow [`update_credentials`](Self::update_credentials).
518    pub fn refresh_allocations(&mut self) -> Result<()> {
519        let relays: Vec<(RelayedAddr, Duration)> = self
520            .relays
521            .iter()
522            .map(|(addr, relay)| (*addr, relay.lifetime))
523            .collect();
524
525        for (relayed_addr, lifetime) in relays {
526            self.relay(relayed_addr)?.refresh_allocation(lifetime)?;
527        }
528
529        Ok(())
530    }
531
532    /// Allocate sends a TURN allocation request to the given transport address
533    pub fn allocate(&mut self) -> Result<TransactionId> {
534        let mut msg = Message::new();
535        msg.build(&[
536            Box::new(TransactionId::new()),
537            Box::new(MessageType::new(METHOD_ALLOCATE, CLASS_REQUEST)),
538            Box::new(RequestedTransport {
539                protocol: if self.transport_protocol == TransportProtocol::UDP {
540                    PROTO_UDP
541                } else {
542                    PROTO_TCP
543                },
544            }),
545            Box::new(FINGERPRINT),
546        ])?;
547
548        debug!("client.Allocate call PerformTransaction 1");
549        let mut tid = self.perform_transaction(
550            &msg,
551            self.turn_server_addr()?,
552            TransactionType::AllocateAttempt,
553        );
554        tid.0[TRANSACTION_ID_SIZE - 1] = tid.0[TRANSACTION_ID_SIZE - 1].wrapping_add(1);
555        Ok(tid)
556    }
557
558    fn handle_allocate_response(
559        &mut self,
560        response: Message,
561        allocate_state: TransactionType,
562    ) -> Result<()> {
563        match allocate_state {
564            TransactionType::AllocateAttempt => {
565                // Anonymous allocate failed, trying to authenticate.
566                let nonce = match Nonce::get_from_as(&response, ATTR_NONCE) {
567                    Ok(nonce) => nonce,
568                    Err(err) => {
569                        self.events
570                            .push_back(Event::AllocateError(response.transaction_id, err));
571                        return Ok(());
572                    }
573                };
574                self.realm = match Realm::get_from_as(&response, ATTR_REALM) {
575                    Ok(realm) => realm,
576                    Err(err) => {
577                        self.events
578                            .push_back(Event::AllocateError(response.transaction_id, err));
579                        return Ok(());
580                    }
581                };
582
583                self.integrity = MessageIntegrity::new_long_term_integrity(
584                    self.username.text.clone(),
585                    self.realm.text.clone(),
586                    self.password.clone(),
587                );
588
589                let mut msg = Message::new();
590
591                // make it same as allocate() return value so that client can retrieve it
592                // from Event::AllocateResponse
593                let mut tid = response.transaction_id;
594                tid.0[TRANSACTION_ID_SIZE - 1] = tid.0[TRANSACTION_ID_SIZE - 1].wrapping_add(1);
595
596                // Trying to authorize.
597                msg.build(&[
598                    Box::new(tid),
599                    Box::new(MessageType::new(METHOD_ALLOCATE, CLASS_REQUEST)),
600                    Box::new(RequestedTransport {
601                        protocol: if self.transport_protocol == TransportProtocol::UDP {
602                            PROTO_UDP
603                        } else {
604                            PROTO_TCP
605                        },
606                    }),
607                    Box::new(self.username.clone()),
608                    Box::new(self.realm.clone()),
609                    Box::new(nonce.clone()),
610                    Box::new(self.integrity.clone()),
611                    Box::new(FINGERPRINT),
612                ])?;
613
614                debug!("client.Allocate call PerformTransaction 2");
615                self.perform_transaction(
616                    &msg,
617                    self.turn_server_addr()?,
618                    TransactionType::AllocateRequest(nonce),
619                );
620            }
621            TransactionType::AllocateRequest(nonce) => {
622                if response.typ.class == CLASS_ERROR_RESPONSE {
623                    let mut code = ErrorCodeAttribute::default();
624                    let err = if code.get_from(&response).is_err() {
625                        Error::Other(format!("{}", response.typ))
626                    } else {
627                        Error::Other(format!("{} (error {})", response.typ, code))
628                    };
629                    self.events
630                        .push_back(Event::AllocateError(response.transaction_id, err));
631                    return Ok(());
632                }
633
634                // Getting relayed addresses from response.
635                let mut relayed = RelayedAddress::default();
636                relayed.get_from(&response)?;
637                let relayed_addr = RelayedAddr::new(relayed.ip, relayed.port);
638
639                // Getting lifetime from response
640                let mut lifetime = Lifetime::default();
641                lifetime.get_from(&response)?;
642
643                self.relays.insert(
644                    relayed_addr,
645                    RelayState::new(relayed_addr, self.integrity.clone(), nonce, lifetime.0),
646                );
647                self.events.push_back(Event::AllocateResponse(
648                    response.transaction_id,
649                    relayed_addr,
650                ));
651            }
652            _ => {}
653        }
654        Ok(())
655    }
656
657    /// turn_server_addr return the TURN server address
658    fn turn_server_addr(&self) -> Result<SocketAddr> {
659        self.turn_serv_addr.ok_or(Error::ErrNilTurnSocket)
660    }
661
662    /// username returns username
663    fn username(&self) -> Username {
664        self.username.clone()
665    }
666
667    /// realm return realm
668    fn realm(&self) -> Realm {
669        self.realm.clone()
670    }
671
672    /// WriteTo sends data to the specified destination using the base socket.
673    fn write_to(&mut self, data: &[u8], remote: SocketAddr) {
674        self.transmits.push_back(TransportMessage {
675            now: Instant::now(),
676            transport: TransportContext {
677                local_addr: self.local_addr,
678                peer_addr: remote,
679                transport_protocol: self.transport_protocol,
680                ecn: None,
681            },
682            message: BytesMut::from(data),
683        });
684    }
685
686    // PerformTransaction performs STUN transaction
687    fn perform_transaction(
688        &mut self,
689        msg: &Message,
690        to: SocketAddr,
691        transaction_type: TransactionType,
692    ) -> TransactionId {
693        let tr = Transaction::new(TransactionConfig {
694            transaction_id: msg.transaction_id,
695            transaction_type,
696            raw: BytesMut::from(&msg.raw[..]),
697            local_addr: self.local_addr,
698            peer_addr: to,
699            transport_protocol: self.transport_protocol,
700            interval: self.rto_in_ms,
701        });
702
703        trace!(
704            "start {} transaction {:?} to {}",
705            msg.typ, msg.transaction_id, tr.peer_addr
706        );
707        self.tr_map.insert(msg.transaction_id, tr);
708
709        self.write_to(&msg.raw, to);
710
711        msg.transaction_id
712    }
713}