Skip to content
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
26 changes: 26 additions & 0 deletions kernel/src/ipc/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ pub enum FdKind {
PipeWrite(Arc<Mutex<super::pipe::PipeBuffer>>),
/// UDP socket (wrapped in Arc<Mutex<>> for sharing and dup/fork)
UdpSocket(Arc<Mutex<crate::socket::udp::UdpSocket>>),
/// TCP socket (unbound, or bound but not connected/listening)
/// The u16 is the bound local port (0 if unbound)
TcpSocket(u16),
/// TCP listener (bound and listening socket)
/// The u16 is the listening port
TcpListener(u16),
/// TCP connection (established connection)
/// Contains the connection ID for lookup in the global TCP connection table
TcpConnection(crate::net::tcp::ConnectionId),
/// Regular file descriptor
#[allow(dead_code)] // Will be constructed when open() is fully implemented
RegularFile(Arc<Mutex<RegularFile>>),
Expand All @@ -104,6 +113,9 @@ impl core::fmt::Debug for FdKind {
FdKind::PipeRead(_) => write!(f, "PipeRead"),
FdKind::PipeWrite(_) => write!(f, "PipeWrite"),
FdKind::UdpSocket(_) => write!(f, "UdpSocket"),
FdKind::TcpSocket(port) => write!(f, "TcpSocket(port={})", port),
FdKind::TcpListener(port) => write!(f, "TcpListener(port={})", port),
FdKind::TcpConnection(id) => write!(f, "TcpConnection({:?})", id),
FdKind::RegularFile(_) => write!(f, "RegularFile"),
FdKind::Directory(_) => write!(f, "Directory"),
FdKind::Device(dt) => write!(f, "Device({:?})", dt),
Expand Down Expand Up @@ -407,6 +419,20 @@ impl Drop for FdTable {
// Socket cleanup handled by UdpSocket::Drop when Arc refcount reaches 0
log::debug!("FdTable::drop() - releasing UDP socket fd {}", i);
}
FdKind::TcpSocket(_) => {
// Unbound TCP socket doesn't need cleanup
log::debug!("FdTable::drop() - releasing TCP socket fd {}", i);
}
FdKind::TcpListener(port) => {
// Remove from listener table
crate::net::tcp::TCP_LISTENERS.lock().remove(&port);
log::debug!("FdTable::drop() - closed TCP listener fd {} on port {}", i, port);
}
FdKind::TcpConnection(conn_id) => {
// Close the TCP connection
let _ = crate::net::tcp::tcp_close(&conn_id);
log::debug!("FdTable::drop() - closed TCP connection fd {}", i);
}
FdKind::StdIo(_) => {
// StdIo doesn't need cleanup
}
Expand Down
40 changes: 40 additions & 0 deletions kernel/src/ipc/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,46 @@ pub fn poll_fd(fd_entry: &FileDescriptor, events: i16) -> i16 {
revents |= events::POLLIN;
}
}
FdKind::TcpSocket(_) => {
// Unconnected TCP socket - always writable (for connect attempt)
if (events & events::POLLOUT) != 0 {
revents |= events::POLLOUT;
}
}
FdKind::TcpListener(port) => {
// Listening socket - check for pending connections
if (events & events::POLLIN) != 0 {
if crate::net::tcp::tcp_has_pending(*port) {
revents |= events::POLLIN;
}
}
}
FdKind::TcpConnection(conn_id) => {
// Connected socket - check for data and connection state
let connections = crate::net::tcp::TCP_CONNECTIONS.lock();
if let Some(conn) = connections.get(conn_id) {
// Check for readable data
if (events & events::POLLIN) != 0 {
if !conn.rx_buffer.is_empty() {
revents |= events::POLLIN;
}
}
// Check for writable
if (events & events::POLLOUT) != 0 {
if conn.state == crate::net::tcp::TcpState::Established {
revents |= events::POLLOUT;
}
}
// Check for connection closed
if conn.state == crate::net::tcp::TcpState::Closed ||
conn.state == crate::net::tcp::TcpState::CloseWait {
revents |= events::POLLHUP;
}
} else {
// Connection not found - error
revents |= events::POLLERR;
}
}
}

revents
Expand Down
14 changes: 14 additions & 0 deletions kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,20 @@ fn kernel_main_continue() -> ! {
}
}
}

// Launch TCP socket test to verify TCP syscalls from userspace
{
serial_println!("RING3_SMOKE: creating tcp_socket_test userspace process");
let tcp_test_buf = crate::userspace_test::get_test_binary("tcp_socket_test");
match process::creation::create_user_process(String::from("tcp_socket_test"), &tcp_test_buf) {
Ok(pid) => {
log::info!("Created tcp_socket_test process with PID {}", pid.as_u64());
}
Err(e) => {
log::error!("Failed to create tcp_socket_test process: {}", e);
}
}
}
});
}

Expand Down
7 changes: 3 additions & 4 deletions kernel/src/net/ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ impl<'a> Ipv4Packet<'a> {
pub fn handle_ipv4(eth_frame: &EthernetFrame, ip: &Ipv4Packet) {
let config = super::config();

// Check if this packet is for us
if ip.dst_ip != config.ip_addr {
// Check if this packet is for us (accept our IP or loopback addresses)
if ip.dst_ip != config.ip_addr && ip.dst_ip[0] != 127 {
// Not for us, ignore (we don't do routing)
return;
}
Expand All @@ -175,8 +175,7 @@ pub fn handle_ipv4(eth_frame: &EthernetFrame, ip: &Ipv4Packet) {
}
}
PROTOCOL_TCP => {
// TCP not implemented yet
log::debug!("IPv4: Received TCP packet (not implemented)");
super::tcp::handle_tcp(ip, ip.payload);
}
PROTOCOL_UDP => {
super::udp::handle_udp(ip, ip.payload);
Expand Down
5 changes: 3 additions & 2 deletions kernel/src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod arp;
pub mod ethernet;
pub mod icmp;
pub mod ipv4;
pub mod tcp;
pub mod udp;

use alloc::vec::Vec;
Expand Down Expand Up @@ -228,8 +229,8 @@ pub fn send_ethernet(dst_mac: &[u8; 6], ethertype: u16, payload: &[u8]) -> Resul
pub fn send_ipv4(dst_ip: [u8; 4], protocol: u8, payload: &[u8]) -> Result<(), &'static str> {
let config = config();

// Check for loopback - sending to ourselves
if dst_ip == config.ip_addr {
// Check for loopback - sending to ourselves or to 127.x.x.x network
if dst_ip == config.ip_addr || dst_ip[0] == 127 {
log::debug!("NET: Loopback detected, queueing packet for deferred delivery");

// Build IP packet
Expand Down
Loading
Loading