TCPSocket.h 7.5 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 <AK/Time.h>
  12. #include <Kernel/Library/LockWeakPtr.h>
  13. #include <Kernel/Locking/MutexProtected.h>
  14. #include <Kernel/Net/IPv4Socket.h>
  15. namespace Kernel {
  16. class TCPSocket final : public IPv4Socket {
  17. public:
  18. static void for_each(Function<void(TCPSocket const&)>);
  19. static ErrorOr<void> try_for_each(Function<ErrorOr<void>(TCPSocket const&)>);
  20. static ErrorOr<NonnullRefPtr<TCPSocket>> try_create(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer);
  21. virtual ~TCPSocket() override;
  22. virtual bool unref() const override;
  23. enum class Direction {
  24. Unspecified,
  25. Outgoing,
  26. Incoming,
  27. Passive,
  28. };
  29. static StringView to_string(Direction direction)
  30. {
  31. switch (direction) {
  32. case Direction::Unspecified:
  33. return "Unspecified"sv;
  34. case Direction::Outgoing:
  35. return "Outgoing"sv;
  36. case Direction::Incoming:
  37. return "Incoming"sv;
  38. case Direction::Passive:
  39. return "Passive"sv;
  40. default:
  41. return "None"sv;
  42. }
  43. }
  44. enum class State {
  45. Closed,
  46. Listen,
  47. SynSent,
  48. SynReceived,
  49. Established,
  50. CloseWait,
  51. LastAck,
  52. FinWait1,
  53. FinWait2,
  54. Closing,
  55. TimeWait,
  56. };
  57. static StringView to_string(State state)
  58. {
  59. switch (state) {
  60. case State::Closed:
  61. return "Closed"sv;
  62. case State::Listen:
  63. return "Listen"sv;
  64. case State::SynSent:
  65. return "SynSent"sv;
  66. case State::SynReceived:
  67. return "SynReceived"sv;
  68. case State::Established:
  69. return "Established"sv;
  70. case State::CloseWait:
  71. return "CloseWait"sv;
  72. case State::LastAck:
  73. return "LastAck"sv;
  74. case State::FinWait1:
  75. return "FinWait1"sv;
  76. case State::FinWait2:
  77. return "FinWait2"sv;
  78. case State::Closing:
  79. return "Closing"sv;
  80. case State::TimeWait:
  81. return "TimeWait"sv;
  82. default:
  83. return "None"sv;
  84. }
  85. }
  86. enum class Error {
  87. None,
  88. FINDuringConnect,
  89. RSTDuringConnect,
  90. UnexpectedFlagsDuringConnect,
  91. RetransmitTimeout,
  92. };
  93. static StringView to_string(Error error)
  94. {
  95. switch (error) {
  96. case Error::None:
  97. return "None"sv;
  98. case Error::FINDuringConnect:
  99. return "FINDuringConnect"sv;
  100. case Error::RSTDuringConnect:
  101. return "RSTDuringConnect"sv;
  102. case Error::UnexpectedFlagsDuringConnect:
  103. return "UnexpectedFlagsDuringConnect"sv;
  104. default:
  105. return "Invalid"sv;
  106. }
  107. }
  108. State state() const { return m_state; }
  109. void set_state(State state);
  110. Direction direction() const { return m_direction; }
  111. bool has_error() const { return m_error != Error::None; }
  112. Error error() const { return m_error; }
  113. void set_error(Error error) { m_error = error; }
  114. void set_ack_number(u32 n) { m_ack_number = n; }
  115. void set_sequence_number(u32 n) { m_sequence_number = n; }
  116. u32 ack_number() const { return m_ack_number; }
  117. u32 sequence_number() const { return m_sequence_number; }
  118. u32 packets_in() const { return m_packets_in; }
  119. u32 bytes_in() const { return m_bytes_in; }
  120. u32 packets_out() const { return m_packets_out; }
  121. u32 bytes_out() const { return m_bytes_out; }
  122. // FIXME: Make this configurable?
  123. static constexpr u32 maximum_duplicate_acks = 5;
  124. void set_duplicate_acks(u32 acks) { m_duplicate_acks = acks; }
  125. u32 duplicate_acks() const { return m_duplicate_acks; }
  126. ErrorOr<void> send_ack(bool allow_duplicate = false);
  127. ErrorOr<void> send_tcp_packet(u16 flags, UserOrKernelBuffer const* = nullptr, size_t = 0, RoutingDecision* = nullptr);
  128. void receive_tcp_packet(TCPPacket const&, u16 size);
  129. bool should_delay_next_ack() const;
  130. static MutexProtected<HashMap<IPv4SocketTuple, TCPSocket*>>& sockets_by_tuple();
  131. static RefPtr<TCPSocket> from_tuple(IPv4SocketTuple const& tuple);
  132. static MutexProtected<HashMap<IPv4SocketTuple, RefPtr<TCPSocket>>>& closing_sockets();
  133. ErrorOr<NonnullRefPtr<TCPSocket>> try_create_client(IPv4Address const& local_address, u16 local_port, IPv4Address const& peer_address, u16 peer_port);
  134. void set_originator(TCPSocket& originator) { m_originator = originator; }
  135. bool has_originator() { return !!m_originator; }
  136. void release_to_originator();
  137. void release_for_accept(NonnullRefPtr<TCPSocket>);
  138. void retransmit_packets();
  139. virtual ErrorOr<void> close() override;
  140. virtual bool can_write(OpenFileDescription const&, u64) const override;
  141. static NetworkOrdered<u16> compute_tcp_checksum(IPv4Address const& source, IPv4Address const& destination, TCPPacket const&, u16 payload_size);
  142. protected:
  143. void set_direction(Direction direction) { m_direction = direction; }
  144. private:
  145. explicit TCPSocket(int protocol, NonnullOwnPtr<DoubleBuffer> receive_buffer, NonnullOwnPtr<KBuffer> scratch_buffer);
  146. virtual StringView class_name() const override { return "TCPSocket"sv; }
  147. virtual void shut_down_for_writing() override;
  148. virtual ErrorOr<size_t> protocol_receive(ReadonlyBytes raw_ipv4_packet, UserOrKernelBuffer& buffer, size_t buffer_size, int flags) override;
  149. virtual ErrorOr<size_t> protocol_send(UserOrKernelBuffer const&, size_t) override;
  150. virtual ErrorOr<void> protocol_connect(OpenFileDescription&) 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() 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. MonotonicTime m_last_ack_sent_time;
  184. // FIXME: Make this configurable (sysctl)
  185. static constexpr u32 maximum_retransmits = 5;
  186. MonotonicTime 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. }