turn_rs/processor/
allocate.rs1use super::{verify_message, Context, Response};
2use crate::{StunClass, SOFTWARE};
3
4use std::{net::SocketAddr, sync::Arc};
5
6use bytes::BytesMut;
7use faster_stun::attribute::ErrKind::*;
8use faster_stun::attribute::*;
9use faster_stun::*;
10
11#[inline(always)]
13fn reject<'a>(
14 ctx: Context,
15 reader: MessageReader,
16 bytes: &'a mut BytesMut,
17 err: ErrKind,
18) -> Result<Option<Response<'a>>, StunError> {
19 let method = Method::Allocate(Kind::Error);
20 let nonce = ctx.env.router.get_nonce(&ctx.addr);
21 let mut pack = MessageWriter::extend(method, &reader, bytes);
22 pack.append::<ErrorCode>(Error::from(err));
23 pack.append::<Realm>(&ctx.env.realm);
24 pack.append::<Nonce>(&nonce);
25 pack.flush(None)?;
26 Ok(Some(Response::new(bytes, StunClass::Msg, None, None)))
27}
28
29#[inline(always)]
40fn resolve<'a>(
41 ctx: &Context,
42 reader: &MessageReader,
43 key: &[u8; 16],
44 port: u16,
45 bytes: &'a mut BytesMut,
46) -> Result<Option<Response<'a>>, StunError> {
47 let method = Method::Allocate(Kind::Response);
48 let alloc_addr = Arc::new(SocketAddr::new(ctx.env.external.ip(), port));
49 let mut pack = MessageWriter::extend(method, reader, bytes);
50 pack.append::<XorRelayedAddress>(*alloc_addr.as_ref());
51 pack.append::<XorMappedAddress>(ctx.addr);
52 pack.append::<Lifetime>(600);
53 pack.append::<Software>(SOFTWARE);
54 pack.flush(Some(key))?;
55 Ok(Some(Response::new(bytes, StunClass::Msg, None, None)))
56}
57
58pub async fn process<'a>(
75 ctx: Context,
76 reader: MessageReader<'_, '_>,
77 bytes: &'a mut BytesMut,
78) -> Result<Option<Response<'a>>, StunError> {
79 if reader.get::<ReqeestedTransport>().is_none() {
80 return reject(ctx, reader, bytes, ServerError);
81 }
82
83 let (username, key) = match verify_message(&ctx, &reader).await {
84 None => return reject(ctx, reader, bytes, Unauthorized),
85 Some(ret) => ret,
86 };
87
88 let port = match ctx.env.router.alloc_port(&ctx.addr) {
89 None => return reject(ctx, reader, bytes, Unauthorized),
90 Some(p) => p,
91 };
92
93 ctx.env.observer.allocated(&ctx.addr, username, port);
94 resolve(&ctx, &reader, &key, port, bytes)
95}