rusturn 0.0.7

A Rust implementation of TURN server and client
Documentation
use crate::attribute::Attribute;
use crate::turn_message::TurnMessage;
use fibers_transport::{
    PollRecv, PollSend, RcTransporter, Result, TcpTransport, Transport, UdpTransport,
};
use futures::Async;
use std::net::SocketAddr;
use stun_codec::{DecodedMessage, Message};

#[derive(Debug)]
pub struct StunTransporter<T: Transport> {
    inner: RcTransporter<T>,
}
impl<T> StunTransporter<T>
where
    T: Transport<SendItem = TurnMessage, RecvItem = TurnMessage>,
{
    pub fn new(inner: RcTransporter<T>) -> Self {
        StunTransporter { inner }
    }

    pub fn with_inner_ref<F, U>(&self, f: F) -> U
    where
        F: FnOnce(&T) -> U,
    {
        self.inner.with_inner_ref(f)
    }
}
impl<T> Transport for StunTransporter<T>
where
    T: Transport<SendItem = TurnMessage, RecvItem = TurnMessage>,
{
    type PeerAddr = T::PeerAddr;
    type SendItem = Message<Attribute>;
    type RecvItem = DecodedMessage<Attribute>;

    fn start_send(&mut self, peer: Self::PeerAddr, item: Self::SendItem) -> Result<()> {
        track!(self.inner.start_send(peer, TurnMessage::Stun(item)))
    }

    fn poll_send(&mut self) -> PollSend {
        track!(self.inner.poll_send())
    }

    fn poll_recv(&mut self) -> PollRecv<(Self::PeerAddr, Self::RecvItem)> {
        let do_recv = track!(self
            .inner
            .with_peek_recv(|_peer, item| { !matches!(item, TurnMessage::ChannelData(_)) }))?;
        if do_recv == Some(true) {
            match track!(self.inner.poll_recv())? {
                Async::Ready(Some((peer, TurnMessage::Stun(item)))) => {
                    Ok(Async::Ready(Some((peer, Ok(item)))))
                }
                Async::Ready(Some((peer, TurnMessage::BrokenStun(item)))) => {
                    Ok(Async::Ready(Some((peer, Err(item)))))
                }
                Async::Ready(Some(_)) => unreachable!(),
                Async::Ready(None) => Ok(Async::Ready(None)),
                Async::NotReady => Ok(Async::NotReady),
            }
        } else {
            Ok(Async::NotReady)
        }
    }
}
impl<T> TcpTransport for StunTransporter<T>
where
    T: TcpTransport<SendItem = TurnMessage, RecvItem = TurnMessage>,
{
    fn peer_addr(&self) -> SocketAddr {
        self.inner.with_inner_ref(|x| x.peer_addr())
    }

    fn local_addr(&self) -> SocketAddr {
        self.inner.with_inner_ref(|x| x.local_addr())
    }
}
impl<T> UdpTransport for StunTransporter<T>
where
    T: UdpTransport<SendItem = TurnMessage, RecvItem = TurnMessage>,
{
    fn local_addr(&self) -> SocketAddr {
        self.inner.with_inner_ref(|x| x.local_addr())
    }
}