From 405a603b0f5da26bfcd46f1e56c16ae8ceb300ff Mon Sep 17 00:00:00 2001 From: Alec Murphy Date: Sat, 20 Sep 2025 19:07:10 -0400 Subject: [PATCH] src/net: Add tcp_rst_packet() --- src/net/tcpip.jakt | 82 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/net/tcpip.jakt b/src/net/tcpip.jakt index af5bd76..fc2b6bb 100644 --- a/src/net/tcpip.jakt +++ b/src/net/tcpip.jakt @@ -722,6 +722,75 @@ class TCPIP { .tx_queue.push(packet) } + fn tcp_rst_packet(mut this, anon mut session: TcpSession) throws { + mut packet: [u8] = [] + + let header_length: u16 = 32 + let flags: u16 = 0x8004 // RST + + let maximum_payload_size_to_transmit: i64 = 1024 + mut payload_size: i64 = maximum_payload_size_to_transmit + let payload_offset: i64 = session.tx_chunk_counter * maximum_payload_size_to_transmit + if session.pending_data_to_transmit.size() as! i64 - payload_offset < maximum_payload_size_to_transmit { + payload_size = session.pending_data_to_transmit.size() as! i64 - payload_offset + } + + mut ipv4_total_length: u16 = 0 + ipv4_total_length += 20; // IPv4 + ipv4_total_length += header_length + payload_size as! u16 // TCP + + .push_ethernet_header(packet, destination_mac: session.remote_mac, source_mac: session.local_mac, ethertype: 0x0800) + .push_ipv4_header(packet, total_length: ipv4_total_length, flags: 0x40, protocol: 0x06, source_address: session.local_address, destination_address: session.remote_address) + + + // FIXME: put this into .push_tcp_header + + Util::push_u16_to_u8_array(packet, session.local_port) + Util::push_u16_to_u8_array(packet, session.remote_port) + Util::push_u32_to_u8_array(packet, session.local_sequence_number) + Util::push_u32_to_u8_array(packet, session.acknowledgement_number) + Util::push_u16_to_u8_array(packet, flags) + Util::push_u16_to_u8_array(packet, session.last_window_size) + Util::push_u16_to_u8_array(packet, 0 as! u16) // Checksum placeholder + Util::push_u16_to_u8_array(packet, 0 as! u16) // Urgent pointer + + mut tcp_options: [u8] = [0x01, 0x01, 0x08, 0x0a] + packet.push_values(&tcp_options) + + let timestamp: u32 = (session.timestamp_origin + (Time::jiffies() - session.timestamp_origin)) as! u32 + Util::push_u32_to_u8_array(packet, timestamp) + Util::push_u32_to_u8_array(packet, session.timestamp_last_echo_reply) + + for i in payload_offset..(payload_offset + payload_size) { + packet.push(session.pending_data_to_transmit[i]) + } + + // Calculate TCP checksum + + mut checksum_packet: [u8] = [] + // Source and destination IP + for i in 26..34 { + checksum_packet.push(packet[i]) + } + // Protocol + checksum_packet.push(0x00u8) + checksum_packet.push(0x06u8) + // TCP Packet length + let tcp_packet_length: u16 = header_length + payload_size as! u16 + Util::push_u16_to_u8_array(checksum_packet, tcp_packet_length) + + for i in 34..packet.size() { + checksum_packet.push(packet[i]) + } + + mut checksum = .calculate_header_checksum(checksum_packet, offset: 0, count: checksum_packet.size() as! i64) + packet[50] = (checksum >> 8) as! u8 + packet[51] = (checksum & 0xff) as! u8 + + .tx_queue.push(packet) + + } + public fn tcp_transmit_pending_data_for_existing_sessions(mut this) throws { for i in 0..this.tcp_sessions.size() { if .tcp_sessions[i].pending_data_to_transmit.size() > 0 { @@ -1013,15 +1082,22 @@ class TCPIP { let socket = session.socket mut length = session.received_data.size() mut max_length: usize = 0 + mut close_connection: bool = false // s[4] = 0; // receive_buffer_size if (socket > 0) { unsafe { cpp { "u64 *s = (u64*)socket; - max_length = s[4];" + max_length = s[4]; + close_connection = s[11]; + if (close_connection) { s[11] = 0; };" } } } + if close_connection { + .tcp_rst_packet(session) + .tcp_sessions[i].state = TcpSessionState::Closed + } // FIXME: Should the client be responsible for malloc()ing the receive buffer? if length > 65536 { length = 65536 @@ -1130,6 +1206,10 @@ class TCPIP { mut echo_reply: u32 = 0 mut tcp_options_offset = 54 + if (.tcp_sessions[i].state as! i64 == TcpSessionState::Closed as! i64) { + return + } + while tcp_options_offset < frame.size() as! i64 { match frame[tcp_options_offset] { 0u8 => { tcp_options_offset++ }