diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/media/webrtc/sdp/rsdparsa_capi/src/network.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | dom/media/webrtc/sdp/rsdparsa_capi/src/network.rs | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/dom/media/webrtc/sdp/rsdparsa_capi/src/network.rs b/dom/media/webrtc/sdp/rsdparsa_capi/src/network.rs new file mode 100644 index 0000000000..970f7c8dec --- /dev/null +++ b/dom/media/webrtc/sdp/rsdparsa_capi/src/network.rs @@ -0,0 +1,266 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +extern crate nserror; + +use std::ffi::{CStr, CString}; +use std::net::IpAddr; +use std::os::raw::c_char; + +use rsdparsa::address::{Address, AddressType, AddressTyped, ExplicitlyTypedAddress}; +use rsdparsa::{SdpBandwidth, SdpConnection, SdpOrigin}; +use std::convert::TryFrom; +use types::{StringView, NULL_STRING}; + +#[repr(C)] +#[derive(Clone, Copy, PartialEq)] +pub enum RustAddressType { + IP4, + IP6, +} + +impl TryFrom<u32> for RustAddressType { + type Error = nserror::nsresult; + fn try_from(address_type: u32) -> Result<Self, Self::Error> { + match address_type { + 1 => Ok(RustAddressType::IP4), + 2 => Ok(RustAddressType::IP6), + _ => Err(nserror::NS_ERROR_INVALID_ARG), + } + } +} + +impl From<AddressType> for RustAddressType { + fn from(address_type: AddressType) -> Self { + match address_type { + AddressType::IpV4 => RustAddressType::IP4, + AddressType::IpV6 => RustAddressType::IP6, + } + } +} + +impl Into<AddressType> for RustAddressType { + fn into(self) -> AddressType { + match self { + RustAddressType::IP4 => AddressType::IpV4, + RustAddressType::IP6 => AddressType::IpV6, + } + } +} + +impl<'a> From<&'a IpAddr> for RustAddressType { + fn from(addr: &IpAddr) -> RustAddressType { + addr.address_type().into() + } +} + +pub fn get_octets(addr: &IpAddr) -> [u8; 16] { + let mut octets = [0; 16]; + match *addr { + IpAddr::V4(v4_addr) => { + let v4_octets = v4_addr.octets(); + (&mut octets[0..4]).copy_from_slice(&v4_octets); + } + IpAddr::V6(v6_addr) => { + let v6_octets = v6_addr.octets(); + octets.copy_from_slice(&v6_octets); + } + } + octets +} + +#[repr(C)] +pub struct RustAddress { + ip_address: [u8; 50], + fqdn: StringView, + is_fqdn: bool, +} + +impl<'a> From<&'a Address> for RustAddress { + fn from(address: &Address) -> Self { + match address { + Address::Ip(ip) => Self::from(ip), + Address::Fqdn(fqdn) => Self { + ip_address: [0; 50], + fqdn: fqdn.as_str().into(), + is_fqdn: true, + }, + } + } +} + +impl<'a> From<&'a IpAddr> for RustAddress { + fn from(addr: &IpAddr) -> Self { + let mut c_addr = [0; 50]; + let str_addr = format!("{}", addr); + let str_bytes = str_addr.as_bytes(); + if str_bytes.len() < 50 { + c_addr[..str_bytes.len()].copy_from_slice(&str_bytes); + } + Self { + ip_address: c_addr, + fqdn: NULL_STRING, + is_fqdn: false, + } + } +} + +#[repr(C)] +pub struct RustExplicitlyTypedAddress { + address_type: RustAddressType, + address: RustAddress, +} + +impl Default for RustExplicitlyTypedAddress { + fn default() -> Self { + Self { + address_type: RustAddressType::IP4, + address: RustAddress { + ip_address: [0; 50], + fqdn: NULL_STRING, + is_fqdn: false, + }, + } + } +} + +impl<'a> From<&'a ExplicitlyTypedAddress> for RustExplicitlyTypedAddress { + fn from(address: &ExplicitlyTypedAddress) -> Self { + match address { + ExplicitlyTypedAddress::Fqdn { domain, .. } => Self { + address_type: address.address_type().into(), + address: RustAddress { + ip_address: [0; 50], + fqdn: StringView::from(domain.as_str()), + is_fqdn: true, + }, + }, + ExplicitlyTypedAddress::Ip(ip_address) => Self { + address_type: ip_address.address_type().into(), + address: ip_address.into(), + }, + } + } +} + +// TODO @@NG remove +impl<'a> From<&'a Option<IpAddr>> for RustExplicitlyTypedAddress { + fn from(addr: &Option<IpAddr>) -> Self { + match *addr { + Some(ref x) => Self { + address_type: RustAddressType::from(x.address_type()), + address: RustAddress::from(x), + }, + None => Self::default(), + } + } +} + +#[repr(C)] +pub struct RustSdpConnection { + pub addr: RustExplicitlyTypedAddress, + pub ttl: u8, + pub amount: u64, +} + +impl<'a> From<&'a SdpConnection> for RustSdpConnection { + fn from(sdp_connection: &SdpConnection) -> Self { + let ttl = match sdp_connection.ttl { + Some(x) => x as u8, + None => 0, + }; + let amount = match sdp_connection.amount { + Some(x) => x as u64, + None => 0, + }; + RustSdpConnection { + addr: RustExplicitlyTypedAddress::from(&sdp_connection.address), + ttl: ttl, + amount: amount, + } + } +} + +#[repr(C)] +pub struct RustSdpOrigin { + username: StringView, + session_id: u64, + session_version: u64, + addr: RustExplicitlyTypedAddress, +} + +fn bandwidth_match(str_bw: &str, enum_bw: &SdpBandwidth) -> bool { + match *enum_bw { + SdpBandwidth::As(_) => str_bw == "AS", + SdpBandwidth::Ct(_) => str_bw == "CT", + SdpBandwidth::Tias(_) => str_bw == "TIAS", + SdpBandwidth::Unknown(ref type_name, _) => str_bw == type_name, + } +} + +fn bandwidth_value(bandwidth: &SdpBandwidth) -> u32 { + match *bandwidth { + SdpBandwidth::As(x) | SdpBandwidth::Ct(x) | SdpBandwidth::Tias(x) => x, + SdpBandwidth::Unknown(_, _) => 0, + } +} + +pub unsafe fn get_bandwidth(bandwidths: &Vec<SdpBandwidth>, bandwidth_type: *const c_char) -> u32 { + let bw_type = match CStr::from_ptr(bandwidth_type).to_str() { + Ok(string) => string, + Err(_) => return 0, + }; + for bandwidth in bandwidths.iter() { + if bandwidth_match(bw_type, bandwidth) { + return bandwidth_value(bandwidth); + } + } + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_serialize_bandwidth(bw: *const Vec<SdpBandwidth>) -> *mut c_char { + let mut builder = String::new(); + for bandwidth in (*bw).iter() { + match *bandwidth { + SdpBandwidth::As(val) => { + builder.push_str("b=AS:"); + builder.push_str(&val.to_string()); + builder.push_str("\r\n"); + } + SdpBandwidth::Ct(val) => { + builder.push_str("b=CT:"); + builder.push_str(&val.to_string()); + builder.push_str("\r\n"); + } + SdpBandwidth::Tias(val) => { + builder.push_str("b=TIAS:"); + builder.push_str(&val.to_string()); + builder.push_str("\r\n"); + } + SdpBandwidth::Unknown(ref name, val) => { + builder.push_str("b="); + builder.push_str(name.as_str()); + builder.push(':'); + builder.push_str(&val.to_string()); + builder.push_str("\r\n"); + } + } + } + CString::from_vec_unchecked(builder.into_bytes()).into_raw() +} + +#[no_mangle] +pub unsafe extern "C" fn sdp_free_string(s: *mut c_char) { + drop(CString::from_raw(s)); +} + +pub unsafe fn origin_view_helper(origin: &SdpOrigin) -> RustSdpOrigin { + RustSdpOrigin { + username: StringView::from(origin.username.as_str()), + session_id: origin.session_id, + session_version: origin.session_version, + addr: RustExplicitlyTypedAddress::from(&origin.unicast_addr), + } +} |