feat(secure): a bunch of stuff
This commit is contained in:
parent
4f26aae1d7
commit
81f7a0a738
15 changed files with 480 additions and 49 deletions
161
src/prudp/station_url.rs
Normal file
161
src/prudp/station_url.rs
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
use std::net::Ipv4Addr;
|
||||
use log::error;
|
||||
use std::fmt::{Display, Formatter, Write};
|
||||
use crate::prudp::station_url::Type::{PRUDP, PRUDPS, UDP};
|
||||
use crate::prudp::station_url::UrlOptions::{Address, ConnectionID, NatFiltering, NatMapping, NatType, Platform, PMP, Port, PrincipalID, RVConnectionID, StreamID, StreamType, UPNP};
|
||||
|
||||
pub enum Type{
|
||||
UDP,
|
||||
PRUDP,
|
||||
PRUDPS
|
||||
}
|
||||
|
||||
pub mod nat_types{
|
||||
pub const BEHIND_NAT: u8 = 1;
|
||||
pub const PUBLIC: u8 = 2;
|
||||
}
|
||||
|
||||
pub enum UrlOptions {
|
||||
Address(Ipv4Addr),
|
||||
Port(u16),
|
||||
StreamType(u8),
|
||||
StreamID(u8),
|
||||
ConnectionID(u8),
|
||||
PrincipalID(u32),
|
||||
NatType(u8),
|
||||
NatMapping(u8),
|
||||
NatFiltering(u8),
|
||||
UPNP(u8),
|
||||
RVConnectionID(u32),
|
||||
Platform(u8),
|
||||
PMP(u8),
|
||||
|
||||
}
|
||||
|
||||
pub struct StationUrl{
|
||||
pub url_type: Type,
|
||||
pub options: Vec<UrlOptions>
|
||||
}
|
||||
|
||||
impl StationUrl{
|
||||
fn read_options(options: &str) -> Option<Vec<UrlOptions>>{
|
||||
let mut options_out = Vec::new();
|
||||
|
||||
for option in options.split(';'){
|
||||
if option == "" { continue; }
|
||||
let mut option_parts = option.split('=');
|
||||
let option_name= option_parts.next()?.to_ascii_lowercase();
|
||||
let option_value = option_parts.next()?;
|
||||
|
||||
match option_name.as_ref(){
|
||||
"address" => {
|
||||
options_out.push(Address(option_value.parse().ok()?))
|
||||
},
|
||||
"port" => {
|
||||
options_out.push(Port(option_value.parse().ok()?))
|
||||
}
|
||||
"natf" => {
|
||||
options_out.push(NatFiltering(option_value.parse().ok()?))
|
||||
}
|
||||
"natm" => {
|
||||
options_out.push(NatMapping(option_value.parse().ok()?))
|
||||
}
|
||||
"sid" => {
|
||||
options_out.push(StreamID(option_value.parse().ok()?))
|
||||
}
|
||||
"upnp" => {
|
||||
options_out.push(UPNP(option_value.parse().ok()?))
|
||||
}
|
||||
"type" => {
|
||||
options_out.push(NatType(option_value.parse().ok()?))
|
||||
}
|
||||
"stream" => {
|
||||
options_out.push(StreamType(option_value.parse().ok()?))
|
||||
}
|
||||
"RVCID" => {
|
||||
options_out.push(RVConnectionID(option_value.parse().ok()?))
|
||||
}
|
||||
"pl" => {
|
||||
options_out.push(Platform(option_value.parse().ok()?))
|
||||
}
|
||||
"pmp" => {
|
||||
options_out.push(PMP(option_value.parse().ok()?))
|
||||
}
|
||||
_ => {
|
||||
error!("unimplemented option type, skipping: {}", option_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Some(options_out)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for StationUrl{
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, ()> {
|
||||
let (url_type, options) = value.split_at(value.find(":/").ok_or(())?);
|
||||
|
||||
let options = &options[2..];
|
||||
|
||||
let url_type = match url_type{
|
||||
"udp" => UDP,
|
||||
"prudp" => PRUDP,
|
||||
"prudps" => PRUDPS,
|
||||
_ => return Err(())
|
||||
};
|
||||
|
||||
let options = Self::read_options(options).ok_or(())?;
|
||||
|
||||
Ok(
|
||||
Self{
|
||||
url_type,
|
||||
options
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<String> for &'a StationUrl{
|
||||
fn into(self) -> String {
|
||||
let mut url = match self.url_type{
|
||||
UDP => "udp:/",
|
||||
PRUDP => "prudp:/",
|
||||
PRUDPS => "prudps:/"
|
||||
}.to_owned();
|
||||
|
||||
for option in &self.options{
|
||||
match option{
|
||||
Address(v) => write!(url, "address={}", v).expect("failed to write"),
|
||||
Port(v) => write!(url, "port={}", v).expect("failed to write"),
|
||||
StreamType(v) => write!(url, "stream={}", v).expect("failed to write"),
|
||||
StreamID(v) => write!(url, "sid={}", v).expect("failed to write"),
|
||||
ConnectionID(v) => write!(url, "CID={}", v).expect("failed to write"),
|
||||
PrincipalID(v) => write!(url, "PID={}", v).expect("failed to write"),
|
||||
NatType(v) => write!(url, "type={}", v).expect("failed to write"),
|
||||
NatMapping(v) => write!(url, "natm={}", v).expect("failed to write"),
|
||||
NatFiltering(v) => write!(url, "natf={}", v).expect("failed to write"),
|
||||
UPNP(v) => write!(url, "upnp={}", v).expect("failed to write"),
|
||||
RVConnectionID(v) => write!(url, "RVCID={}", v).expect("failed to write"),
|
||||
Platform(v) => write!(url, "pl={}", v).expect("failed to write"),
|
||||
PMP(v) => write!(url, "pmp={}", v).expect("failed to write"),
|
||||
}
|
||||
}
|
||||
|
||||
url
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for StationUrl{
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let str: String = self.into();
|
||||
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue