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}