纸糊忙等tcp connecting,尚不明确连接可用的机制。

This commit is contained in:
Samuka007 2024-11-20 16:59:11 +08:00
parent bd5f713617
commit f438808421
8 changed files with 133 additions and 96 deletions

View File

@ -104,33 +104,32 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
];
mfence();
let pid = ProcessManager::current_pcb().pid();
let mut show =
(syscall_num != SYS_SCHED) && (pid.data() >= 7);
// false;
let mut show = (syscall_num != SYS_SCHED) && (pid.data() >= 7);
// false;
let to_print = SysCall::try_from(syscall_num);
if let Ok(to_print) = to_print {
use SysCall::*;
match to_print {
SYS_ACCEPT | SYS_ACCEPT4 | SYS_BIND | SYS_CONNECT | SYS_SHUTDOWN | SYS_LISTEN => {
show &= false;
// show &= false;
}
SYS_RECVFROM | SYS_SENDTO | SYS_SENDMSG | SYS_RECVMSG => {
show &= false;
// show &= false;
}
SYS_SOCKET | SYS_GETSOCKNAME | SYS_GETPEERNAME | SYS_SOCKETPAIR | SYS_SETSOCKOPT
| SYS_GETSOCKOPT => {
show &= false;
// show &= false;
}
SYS_OPEN | SYS_OPENAT | SYS_CREAT | SYS_CLOSE => {
show &= false;
// show &= false;
}
SYS_READ | SYS_WRITE | SYS_READV | SYS_WRITEV | SYS_PREAD64 | SYS_PWRITE64
| SYS_PREADV | SYS_PWRITEV | SYS_PREADV2 => {
show &= false;
}
_ => {
show &= false;
// show &= false;
}
}
if show {

View File

@ -246,8 +246,8 @@ impl IfaceCommon {
self.bounds.read().iter().for_each(|bound_socket| {
// incase our inet socket missed the event, we manually notify it each time we poll
bound_socket.on_iface_events();
if has_events {
bound_socket.on_iface_events();
bound_socket
.wait_queue()
.wakeup(Some(ProcessState::Blocked(true)));

View File

@ -645,6 +645,7 @@ impl Iface for VirtioInterface {
}
fn poll(&self) {
// log::debug!("VirtioInterface: poll");
self.iface_common.poll(self.device_inner.force_get_mut())
}

View File

@ -42,7 +42,7 @@ pub fn net_init() -> Result<(), SystemError> {
fn dhcp_query() -> Result<(), SystemError> {
let binding = NET_DEVICES.write_irqsave();
log::debug!("binding: {:?}", *binding);
// log::debug!("binding: {:?}", *binding);
//由于现在os未实现在用户态为网卡动态分配内存而lo网卡的id最先分配且ip固定不能被分配
//所以特判取用id为1的网卡也就是virtio_net
let net_face = binding.get(&1).ok_or(SystemError::ENODEV)?.clone();
@ -63,7 +63,7 @@ fn dhcp_query() -> Result<(), SystemError> {
// let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket);
let dhcp_handle = sockets().add(dhcp_socket);
const DHCP_TRY_ROUND: u8 = 10;
const DHCP_TRY_ROUND: u8 = 100;
for i in 0..DHCP_TRY_ROUND {
log::debug!("DHCP try round: {}", i);
net_face.poll();
@ -137,8 +137,8 @@ fn dhcp_query() -> Result<(), SystemError> {
drop(binding);
let sleep_time = PosixTimeSpec {
tv_sec: 5,
tv_nsec: 0,
tv_sec: 0,
tv_nsec: 50,
};
let _ = nanosleep(sleep_time)?;
}
@ -147,7 +147,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!");

View File

@ -106,10 +106,8 @@ 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;
return <Self as FromPrimitive>::from_u16(x).ok_or({
log::debug!("AddressFamily::try_from failed: x={}", x);
Self::Error::EINVAL
});
// this will return EINVAL but still works, idk why
return <Self as FromPrimitive>::from_u16(x).ok_or(Self::Error::EINVAL);
}
}

View File

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

View File

@ -207,16 +207,20 @@ impl Connecting {
self.inner.with_mut(f)
}
pub fn into_result(self) -> (Inner, Option<SystemError>) {
pub fn into_result(self) -> (Inner, Result<(), SystemError>) {
use ConnectResult::*;
let result = *self.result.read_irqsave();
match result {
Connecting => (Inner::Connecting(self), Some(EAGAIN_OR_EWOULDBLOCK)),
Connected => (Inner::Established(Established { inner: self.inner }), None),
Refused => (Inner::Init(Init::new_bound(self.inner)), Some(ECONNREFUSED)),
Connecting => (Inner::Connecting(self), Err(EAGAIN_OR_EWOULDBLOCK)),
Connected => (Inner::Established(Established { inner: self.inner }), Ok(())),
Refused => (Inner::Init(Init::new_bound(self.inner)), Err(ECONNREFUSED)),
}
}
pub unsafe fn into_established(self) -> Established {
Established { inner: self.inner }
}
/// Returns `true` when `conn_result` becomes ready, which indicates that the caller should
/// invoke the `into_result()` method as soon as possible.
///
@ -224,9 +228,9 @@ impl Connecting {
/// _exactly_ once. The caller is responsible for not missing this event.
#[must_use]
pub(super) fn update_io_events(&self) -> bool {
if matches!(*self.result.read_irqsave(), ConnectResult::Connecting) {
return false;
}
// if matches!(*self.result.read_irqsave(), ConnectResult::Connecting) {
// return false;
// }
self.inner
.with_mut(|socket: &mut smoltcp::socket::tcp::Socket| {
@ -237,11 +241,14 @@ impl Connecting {
// Connected
if socket.can_send() {
log::debug!("can send");
*result = ConnectResult::Connected;
return true;
}
// Connecting
if socket.is_open() {
log::debug!("connecting");
*result = ConnectResult::Connecting;
return false;
}
// Refused
@ -309,7 +316,6 @@ impl Listening {
});
if let Some(position) = position {
// log::debug!("Can accept!");
self.connect
.store(position, core::sync::atomic::Ordering::Relaxed);
pollee.fetch_or(
@ -317,7 +323,6 @@ impl Listening {
core::sync::atomic::Ordering::Relaxed,
);
} else {
// log::debug!("Can't accept!");
pollee.fetch_and(
!EPollEventType::EPOLLIN.bits() as usize,
core::sync::atomic::Ordering::Relaxed,

View File

@ -4,7 +4,6 @@ use system_error::SystemError::{self, *};
use crate::libs::rwlock::RwLock;
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_V4, UNSPECIFIED_LOCAL_ENDPOINT_V6};
@ -29,14 +28,14 @@ pub struct TcpSocket {
}
impl TcpSocket {
pub fn new(nonblock: bool, ver: smoltcp::wire::IpVersion) -> Arc<Self> {
pub fn new(_nonblock: bool, ver: smoltcp::wire::IpVersion) -> Arc<Self> {
Arc::new_cyclic(|me| Self {
inner: RwLock::new(Some(Inner::Init(Init::new(ver)))),
shutdown: Shutdown::new(),
nonblock: AtomicBool::new(nonblock),
nonblock: AtomicBool::new(false),
wait_queue: WaitQueue::default(),
self_ref: me.clone(),
pollee: AtomicUsize::new((EP::EPOLLIN.bits() | EP::EPOLLOUT.bits()) as usize),
pollee: AtomicUsize::new(0_usize),
})
}
@ -100,7 +99,7 @@ impl TcpSocket {
}
pub fn try_accept(&self) -> Result<(Arc<TcpSocket>, smoltcp::wire::IpEndpoint), SystemError> {
poll_ifaces();
// poll_ifaces();
match self.inner.write().as_mut().expect("Tcp Inner is None") {
Inner::Listening(listening) => listening.accept().map(|(stream, remote)| {
(
@ -112,46 +111,48 @@ impl TcpSocket {
}
}
// SHOULD refactor
pub fn start_connect(
&self,
remote_endpoint: smoltcp::wire::IpEndpoint,
) -> Result<(), SystemError> {
let mut writer = self.inner.write();
let inner = writer.take().expect("Tcp Inner is None");
let (init, err) = match inner {
let (init, result) = match inner {
Inner::Init(init) => {
let conn_result = init.connect(remote_endpoint);
match conn_result {
Ok(connecting) => (
Inner::Connecting(connecting),
if self.is_nonblock() {
None
if !self.is_nonblock() {
Ok(())
} else {
Some(EINPROGRESS)
Err(EINPROGRESS)
},
),
Err((init, err)) => (Inner::Init(init), Some(err)),
Err((init, err)) => (Inner::Init(init), Err(err)),
}
}
Inner::Connecting(connecting) if self.is_nonblock() => {
(Inner::Connecting(connecting), Some(EALREADY))
(Inner::Connecting(connecting), Err(EALREADY))
}
Inner::Connecting(connecting) => (Inner::Connecting(connecting), None),
Inner::Listening(inner) => (Inner::Listening(inner), Some(EISCONN)),
Inner::Established(inner) => (Inner::Established(inner), Some(EISCONN)),
Inner::Connecting(connecting) => (Inner::Connecting(connecting), Ok(())),
Inner::Listening(inner) => (Inner::Listening(inner), Err(EISCONN)),
Inner::Established(inner) => (Inner::Established(inner), Err(EISCONN)),
};
writer.replace(init);
drop(writer);
poll_ifaces();
if let Some(err) = err {
return Err(err);
match result {
Ok(()) | Err(EINPROGRESS) => {
init.iface().unwrap().poll();
},
_ => {}
}
return Ok(());
writer.replace(init);
return result;
}
// for irq use
pub fn finish_connect(&self) -> Result<(), SystemError> {
let mut writer = self.inner.write();
let Inner::Connecting(conn) = writer.take().expect("Tcp Inner is None") else {
@ -159,22 +160,32 @@ impl TcpSocket {
return Err(EINVAL);
};
let (inner, err) = conn.into_result();
let (inner, result) = conn.into_result();
writer.replace(inner);
drop(writer);
if let Some(err) = err {
return Err(err);
}
return Ok(());
result
}
pub fn check_connect(&self) -> Result<(), SystemError> {
match self.inner.read().as_ref().expect("Tcp Inner is None") {
Inner::Connecting(_) => Err(EAGAIN_OR_EWOULDBLOCK),
Inner::Established(_) => Ok(()), // TODO check established
_ => Err(EINVAL), // TODO socket error options
}
self.update_events();
let mut write_state = self.inner.write();
let inner = write_state.take().expect("Tcp Inner is None");
let (replace, result) = match inner {
Inner::Connecting(conn) => {
conn.into_result()
}
Inner::Established(es) => {
log::warn!("TODO: check new established");
(Inner::Established(es), Ok(()))
}, // TODO check established
_ => {
log::warn!("TODO: connecting socket error options");
(inner, Err(EINVAL))
}, // TODO socket error options
};
write_state.replace(replace);
result
}
pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize, SystemError> {
@ -194,20 +205,23 @@ impl TcpSocket {
}
pub fn try_send(&self, buf: &[u8]) -> Result<usize, SystemError> {
match self.inner.read().as_ref().expect("Tcp Inner is None") {
// TODO: add nonblock check of connecting socket
let sent = match self.inner.read().as_ref().expect("Tcp Inner is None") {
Inner::Established(inner) => {
let sent = inner.send_slice(buf);
poll_ifaces();
sent
inner.send_slice(buf)
}
_ => Err(EINVAL),
}
};
self.inner.read().as_ref().unwrap().iface().unwrap().poll();
sent
}
fn update_events(&self) -> bool {
match self.inner.read().as_ref().expect("Tcp Inner is None") {
Inner::Init(_) => false,
Inner::Connecting(connecting) => connecting.update_io_events(),
Inner::Connecting(connecting) => {
connecting.update_io_events()
},
Inner::Established(established) => {
established.update_io_events(&self.pollee);
false
@ -219,12 +233,16 @@ impl TcpSocket {
}
}
// should only call on accept
fn is_acceptable(&self) -> bool {
// (self.poll() & EP::EPOLLIN.bits() as usize) != 0
self.inner.read().as_ref().unwrap().iface().unwrap().poll();
fn in_notify(&self) -> bool {
self.update_events();
// shouldn't pollee but just get the status of the socket
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 {
@ -254,10 +272,18 @@ impl Socket for TcpSocket {
}
fn connect(&self, endpoint: Endpoint) -> Result<(), SystemError> {
if let Endpoint::Ip(addr) = endpoint {
return self.start_connect(addr);
let Endpoint::Ip(endpoint) = endpoint else {
log::debug!("TcpSocket::connect: invalid endpoint");
return Err(EINVAL);
};
self.start_connect(endpoint)?; // Only Nonblock or error will return error.
return loop {
match self.check_connect() {
Err(EAGAIN_OR_EWOULDBLOCK) => {},
result => break result,
}
}
return Err(EINVAL);
}
fn poll(&self) -> usize {
@ -269,15 +295,17 @@ impl Socket for TcpSocket {
}
fn accept(&self) -> Result<(Arc<Inode>, Endpoint), SystemError> {
// could block io
if self.is_nonblock() {
self.try_accept()
} else {
loop {
// log::debug!("TcpSocket::accept: wake up");
match self.try_accept() {
Err(EAGAIN_OR_EWOULDBLOCK) => {
wq_wait_event_interruptible!(self.wait_queue, self.is_acceptable(), {})?;
wq_wait_event_interruptible!(
self.wait_queue,
self.in_notify(),
{}
)?;
}
result => break result,
}
@ -311,26 +339,32 @@ impl Socket for TcpSocket {
}
fn close(&self) -> Result<(), SystemError> {
self.inner
.read()
.as_ref()
.map(|inner| match inner {
Inner::Connecting(_) => Err(EINPROGRESS),
Inner::Established(es) => {
es.close();
es.release();
Ok(())
}
Inner::Listening(ls) => {
ls.close();
Ok(())
}
Inner::Init(init) => {
init.close();
Ok(())
}
})
.unwrap_or(Ok(()))
let inner = self.inner
.write()
.take().unwrap();
match inner {
// complete connecting socket close logic
Inner::Connecting(conn) => {
let conn = unsafe { conn.into_established() };
conn.close();
conn.release();
Ok(())
},
Inner::Established(es) => {
es.close();
es.release();
Ok(())
}
Inner::Listening(ls) => {
ls.close();
Ok(())
}
Inner::Init(init) => {
init.close();
Ok(())
}
}
}
fn set_option(&self, level: PSOL, name: usize, val: &[u8]) -> Result<(), SystemError> {