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:
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user