diff --git a/kernel/aster-nix/src/net/socket/vsock/common.rs b/kernel/aster-nix/src/net/socket/vsock/common.rs index be6a327f0..36a79d1f1 100644 --- a/kernel/aster-nix/src/net/socket/vsock/common.rs +++ b/kernel/aster-nix/src/net/socket/vsock/common.rs @@ -13,6 +13,7 @@ use super::{ addr::VsockSocketAddr, stream::{ connected::{Connected, ConnectionID}, + connecting::Connecting, listen::Listen, }, }; @@ -22,7 +23,7 @@ use crate::{events::IoEvents, prelude::*, return_errno_with_message}; pub struct VsockSpace { pub driver: Arc>, // (key, value) = (local_addr, connecting) - pub connecting_sockets: SpinLock>>, + pub connecting_sockets: SpinLock>>, // (key, value) = (local_addr, listen) pub listen_sockets: SpinLock>>, // (key, value) = (id(local_addr,peer_addr), connected) diff --git a/kernel/aster-nix/src/net/socket/vsock/stream/connected.rs b/kernel/aster-nix/src/net/socket/vsock/stream/connected.rs index c8b211962..d4be7be75 100644 --- a/kernel/aster-nix/src/net/socket/vsock/stream/connected.rs +++ b/kernel/aster-nix/src/net/socket/vsock/stream/connected.rs @@ -5,6 +5,7 @@ use core::cmp::min; use aster_virtio::device::socket::connect::{ConnectionInfo, VsockEvent}; +use super::connecting::Connecting; use crate::{ events::IoEvents, net::socket::{ @@ -31,6 +32,14 @@ impl Connected { pollee: Pollee::new(IoEvents::empty()), } } + + pub fn from_connecting(connecting: Arc) -> Self { + Self { + connection: SpinLock::new(Connection::from_info(connecting.info())), + id: connecting.id(), + pollee: Pollee::new(IoEvents::empty()), + } + } pub fn peer_addr(&self) -> VsockSocketAddr { self.id.peer_addr } @@ -156,6 +165,15 @@ impl Connection { peer_requested_shutdown: false, } } + pub fn from_info(info: ConnectionInfo) -> Self { + let mut info = info.clone(); + info.buf_alloc = PER_CONNECTION_BUFFER_CAPACITY.try_into().unwrap(); + Self { + info, + buffer: RingBuffer::new(PER_CONNECTION_BUFFER_CAPACITY), + peer_requested_shutdown: false, + } + } pub fn update_for_event(&mut self, event: &VsockEvent) { self.info.update_for_event(event) } diff --git a/kernel/aster-nix/src/net/socket/vsock/stream/connecting.rs b/kernel/aster-nix/src/net/socket/vsock/stream/connecting.rs new file mode 100644 index 000000000..087ad7830 --- /dev/null +++ b/kernel/aster-nix/src/net/socket/vsock/stream/connecting.rs @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: MPL-2.0 + +use alloc::boxed::Box; +use core::cmp::min; + +use aster_virtio::device::socket::connect::{ConnectionInfo, VsockEvent}; + +use super::connected::ConnectionID; +use crate::{ + events::IoEvents, + net::socket::{ + vsock::{addr::VsockSocketAddr, VSOCK_GLOBAL}, + SendRecvFlags, SockShutdownCmd, + }, + prelude::*, + process::signal::{Pollee, Poller}, +}; + +pub struct Connecting { + id: ConnectionID, + info: SpinLock, + pollee: Pollee, +} + +impl Connecting { + pub fn new(peer_addr: VsockSocketAddr, local_addr: VsockSocketAddr) -> Self { + Self { + info: SpinLock::new(ConnectionInfo::new(peer_addr.into(), local_addr.port)), + id: ConnectionID::new(local_addr, peer_addr), + pollee: Pollee::new(IoEvents::empty()), + } + } + pub fn peer_addr(&self) -> VsockSocketAddr { + self.id.peer_addr + } + + pub fn local_addr(&self) -> VsockSocketAddr { + self.id.local_addr + } + + pub fn id(&self) -> ConnectionID { + self.id + } + pub fn info(&self) -> ConnectionInfo { + self.info.lock_irq_disabled().clone() + } + pub fn update_for_event(&self, event: &VsockEvent) { + self.info.lock_irq_disabled().update_for_event(event) + } + pub fn poll(&self, mask: IoEvents, poller: Option<&Poller>) -> IoEvents { + self.pollee.poll(mask, poller) + } + pub fn add_events(&self, events: IoEvents) { + self.pollee.add_events(events) + } +} + +impl Drop for Connecting { + fn drop(&mut self) { + let vsockspace = VSOCK_GLOBAL.get().unwrap(); + vsockspace + .used_ports + .lock_irq_disabled() + .remove(&self.local_addr().port); + } +} diff --git a/kernel/aster-nix/src/net/socket/vsock/stream/listen.rs b/kernel/aster-nix/src/net/socket/vsock/stream/listen.rs index 4a572f939..ffcf72501 100644 --- a/kernel/aster-nix/src/net/socket/vsock/stream/listen.rs +++ b/kernel/aster-nix/src/net/socket/vsock/stream/listen.rs @@ -50,7 +50,9 @@ impl Listen { .incoming_connection .lock_irq_disabled() .pop_front() - .unwrap(); + .ok_or_else(|| { + Error::with_message(Errno::EAGAIN, "no pending connection is available") + })?; Ok(connection) } diff --git a/kernel/aster-nix/src/net/socket/vsock/stream/mod.rs b/kernel/aster-nix/src/net/socket/vsock/stream/mod.rs index 5fc3337a2..1b8422957 100644 --- a/kernel/aster-nix/src/net/socket/vsock/stream/mod.rs +++ b/kernel/aster-nix/src/net/socket/vsock/stream/mod.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 pub mod connected; +pub mod connecting; pub mod init; pub mod listen; diff --git a/kernel/aster-nix/src/net/socket/vsock/stream/socket.rs b/kernel/aster-nix/src/net/socket/vsock/stream/socket.rs index 2af956d03..39fef472b 100644 --- a/kernel/aster-nix/src/net/socket/vsock/stream/socket.rs +++ b/kernel/aster-nix/src/net/socket/vsock/stream/socket.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -use super::{connected::Connected, init::Init, listen::Listen}; +use super::{connected::Connected, connecting::Connecting, init::Init, listen::Listen}; use crate::{ events::IoEvents, fs::file_handle::FileLike, @@ -101,7 +101,7 @@ impl Socket for VsockStreamSocket { init.bind(VsockSocketAddr::any_addr())?; } - let connecting = Arc::new(Connected::new(remote_addr, init.bound_addr().unwrap())); + let connecting = Arc::new(Connecting::new(remote_addr, init.bound_addr().unwrap())); let vsockspace = VSOCK_GLOBAL.get().unwrap(); vsockspace .connecting_sockets @@ -112,7 +112,7 @@ impl Socket for VsockStreamSocket { vsockspace .driver .lock_irq_disabled() - .request(&connecting.get_info()) + .request(&connecting.info()) .map_err(|e| Error::with_message(Errno::EAGAIN, "can not send connect packet"))?; // wait for response from driver @@ -124,18 +124,19 @@ impl Socket for VsockStreamSocket { { poller.wait()?; } - - *self.0.write() = Status::Connected(connecting.clone()); - // move connecting socket map to connected sockmap vsockspace .connecting_sockets .lock_irq_disabled() .remove(&connecting.local_addr()) .unwrap(); + + let connected = Arc::new(Connected::from_connecting(connecting)); + *self.0.write() = Status::Connected(connected.clone()); + // move connecting socket map to connected sockmap vsockspace .connected_sockets .lock_irq_disabled() - .insert(connecting.id(), connecting); + .insert(connected.id(), connected); Ok(()) }