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_PUBLIC_DCSCTP_HANDOVER_STATE_H_ 11 #define NET_DCSCTP_PUBLIC_DCSCTP_HANDOVER_STATE_H_ 12 13 #include <cstdint> 14 #include <string> 15 #include <vector> 16 17 #include "rtc_base/strong_alias.h" 18 19 namespace dcsctp { 20 21 // Stores state snapshot of a dcSCTP socket. The snapshot can be used to 22 // recreate the socket - possibly in another process. This state should be 23 // treaded as opaque - the calling client should not inspect or alter it except 24 // for serialization. Serialization is not provided by dcSCTP. If needed it has 25 // to be implemented in the calling client. 26 struct DcSctpSocketHandoverState { 27 enum class SocketState { 28 kClosed, 29 kConnected, 30 }; 31 SocketState socket_state = SocketState::kClosed; 32 33 uint32_t my_verification_tag = 0; 34 uint32_t my_initial_tsn = 0; 35 uint32_t peer_verification_tag = 0; 36 uint32_t peer_initial_tsn = 0; 37 uint64_t tie_tag = 0; 38 39 struct Capabilities { 40 bool partial_reliability = false; 41 bool message_interleaving = false; 42 bool reconfig = false; 43 uint16_t negotiated_maximum_incoming_streams = 0; 44 uint16_t negotiated_maximum_outgoing_streams = 0; 45 }; 46 Capabilities capabilities; 47 48 struct OutgoingStream { 49 uint32_t id = 0; 50 uint32_t next_ssn = 0; 51 uint32_t next_unordered_mid = 0; 52 uint32_t next_ordered_mid = 0; 53 uint16_t priority = 0; 54 }; 55 struct Transmission { 56 uint32_t next_tsn = 0; 57 uint32_t next_reset_req_sn = 0; 58 uint32_t cwnd = 0; 59 uint32_t rwnd = 0; 60 uint32_t ssthresh = 0; 61 uint32_t partial_bytes_acked = 0; 62 std::vector<OutgoingStream> streams; 63 }; 64 Transmission tx; 65 66 struct OrderedStream { 67 uint32_t id = 0; 68 uint32_t next_ssn = 0; 69 }; 70 struct UnorderedStream { 71 uint32_t id = 0; 72 }; 73 struct Receive { 74 bool seen_packet = false; 75 uint32_t last_cumulative_acked_tsn = 0; 76 uint32_t last_assembled_tsn = 0; 77 uint32_t last_completed_deferred_reset_req_sn = 0; 78 uint32_t last_completed_reset_req_sn = 0; 79 std::vector<OrderedStream> ordered_streams; 80 std::vector<UnorderedStream> unordered_streams; 81 }; 82 Receive rx; 83 }; 84 85 // A list of possible reasons for a socket to be not ready for handover. 86 enum class HandoverUnreadinessReason : uint32_t { 87 kWrongConnectionState = 1, 88 kSendQueueNotEmpty = 2, 89 kPendingStreamResetRequest = 4, 90 kDataTrackerTsnBlocksPending = 8, 91 kPendingStreamReset = 16, 92 kReassemblyQueueDeliveredTSNsGap = 32, 93 kStreamResetDeferred = 64, 94 kOrderedStreamHasUnassembledChunks = 128, 95 kUnorderedStreamHasUnassembledChunks = 256, 96 kRetransmissionQueueOutstandingData = 512, 97 kRetransmissionQueueFastRecovery = 1024, 98 kRetransmissionQueueNotEmpty = 2048, 99 kMax = kRetransmissionQueueNotEmpty, 100 }; 101 102 // Return value of `DcSctpSocketInterface::GetHandoverReadiness`. Set of 103 // `HandoverUnreadinessReason` bits. When no bit is set, the socket is in the 104 // state in which a snapshot of the state can be made by 105 // `GetHandoverStateAndClose()`. 106 class HandoverReadinessStatus 107 : public webrtc::StrongAlias<class HandoverReadinessStatusTag, uint32_t> { 108 public: 109 // Constructs an empty `HandoverReadinessStatus` which represents ready state. HandoverReadinessStatus()110 constexpr HandoverReadinessStatus() 111 : webrtc::StrongAlias<class HandoverReadinessStatusTag, uint32_t>(0) {} 112 // Constructs status object that contains a single reason for not being 113 // handover ready. HandoverReadinessStatus(HandoverUnreadinessReason reason)114 constexpr explicit HandoverReadinessStatus(HandoverUnreadinessReason reason) 115 : webrtc::StrongAlias<class HandoverReadinessStatusTag, uint32_t>( 116 static_cast<uint32_t>(reason)) {} 117 118 // Convenience methods IsReady()119 constexpr bool IsReady() const { return value() == 0; } Contains(HandoverUnreadinessReason reason)120 constexpr bool Contains(HandoverUnreadinessReason reason) const { 121 return value() & static_cast<uint32_t>(reason); 122 } Add(HandoverUnreadinessReason reason)123 HandoverReadinessStatus& Add(HandoverUnreadinessReason reason) { 124 return Add(HandoverReadinessStatus(reason)); 125 } Add(HandoverReadinessStatus status)126 HandoverReadinessStatus& Add(HandoverReadinessStatus status) { 127 value() |= status.value(); 128 return *this; 129 } 130 std::string ToString() const; 131 }; 132 133 } // namespace dcsctp 134 135 #endif // NET_DCSCTP_PUBLIC_DCSCTP_HANDOVER_STATE_H_ 136