turn_rs/processor/
allocate.rsuse super::{verify_message, Context, Response};
use crate::{StunClass, SOFTWARE};
use std::{net::SocketAddr, sync::Arc};
use bytes::BytesMut;
use faster_stun::attribute::ErrKind::*;
use faster_stun::attribute::*;
use faster_stun::*;
#[inline(always)]
fn reject<'a>(
ctx: Context,
reader: MessageReader,
bytes: &'a mut BytesMut,
err: ErrKind,
) -> Result<Option<Response<'a>>, StunError> {
let method = Method::Allocate(Kind::Error);
let nonce = ctx.env.router.get_nonce(&ctx.addr);
let mut pack = MessageWriter::extend(method, &reader, bytes);
pack.append::<ErrorCode>(Error::from(err));
pack.append::<Realm>(&ctx.env.realm);
pack.append::<Nonce>(&nonce);
pack.flush(None)?;
Ok(Some(Response::new(bytes, StunClass::Msg, None, None)))
}
#[inline(always)]
fn resolve<'a>(
ctx: &Context,
reader: &MessageReader,
key: &[u8; 16],
port: u16,
bytes: &'a mut BytesMut,
) -> Result<Option<Response<'a>>, StunError> {
let method = Method::Allocate(Kind::Response);
let alloc_addr = Arc::new(SocketAddr::new(ctx.env.external.ip(), port));
let mut pack = MessageWriter::extend(method, reader, bytes);
pack.append::<XorRelayedAddress>(*alloc_addr.as_ref());
pack.append::<XorMappedAddress>(ctx.addr);
pack.append::<Lifetime>(600);
pack.append::<Software>(SOFTWARE);
pack.flush(Some(key))?;
Ok(Some(Response::new(bytes, StunClass::Msg, None, None)))
}
pub async fn process<'a>(
ctx: Context,
reader: MessageReader<'_, '_>,
bytes: &'a mut BytesMut,
) -> Result<Option<Response<'a>>, StunError> {
if reader.get::<ReqeestedTransport>().is_none() {
return reject(ctx, reader, bytes, ServerError);
}
let (username, key) = match verify_message(&ctx, &reader).await {
None => return reject(ctx, reader, bytes, Unauthorized),
Some(ret) => ret,
};
let port = match ctx.env.router.alloc_port(&ctx.addr) {
None => return reject(ctx, reader, bytes, Unauthorized),
Some(p) => p,
};
ctx.env.observer.allocated(&ctx.addr, username, port);
resolve(&ctx, &reader, &key, port, bytes)
}