turn_server/turn/operations/
indication.rs

1use std::net::SocketAddr;
2
3use super::{Observer, Requet, Response, ResponseMethod};
4
5use crate::stun::{
6    MessageEncoder, MessageRef,
7    attribute::{Data, XorPeerAddress},
8    method::DATA_INDICATION,
9};
10
11/// process send indication request
12///
13/// When the server receives a Send indication, it processes as per
14/// [Section 5](https://tools.ietf.org/html/rfc8656#section-5) plus
15/// the specific rules mentioned here.
16///
17/// The message is first checked for validity.  The Send indication MUST
18/// contain both an XOR-PEER-ADDRESS attribute and a DATA attribute.  If
19/// one of these attributes is missing or invalid, then the message is
20/// discarded.  Note that the DATA attribute is allowed to contain zero
21/// bytes of data.
22///
23/// The Send indication may also contain the DONT-FRAGMENT attribute.  If
24/// the server is unable to set the DF bit on outgoing UDP datagrams when
25/// this attribute is present, then the server acts as if the DONT-
26/// FRAGMENT attribute is an unknown comprehension-required attribute
27/// (and thus the Send indication is discarded).
28///
29/// The server also checks that there is a permission installed for the
30/// IP address contained in the XOR-PEER-ADDRESS attribute.  If no such
31/// permission exists, the message is discarded.  Note that a Send
32/// indication never causes the server to refresh the permission.
33///
34/// The server MAY impose restrictions on the IP address and port values
35/// allowed in the XOR-PEER-ADDRESS attribute; if a value is not allowed,
36/// the server silently discards the Send indication.
37///
38/// If everything is OK, then the server forms a UDP datagram as follows:
39///
40/// * the source transport address is the relayed transport address of the
41///   allocation, where the allocation is determined by the 5-tuple on which the
42///   Send indication arrived;
43///
44/// * the destination transport address is taken from the XOR-PEER-ADDRESS
45///   attribute;
46///
47/// * the data following the UDP header is the contents of the value field of
48///   the DATA attribute.
49///
50/// The handling of the DONT-FRAGMENT attribute (if present), is
51/// described in Sections [14](https://tools.ietf.org/html/rfc8656#section-14)
52/// and [15](https://tools.ietf.org/html/rfc8656#section-15).
53///
54/// The resulting UDP datagram is then sent to the peer.
55pub fn process<'a, T: Observer>(req: Requet<'_, 'a, T, MessageRef<'_>>) -> Option<Response<'a>> {
56    let peer = req.message.get::<XorPeerAddress>()?;
57    let data = req.message.get::<Data>()?;
58
59    let relay = req.service.sessions.get_relay_address(&req.address, peer.port())?;
60    let local_port = req
61        .service
62        .sessions
63        .get_session(&req.address)
64        .get_ref()?
65        .allocate
66        .port?;
67
68    {
69        let mut message = MessageEncoder::extend(DATA_INDICATION, &req.message, req.bytes);
70        message.append::<XorPeerAddress>(SocketAddr::new(req.service.interface.ip(), local_port));
71        message.append::<Data>(data);
72        message.flush(None).ok()?;
73    }
74
75    Some(Response {
76        method: ResponseMethod::Stun(DATA_INDICATION),
77        endpoint: if req.service.endpoint != relay.endpoint {
78            Some(relay.endpoint)
79        } else {
80            None
81        },
82        relay: Some(relay.address),
83        bytes: req.bytes,
84    })
85}