From e49d2a9fa5a485c33a250ce843d44fc6dedea8b5 Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Mon, 8 Jul 2024 21:37:15 +0200 Subject: Kernel/Net: Don't use kmalloc to create send buffers Current method is also really bad since it uses multiple copies when it should instead just copy to the send buffer of the network card directly. But I have other things that I want to prioritize first. --- kernel/network/ethernet.c | 14 +++++++------- kernel/network/ipv4.c | 5 +++-- kernel/network/tcp.c | 17 +++++++++++------ 3 files changed, 21 insertions(+), 15 deletions(-) (limited to 'kernel/network') diff --git a/kernel/network/ethernet.c b/kernel/network/ethernet.c index 7b1de7f..dbd1b6d 100644 --- a/kernel/network/ethernet.c +++ b/kernel/network/ethernet.c @@ -68,14 +68,14 @@ void handle_ethernet(const u8 *packet, u64 packet_length) { } } +u8 ethernet_buffer[0x1000]; void send_ethernet_packet(u8 mac_dst[6], u16 type, u8 *payload, u64 payload_length) { - // FIXME: Janky allocation, do this better u64 buffer_size = sizeof(struct EthernetHeader) + payload_length + sizeof(u32); - u8 *buffer = kmalloc(buffer_size); - memset(buffer, 0, buffer_size); - u8 *buffer_start = buffer; + assert(buffer_size < 0x1000); + memset(ethernet_buffer, 0, buffer_size); + u8 *buffer = ethernet_buffer; struct EthernetHeader *eth_header = (struct EthernetHeader *)buffer; buffer += sizeof(struct EthernetHeader); memcpy(buffer, payload, payload_length); @@ -84,8 +84,8 @@ void send_ethernet_packet(u8 mac_dst[6], u16 type, u8 *payload, memcpy(eth_header->mac_dst, mac_dst, sizeof(u8[6])); get_mac_address(eth_header->mac_src); eth_header->type = htons(type); - *(u32 *)(buffer) = htonl(crc32((const char *)buffer_start, buffer_size - 4)); + *(u32 *)(buffer) = + htonl(crc32((const char *)ethernet_buffer, buffer_size - 4)); - rtl8139_send_data(buffer_start, buffer_size); - kfree(buffer_start); + rtl8139_send_data(ethernet_buffer, buffer_size); } diff --git a/kernel/network/ipv4.c b/kernel/network/ipv4.c index 69ceef7..6074141 100644 --- a/kernel/network/ipv4.c +++ b/kernel/network/ipv4.c @@ -26,6 +26,7 @@ static u16 ip_checksum(const u16 *data, u16 length) { return htons(~acc); } +u8 ipv4_buffer[0x1000]; void send_ipv4_packet(ipv4_t ip, u8 protocol, const u8 *payload, u16 length) { u16 header[10]; header[0] = (4 /*version*/ << 4) | (5 /*IHL*/); @@ -46,7 +47,8 @@ void send_ipv4_packet(ipv4_t ip, u8 protocol, const u8 *payload, u16 length) { header[5] = ip_checksum(header, 20); u16 packet_length = length + 20; - u8 *packet = kmalloc(packet_length); + assert(packet_length < sizeof(ipv4_buffer)); + u8 *packet = ipv4_buffer; memcpy(packet, header, 20); memcpy(packet + 20, payload, length); @@ -54,7 +56,6 @@ void send_ipv4_packet(ipv4_t ip, u8 protocol, const u8 *payload, u16 length) { for (; !get_mac_from_ip(ip, mac);) ; send_ethernet_packet(mac, 0x0800, packet, packet_length); - kfree(packet); } void handle_ipv4(const u8 *payload, u32 packet_length) { diff --git a/kernel/network/tcp.c b/kernel/network/tcp.c index 8a56dd1..8717250 100644 --- a/kernel/network/tcp.c +++ b/kernel/network/tcp.c @@ -87,6 +87,7 @@ static void tcp_send(struct TcpConnection *con, u8 *buffer, u16 length, send_ipv4_packet((ipv4_t){.d = con->outgoing_ip}, 6, buffer, length); } +u8 tcp_buffer[0x1000]; void tcp_send_empty_payload(struct TcpConnection *con, u8 flags) { struct TcpHeader header; memset(&header, 0, sizeof(header)); @@ -110,8 +111,10 @@ void tcp_send_empty_payload(struct TcpConnection *con, u8 flags) { header.checksum = tcp_calculate_checksum( ip_address, con->outgoing_ip, (const u8 *)payload, payload_length, &header, sizeof(struct TcpHeader) + payload_length); - int send_len = sizeof(header) + payload_length; - u8 *send_buffer = kmalloc(send_len); + u32 send_len = sizeof(header) + payload_length; + + assert(send_len < sizeof(tcp_buffer)); + u8 *send_buffer = tcp_buffer; memcpy(send_buffer, &header, sizeof(header)); memcpy(send_buffer + sizeof(header), payload, payload_length); @@ -133,13 +136,15 @@ void tcp_close_connection(struct TcpConnection *con) { if (TCP_STATE_CLOSE_WAIT == con->state) { tcp_send_empty_payload(con, FIN); con->state = TCP_STATE_LAST_ACK; + tcp_destroy_connection(con); // Client does not appear to respond + // with last ack? return; } if (TCP_STATE_ESTABLISHED == con->state) { // FIXME: // Book says it should be FIN but observed network traffic says it // should be FIN|ACK? - tcp_send_empty_payload(con, FIN | ACK); + tcp_send_empty_payload(con, FIN); con->state = TCP_STATE_FIN_WAIT1; return; } @@ -189,9 +194,9 @@ int send_tcp_packet(struct TcpConnection *con, const u8 *payload, header.checksum = tcp_calculate_checksum( ip_address, con->outgoing_ip, (const u8 *)payload, payload_length, &header, sizeof(struct TcpHeader) + payload_length); - int send_len = sizeof(header) + payload_length; - u8 *send_buffer = kmalloc(send_len); - assert(send_buffer); + u32 send_len = sizeof(header) + payload_length; + assert(send_len < sizeof(tcp_buffer)); + u8 *send_buffer = tcp_buffer; memcpy(send_buffer, &header, sizeof(header)); memcpy(send_buffer + sizeof(header), payload, payload_length); -- cgit v1.2.3