Kernel: Rewrite a lot of TCP code and implement TCP server sockets

TCP stack is now implemented much closer to spec
This commit is contained in:
2024-06-20 13:26:50 +03:00
parent 30fdc2198f
commit 4f0457a268
8 changed files with 484 additions and 336 deletions

View File

@@ -51,6 +51,7 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> sendto(NetworkSocket&, BAN::ConstByteSpan, const sockaddr*, socklen_t) override;
virtual SocketDomain domain() const override { return SocketDomain::INET ;}
virtual size_t header_size() const override { return sizeof(IPv4Header); }
private:

View File

@@ -15,6 +15,7 @@ namespace Kernel
static_assert(sizeof(PseudoHeader) == 12);
class NetworkSocket;
enum class SocketDomain;
enum class SocketType;
class NetworkLayer
@@ -29,6 +30,7 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> sendto(NetworkSocket&, BAN::ConstByteSpan, const sockaddr*, socklen_t) = 0;
virtual SocketDomain domain() const = 0;
virtual size_t header_size() const = 0;
protected:

View File

@@ -34,7 +34,7 @@ namespace Kernel
virtual void add_protocol_header(BAN::ByteSpan packet, uint16_t dst_port, PseudoHeader) = 0;
virtual NetworkProtocol protocol() const = 0;
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr_storage& sender) = 0;
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) = 0;
bool is_bound() const { return m_interface != nullptr; }

View File

@@ -1,6 +1,7 @@
#pragma once
#include <BAN/Endianness.h>
#include <BAN/Queue.h>
#include <kernel/Lock/Mutex.h>
#include <kernel/Memory/VirtualRange.h>
#include <kernel/Networking/NetworkInterface.h>
@@ -11,6 +12,18 @@
namespace Kernel
{
enum TCPFlags : uint8_t
{
FIN = 0x01,
SYN = 0x02,
RST = 0x04,
PSH = 0x08,
ACK = 0x10,
URG = 0x20,
ECE = 0x40,
CWR = 0x80,
};
struct TCPHeader
{
BAN::NetworkEndian<uint16_t> src_port { 0 };
@@ -19,14 +32,7 @@ namespace Kernel
BAN::NetworkEndian<uint32_t> ack_number { 0 };
uint8_t reserved : 4 { 0 };
uint8_t data_offset : 4 { 0 };
uint8_t fin : 1 { 0 };
uint8_t syn : 1 { 0 };
uint8_t rst : 1 { 0 };
uint8_t psh : 1 { 0 };
uint8_t ack : 1 { 0 };
uint8_t urg : 1 { 0 };
uint8_t ece : 1 { 0 };
uint8_t cwr : 1 { 0 };
uint8_t flags { };
BAN::NetworkEndian<uint16_t> window_size { 0 };
BAN::NetworkEndian<uint16_t> checksum { 0 };
BAN::NetworkEndian<uint16_t> urgent_pointer { 0 };
@@ -49,16 +55,18 @@ namespace Kernel
virtual void add_protocol_header(BAN::ByteSpan packet, uint16_t dst_port, PseudoHeader) override;
protected:
virtual BAN::ErrorOr<long> accept_impl(sockaddr*, socklen_t*) override;
virtual BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<void> listen_impl(int) override;
virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) override;
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) override;
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr_storage& sender) override;
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override;
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len) override;
virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan message, sockaddr* address, socklen_t* address_len) override;
virtual bool can_read_impl() const override { return m_recv_window.data_size; }
virtual bool can_write_impl() const override { return m_state == State::Established; }
virtual bool has_error_impl() const override { return m_state != State::Established && m_state != State::Listen && m_state != State::SynSent && m_state != State::SynReceived; }
virtual bool can_read_impl() const override;
virtual bool can_write_impl() const override;
virtual bool has_error_impl() const override { return false; }
private:
enum class State
@@ -105,6 +113,33 @@ namespace Kernel
BAN::UniqPtr<VirtualRange> buffer;
};
struct ConnectionInfo
{
sockaddr_storage address;
socklen_t address_len;
};
struct PendingConnection
{
ConnectionInfo target;
uint32_t target_start_seq;
};
struct ListenKey
{
ListenKey(const sockaddr* addr, socklen_t addr_len);
ListenKey(BAN::IPv4Address addr, uint16_t port)
: address(addr), port(port)
{}
bool operator==(const ListenKey& other) const;
BAN::IPv4Address address { 0 };
uint16_t port { 0 };
};
struct ListenKeyHash
{
BAN::hash_t operator()(ListenKey key) const;
};
private:
TCPSocket(NetworkLayer&, ino_t, const TmpInodeInfo&);
void process_task();
@@ -112,27 +147,35 @@ namespace Kernel
void start_close_sequence();
void set_connection_as_closed();
void remove_listen_child(BAN::RefPtr<TCPSocket>);
BAN::ErrorOr<size_t> return_with_maybe_zero();
private:
State m_state = State::Closed;
State m_next_state { State::Closed };
uint8_t m_next_flags { 0 };
Process* m_process { nullptr };
uint64_t m_time_wait_start_ms { 0 };
Mutex m_lock;
Semaphore m_semaphore;
BAN::Atomic<bool> m_should_ack { false };
Semaphore m_semaphore;
RecvWindowInfo m_recv_window;
SendWindowInfo m_send_window;
struct ConnectionInfo
{
sockaddr_storage address;
socklen_t address_len;
};
bool m_has_connected { false };
bool m_has_sent_zero { false };
BAN::Optional<ConnectionInfo> m_connection_info;
BAN::Queue<PendingConnection> m_pending_connections;
BAN::RefPtr<TCPSocket> m_listen_parent;
BAN::HashMap<ListenKey, BAN::RefPtr<TCPSocket>, ListenKeyHash> m_listen_children;
friend class BAN::RefPtr<TCPSocket>;
};
}

View File

@@ -31,7 +31,7 @@ namespace Kernel
virtual void add_protocol_header(BAN::ByteSpan packet, uint16_t dst_port, PseudoHeader) override;
protected:
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr_storage& sender) override;
virtual void receive_packet(BAN::ConstByteSpan, const sockaddr* sender, socklen_t sender_len) override;
virtual BAN::ErrorOr<void> bind_impl(const sockaddr* address, socklen_t address_len) override;
virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len) override;