1 /* 2 * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 #ifndef NET_DCSCTP_SOCKET_DCSCTP_SOCKET_H_ 11 #define NET_DCSCTP_SOCKET_DCSCTP_SOCKET_H_ 12 13 #include <cstdint> 14 #include <memory> 15 #include <string> 16 #include <utility> 17 18 #include "absl/strings/string_view.h" 19 #include "api/array_view.h" 20 #include "api/sequence_checker.h" 21 #include "net/dcsctp/packet/chunk/abort_chunk.h" 22 #include "net/dcsctp/packet/chunk/chunk.h" 23 #include "net/dcsctp/packet/chunk/cookie_ack_chunk.h" 24 #include "net/dcsctp/packet/chunk/cookie_echo_chunk.h" 25 #include "net/dcsctp/packet/chunk/data_chunk.h" 26 #include "net/dcsctp/packet/chunk/data_common.h" 27 #include "net/dcsctp/packet/chunk/error_chunk.h" 28 #include "net/dcsctp/packet/chunk/forward_tsn_chunk.h" 29 #include "net/dcsctp/packet/chunk/forward_tsn_common.h" 30 #include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h" 31 #include "net/dcsctp/packet/chunk/heartbeat_request_chunk.h" 32 #include "net/dcsctp/packet/chunk/idata_chunk.h" 33 #include "net/dcsctp/packet/chunk/iforward_tsn_chunk.h" 34 #include "net/dcsctp/packet/chunk/init_ack_chunk.h" 35 #include "net/dcsctp/packet/chunk/init_chunk.h" 36 #include "net/dcsctp/packet/chunk/reconfig_chunk.h" 37 #include "net/dcsctp/packet/chunk/sack_chunk.h" 38 #include "net/dcsctp/packet/chunk/shutdown_ack_chunk.h" 39 #include "net/dcsctp/packet/chunk/shutdown_chunk.h" 40 #include "net/dcsctp/packet/chunk/shutdown_complete_chunk.h" 41 #include "net/dcsctp/packet/data.h" 42 #include "net/dcsctp/packet/sctp_packet.h" 43 #include "net/dcsctp/public/dcsctp_message.h" 44 #include "net/dcsctp/public/dcsctp_options.h" 45 #include "net/dcsctp/public/dcsctp_socket.h" 46 #include "net/dcsctp/public/packet_observer.h" 47 #include "net/dcsctp/rx/data_tracker.h" 48 #include "net/dcsctp/rx/reassembly_queue.h" 49 #include "net/dcsctp/socket/callback_deferrer.h" 50 #include "net/dcsctp/socket/packet_sender.h" 51 #include "net/dcsctp/socket/state_cookie.h" 52 #include "net/dcsctp/socket/transmission_control_block.h" 53 #include "net/dcsctp/timer/timer.h" 54 #include "net/dcsctp/tx/retransmission_error_counter.h" 55 #include "net/dcsctp/tx/retransmission_queue.h" 56 #include "net/dcsctp/tx/retransmission_timeout.h" 57 #include "net/dcsctp/tx/rr_send_queue.h" 58 59 namespace dcsctp { 60 61 // DcSctpSocket represents a single SCTP socket, to be used over DTLS. 62 // 63 // Every dcSCTP is completely isolated from any other socket. 64 // 65 // This class manages all packet and chunk dispatching and mainly handles the 66 // connection sequences (connect, close, shutdown, etc) as well as managing 67 // the Transmission Control Block (tcb). 68 // 69 // This class is thread-compatible. 70 class DcSctpSocket : public DcSctpSocketInterface { 71 public: 72 // Instantiates a DcSctpSocket, which interacts with the world through the 73 // `callbacks` interface and is configured using `options`. 74 // 75 // For debugging, `log_prefix` will prefix all debug logs, and a 76 // `packet_observer` can be attached to e.g. dump sent and received packets. 77 DcSctpSocket(absl::string_view log_prefix, 78 DcSctpSocketCallbacks& callbacks, 79 std::unique_ptr<PacketObserver> packet_observer, 80 const DcSctpOptions& options); 81 82 DcSctpSocket(const DcSctpSocket&) = delete; 83 DcSctpSocket& operator=(const DcSctpSocket&) = delete; 84 85 // Implementation of `DcSctpSocketInterface`. 86 void ReceivePacket(rtc::ArrayView<const uint8_t> data) override; 87 void HandleTimeout(TimeoutID timeout_id) override; 88 void Connect() override; 89 void RestoreFromState(const DcSctpSocketHandoverState& state) override; 90 void Shutdown() override; 91 void Close() override; 92 SendStatus Send(DcSctpMessage message, 93 const SendOptions& send_options) override; 94 ResetStreamsStatus ResetStreams( 95 rtc::ArrayView<const StreamID> outgoing_streams) override; 96 SocketState state() const override; options()97 const DcSctpOptions& options() const override { return options_; } 98 void SetMaxMessageSize(size_t max_message_size) override; 99 void SetStreamPriority(StreamID stream_id, StreamPriority priority) override; 100 StreamPriority GetStreamPriority(StreamID stream_id) const override; 101 size_t buffered_amount(StreamID stream_id) const override; 102 size_t buffered_amount_low_threshold(StreamID stream_id) const override; 103 void SetBufferedAmountLowThreshold(StreamID stream_id, size_t bytes) override; 104 absl::optional<Metrics> GetMetrics() const override; 105 HandoverReadinessStatus GetHandoverReadiness() const override; 106 absl::optional<DcSctpSocketHandoverState> GetHandoverStateAndClose() override; peer_implementation()107 SctpImplementation peer_implementation() const override { 108 return metrics_.peer_implementation; 109 } 110 // Returns this socket's verification tag, or zero if not yet connected. verification_tag()111 VerificationTag verification_tag() const { 112 return tcb_ != nullptr ? tcb_->my_verification_tag() : VerificationTag(0); 113 } 114 115 private: 116 // Parameter proposals valid during the connect phase. 117 struct ConnectParameters { 118 TSN initial_tsn = TSN(0); 119 VerificationTag verification_tag = VerificationTag(0); 120 }; 121 122 // Detailed state (separate from SocketState, which is the public state). 123 enum class State { 124 kClosed, 125 kCookieWait, 126 // TCB valid in these: 127 kCookieEchoed, 128 kEstablished, 129 kShutdownPending, 130 kShutdownSent, 131 kShutdownReceived, 132 kShutdownAckSent, 133 }; 134 135 // Returns the log prefix used for debug logging. 136 std::string log_prefix() const; 137 138 bool IsConsistent() const; 139 static constexpr absl::string_view ToString(DcSctpSocket::State state); 140 141 void CreateTransmissionControlBlock(const Capabilities& capabilities, 142 VerificationTag my_verification_tag, 143 TSN my_initial_tsn, 144 VerificationTag peer_verification_tag, 145 TSN peer_initial_tsn, 146 size_t a_rwnd, 147 TieTag tie_tag); 148 149 // Changes the socket state, given a `reason` (for debugging/logging). 150 void SetState(State state, absl::string_view reason); 151 // Fills in `connect_params` with random verification tag and initial TSN. 152 void MakeConnectionParameters(); 153 // Closes the association. Note that the TCB will not be valid past this call. 154 void InternalClose(ErrorKind error, absl::string_view message); 155 // Closes the association, because of too many retransmission errors. 156 void CloseConnectionBecauseOfTooManyTransmissionErrors(); 157 // Timer expiration handlers 158 absl::optional<DurationMs> OnInitTimerExpiry(); 159 absl::optional<DurationMs> OnCookieTimerExpiry(); 160 absl::optional<DurationMs> OnShutdownTimerExpiry(); 161 void OnSentPacket(rtc::ArrayView<const uint8_t> packet, 162 SendPacketStatus status); 163 // Sends SHUTDOWN or SHUTDOWN-ACK if the socket is shutting down and if all 164 // outstanding data has been acknowledged. 165 void MaybeSendShutdownOrAck(); 166 // If the socket is shutting down, responds SHUTDOWN to any incoming DATA. 167 void MaybeSendShutdownOnPacketReceived(const SctpPacket& packet); 168 // If there are streams pending to be reset, send a request to reset them. 169 void MaybeSendResetStreamsRequest(); 170 // Sends a INIT chunk. 171 void SendInit(); 172 // Sends a SHUTDOWN chunk. 173 void SendShutdown(); 174 // Sends a SHUTDOWN-ACK chunk. 175 void SendShutdownAck(); 176 // Validates the SCTP packet, as a whole - not the validity of individual 177 // chunks within it, as that's done in the different chunk handlers. 178 bool ValidatePacket(const SctpPacket& packet); 179 // Parses `payload`, which is a serialized packet that is just going to be 180 // sent and prints all chunks. 181 void DebugPrintOutgoing(rtc::ArrayView<const uint8_t> payload); 182 // Called whenever there may be reassembled messages, and delivers those. 183 void DeliverReassembledMessages(); 184 // Returns true if there is a TCB, and false otherwise (and reports an error). 185 bool ValidateHasTCB(); 186 187 // Returns true if the parsing of a chunk of type `T` succeeded. If it didn't, 188 // it reports an error and returns false. 189 template <class T> ValidateParseSuccess(const absl::optional<T> & c)190 bool ValidateParseSuccess(const absl::optional<T>& c) { 191 if (c.has_value()) { 192 return true; 193 } 194 195 ReportFailedToParseChunk(T::kType); 196 return false; 197 } 198 199 // Reports failing to have parsed a chunk with the provided `chunk_type`. 200 void ReportFailedToParseChunk(int chunk_type); 201 // Called when unknown chunks are received. May report an error. 202 bool HandleUnrecognizedChunk(const SctpPacket::ChunkDescriptor& descriptor); 203 204 // Will dispatch more specific chunk handlers. 205 bool Dispatch(const CommonHeader& header, 206 const SctpPacket::ChunkDescriptor& descriptor); 207 // Handles incoming DATA chunks. 208 void HandleData(const CommonHeader& header, 209 const SctpPacket::ChunkDescriptor& descriptor); 210 // Handles incoming I-DATA chunks. 211 void HandleIData(const CommonHeader& header, 212 const SctpPacket::ChunkDescriptor& descriptor); 213 // Common handler for DATA and I-DATA chunks. 214 void HandleDataCommon(AnyDataChunk& chunk); 215 // Handles incoming INIT chunks. 216 void HandleInit(const CommonHeader& header, 217 const SctpPacket::ChunkDescriptor& descriptor); 218 // Handles incoming INIT-ACK chunks. 219 void HandleInitAck(const CommonHeader& header, 220 const SctpPacket::ChunkDescriptor& descriptor); 221 // Handles incoming SACK chunks. 222 void HandleSack(const CommonHeader& header, 223 const SctpPacket::ChunkDescriptor& descriptor); 224 // Handles incoming HEARTBEAT chunks. 225 void HandleHeartbeatRequest(const CommonHeader& header, 226 const SctpPacket::ChunkDescriptor& descriptor); 227 // Handles incoming HEARTBEAT-ACK chunks. 228 void HandleHeartbeatAck(const CommonHeader& header, 229 const SctpPacket::ChunkDescriptor& descriptor); 230 // Handles incoming ABORT chunks. 231 void HandleAbort(const CommonHeader& header, 232 const SctpPacket::ChunkDescriptor& descriptor); 233 // Handles incoming ERROR chunks. 234 void HandleError(const CommonHeader& header, 235 const SctpPacket::ChunkDescriptor& descriptor); 236 // Handles incoming COOKIE-ECHO chunks. 237 void HandleCookieEcho(const CommonHeader& header, 238 const SctpPacket::ChunkDescriptor& descriptor); 239 // Handles receiving COOKIE-ECHO when there already is a TCB. The return value 240 // indicates if the processing should continue. 241 bool HandleCookieEchoWithTCB(const CommonHeader& header, 242 const StateCookie& cookie); 243 // Handles incoming COOKIE-ACK chunks. 244 void HandleCookieAck(const CommonHeader& header, 245 const SctpPacket::ChunkDescriptor& descriptor); 246 // Handles incoming SHUTDOWN chunks. 247 void HandleShutdown(const CommonHeader& header, 248 const SctpPacket::ChunkDescriptor& descriptor); 249 // Handles incoming SHUTDOWN-ACK chunks. 250 void HandleShutdownAck(const CommonHeader& header, 251 const SctpPacket::ChunkDescriptor& descriptor); 252 // Handles incoming FORWARD-TSN chunks. 253 void HandleForwardTsn(const CommonHeader& header, 254 const SctpPacket::ChunkDescriptor& descriptor); 255 // Handles incoming I-FORWARD-TSN chunks. 256 void HandleIForwardTsn(const CommonHeader& header, 257 const SctpPacket::ChunkDescriptor& descriptor); 258 // Handles incoming RE-CONFIG chunks. 259 void HandleReconfig(const CommonHeader& header, 260 const SctpPacket::ChunkDescriptor& descriptor); 261 // Common handled for FORWARD-TSN/I-FORWARD-TSN. 262 void HandleForwardTsnCommon(const AnyForwardTsnChunk& chunk); 263 // Handles incoming SHUTDOWN-COMPLETE chunks 264 void HandleShutdownComplete(const CommonHeader& header, 265 const SctpPacket::ChunkDescriptor& descriptor); 266 267 const std::string log_prefix_; 268 const std::unique_ptr<PacketObserver> packet_observer_; 269 RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker thread_checker_; 270 Metrics metrics_; 271 DcSctpOptions options_; 272 273 // Enqueues callbacks and dispatches them just before returning to the caller. 274 CallbackDeferrer callbacks_; 275 276 TimerManager timer_manager_; 277 const std::unique_ptr<Timer> t1_init_; 278 const std::unique_ptr<Timer> t1_cookie_; 279 const std::unique_ptr<Timer> t2_shutdown_; 280 281 // Packets that failed to be sent, but should be retried. 282 PacketSender packet_sender_; 283 284 // The actual SendQueue implementation. As data can be sent on a socket before 285 // the connection is established, this component is not in the TCB. 286 RRSendQueue send_queue_; 287 288 // Contains verification tag and initial TSN between having sent the INIT 289 // until the connection is established (there is no TCB at this point). 290 ConnectParameters connect_params_; 291 // The socket state. 292 State state_ = State::kClosed; 293 // If the connection is established, contains a transmission control block. 294 std::unique_ptr<TransmissionControlBlock> tcb_; 295 }; 296 } // namespace dcsctp 297 298 #endif // NET_DCSCTP_SOCKET_DCSCTP_SOCKET_H_ 299