mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +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;
|
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;
|
||||||
|
|
||||||
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
@ -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`
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user