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;
let addr = unsafe { addr.as_ref() }.ok_or(SystemError::EFAULT)?;
unsafe {
match AddressFamily::try_from(addr.family)? {
AddressFamily::INet => {
@ -128,6 +127,22 @@ impl SockAddr {
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 => {
let addr_un: SockAddrUn = addr.addr_un;

View File

@ -102,14 +102,14 @@ pub enum AddressFamily {
Max = 46,
}
use system_error::SystemError;
impl core::convert::TryFrom<u16> for AddressFamily {
type Error = system_error::SystemError;
fn try_from(x: u16) -> Result<Self, Self::Error> {
use num_traits::FromPrimitive;
use SystemError::*;
return <Self as FromPrimitive>::from_u16(x).ok_or(EINVAL);
return <Self as FromPrimitive>::from_u16(x).ok_or({
log::debug!("AddressFamily::try_from failed: x={}", x);
Self::Error::EINVAL
});
}
}
@ -117,5 +117,8 @@ use crate::net::socket;
use alloc::sync::Arc;
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
/// even if the socket is unbound. Instead, it will return an unspecified socket address. This
/// unspecified endpoint helps with that.
const UNSPECIFIED_LOCAL_ENDPOINT: IpEndpoint =
const UNSPECIFIED_LOCAL_ENDPOINT_V4: IpEndpoint =
IpEndpoint::new(IpAddress::Ipv4(Ipv4Address::UNSPECIFIED), 0);
const UNSPECIFIED_LOCAL_ENDPOINT_V6: IpEndpoint =
IpEndpoint::new(IpAddress::Ipv6(Ipv6Address::UNSPECIFIED), 0);
pub trait InetSocket: Socket {
/// `on_iface_events`

View File

@ -8,7 +8,7 @@ use alloc::vec::Vec;
use smoltcp;
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_RX_BUF_SIZE: usize = 512 * 1024;
@ -31,13 +31,13 @@ where
#[derive(Debug)]
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)),
}
impl Init {
pub(super) fn new() -> Self {
Init::Unbound(Box::new(new_smoltcp_socket()))
pub(super) fn new(v4: bool) -> Self {
Init::Unbound((Box::new(new_smoltcp_socket()), v4))
}
/// 传入一个已经绑定的socket
@ -55,7 +55,7 @@ impl Init {
local_endpoint: smoltcp::wire::IpEndpoint,
) -> Result<Self, SystemError> {
match self {
Init::Unbound(socket) => {
Init::Unbound((socket, _)) => {
let bound = socket::inet::BoundInner::bind(*socket, &local_endpoint.addr)?;
bound
.port_manager()
@ -63,7 +63,10 @@ impl Init {
// bound.iface().common().bind_socket()
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,
) -> Result<(socket::inet::BoundInner, smoltcp::wire::IpEndpoint), (Self, SystemError)> {
match self {
Init::Unbound(socket) => {
Init::Unbound((socket, v4)) => {
let (bound, address) =
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
.port_manager()
.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);
Ok((bound, endpoint))
}
@ -308,7 +311,8 @@ impl Listening {
if let Some(name) = socket.local_endpoint() {
return name;
} 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::socket::*;
use crate::sched::SchedMode;
use inet::{InetSocket, UNSPECIFIED_LOCAL_ENDPOINT};
use inet::{InetSocket, UNSPECIFIED_LOCAL_ENDPOINT_V4, UNSPECIFIED_LOCAL_ENDPOINT_V6};
use smoltcp;
mod inner;
@ -29,9 +29,9 @@ pub struct TcpSocket {
}
impl TcpSocket {
pub fn new(nonblock: bool) -> Arc<Self> {
pub fn new(nonblock: bool, v4: bool) -> Arc<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(),
nonblock: AtomicBool::new(nonblock),
wait_queue: WaitQueue::default(),
@ -69,7 +69,11 @@ impl TcpSocket {
writer.replace(Inner::Init(bound));
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> {
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::Connecting(connecting) => Ok(Endpoint::Ip(connecting.get_name())),
Inner::Established(established) => Ok(Endpoint::Ip(established.local_endpoint())),
@ -242,6 +252,7 @@ impl Socket for TcpSocket {
if let Endpoint::Ip(addr) = endpoint {
return self.do_bind(addr);
}
log::warn!("TcpSocket::bind: invalid endpoint");
return Err(EINVAL);
}

View File

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

View File

@ -13,12 +13,11 @@ pub fn create_socket(
type AF = socket::AddressFamily;
let inode = match family {
AF::INet => socket::inet::Inet::socket(socket_type, protocol)?,
AF::INet6 => {
todo!("AF_INET6 unimplemented");
}
// AF::INet6 => socket::inet::Inet6::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);