TCPSocket.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Error.h>
  8. #include <AK/Function.h>
  9. #include <AK/HashMap.h>
  10. #include <AK/SinglyLinkedList.h>
  11. #include <Kernel/Library/LockWeakPtr.h>
  12. #include <Kernel/Locking/MutexProtected.h>
  13. #include <Kernel/Net/IPv4Socket.h>
  14. namespace Kernel {
  15. class TCPSocket final : public IPv4Socket {
  16. public:
  17. static void for_each(Function<void(TCPSocket const&)>);
  18. static ErrorOr<void> try_for_each(Function<ErrorOr<void>(TCPSocket const&)>);
  19. static ErrorOr<NonnullRefPtr<TCPSocket>> try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer);
  20. virtual ~TCPSocket() override;
  21. virtual bool unref() const override;
  22. enum class Direction {
  23. Unspecified,
  24. Outgoing,
  25. Incoming,
  26. Passive,
  27. };
  28. static StringView to_string(Direction direction)
  29. {
  30. switch (direction) {
  31. case Direction::Unspecified:
  32. return "Unspecified"sv;
  33. case Direction::Outgoing:
  34. return "Outgoing"sv;
  35. case Direction::Incoming:
  36. return "Incoming"sv;
  37. case Direction::Passive:
  38. return "Passive"sv;
  39. default:
  40. return "None"sv;
  41. }
  42. }
  43. enum class State {
  44. Closed,
  45. Listen,
  46. SynSent,
  47. SynReceived,
  48. Established,
  49. CloseWait,
  50. LastAck,
  51. FinWait1,
  52. FinWait2,
  53. Closing,
  54. TimeWait,
  55. };
  56. static StringView to_string(State state)
  57. {
  58. switch (state) {
  59. case State::Closed:
  60. return "Closed"sv;
  61. case State::Listen:
  62. return "Listen"sv;
  63. case State::SynSent:
  64. return "SynSent"sv;
  65. case State::SynReceived:
  66. return "SynReceived"sv;
  67. case State::Established:
  68. return "Established"sv;
  69. case State::CloseWait:
  70. return "CloseWait"sv;
  71. case State::LastAck:
  72. return "LastAck"sv;
  73. case State::FinWait1:
  74. return "FinWait1"sv;
  75. case State::FinWait2:
  76. return "FinWait2"sv;
  77. case State::Closing:
  78. return "Closing"sv;
  79. case State::TimeWait:
  80. return "TimeWait"sv;
  81. default:
  82. return "None"sv;
  83. }
  84. }
  85. enum class Error {
  86. None,
  87. FINDuringConnect,
  88. RSTDuringConnect,
  89. UnexpectedFlagsDuringConnect,
  90. RetransmitTimeout,
  91. };
  92. static StringView to_string(Error error)
  93. {
  94. switch (error) {
  95. case Error::None:
  96. return "None"sv;
  97. case Error::FINDuringConnect:
  98. return "FINDuringConnect"sv;
  99. case Error::RSTDuringConnect:
  100. return "RSTDuringConnect"sv;
  101. case Error::UnexpectedFlagsDuringConnect:
  102. return "UnexpectedFlagsDuringConnect"sv;
  103. default:
  104. return "Invalid"sv;
  105. }
  106. }
  107. State state() const { return m_state; }
  108. void set_state(State state);
  109. Direction direction() const { return m_direction; }
  110. bool has_error() const { return m_error != Error::None; }
  111. Error error() const { return m_error; }
  112. void set_error(Error error) { m_error = error; }
  113. void set_ack_number(u32 n) { m_ack_number = n; }
  114. void set_sequence_number(u32 n) { m_sequence_number = n; }
  115. u32 ack_number() const { return m_ack_number; }
  116. u32 sequence_number() const { return m_sequence_number; }
  117. u32 packets_in() const { return m_packets_in; }
  118. u32 bytes_in() const { return m_bytes_in; }
  119. u32 packets_out() const { return m_packets_out; }
  120. u32 bytes_out() const { return m_bytes_out; }
  121. // FIXME: Make this configurable?
  122. static constexpr u32 maximum_duplicate_acks = 5;
  123. void set_duplicate_acks(u32 acks) { m_duplicate_acks = acks; }
  124. u32 duplicate_acks() const { return m_duplicate_acks; }
  125. ErrorOr<void> send_ack(bool allow_duplicate = false);
  126. ErrorOr<void> send_tcp_packet(u16 flags, UserOrKernelBuffer const* = nullptr, size_t = 0, RoutingDecision* = nullptr);
  127. void receive_tcp_packet(TCPPacket const&, u16 size);
  128. bool should_delay_next_ack() const;
  129. static MutexProtected<HashMap<IPv4SocketTuple, TCPSocket*>>& sockets_by_tuple();
  130. static RefPtr<TCPSocket> from_tuple(IPv4SocketTuple const& tuple);
  131. static MutexProtected<HashMap<IPv4SocketTuple, RefPtr<TCPSocket>>>& closing_sockets();
  132. ErrorOr<NonnullRefPtr<TCPSocket>> try_create_client(IPv4Address const& local_address, u16 local_port, IPv4Address const& peer_address, u16 peer_port);
  133. void set_originator(TCPSocket& originator) { m_originator = originator; }
  134. bool has_originator() { return !!m_originator; }
  135. void release_to_originator();
  136. void release_for_accept(NonnullRefPtr<TCPSocket>);
  137. void retransmit_packets();
  138. virtual ErrorOr<void> close() override;
  139. virtual bool can_write(OpenFileDescription const&, u64) const override;
  140. static NetworkOrdered<u16> compute_tcp_checksum(IPv4Address const& source, IPv4Address const& destination, TCPPacket const&, u16 payload_size);
  141. protected:
  142. void set_direction(Direction direction) { m_direction = direction; }
  143. private:
  144. explicit TCPSocket(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer, NonnullOwnPtr<KBuffer> scratch_buffer);
  145. virtual StringView class_name() const override { return "TCPSocket"sv; }
  146. virtual void shut_down_for_writing() override;
  147. virtual ErrorOr<size_t> protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, int flags) override;
  148. virtual ErrorOr<size_t> protocol_send(UserOrKernelBuffer const&, size_t) override;
  149. virtual ErrorOr<void> protocol_connect(OpenFileDescription&) override;
  150. virtual ErrorOr<u16> protocol_allocate_local_port() override;
  151. virtual ErrorOr<size_t> protocol_size(ReadonlyBytes raw_ipv4_packet) override;
  152. virtual bool protocol_is_disconnected() const override;
  153. virtual ErrorOr<void> protocol_bind() override;
  154. virtual ErrorOr<void> protocol_listen(bool did_allocate_port) override;
  155. void enqueue_for_retransmit();
  156. void dequeue_for_retransmit();
  157. LockWeakPtr<TCPSocket> m_originator;
  158. HashMap<IPv4SocketTuple, NonnullRefPtr<TCPSocket>> m_pending_release_for_accept;
  159. Direction m_direction { Direction::Unspecified };
  160. Error m_error { Error::None };
  161. SpinlockProtected<RefPtr<NetworkAdapter>, LockRank::None> m_adapter;
  162. u32 m_sequence_number { 0 };
  163. u32 m_ack_number { 0 };
  164. State m_state { State::Closed };
  165. u32 m_packets_in { 0 };
  166. u32 m_bytes_in { 0 };
  167. u32 m_packets_out { 0 };
  168. u32 m_bytes_out { 0 };
  169. struct OutgoingPacket {
  170. u32 ack_number { 0 };
  171. RefPtr<PacketWithTimestamp> buffer;
  172. size_t ipv4_payload_offset;
  173. LockWeakPtr<NetworkAdapter> adapter;
  174. int tx_counter { 0 };
  175. };
  176. struct UnackedPackets {
  177. SinglyLinkedList<OutgoingPacket> packets;
  178. size_t size { 0 };
  179. };
  180. MutexProtected<UnackedPackets> m_unacked_packets;
  181. u32 m_duplicate_acks { 0 };
  182. u32 m_last_ack_number_sent { 0 };
  183. UnixDateTime m_last_ack_sent_time;
  184. // FIXME: Make this configurable (sysctl)
  185. static constexpr u32 maximum_retransmits = 5;
  186. UnixDateTime m_last_retransmit_time;
  187. u32 m_retransmit_attempts { 0 };
  188. // Default to maximum window size. receive_tcp_packet() will update from the
  189. // peer's advertised window size.
  190. u32 m_send_window_size { 64 * KiB };
  191. IntrusiveListNode<TCPSocket> m_retransmit_list_node;
  192. public:
  193. using RetransmitList = IntrusiveList<&TCPSocket::m_retransmit_list_node>;
  194. static MutexProtected<TCPSocket::RetransmitList>& sockets_for_retransmit();
  195. };
  196. }