From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- third_party/libwebrtc/p2p/base/stun_dictionary.h | 204 +++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 third_party/libwebrtc/p2p/base/stun_dictionary.h (limited to 'third_party/libwebrtc/p2p/base/stun_dictionary.h') diff --git a/third_party/libwebrtc/p2p/base/stun_dictionary.h b/third_party/libwebrtc/p2p/base/stun_dictionary.h new file mode 100644 index 0000000000..f93a1f151f --- /dev/null +++ b/third_party/libwebrtc/p2p/base/stun_dictionary.h @@ -0,0 +1,204 @@ +/* + * Copyright 2020 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef P2P_BASE_STUN_DICTIONARY_H_ +#define P2P_BASE_STUN_DICTIONARY_H_ + +#include +#include +#include +#include +#include + +#include "api/rtc_error.h" +#include "api/transport/stun.h" + +namespace cricket { + +// A StunDictionaryView is a dictionary of StunAttributes. +// - the StunAttributes can be read using the |Get|-methods. +// - the dictionary is updated by using the |ApplyDelta|-method. +// +// A StunDictionaryWriter is used to create |delta|s for the |ApplyDelta|-method +// - It keeps track of which updates has been applied at StunDictionaryView. +// - It optionally keeps a local StunDictionaryView contains modification made +// `locally` +// +// A pair StunDictionaryView(A)/StunDictionaryWriter(B) are linked so that +// modifications to B is transfered to A using the STUN_ATTR_GOOG_DELTA +// (StunByteStringAttribute) and the modification is ack:ed using +// STUN_ATTR_GOOG_DELTA_ACK (StunUInt64Attribute). +// +// Note: +// 1) It is possible to update one StunDictionaryView from multiple writers, +// but this only works of the different writers write disjoint keys (which +// is not checked/enforced by these classes). +// 2) The opposite, one writer updating multiple StunDictionaryView, is not +// possible. +class StunDictionaryView { + public: + // A reserved key used to transport the version number + static constexpr uint16_t kVersionKey = 0xFFFF; + + // A magic number used when transporting deltas. + static constexpr uint16_t kDeltaMagic = 0x7788; + + // The version number for the delta format. + static constexpr uint16_t kDeltaVersion = 0x1; + + // Gets the desired attribute value, or NULL if no such attribute type exists. + // The pointer returned is guaranteed to be valid until ApplyDelta is called. + const StunAddressAttribute* GetAddress(int key) const; + const StunUInt32Attribute* GetUInt32(int key) const; + const StunUInt64Attribute* GetUInt64(int key) const; + const StunByteStringAttribute* GetByteString(int key) const; + const StunUInt16ListAttribute* GetUInt16List(int key) const; + + bool empty() const { return attrs_.empty(); } + size_t size() const { return attrs_.size(); } + int bytes_stored() const { return bytes_stored_; } + void set_max_bytes_stored(int max_bytes_stored) { + max_bytes_stored_ = max_bytes_stored; + } + + // Apply a delta and return + // a pair with + // - StunUInt64Attribute to ack the |delta|. + // - vector of keys that was modified. + webrtc::RTCErrorOr< + std::pair, std::vector>> + ApplyDelta(const StunByteStringAttribute& delta); + + private: + friend class StunDictionaryWriter; + + const StunAttribute* GetOrNull( + int key, + absl::optional = absl::nullopt) const; + size_t GetLength(int key) const; + static webrtc::RTCErrorOr< + std::pair>>> + ParseDelta(const StunByteStringAttribute& delta); + + std::map> attrs_; + std::map version_per_key_; + + int max_bytes_stored_ = 16384; + int bytes_stored_ = 0; +}; + +class StunDictionaryWriter { + public: + StunDictionaryWriter() { + dictionary_ = std::make_unique(); + } + explicit StunDictionaryWriter( + std::unique_ptr dictionary) { + dictionary_ = std::move(dictionary); + } + + // A pending modification. + template + class Modification { + public: + ~Modification() { commit(); } + + T* operator->() { return attr_.get(); } + + void abort() { attr_ = nullptr; } + void commit() { + if (attr_) { + writer_->Set(std::move(attr_)); + } + } + + private: + friend class StunDictionaryWriter; + Modification(StunDictionaryWriter* writer, std::unique_ptr attr) + : writer_(writer), attr_(std::move(attr)) {} + StunDictionaryWriter* writer_; + std::unique_ptr attr_; + + Modification(const Modification&) = + delete; // not copyable (but movable). + Modification& operator=(Modification&) = + delete; // not copyable (but movable). + }; + + // Record a modification. + Modification SetAddress(int key) { + return Modification( + this, StunAttribute::CreateAddress(key)); + } + Modification SetUInt32(int key) { + return Modification(this, + StunAttribute::CreateUInt32(key)); + } + Modification SetUInt64(int key) { + return Modification(this, + StunAttribute::CreateUInt64(key)); + } + Modification SetByteString(int key) { + return Modification( + this, StunAttribute::CreateByteString(key)); + } + Modification SetUInt16List(int key) { + return Modification( + this, StunAttribute::CreateUInt16ListAttribute(key)); + } + + // Delete a key. + void Delete(int key); + + // Check if a key has a pending change (i.e a change + // that has not been acked). + bool Pending(int key) const; + + // Return number of of pending modifications. + int Pending() const; + + // Create an StunByteStringAttribute containing the pending (e.g not ack:ed) + // modifications. + std::unique_ptr CreateDelta(); + + // Apply an delta ack. + void ApplyDeltaAck(const StunUInt64Attribute&); + + // Return pointer to (optional) StunDictionaryView. + const StunDictionaryView* dictionary() { return dictionary_.get(); } + const StunDictionaryView* operator->() { return dictionary_.get(); } + + // Disable writer, + // i.e CreateDelta always return null, and no modifications are made. + // This is called if remote peer does not support GOOG_DELTA. + void Disable(); + bool disabled() const { return disabled_; } + + private: + void Set(std::unique_ptr attr); + + bool disabled_ = false; + + // version of modification. + int64_t version_ = 1; + + // (optional) StunDictionaryView. + std::unique_ptr dictionary_; + + // sorted list of changes that has not been yet been ack:ed. + std::vector> pending_; + + // tombstones, i.e values that has been deleted but not yet acked. + std::map> tombstones_; +}; + +} // namespace cricket + +#endif // P2P_BASE_STUN_DICTIONARY_H_ -- cgit v1.2.3