| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 | use crate::net::{Iface, NET_DEVICES};use alloc::sync::Arc;use system_error::SystemError::{self, *};pub mod port;pub use port::PortManager;#[allow(dead_code)]#[derive(Debug, Clone, Copy, PartialEq)]pub enum Types {    Raw,    Icmp,    Udp,    Tcp,    Dhcpv4,    Dns,}/** * 目前,以下设计仍然没有考虑多网卡的listen问题,仅只解决了socket在绑定单网卡下的问题。 */#[derive(Debug)]pub struct BoundInner {    handle: smoltcp::iface::SocketHandle,    iface: Arc<dyn Iface>,    // inner: Vec<(smoltcp::iface::SocketHandle, Arc<dyn Iface>)>    // address: smoltcp::wire::IpAddress,}impl BoundInner {    /// # `bind`    /// 将socket绑定到指定的地址上,置入指定的网络接口中    pub fn bind<T>(        socket: T,        // socket_type: Types,        address: &smoltcp::wire::IpAddress,    ) -> Result<Self, SystemError>    where        T: smoltcp::socket::AnySocket<'static>,    {        if address.is_unspecified() {            // 强绑VirtualIO            let iface = NET_DEVICES                .read_irqsave()                .iter()                .find_map(|(_, v)| {                    if v.common().is_default_iface() {                        Some(v.clone())                    } else {                        None                    }                })                .expect("No default interface");            let handle = iface.sockets().lock_no_preempt().add(socket);            return Ok(Self { handle, iface });        } else {            let iface = get_iface_to_bind(address).ok_or(ENODEV)?;            let handle = iface.sockets().lock_no_preempt().add(socket);            return Ok(Self { handle, iface });        }    }    pub fn bind_ephemeral<T>(        socket: T,        // socket_type: Types,        remote: smoltcp::wire::IpAddress,    ) -> Result<(Self, smoltcp::wire::IpAddress), SystemError>    where        T: smoltcp::socket::AnySocket<'static>,    {        let (iface, address) = get_ephemeral_iface(&remote);        // let bound_port = iface.port_manager().bind_ephemeral_port(socket_type)?;        let handle = iface.sockets().lock_no_preempt().add(socket);        // let endpoint = smoltcp::wire::IpEndpoint::new(local_addr, bound_port);        Ok((Self { handle, iface }, address))    }    pub fn port_manager(&self) -> &PortManager {        self.iface.port_manager()    }    pub fn with_mut<T: smoltcp::socket::AnySocket<'static>, R, F: FnMut(&mut T) -> R>(        &self,        mut f: F,    ) -> R {        f(self.iface.sockets().lock().get_mut::<T>(self.handle))    }    pub fn with<T: smoltcp::socket::AnySocket<'static>, R, F: Fn(&T) -> R>(&self, f: F) -> R {        f(self.iface.sockets().lock().get::<T>(self.handle))    }    pub fn iface(&self) -> &Arc<dyn Iface> {        &self.iface    }    pub fn release(&self) {        self.iface.sockets().lock().remove(self.handle);    }}#[inline]pub fn get_iface_to_bind(ip_addr: &smoltcp::wire::IpAddress) -> Option<Arc<dyn Iface>> {    // log::debug!("get_iface_to_bind: {:?}", ip_addr);    // if ip_addr.is_unspecified()    crate::net::NET_DEVICES        .read_irqsave()        .iter()        .find(|(_, iface)| {            let guard = iface.smol_iface().lock();            // log::debug!("iface name: {}, ip: {:?}", iface.iface_name(), guard.ip_addrs());            return guard.has_ip_addr(*ip_addr);        })        .map(|(_, iface)| iface.clone())}/// Get a suitable iface to deal with sendto/connect request if the socket is not bound to an iface./// If the remote address is the same as that of some iface, we will use the iface./// Otherwise, we will use a default interface.fn get_ephemeral_iface(    remote_ip_addr: &smoltcp::wire::IpAddress,) -> (Arc<dyn Iface>, smoltcp::wire::IpAddress) {    get_iface_to_bind(remote_ip_addr)        .map(|iface| (iface, *remote_ip_addr))        .or({            let ifaces = NET_DEVICES.read_irqsave();            ifaces.iter().find_map(|(_, iface)| {                iface                    .smol_iface()                    .lock()                    .ip_addrs()                    .iter()                    .find(|cidr| cidr.contains_addr(remote_ip_addr))                    .map(|cidr| (iface.clone(), cidr.address()))            })        })        .or({            NET_DEVICES.read_irqsave().values().next().map(|iface| {                (                    iface.clone(),                    iface.smol_iface().lock().ip_addrs()[0].address(),                )            })        })        .expect("No network interface")}
 |