mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
Merge pull request #1004 from Samuka007/feat-network-rebuild
fix(net): address family错误返回错误导致的redis跑不起来
This commit is contained in:
commit
8189cb1771
@ -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;
|
||||
|
||||
|
@ -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>;
|
||||
}
|
||||
|
@ -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`
|
||||
|
@ -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;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user