use crate::attribute::{Attribute, AttributeType};
use crate::message::Message;
use crate::net::{socket_addr_xor, SocketAddrDecoder, SocketAddrEncoder};
use bytecodec::bytes::{BytesEncoder, RemainingBytesDecoder};
use bytecodec::fixnum::{
U32beDecoder, U32beEncoder, U64beDecoder, U64beEncoder, U8Decoder, U8Encoder,
};
use bytecodec::null::{NullDecoder, NullEncoder};
use bytecodec::{ByteCount, Decode, Encode, Eos, ErrorKind, Result, SizedEncode, TryTaggedDecode};
use std::net::SocketAddr;
use std::time::Duration;
macro_rules! impl_decode {
($decoder:ty, $item:ident, $and_then:expr) => {
impl Decode for $decoder {
type Item = $item;
fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
track!(self.0.decode(buf, eos))
}
fn finish_decoding(&mut self) -> Result<Self::Item> {
track!(self.0.finish_decoding()).and_then($and_then)
}
fn requiring_bytes(&self) -> ByteCount {
self.0.requiring_bytes()
}
fn is_idle(&self) -> bool {
self.0.is_idle()
}
}
impl TryTaggedDecode for $decoder {
type Tag = AttributeType;
fn try_start_decoding(&mut self, attr_type: Self::Tag) -> Result<bool> {
Ok(attr_type.as_u16() == $item::CODEPOINT)
}
}
};
}
macro_rules! impl_encode {
($encoder:ty, $item:ty, $map_from:expr) => {
impl Encode for $encoder {
type Item = $item;
fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
track!(self.0.encode(buf, eos))
}
fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
track!(self.0.start_encoding($map_from(item)))
}
fn requiring_bytes(&self) -> ByteCount {
self.0.requiring_bytes()
}
fn is_idle(&self) -> bool {
self.0.is_idle()
}
}
impl SizedEncode for $encoder {
fn exact_requiring_bytes(&self) -> u64 {
self.0.exact_requiring_bytes()
}
}
};
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ChannelNumber(u16);
impl ChannelNumber {
pub const CODEPOINT: u16 = 0x000C;
pub const MIN: u16 = 0x4000;
pub const MAX: u16 = 0x7FFF;
pub fn new(n: u16) -> Result<Self> {
track_assert!(n >= Self::MIN, ErrorKind::InvalidInput; n);
track_assert!(n <= Self::MAX, ErrorKind::InvalidInput; n);
Ok(ChannelNumber(n))
}
pub fn value(self) -> u16 {
self.0
}
pub fn min() -> Self {
ChannelNumber(Self::MIN)
}
pub fn max() -> Self {
ChannelNumber(Self::MAX)
}
pub fn wrapping_increment(self) -> Self {
if self.0 == Self::MAX {
Self::min()
} else {
ChannelNumber(self.0 + 1)
}
}
}
impl Attribute for ChannelNumber {
type Decoder = ChannelNumberDecoder;
type Encoder = ChannelNumberEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
}
#[derive(Debug, Default)]
pub struct ChannelNumberDecoder(U32beDecoder);
impl ChannelNumberDecoder {
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(ChannelNumberDecoder, ChannelNumber, |item| track!(
ChannelNumber::new((item >> 16) as u16)
));
#[derive(Debug, Default)]
pub struct ChannelNumberEncoder(U32beEncoder);
impl ChannelNumberEncoder {
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(
ChannelNumberEncoder,
ChannelNumber,
|item: Self::Item| u32::from(item.0) << 16
);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Lifetime(Duration);
impl Lifetime {
pub const CODEPOINT: u16 = 0x000D;
pub fn new(lifetime: Duration) -> Result<Self> {
let lifetime_seconds = lifetime.as_secs();
track_assert!(lifetime_seconds <= 0xFFFF_FFFF, ErrorKind::InvalidInput);
Ok(Lifetime(Duration::from_secs(lifetime_seconds)))
}
pub fn from_u32(lifetime_seconds: u32) -> Self {
Lifetime(Duration::from_secs(u64::from(lifetime_seconds)))
}
pub fn lifetime(&self) -> Duration {
self.0
}
}
impl Attribute for Lifetime {
type Decoder = LifetimeDecoder;
type Encoder = LifetimeEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
}
#[derive(Debug, Default)]
pub struct LifetimeDecoder(U32beDecoder);
impl LifetimeDecoder {
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(LifetimeDecoder, Lifetime, |item| Ok(Lifetime(
Duration::from_secs(u64::from(item))
)));
#[derive(Debug, Default)]
pub struct LifetimeEncoder(U32beEncoder);
impl LifetimeEncoder {
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(
LifetimeEncoder,
Lifetime,
|item: Self::Item| item.0.as_secs() as u32
);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct XorPeerAddress(SocketAddr);
impl XorPeerAddress {
pub const CODEPOINT: u16 = 0x0012;
pub fn new(addr: SocketAddr) -> Self {
XorPeerAddress(addr)
}
pub fn address(&self) -> SocketAddr {
self.0
}
}
impl Attribute for XorPeerAddress {
type Decoder = XorPeerAddressDecoder;
type Encoder = XorPeerAddressEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
fn before_encode<A: Attribute>(&mut self, message: &Message<A>) -> Result<()> {
self.0 = socket_addr_xor(self.0, message.transaction_id());
Ok(())
}
fn after_decode<A: Attribute>(&mut self, message: &Message<A>) -> Result<()> {
self.0 = socket_addr_xor(self.0, message.transaction_id());
Ok(())
}
}
#[derive(Debug, Default)]
pub struct XorPeerAddressDecoder(SocketAddrDecoder);
impl XorPeerAddressDecoder {
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(XorPeerAddressDecoder, XorPeerAddress, |item| Ok(
XorPeerAddress(item)
));
#[derive(Debug, Default)]
pub struct XorPeerAddressEncoder(SocketAddrEncoder);
impl XorPeerAddressEncoder {
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(XorPeerAddressEncoder, XorPeerAddress, |item: Self::Item| {
item.0
});
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Data(Vec<u8>);
impl Data {
pub const CODEPOINT: u16 = 0x0013;
pub fn new(data: Vec<u8>) -> Result<Self> {
track_assert!(data.len() <= 0xFFFF, ErrorKind::InvalidInput);
Ok(Data(data))
}
pub fn data(&self) -> &[u8] {
&self.0
}
}
impl Attribute for Data {
type Decoder = DataDecoder;
type Encoder = DataEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
}
#[derive(Debug, Default)]
pub struct DataDecoder(RemainingBytesDecoder);
impl DataDecoder {
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(DataDecoder, Data, |item| Ok(Data(item)));
#[derive(Debug, Default)]
pub struct DataEncoder(BytesEncoder);
impl DataEncoder {
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(DataEncoder, Data, |item: Self::Item| item.0);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct XorRelayAddress(SocketAddr);
impl XorRelayAddress {
pub const CODEPOINT: u16 = 0x0016;
pub fn new(addr: SocketAddr) -> Self {
XorRelayAddress(addr)
}
pub fn address(&self) -> SocketAddr {
self.0
}
}
impl Attribute for XorRelayAddress {
type Decoder = XorRelayAddressDecoder;
type Encoder = XorRelayAddressEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
fn before_encode<A: Attribute>(&mut self, message: &Message<A>) -> Result<()> {
self.0 = socket_addr_xor(self.0, message.transaction_id());
Ok(())
}
fn after_decode<A: Attribute>(&mut self, message: &Message<A>) -> Result<()> {
self.0 = socket_addr_xor(self.0, message.transaction_id());
Ok(())
}
}
#[derive(Debug, Default)]
pub struct XorRelayAddressDecoder(SocketAddrDecoder);
impl XorRelayAddressDecoder {
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(XorRelayAddressDecoder, XorRelayAddress, |item| Ok(
XorRelayAddress(item)
));
#[derive(Debug, Default)]
pub struct XorRelayAddressEncoder(SocketAddrEncoder);
impl XorRelayAddressEncoder {
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(
XorRelayAddressEncoder,
XorRelayAddress,
|item: Self::Item| item.0
);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct EvenPort(bool);
impl EvenPort {
pub const CODEPOINT: u16 = 0x0018;
pub fn new(is_requested: bool) -> Self {
EvenPort(is_requested)
}
pub fn is_requested(&self) -> bool {
self.0
}
}
impl Attribute for EvenPort {
type Decoder = EvenPortDecoder;
type Encoder = EvenPortEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
}
#[derive(Debug, Default)]
pub struct EvenPortDecoder(U8Decoder);
impl EvenPortDecoder {
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(EvenPortDecoder, EvenPort, |item| Ok(EvenPort(
(item & 0b1000_0000) != 0
)));
#[derive(Debug, Default)]
pub struct EvenPortEncoder(U8Encoder);
impl EvenPortEncoder {
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(EvenPortEncoder, EvenPort, |item: Self::Item| u8::from(
item.0
) << 7);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RequestedTransport(u8);
impl RequestedTransport {
pub const CODEPOINT: u16 = 0x0019;
pub fn new(protocol: u8) -> Self {
RequestedTransport(protocol)
}
pub fn protocol(&self) -> u8 {
self.0
}
}
impl Attribute for RequestedTransport {
type Decoder = RequestedTransportDecoder;
type Encoder = RequestedTransportEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
}
#[derive(Debug, Default)]
pub struct RequestedTransportDecoder(U32beDecoder);
impl RequestedTransportDecoder {
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(RequestedTransportDecoder, RequestedTransport, |item| Ok(
RequestedTransport((item >> 24) as u8)
));
#[derive(Debug, Default)]
pub struct RequestedTransportEncoder(U32beEncoder);
impl RequestedTransportEncoder {
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(
RequestedTransportEncoder,
RequestedTransport,
|item: Self::Item| u32::from(item.0) << 24
);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DontFragment;
impl DontFragment {
pub const CODEPOINT: u16 = 0x001A;
}
impl Attribute for DontFragment {
type Decoder = DontFragmentDecoder;
type Encoder = DontFragmentEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
}
#[derive(Debug, Default)]
pub struct DontFragmentDecoder(NullDecoder);
impl DontFragmentDecoder {
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(DontFragmentDecoder, DontFragment, |()| Ok(DontFragment));
#[derive(Debug, Default)]
pub struct DontFragmentEncoder(NullEncoder);
impl DontFragmentEncoder {
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(DontFragmentEncoder, DontFragment, |_: Self::Item| ());
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ReservationToken(u64);
impl ReservationToken {
pub const CODEPOINT: u16 = 0x0022;
pub fn new(token: u64) -> Self {
ReservationToken(token)
}
pub fn token(&self) -> u64 {
self.0
}
}
impl Attribute for ReservationToken {
type Decoder = ReservationTokenDecoder;
type Encoder = ReservationTokenEncoder;
fn get_type(&self) -> AttributeType {
AttributeType::new(Self::CODEPOINT)
}
}
#[derive(Debug, Default)]
pub struct ReservationTokenDecoder(U64beDecoder);
impl ReservationTokenDecoder {
pub fn new() -> Self {
Self::default()
}
}
impl_decode!(ReservationTokenDecoder, ReservationToken, |item| Ok(
ReservationToken(item)
));
#[derive(Debug, Default)]
pub struct ReservationTokenEncoder(U64beEncoder);
impl ReservationTokenEncoder {
pub fn new() -> Self {
Self::default()
}
}
impl_encode!(
ReservationTokenEncoder,
ReservationToken,
|item: Self::Item| item.0
);