tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

network.rs (7635B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 extern crate nserror;
      6 
      7 use std::ffi::{CStr, CString};
      8 use std::net::IpAddr;
      9 use std::os::raw::c_char;
     10 
     11 use rsdparsa::address::{Address, AddressType, AddressTyped, ExplicitlyTypedAddress};
     12 use rsdparsa::{SdpBandwidth, SdpConnection, SdpOrigin};
     13 use std::convert::TryFrom;
     14 use types::{StringView, NULL_STRING};
     15 
     16 #[repr(C)]
     17 #[derive(Clone, Copy, PartialEq)]
     18 pub enum RustAddressType {
     19    IP4,
     20    IP6,
     21 }
     22 
     23 impl TryFrom<u32> for RustAddressType {
     24    type Error = nserror::nsresult;
     25    fn try_from(address_type: u32) -> Result<Self, Self::Error> {
     26        match address_type {
     27            1 => Ok(RustAddressType::IP4),
     28            2 => Ok(RustAddressType::IP6),
     29            _ => Err(nserror::NS_ERROR_INVALID_ARG),
     30        }
     31    }
     32 }
     33 
     34 impl From<AddressType> for RustAddressType {
     35    fn from(address_type: AddressType) -> Self {
     36        match address_type {
     37            AddressType::IpV4 => RustAddressType::IP4,
     38            AddressType::IpV6 => RustAddressType::IP6,
     39        }
     40    }
     41 }
     42 
     43 impl Into<AddressType> for RustAddressType {
     44    fn into(self) -> AddressType {
     45        match self {
     46            RustAddressType::IP4 => AddressType::IpV4,
     47            RustAddressType::IP6 => AddressType::IpV6,
     48        }
     49    }
     50 }
     51 
     52 impl<'a> From<&'a IpAddr> for RustAddressType {
     53    fn from(addr: &IpAddr) -> RustAddressType {
     54        addr.address_type().into()
     55    }
     56 }
     57 
     58 pub fn get_octets(addr: &IpAddr) -> [u8; 16] {
     59    let mut octets = [0; 16];
     60    match *addr {
     61        IpAddr::V4(v4_addr) => {
     62            let v4_octets = v4_addr.octets();
     63            (&mut octets[0..4]).copy_from_slice(&v4_octets);
     64        }
     65        IpAddr::V6(v6_addr) => {
     66            let v6_octets = v6_addr.octets();
     67            octets.copy_from_slice(&v6_octets);
     68        }
     69    }
     70    octets
     71 }
     72 
     73 #[repr(C)]
     74 pub struct RustAddress {
     75    ip_address: [u8; 50],
     76    fqdn: StringView,
     77    is_fqdn: bool,
     78 }
     79 
     80 impl<'a> From<&'a Address> for RustAddress {
     81    fn from(address: &Address) -> Self {
     82        match address {
     83            Address::Ip(ip) => Self::from(ip),
     84            Address::Fqdn(fqdn) => Self {
     85                ip_address: [0; 50],
     86                fqdn: fqdn.as_str().into(),
     87                is_fqdn: true,
     88            },
     89        }
     90    }
     91 }
     92 
     93 impl<'a> From<&'a IpAddr> for RustAddress {
     94    fn from(addr: &IpAddr) -> Self {
     95        let mut c_addr = [0; 50];
     96        let str_addr = format!("{}", addr);
     97        let str_bytes = str_addr.as_bytes();
     98        if str_bytes.len() < 50 {
     99            c_addr[..str_bytes.len()].copy_from_slice(&str_bytes);
    100        }
    101        Self {
    102            ip_address: c_addr,
    103            fqdn: NULL_STRING,
    104            is_fqdn: false,
    105        }
    106    }
    107 }
    108 
    109 #[repr(C)]
    110 pub struct RustExplicitlyTypedAddress {
    111    address_type: RustAddressType,
    112    address: RustAddress,
    113 }
    114 
    115 impl Default for RustExplicitlyTypedAddress {
    116    fn default() -> Self {
    117        Self {
    118            address_type: RustAddressType::IP4,
    119            address: RustAddress {
    120                ip_address: [0; 50],
    121                fqdn: NULL_STRING,
    122                is_fqdn: false,
    123            },
    124        }
    125    }
    126 }
    127 
    128 impl<'a> From<&'a ExplicitlyTypedAddress> for RustExplicitlyTypedAddress {
    129    fn from(address: &ExplicitlyTypedAddress) -> Self {
    130        match address {
    131            ExplicitlyTypedAddress::Fqdn { domain, .. } => Self {
    132                address_type: address.address_type().into(),
    133                address: RustAddress {
    134                    ip_address: [0; 50],
    135                    fqdn: StringView::from(domain.as_str()),
    136                    is_fqdn: true,
    137                },
    138            },
    139            ExplicitlyTypedAddress::Ip(ip_address) => Self {
    140                address_type: ip_address.address_type().into(),
    141                address: ip_address.into(),
    142            },
    143        }
    144    }
    145 }
    146 
    147 // TODO @@NG remove
    148 impl<'a> From<&'a Option<IpAddr>> for RustExplicitlyTypedAddress {
    149    fn from(addr: &Option<IpAddr>) -> Self {
    150        match *addr {
    151            Some(ref x) => Self {
    152                address_type: RustAddressType::from(x.address_type()),
    153                address: RustAddress::from(x),
    154            },
    155            None => Self::default(),
    156        }
    157    }
    158 }
    159 
    160 #[repr(C)]
    161 pub struct RustSdpConnection {
    162    pub addr: RustExplicitlyTypedAddress,
    163    pub ttl: u8,
    164    pub amount: u64,
    165 }
    166 
    167 impl<'a> From<&'a SdpConnection> for RustSdpConnection {
    168    fn from(sdp_connection: &SdpConnection) -> Self {
    169        let ttl = match sdp_connection.ttl {
    170            Some(x) => x as u8,
    171            None => 0,
    172        };
    173        let amount = match sdp_connection.amount {
    174            Some(x) => x as u64,
    175            None => 0,
    176        };
    177        RustSdpConnection {
    178            addr: RustExplicitlyTypedAddress::from(&sdp_connection.address),
    179            ttl: ttl,
    180            amount: amount,
    181        }
    182    }
    183 }
    184 
    185 #[repr(C)]
    186 pub struct RustSdpOrigin {
    187    username: StringView,
    188    session_id: u64,
    189    session_version: u64,
    190    addr: RustExplicitlyTypedAddress,
    191 }
    192 
    193 fn bandwidth_match(str_bw: &str, enum_bw: &SdpBandwidth) -> bool {
    194    match *enum_bw {
    195        SdpBandwidth::As(_) => str_bw == "AS",
    196        SdpBandwidth::Ct(_) => str_bw == "CT",
    197        SdpBandwidth::Tias(_) => str_bw == "TIAS",
    198        SdpBandwidth::Unknown(ref type_name, _) => str_bw == type_name,
    199    }
    200 }
    201 
    202 fn bandwidth_value(bandwidth: &SdpBandwidth) -> u32 {
    203    match *bandwidth {
    204        SdpBandwidth::As(x) | SdpBandwidth::Ct(x) | SdpBandwidth::Tias(x) => x,
    205        SdpBandwidth::Unknown(_, _) => 0,
    206    }
    207 }
    208 
    209 pub unsafe fn get_bandwidth(bandwidths: &Vec<SdpBandwidth>, bandwidth_type: *const c_char) -> u32 {
    210    let bw_type = match CStr::from_ptr(bandwidth_type).to_str() {
    211        Ok(string) => string,
    212        Err(_) => return 0,
    213    };
    214    for bandwidth in bandwidths.iter() {
    215        if bandwidth_match(bw_type, bandwidth) {
    216            return bandwidth_value(bandwidth);
    217        }
    218    }
    219    0
    220 }
    221 
    222 #[no_mangle]
    223 pub unsafe extern "C" fn sdp_serialize_bandwidth(bw: *const Vec<SdpBandwidth>) -> *mut c_char {
    224    let mut builder = String::new();
    225    for bandwidth in (*bw).iter() {
    226        match *bandwidth {
    227            SdpBandwidth::As(val) => {
    228                builder.push_str("b=AS:");
    229                builder.push_str(&val.to_string());
    230                builder.push_str("\r\n");
    231            }
    232            SdpBandwidth::Ct(val) => {
    233                builder.push_str("b=CT:");
    234                builder.push_str(&val.to_string());
    235                builder.push_str("\r\n");
    236            }
    237            SdpBandwidth::Tias(val) => {
    238                builder.push_str("b=TIAS:");
    239                builder.push_str(&val.to_string());
    240                builder.push_str("\r\n");
    241            }
    242            SdpBandwidth::Unknown(ref name, val) => {
    243                builder.push_str("b=");
    244                builder.push_str(name.as_str());
    245                builder.push(':');
    246                builder.push_str(&val.to_string());
    247                builder.push_str("\r\n");
    248            }
    249        }
    250    }
    251    CString::from_vec_unchecked(builder.into_bytes()).into_raw()
    252 }
    253 
    254 #[no_mangle]
    255 pub unsafe extern "C" fn sdp_free_string(s: *mut c_char) {
    256    drop(CString::from_raw(s));
    257 }
    258 
    259 pub unsafe fn origin_view_helper(origin: &SdpOrigin) -> RustSdpOrigin {
    260    RustSdpOrigin {
    261        username: StringView::from(origin.username.as_str()),
    262        session_id: origin.session_id,
    263        session_version: origin.session_version,
    264        addr: RustExplicitlyTypedAddress::from(&origin.unicast_addr),
    265    }
    266 }