turn_rs/processor/
channel_bind.rs

1use super::{verify_message, Context, Response};
2use crate::StunClass;
3
4use bytes::BytesMut;
5use faster_stun::attribute::ErrKind::*;
6use faster_stun::attribute::*;
7use faster_stun::*;
8
9/// return channel binding error response
10#[inline(always)]
11fn reject<'a>(
12    ctx: Context,
13    reader: MessageReader,
14    bytes: &'a mut BytesMut,
15    err: ErrKind,
16) -> Result<Option<Response<'a>>, StunError> {
17    let method = Method::ChannelBind(Kind::Error);
18    let mut pack = MessageWriter::extend(method, &reader, bytes);
19    pack.append::<ErrorCode>(Error::from(err));
20    pack.append::<Realm>(&ctx.env.realm);
21    pack.flush(None)?;
22    Ok(Some(Response::new(bytes, StunClass::Msg, None, None)))
23}
24
25/// return channel binding ok response
26#[inline(always)]
27fn resolve<'a>(
28    reader: &MessageReader,
29    key: &[u8; 16],
30    bytes: &'a mut BytesMut,
31) -> Result<Option<Response<'a>>, StunError> {
32    let method = Method::ChannelBind(Kind::Response);
33    MessageWriter::extend(method, reader, bytes).flush(Some(key))?;
34    Ok(Some(Response::new(bytes, StunClass::Msg, None, None)))
35}
36
37/// process channel binding request
38///
39/// The server MAY impose restrictions on the IP address and port values
40/// allowed in the XOR-PEER-ADDRESS attribute; if a value is not allowed,
41/// the server rejects the request with a 403 (Forbidden) error.
42///
43/// If the request is valid, but the server is unable to fulfill the
44/// request due to some capacity limit or similar, the server replies
45/// with a 508 (Insufficient Capacity) error.
46///
47/// Otherwise, the server replies with a ChannelBind success response.
48/// There are no required attributes in a successful ChannelBind
49/// response.
50///
51/// If the server can satisfy the request, then the server creates or
52/// refreshes the channel binding using the channel number in the
53/// CHANNEL-NUMBER attribute and the transport address in the XOR-PEER-
54/// ADDRESS attribute.  The server also installs or refreshes a
55/// permission for the IP address in the XOR-PEER-ADDRESS attribute as
56/// described in Section 9.
57///
58/// NOTE: A server need not do anything special to implement
59/// idempotency of ChannelBind requests over UDP using the
60/// "stateless stack approach".  Retransmitted ChannelBind requests
61/// will simply refresh the channel binding and the corresponding
62/// permission.  Furthermore, the client must wait 5 minutes before
63/// binding a previously bound channel number or peer address to a
64/// different channel, eliminating the possibility that the
65/// transaction would initially fail but succeed on a
66/// retransmission.
67pub async fn process<'a>(
68    ctx: Context,
69    reader: MessageReader<'_, '_>,
70    bytes: &'a mut BytesMut,
71) -> Result<Option<Response<'a>>, StunError> {
72    let peer = match reader.get::<XorPeerAddress>() {
73        None => return reject(ctx, reader, bytes, BadRequest),
74        Some(a) => a,
75    };
76
77    let number = match reader.get::<ChannelNumber>() {
78        None => return reject(ctx, reader, bytes, BadRequest),
79        Some(c) => c,
80    };
81
82    if ctx.env.external.ip() != peer.ip() {
83        return reject(ctx, reader, bytes, Forbidden);
84    }
85
86    if !(0x4000..=0x7FFF).contains(&number) {
87        return reject(ctx, reader, bytes, BadRequest);
88    }
89
90    let (username, key) = match verify_message(&ctx, &reader).await {
91        None => return reject(ctx, reader, bytes, Unauthorized),
92        Some(ret) => ret,
93    };
94
95    if ctx
96        .env
97        .router
98        .bind_channel(&ctx.addr, peer.port(), number)
99        .is_none()
100    {
101        return reject(ctx, reader, bytes, InsufficientCapacity);
102    }
103
104    ctx.env.observer.channel_bind(&ctx.addr, username, number);
105    resolve(&reader, &key, bytes)
106}