mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-24 01:43:22 +00:00
Receive RST packets as ECONNRESET
errors
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
aa29640ed7
commit
d40d452e9d
@ -94,8 +94,12 @@ impl ConnectedStream {
|
||||
debug_assert!(!*need_poll);
|
||||
Err(e)
|
||||
}
|
||||
Err(RecvError::Finished) => Ok((0, NeedIfacePoll::FALSE)),
|
||||
Err(RecvError::InvalidState) => {
|
||||
Err(RecvError::Finished) | Err(RecvError::InvalidState) => {
|
||||
// `InvalidState` occurs when the connection is reset but `ECONNRESET` was reported
|
||||
// earlier. Linux returns EOF in this case, so we follow it.
|
||||
Ok((0, NeedIfacePoll::FALSE))
|
||||
}
|
||||
Err(RecvError::ConnReset) => {
|
||||
return_errno_with_message!(Errno::ECONNRESET, "the connection is reset")
|
||||
}
|
||||
}
|
||||
@ -106,10 +110,6 @@ impl ConnectedStream {
|
||||
reader: &mut dyn MultiRead,
|
||||
_flags: SendRecvFlags,
|
||||
) -> Result<(usize, NeedIfacePoll)> {
|
||||
if reader.is_empty() {
|
||||
return Ok((0, NeedIfacePoll::FALSE));
|
||||
}
|
||||
|
||||
let result = self.tcp_conn.send(|socket_buffer| {
|
||||
match reader.read(&mut VmWriter::from(socket_buffer)) {
|
||||
Ok(len) => (len, Ok(len)),
|
||||
@ -128,9 +128,9 @@ impl ConnectedStream {
|
||||
Err(e)
|
||||
}
|
||||
Err(SendError::InvalidState) => {
|
||||
// FIXME: `EPIPE` is another possibility, which means that the socket is shut down
|
||||
// for writing. In that case, we should also trigger a `SIGPIPE` if `MSG_NOSIGNAL`
|
||||
// is not specified.
|
||||
return_errno_with_message!(Errno::EPIPE, "the connection is closed");
|
||||
}
|
||||
Err(SendError::ConnReset) => {
|
||||
return_errno_with_message!(Errno::ECONNRESET, "the connection is reset");
|
||||
}
|
||||
}
|
||||
@ -187,10 +187,26 @@ impl ConnectedStream {
|
||||
events |= IoEvents::HUP;
|
||||
}
|
||||
|
||||
// If the connection is reset, add an ERR event.
|
||||
if socket.is_rst_closed() {
|
||||
events |= IoEvents::ERR;
|
||||
}
|
||||
|
||||
events
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn test_and_clear_error(&self) -> Option<Error> {
|
||||
if self.tcp_conn.clear_rst_closed() {
|
||||
Some(Error::with_message(
|
||||
Errno::ECONNRESET,
|
||||
"the connection is reset",
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn set_raw_option<R>(
|
||||
&self,
|
||||
set_option: impl FnOnce(&dyn RawTcpSetOption) -> R,
|
||||
|
@ -331,7 +331,10 @@ impl StreamSocket {
|
||||
}
|
||||
};
|
||||
|
||||
let (recv_bytes, need_poll) = connected_stream.try_recv(writer, flags)?;
|
||||
let result = connected_stream.try_recv(writer, flags);
|
||||
self.pollee.invalidate();
|
||||
|
||||
let (recv_bytes, need_poll) = result?;
|
||||
let iface_to_poll = need_poll.then(|| connected_stream.iface().clone());
|
||||
let remote_endpoint = connected_stream.remote_endpoint();
|
||||
|
||||
@ -355,7 +358,6 @@ impl StreamSocket {
|
||||
return result;
|
||||
}
|
||||
State::Listen(_) => {
|
||||
// TODO: Trigger `SIGPIPE` if `MSG_NOSIGNAL` is not specified
|
||||
return_errno_with_message!(Errno::EPIPE, "the socket is not connected");
|
||||
}
|
||||
State::Connecting(_) => {
|
||||
@ -365,11 +367,13 @@ impl StreamSocket {
|
||||
}
|
||||
};
|
||||
|
||||
let (sent_bytes, need_poll) = connected_stream.try_send(reader, flags)?;
|
||||
let result = connected_stream.try_send(reader, flags);
|
||||
self.pollee.invalidate();
|
||||
|
||||
let (sent_bytes, need_poll) = result?;
|
||||
let iface_to_poll = need_poll.then(|| connected_stream.iface().clone());
|
||||
|
||||
drop(state);
|
||||
self.pollee.invalidate();
|
||||
if let Some(iface) = iface_to_poll {
|
||||
iface.poll();
|
||||
}
|
||||
@ -393,7 +397,8 @@ impl StreamSocket {
|
||||
|
||||
let error = match state.as_ref() {
|
||||
State::Init(init_stream) => init_stream.test_and_clear_error(),
|
||||
State::Connecting(_) | State::Listen(_) | State::Connected(_) => None,
|
||||
State::Connected(connected_stream) => connected_stream.test_and_clear_error(),
|
||||
State::Connecting(_) | State::Listen(_) => None,
|
||||
};
|
||||
self.pollee.invalidate();
|
||||
error
|
||||
@ -553,6 +558,8 @@ impl Socket for StreamSocket {
|
||||
}
|
||||
|
||||
self.block_on(IoEvents::OUT, || self.try_send(reader, flags))
|
||||
|
||||
// TODO: Trigger `SIGPIPE` if the error code is `EPIPE` and `MSG_NOSIGNAL` is not specified
|
||||
}
|
||||
|
||||
fn recvmsg(
|
||||
|
Reference in New Issue
Block a user