Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: loopback and udp resource problem #1086

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ linkme = "=0.3.27"
num = { version = "=0.4.0", default-features = false }
num-derive = "=0.3"
num-traits = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/num-traits.git", rev="1597c1c", default-features = false }
smoltcp = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/smoltcp.git", rev = "3e61c909fd540d05575068d16dc4574e196499ed", default-features = false, features = ["log", "alloc", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6"]}
smoltcp = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/smoltcp.git", rev = "3e61c909fd540d05575068d16dc4574e196499ed", default-features = false, features = ["log", "alloc", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6", "medium-ip"]}
system_error = { path = "crates/system_error" }
uefi = { version = "=0.26.0", features = ["alloc"] }
uefi-raw = "=0.5.0"
Expand Down
10 changes: 6 additions & 4 deletions kernel/src/driver/net/loopback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ impl phy::Device for LoopbackDriver {
let mut result = phy::DeviceCapabilities::default();
result.max_transmission_unit = 65535;
result.max_burst_size = Some(1);
result.medium = smoltcp::phy::Medium::Ethernet;
result.medium = smoltcp::phy::Medium::Ip;
return result;
}
/// ## Loopback驱动处理接受数据事件
Expand Down Expand Up @@ -284,9 +284,11 @@ impl LoopbackInterface {
pub fn new(mut driver: LoopbackDriver) -> Arc<Self> {
let iface_id = generate_iface_id();

let hardware_addr = HardwareAddress::Ethernet(smoltcp::wire::EthernetAddress([
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]));
// let hardware_addr = HardwareAddress::Ethernet(smoltcp::wire::EthernetAddress([
// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// ]));

let hardware_addr = HardwareAddress::Ip;

let mut iface_config = smoltcp::iface::Config::new(hardware_addr);

Expand Down
46 changes: 12 additions & 34 deletions kernel/src/net/net_core.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloc::{boxed::Box, collections::BTreeMap, sync::Arc};
use alloc::{collections::BTreeMap, sync::Arc};
use log::{debug, info, warn};
use smoltcp::{socket::dhcpv4, wire};
use system_error::SystemError;
Expand All @@ -7,45 +7,23 @@ use crate::{
driver::net::{Iface, Operstate},
libs::rwlock::RwLockReadGuard,
net::NET_DEVICES,
time::{
sleep::nanosleep,
timer::{next_n_ms_timer_jiffies, Timer, TimerFunction},
PosixTimeSpec,
},
time::{sleep::nanosleep, PosixTimeSpec},
};

/// The network poll function, which will be called by timer.
///
/// The main purpose of this function is to poll all network interfaces.
#[derive(Debug)]
#[allow(dead_code)]
struct NetWorkPollFunc;

impl TimerFunction for NetWorkPollFunc {
fn run(&mut self) -> Result<(), SystemError> {
poll_ifaces();
let next_time = next_n_ms_timer_jiffies(10);
let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
timer.activate();
return Ok(());
}
}

pub fn net_init() -> Result<(), SystemError> {
dhcp_query()?;
// Init poll timer function
// let next_time = next_n_ms_timer_jiffies(5);
// let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
// timer.activate();
return Ok(());
dhcp_query()
}

fn dhcp_query() -> Result<(), SystemError> {
let binding = NET_DEVICES.write_irqsave();
// log::debug!("binding: {:?}", *binding);
//由于现在os未实现在用户态为网卡动态分配内存,而lo网卡的id最先分配且ip固定不能被分配
//所以特判取用id为1的网卡(也就是virtio_net)
let net_face = binding.get(&1).ok_or(SystemError::ENODEV)?.clone();

// Default iface, misspelled to net_face
let net_face = binding
.iter()
.find(|(_, iface)| iface.common().is_default_iface())
.unwrap()
.1
.clone();

drop(binding);

Expand Down Expand Up @@ -149,7 +127,7 @@ fn dhcp_query() -> Result<(), SystemError> {
}

pub fn poll_ifaces() {
log::debug!("poll_ifaces");
// log::debug!("poll_ifaces");
let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn Iface>>> = NET_DEVICES.read_irqsave();
if guard.len() == 0 {
warn!("poll_ifaces: No net driver found!");
Expand Down
12 changes: 3 additions & 9 deletions kernel/src/net/socket/inet/datagram/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,14 @@ impl UnboundUdp {
}

pub fn bind(self, local_endpoint: smoltcp::wire::IpEndpoint) -> Result<BoundUdp, SystemError> {
// let (addr, port) = (local_endpoint.addr, local_endpoint.port);
// if self.socket.bind(local_endpoint).is_err() {
// log::debug!("bind failed!");
// return Err(EINVAL);
// }
let inner = BoundInner::bind(self.socket, &local_endpoint.addr)?;
let bind_addr = local_endpoint.addr;
let bind_port = if local_endpoint.port == 0 {
inner.port_manager().bind_ephemeral_port(InetTypes::Udp)?
} else {
inner
.port_manager()
.bind_port(InetTypes::Udp, local_endpoint.port)?;
local_endpoint.port
};

Expand Down Expand Up @@ -77,10 +75,6 @@ impl UnboundUdp {
remote: SpinLock::new(Some(endpoint)),
})
}

pub fn close(&mut self) {
self.socket.close();
}
}

#[derive(Debug)]
Expand Down
32 changes: 20 additions & 12 deletions kernel/src/net/socket/inet/datagram/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,28 +78,31 @@ impl UdpSocket {
bound.close();
inner.take();
}
// unbound socket just drop (only need to free memory)
}

pub fn try_recv(
&self,
buf: &mut [u8],
) -> Result<(usize, smoltcp::wire::IpEndpoint), SystemError> {
let received = match self.inner.read().as_ref().expect("Udp Inner is None") {
UdpInner::Bound(bound) => bound.try_recv(buf),
match self.inner.read().as_ref().expect("Udp Inner is None") {
UdpInner::Bound(bound) => {
let ret = bound.try_recv(buf);
poll_ifaces();
ret
}
_ => Err(ENOTCONN),
};
poll_ifaces();
return received;
}
}

#[inline]
pub fn can_recv(&self) -> bool {
self.on_events().contains(EP::EPOLLIN)
self.event().contains(EP::EPOLLIN)
}

#[inline]
pub fn can_send(&self) -> bool {
self.on_events().contains(EP::EPOLLOUT)
self.event().contains(EP::EPOLLOUT)
}

pub fn try_send(
Expand Down Expand Up @@ -138,7 +141,7 @@ impl UdpSocket {
}
}

pub fn on_events(&self) -> EPollEventType {
pub fn event(&self) -> EPollEventType {
let mut event = EPollEventType::empty();
match self.inner.read().as_ref().unwrap() {
UdpInner::Unbound(_) => {
Expand All @@ -154,8 +157,6 @@ impl UdpSocket {

if can_send {
event.insert(EP::EPOLLOUT | EP::EPOLLWRNORM | EP::EPOLLWRBAND);
} else {
todo!("缓冲区空间不够,需要使用信号处理");
}
}
}
Expand All @@ -169,7 +170,7 @@ impl Socket for UdpSocket {
}

fn poll(&self) -> usize {
self.on_events().bits() as usize
self.event().bits() as usize
}

fn bind(&self, local_endpoint: Endpoint) -> Result<(), SystemError> {
Expand All @@ -195,7 +196,9 @@ impl Socket for UdpSocket {

fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> {
if let Endpoint::Ip(remote) = endpoint {
self.bind_emphemeral(remote.addr)?;
if !self.is_bound() {
self.bind_emphemeral(remote.addr)?;
}
if let UdpInner::Bound(inner) = self.inner.read().as_ref().expect("UDP Inner disappear")
{
inner.connect(remote);
Expand Down Expand Up @@ -272,6 +275,11 @@ impl Socket for UdpSocket {
}
.map(|(len, remote)| (len, Endpoint::Ip(remote)));
}

fn close(&self) -> Result<(), SystemError> {
self.close();
Ok(())
}
}

impl InetSocket for UdpSocket {
Expand Down
17 changes: 11 additions & 6 deletions kernel/src/net/socket/inet/stream/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ impl Connecting {
.expect("A Connecting Tcp With No Local Endpoint")
})
}

pub fn get_peer_name(&self) -> smoltcp::wire::IpEndpoint {
self.inner
.with::<smoltcp::socket::tcp::Socket, _, _>(|socket| {
socket
.remote_endpoint()
.expect("A Connecting Tcp With No Remote Endpoint")
})
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -377,10 +386,6 @@ impl Established {
self.inner.with_mut(f)
}

pub fn with<R, F: Fn(&smoltcp::socket::tcp::Socket<'static>) -> R>(&self, f: F) -> R {
self.inner.with(f)
}

pub fn close(&self) {
self.inner
.with_mut::<smoltcp::socket::tcp::Socket, _, _>(|socket| socket.close());
Expand All @@ -391,13 +396,13 @@ impl Established {
self.inner.release();
}

pub fn local_endpoint(&self) -> smoltcp::wire::IpEndpoint {
pub fn get_name(&self) -> smoltcp::wire::IpEndpoint {
self.inner
.with::<smoltcp::socket::tcp::Socket, _, _>(|socket| socket.local_endpoint())
.unwrap()
}

pub fn remote_endpoint(&self) -> smoltcp::wire::IpEndpoint {
pub fn get_peer_name(&self) -> smoltcp::wire::IpEndpoint {
self.inner
.with::<smoltcp::socket::tcp::Socket, _, _>(|socket| socket.remote_endpoint().unwrap())
}
Expand Down
25 changes: 13 additions & 12 deletions kernel/src/net/socket/inet/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ impl TcpSocket {
}

pub fn try_accept(&self) -> Result<(Arc<TcpSocket>, smoltcp::wire::IpEndpoint), SystemError> {
// poll_ifaces();
match self.inner.write().as_mut().expect("Tcp Inner is None") {
Inner::Listening(listening) => listening.accept().map(|(stream, remote)| {
(
Expand Down Expand Up @@ -227,16 +226,9 @@ impl TcpSocket {
}
}

fn in_notify(&self) -> bool {
self.update_events();
// shouldn't pollee but just get the status of the socket
fn incoming(&self) -> bool {
EP::from_bits_truncate(self.poll() as u32).contains(EP::EPOLLIN)
}

fn out_notify(&self) -> bool {
self.update_events();
EP::from_bits_truncate(self.poll() as u32).contains(EP::EPOLLOUT)
}
}

impl Socket for TcpSocket {
Expand All @@ -252,16 +244,25 @@ impl Socket for TcpSocket {
})),
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())),
Inner::Established(established) => Ok(Endpoint::Ip(established.get_name())),
Inner::Listening(listening) => Ok(Endpoint::Ip(listening.get_name())),
}
}

fn get_peer_name(&self) -> Result<Endpoint, SystemError> {
match self.inner.read().as_ref().expect("Tcp Inner is None") {
Inner::Init(_) => Err(ENOTCONN),
Inner::Connecting(connecting) => Ok(Endpoint::Ip(connecting.get_peer_name())),
Inner::Established(established) => Ok(Endpoint::Ip(established.get_peer_name())),
Inner::Listening(_) => Err(ENOTCONN),
}
}

fn bind(&self, endpoint: Endpoint) -> Result<(), SystemError> {
if let Endpoint::Ip(addr) = endpoint {
return self.do_bind(addr);
}
log::warn!("TcpSocket::bind: invalid endpoint");
log::debug!("TcpSocket::bind: invalid endpoint");
return Err(EINVAL);
}

Expand Down Expand Up @@ -295,7 +296,7 @@ impl Socket for TcpSocket {
loop {
match self.try_accept() {
Err(EAGAIN_OR_EWOULDBLOCK) => {
wq_wait_event_interruptible!(self.wait_queue, self.in_notify(), {})?;
wq_wait_event_interruptible!(self.wait_queue, self.incoming(), {})?;
}
result => break result,
}
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/net/socket/unix/seqpacket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,12 +471,12 @@ impl Socket for SeqpacketSocket {
}

fn send_buffer_size(&self) -> usize {
log::warn!("using default buffer size");
// log::warn!("using default buffer size");
SeqpacketSocket::DEFAULT_BUF_SIZE
}

fn recv_buffer_size(&self) -> usize {
log::warn!("using default buffer size");
// log::warn!("using default buffer size");
SeqpacketSocket::DEFAULT_BUF_SIZE
}

Expand Down
Loading