PortAllocatePools

Struct PortAllocatePools 

Source
pub struct PortAllocatePools {
    pub buckets: Vec<u64>,
    /* private fields */
}
Expand description

Random Port

Recently, awareness has been raised about a number of “blind” attacks (i.e., attacks that can be performed without the need to sniff the packets that correspond to the transport protocol instance to be attacked) that can be performed against the Transmission Control Protocol (TCP) [RFC0793] and similar protocols. The consequences of these attacks range from throughput reduction to broken connections or data corruption [RFC5927] [RFC4953] [Watson].

All these attacks rely on the attacker’s ability to guess or know the five-tuple (Protocol, Source Address, Source port, Destination Address, Destination Port) that identifies the transport protocol instance to be attacked.

Services are usually located at fixed, “well-known” ports [IANA] at the host supplying the service (the server). Client applications connecting to any such service will contact the server by specifying the server IP address and service port number. The IP address and port number of the client are normally left unspecified by the client application and thus are chosen automatically by the client networking stack. Ports chosen automatically by the networking stack are known as ephemeral ports [Stevens].

While the server IP address, the well-known port, and the client IP address may be known by an attacker, the ephemeral port of the client is usually unknown and must be guessed.

§Test

use std::collections::HashSet;
use turn_server::turn::sessions::*;

let mut pool = PortAllocatePools::default();
let mut ports = HashSet::with_capacity(PortAllocatePools::capacity());

while let Some(port) = pool.alloc(None) {
    ports.insert(port);
}

assert_eq!(PortAllocatePools::capacity() + 1, ports.len());

Fields§

§buckets: Vec<u64>

Implementations§

Source§

impl PortAllocatePools

Source

pub fn bucket_size() -> usize

compute bucket size.

§Test
use turn_server::turn::sessions::*;

assert_eq!(PortAllocatePools::bucket_size(), 256);
Source

pub fn bit_len() -> u32

compute bucket last bit max offset.

§Test
use turn_server::turn::sessions::*;

assert_eq!(PortAllocatePools::bit_len(), 63);
Source

pub const fn capacity() -> usize

get pools capacity.

§Test
use turn_server::turn::sessions::Bit;
use turn_server::turn::sessions::PortAllocatePools;

assert_eq!(PortAllocatePools::capacity(), 65535 - 49152);
Source

pub const fn port_range() -> Range<u16>

get port range.

§Test
use turn_server::turn::sessions::*;

assert_eq!(PortAllocatePools::port_range(), 49152..65535);
Source

pub fn len(&self) -> usize

get pools allocated size.

use turn_server::turn::sessions::PortAllocatePools;

let mut pools = PortAllocatePools::default();
assert_eq!(pools.len(), 0);

pools.alloc(None).unwrap();
assert_eq!(pools.len(), 1);
Source

pub fn is_empty(&self) -> bool

get pools allocated size is empty.

use turn_server::turn::sessions::PortAllocatePools;

let mut pools = PortAllocatePools::default();
assert_eq!(pools.len(), 0);
assert_eq!(pools.is_empty(), true);
Source

pub fn alloc(&mut self, start_index: Option<usize>) -> Option<u16>

random assign a port.

§Test
use turn_server::turn::sessions::PortAllocatePools;

let mut pool = PortAllocatePools::default();

assert_eq!(pool.alloc(Some(0)), Some(49152));
assert_eq!(pool.alloc(Some(0)), Some(49153));

assert!(pool.alloc(None).is_some());
Source

pub fn set_bit(&mut self, bucket: usize, index: usize, bit: Bit)

write bit flag in the bucket.

§Test
use turn_server::turn::sessions::Bit;
use turn_server::turn::sessions::PortAllocatePools;

let mut pool = PortAllocatePools::default();

assert_eq!(pool.alloc(Some(0)), Some(49152));
assert_eq!(pool.alloc(Some(0)), Some(49153));

pool.set_bit(0, 0, Bit::High);
pool.set_bit(0, 1, Bit::High);

assert_eq!(pool.alloc(Some(0)), Some(49154));
assert_eq!(pool.alloc(Some(0)), Some(49155));
Source

pub fn restore(&mut self, port: u16)

restore port in the buckets.

§Test
use turn_server::turn::sessions::PortAllocatePools;

let mut pool = PortAllocatePools::default();

assert_eq!(pool.alloc(Some(0)), Some(49152));
assert_eq!(pool.alloc(Some(0)), Some(49153));

pool.restore(49152);
pool.restore(49153);

assert_eq!(pool.alloc(Some(0)), Some(49152));
assert_eq!(pool.alloc(Some(0)), Some(49153));

Trait Implementations§

Source§

impl Default for PortAllocatePools

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,