#pragma once #include #include #include #include #include #include namespace Kernel { struct UDPHeader { BAN::NetworkEndian src_port; BAN::NetworkEndian dst_port; BAN::NetworkEndian length; BAN::NetworkEndian checksum; }; static_assert(sizeof(UDPHeader) == 8); class UDPSocket final : public NetworkSocket { public: static BAN::ErrorOr> create(NetworkLayer&, ino_t, const TmpInodeInfo&); virtual NetworkProtocol protocol() const override { return NetworkProtocol::UDP; } virtual size_t protocol_header_size() const override { return sizeof(UDPHeader); } virtual void add_protocol_header(BAN::ByteSpan packet, uint16_t dst_port, PseudoHeader) override; protected: virtual void add_packet(BAN::ConstByteSpan, BAN::IPv4Address sender_addr, uint16_t sender_port) override; virtual BAN::ErrorOr read_packet(BAN::ByteSpan, sockaddr_in* sender_address) override; private: UDPSocket(NetworkLayer&, ino_t, const TmpInodeInfo&); struct PacketInfo { BAN::IPv4Address sender_addr; uint16_t sender_port; size_t packet_size; }; private: static constexpr size_t packet_buffer_size = 10 * PAGE_SIZE; BAN::UniqPtr m_packet_buffer; BAN::CircularQueue m_packets; size_t m_packet_total_size { 0 }; SpinLock m_packet_lock; Semaphore m_packet_semaphore; friend class BAN::RefPtr; }; }