Merge pull request #1004 from Samuka007/feat-network-rebuild

fix(net): address family错误返回错误导致的redis跑不起来
This commit is contained in:
Samuel Dai 2024-10-21 22:36:59 +08:00 committed by GitHub
commit 8189cb1771
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 78 additions and 29 deletions

View File

@ -109,7 +109,6 @@ impl SockAddr {
use crate::net::socket::AddressFamily; use crate::net::socket::AddressFamily;
let addr = unsafe { addr.as_ref() }.ok_or(SystemError::EFAULT)?; let addr = unsafe { addr.as_ref() }.ok_or(SystemError::EFAULT)?;
unsafe { unsafe {
match AddressFamily::try_from(addr.family)? { match AddressFamily::try_from(addr.family)? {
AddressFamily::INet => { AddressFamily::INet => {
@ -128,6 +127,22 @@ impl SockAddr {
return Ok(Endpoint::Ip(wire::IpEndpoint::new(ip, port))); return Ok(Endpoint::Ip(wire::IpEndpoint::new(ip, port)));
} }
AddressFamily::INet6 => {
if len < addr.len()? {
log::error!("len < addr.len()");
return Err(SystemError::EINVAL);
}
log::debug!("INet6");
let addr_in: SockAddrIn = addr.addr_in;
use smoltcp::wire;
let ip: wire::IpAddress = wire::IpAddress::from(wire::Ipv6Address::from_bytes(
&u32::from_be(addr_in.sin_addr).to_be_bytes()[..],
));
let port = u16::from_be(addr_in.sin_port);
return Ok(Endpoint::Ip(wire::IpEndpoint::new(ip, port)));
}
AddressFamily::Unix => { AddressFamily::Unix => {
let addr_un: SockAddrUn = addr.addr_un; let addr_un: SockAddrUn = addr.addr_un;

View File

@ -102,14 +102,14 @@ pub enum AddressFamily {
Max = 46, Max = 46,
} }
use system_error::SystemError;
impl core::convert::TryFrom<u16> for AddressFamily { impl core::convert::TryFrom<u16> for AddressFamily {
type Error = system_error::SystemError; type Error = system_error::SystemError;
fn try_from(x: u16) -> Result<Self, Self::Error> { fn try_from(x: u16) -> Result<Self, Self::Error> {
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use SystemError::*; return <Self as FromPrimitive>::from_u16(x).ok_or({
return <Self as FromPrimitive>::from_u16(x).ok_or(EINVAL); log::debug!("AddressFamily::try_from failed: x={}", x);
Self::Error::EINVAL
});
} }
} }
@ -117,5 +117,8 @@ use crate::net::socket;
use alloc::sync::Arc; use alloc::sync::Arc;
pub trait Family { pub trait Family {
fn socket(stype: socket::PSOCK, protocol: u32) -> Result<Arc<socket::Inode>, SystemError>; fn socket(
stype: socket::PSOCK,
protocol: u32,
) -> Result<Arc<socket::Inode>, system_error::SystemError>;
} }

View File

@ -22,8 +22,10 @@ use smoltcp::wire::*;
/// According to the Linux man pages and the Linux implementation, `getsockname()` will _not_ fail /// According to the Linux man pages and the Linux implementation, `getsockname()` will _not_ fail
/// even if the socket is unbound. Instead, it will return an unspecified socket address. This /// even if the socket is unbound. Instead, it will return an unspecified socket address. This
/// unspecified endpoint helps with that. /// unspecified endpoint helps with that.
const UNSPECIFIED_LOCAL_ENDPOINT: IpEndpoint = const UNSPECIFIED_LOCAL_ENDPOINT_V4: IpEndpoint =
IpEndpoint::new(IpAddress::Ipv4(Ipv4Address::UNSPECIFIED), 0); IpEndpoint::new(IpAddress::Ipv4(Ipv4Address::UNSPECIFIED), 0);
const UNSPECIFIED_LOCAL_ENDPOINT_V6: IpEndpoint =
IpEndpoint::new(IpAddress::Ipv6(Ipv6Address::UNSPECIFIED), 0);
pub trait InetSocket: Socket { pub trait InetSocket: Socket {
/// `on_iface_events` /// `on_iface_events`

View File

@ -8,7 +8,7 @@ use alloc::vec::Vec;
use smoltcp; use smoltcp;
use system_error::SystemError::{self, *}; use system_error::SystemError::{self, *};
use super::inet::UNSPECIFIED_LOCAL_ENDPOINT; use super::inet::UNSPECIFIED_LOCAL_ENDPOINT_V4;
// pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024; // pub const DEFAULT_METADATA_BUF_SIZE: usize = 1024;
pub const DEFAULT_RX_BUF_SIZE: usize = 512 * 1024; pub const DEFAULT_RX_BUF_SIZE: usize = 512 * 1024;
@ -31,13 +31,13 @@ where
#[derive(Debug)] #[derive(Debug)]
pub enum Init { pub enum Init {
Unbound(Box<smoltcp::socket::tcp::Socket<'static>>), Unbound((Box<smoltcp::socket::tcp::Socket<'static>>, bool)),
Bound((socket::inet::BoundInner, smoltcp::wire::IpEndpoint)), Bound((socket::inet::BoundInner, smoltcp::wire::IpEndpoint)),
} }
impl Init { impl Init {
pub(super) fn new() -> Self { pub(super) fn new(v4: bool) -> Self {
Init::Unbound(Box::new(new_smoltcp_socket())) Init::Unbound((Box::new(new_smoltcp_socket()), v4))
} }
/// 传入一个已经绑定的socket /// 传入一个已经绑定的socket
@ -55,7 +55,7 @@ impl Init {
local_endpoint: smoltcp::wire::IpEndpoint, local_endpoint: smoltcp::wire::IpEndpoint,
) -> Result<Self, SystemError> { ) -> Result<Self, SystemError> {
match self { match self {
Init::Unbound(socket) => { Init::Unbound((socket, _)) => {
let bound = socket::inet::BoundInner::bind(*socket, &local_endpoint.addr)?; let bound = socket::inet::BoundInner::bind(*socket, &local_endpoint.addr)?;
bound bound
.port_manager() .port_manager()
@ -63,7 +63,10 @@ impl Init {
// bound.iface().common().bind_socket() // bound.iface().common().bind_socket()
Ok(Init::Bound((bound, local_endpoint))) Ok(Init::Bound((bound, local_endpoint)))
} }
Init::Bound(_) => Err(EINVAL), Init::Bound(_) => {
log::debug!("Already Bound");
Err(EINVAL)
}
} }
} }
@ -72,14 +75,14 @@ impl Init {
remote_endpoint: smoltcp::wire::IpEndpoint, remote_endpoint: smoltcp::wire::IpEndpoint,
) -> Result<(socket::inet::BoundInner, smoltcp::wire::IpEndpoint), (Self, SystemError)> { ) -> Result<(socket::inet::BoundInner, smoltcp::wire::IpEndpoint), (Self, SystemError)> {
match self { match self {
Init::Unbound(socket) => { Init::Unbound((socket, v4)) => {
let (bound, address) = let (bound, address) =
socket::inet::BoundInner::bind_ephemeral(*socket, remote_endpoint.addr) socket::inet::BoundInner::bind_ephemeral(*socket, remote_endpoint.addr)
.map_err(|err| (Self::new(), err))?; .map_err(|err| (Self::new(v4), err))?;
let bound_port = bound let bound_port = bound
.port_manager() .port_manager()
.bind_ephemeral_port(Types::Tcp) .bind_ephemeral_port(Types::Tcp)
.map_err(|err| (Self::new(), err))?; .map_err(|err| (Self::new(v4), err))?;
let endpoint = smoltcp::wire::IpEndpoint::new(address, bound_port); let endpoint = smoltcp::wire::IpEndpoint::new(address, bound_port);
Ok((bound, endpoint)) Ok((bound, endpoint))
} }
@ -308,7 +311,8 @@ impl Listening {
if let Some(name) = socket.local_endpoint() { if let Some(name) = socket.local_endpoint() {
return name; return name;
} else { } else {
return UNSPECIFIED_LOCAL_ENDPOINT; // TODO: IPV6
return UNSPECIFIED_LOCAL_ENDPOINT_V4;
} }
}) })
} }

View File

@ -7,7 +7,7 @@ use crate::net::event_poll::EPollEventType;
use crate::net::net_core::poll_ifaces; use crate::net::net_core::poll_ifaces;
use crate::net::socket::*; use crate::net::socket::*;
use crate::sched::SchedMode; use crate::sched::SchedMode;
use inet::{InetSocket, UNSPECIFIED_LOCAL_ENDPOINT}; use inet::{InetSocket, UNSPECIFIED_LOCAL_ENDPOINT_V4, UNSPECIFIED_LOCAL_ENDPOINT_V6};
use smoltcp; use smoltcp;
mod inner; mod inner;
@ -29,9 +29,9 @@ pub struct TcpSocket {
} }
impl TcpSocket { impl TcpSocket {
pub fn new(nonblock: bool) -> Arc<Self> { pub fn new(nonblock: bool, v4: bool) -> Arc<Self> {
Arc::new_cyclic(|me| Self { Arc::new_cyclic(|me| Self {
inner: RwLock::new(Some(Inner::Init(Init::new()))), inner: RwLock::new(Some(Inner::Init(Init::new(v4)))),
shutdown: Shutdown::new(), shutdown: Shutdown::new(),
nonblock: AtomicBool::new(nonblock), nonblock: AtomicBool::new(nonblock),
wait_queue: WaitQueue::default(), wait_queue: WaitQueue::default(),
@ -69,7 +69,11 @@ impl TcpSocket {
writer.replace(Inner::Init(bound)); writer.replace(Inner::Init(bound));
Ok(()) Ok(())
} }
_ => Err(EINVAL), any => {
writer.replace(any);
log::error!("TcpSocket::do_bind: not Init");
Err(EINVAL)
}
} }
} }
@ -230,7 +234,13 @@ impl Socket for TcpSocket {
fn get_name(&self) -> Result<Endpoint, SystemError> { fn get_name(&self) -> Result<Endpoint, SystemError> {
match self.inner.read().as_ref().expect("Tcp Inner is None") { match self.inner.read().as_ref().expect("Tcp Inner is None") {
Inner::Init(Init::Unbound(_)) => Ok(Endpoint::Ip(UNSPECIFIED_LOCAL_ENDPOINT)), Inner::Init(Init::Unbound((_, v4))) => {
if *v4 {
Ok(Endpoint::Ip(UNSPECIFIED_LOCAL_ENDPOINT_V4))
} else {
Ok(Endpoint::Ip(UNSPECIFIED_LOCAL_ENDPOINT_V6))
}
}
Inner::Init(Init::Bound((_, local))) => Ok(Endpoint::Ip(*local)), Inner::Init(Init::Bound((_, local))) => Ok(Endpoint::Ip(*local)),
Inner::Connecting(connecting) => Ok(Endpoint::Ip(connecting.get_name())), Inner::Connecting(connecting) => Ok(Endpoint::Ip(connecting.get_name())),
Inner::Established(established) => Ok(Endpoint::Ip(established.local_endpoint())), Inner::Established(established) => Ok(Endpoint::Ip(established.local_endpoint())),
@ -242,6 +252,7 @@ impl Socket for TcpSocket {
if let Endpoint::Ip(addr) = endpoint { if let Endpoint::Ip(addr) = endpoint {
return self.do_bind(addr); return self.do_bind(addr);
} }
log::warn!("TcpSocket::bind: invalid endpoint");
return Err(EINVAL); return Err(EINVAL);
} }

View File

@ -8,6 +8,7 @@ use inet::{TcpSocket, UdpSocket};
use crate::net::socket::*; use crate::net::socket::*;
fn create_inet_socket( fn create_inet_socket(
v4: bool,
socket_type: PSOCK, socket_type: PSOCK,
protocol: smoltcp::wire::IpProtocol, protocol: smoltcp::wire::IpProtocol,
) -> Result<Arc<dyn Socket>, SystemError> { ) -> Result<Arc<dyn Socket>, SystemError> {
@ -16,7 +17,8 @@ fn create_inet_socket(
match socket_type { match socket_type {
PSOCK::Datagram => match protocol { PSOCK::Datagram => match protocol {
HopByHop | Udp => { HopByHop | Udp => {
return Ok(UdpSocket::new(false)); return Err(EPROTONOSUPPORT);
// return Ok(UdpSocket::new(false));
} }
_ => { _ => {
return Err(EPROTONOSUPPORT); return Err(EPROTONOSUPPORT);
@ -24,7 +26,7 @@ fn create_inet_socket(
}, },
PSOCK::Stream => match protocol { PSOCK::Stream => match protocol {
HopByHop | Tcp => { HopByHop | Tcp => {
return Ok(TcpSocket::new(false)); return Ok(TcpSocket::new(false, v4));
} }
_ => { _ => {
return Err(EPROTONOSUPPORT); return Err(EPROTONOSUPPORT);
@ -42,7 +44,20 @@ fn create_inet_socket(
pub struct Inet; pub struct Inet;
impl family::Family for Inet { impl family::Family for Inet {
fn socket(stype: PSOCK, protocol: u32) -> Result<Arc<Inode>, SystemError> { fn socket(stype: PSOCK, protocol: u32) -> Result<Arc<Inode>, SystemError> {
let socket = create_inet_socket(stype, smoltcp::wire::IpProtocol::from(protocol as u8))?; let socket =
create_inet_socket(true, stype, smoltcp::wire::IpProtocol::from(protocol as u8))?;
Ok(Inode::new(socket))
}
}
pub struct Inet6;
impl family::Family for Inet6 {
fn socket(stype: PSOCK, protocol: u32) -> Result<Arc<Inode>, SystemError> {
let socket = create_inet_socket(
false,
stype,
smoltcp::wire::IpProtocol::from(protocol as u8),
)?;
Ok(Inode::new(socket)) Ok(Inode::new(socket))
} }
} }

View File

@ -13,12 +13,11 @@ pub fn create_socket(
type AF = socket::AddressFamily; type AF = socket::AddressFamily;
let inode = match family { let inode = match family {
AF::INet => socket::inet::Inet::socket(socket_type, protocol)?, AF::INet => socket::inet::Inet::socket(socket_type, protocol)?,
AF::INet6 => { // AF::INet6 => socket::inet::Inet6::socket(socket_type, protocol)?,
todo!("AF_INET6 unimplemented");
}
AF::Unix => socket::unix::Unix::socket(socket_type, protocol)?, AF::Unix => socket::unix::Unix::socket(socket_type, protocol)?,
_ => { _ => {
todo!("unsupport address family"); log::warn!("unsupport address family");
return Err(SystemError::EAFNOSUPPORT);
} }
}; };
inode.set_nonblock(is_nonblock); inode.set_nonblock(is_nonblock);