src/net: Add tcp_rst_packet()

This commit is contained in:
Alec Murphy
2025-09-20 19:07:10 -04:00
parent 9e4fd9c5a3
commit 405a603b0f

View File

@@ -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++ }