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 #include "net/dcsctp/socket/state_cookie.h" 11 12 #include <cstdint> 13 #include <vector> 14 15 #include "absl/types/optional.h" 16 #include "api/array_view.h" 17 #include "net/dcsctp/packet/bounded_byte_reader.h" 18 #include "net/dcsctp/packet/bounded_byte_writer.h" 19 #include "net/dcsctp/socket/capabilities.h" 20 #include "rtc_base/logging.h" 21 22 namespace dcsctp { 23 24 // Magic values, which the state cookie is prefixed with. 25 constexpr uint32_t kMagic1 = 1684230979; 26 constexpr uint32_t kMagic2 = 1414541360; 27 constexpr size_t StateCookie::kCookieSize; 28 Serialize()29std::vector<uint8_t> StateCookie::Serialize() { 30 std::vector<uint8_t> cookie; 31 cookie.resize(kCookieSize); 32 BoundedByteWriter<kCookieSize> buffer(cookie); 33 buffer.Store32<0>(kMagic1); 34 buffer.Store32<4>(kMagic2); 35 buffer.Store32<8>(*initiate_tag_); 36 buffer.Store32<12>(*initial_tsn_); 37 buffer.Store32<16>(a_rwnd_); 38 buffer.Store32<20>(static_cast<uint32_t>(*tie_tag_ >> 32)); 39 buffer.Store32<24>(static_cast<uint32_t>(*tie_tag_)); 40 buffer.Store8<28>(capabilities_.partial_reliability); 41 buffer.Store8<29>(capabilities_.message_interleaving); 42 buffer.Store8<30>(capabilities_.reconfig); 43 buffer.Store16<32>(capabilities_.negotiated_maximum_incoming_streams); 44 buffer.Store16<34>(capabilities_.negotiated_maximum_outgoing_streams); 45 return cookie; 46 } 47 Deserialize(rtc::ArrayView<const uint8_t> cookie)48absl::optional<StateCookie> StateCookie::Deserialize( 49 rtc::ArrayView<const uint8_t> cookie) { 50 if (cookie.size() != kCookieSize) { 51 RTC_DLOG(LS_WARNING) << "Invalid state cookie: " << cookie.size() 52 << " bytes"; 53 return absl::nullopt; 54 } 55 56 BoundedByteReader<kCookieSize> buffer(cookie); 57 uint32_t magic1 = buffer.Load32<0>(); 58 uint32_t magic2 = buffer.Load32<4>(); 59 if (magic1 != kMagic1 || magic2 != kMagic2) { 60 RTC_DLOG(LS_WARNING) << "Invalid state cookie; wrong magic"; 61 return absl::nullopt; 62 } 63 64 VerificationTag verification_tag(buffer.Load32<8>()); 65 TSN initial_tsn(buffer.Load32<12>()); 66 uint32_t a_rwnd = buffer.Load32<16>(); 67 uint32_t tie_tag_upper = buffer.Load32<20>(); 68 uint32_t tie_tag_lower = buffer.Load32<24>(); 69 TieTag tie_tag(static_cast<uint64_t>(tie_tag_upper) << 32 | 70 static_cast<uint64_t>(tie_tag_lower)); 71 Capabilities capabilities; 72 capabilities.partial_reliability = buffer.Load8<28>() != 0; 73 capabilities.message_interleaving = buffer.Load8<29>() != 0; 74 capabilities.reconfig = buffer.Load8<30>() != 0; 75 capabilities.negotiated_maximum_incoming_streams = buffer.Load16<32>(); 76 capabilities.negotiated_maximum_outgoing_streams = buffer.Load16<34>(); 77 78 return StateCookie(verification_tag, initial_tsn, a_rwnd, tie_tag, 79 capabilities); 80 } 81 82 } // namespace dcsctp 83