Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
204
TMessagesProj/jni/voip/webrtc/p2p/base/stun_dictionary.h
Normal file
204
TMessagesProj/jni/voip/webrtc/p2p/base/stun_dictionary.h
Normal file
|
|
@ -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 <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#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::unique_ptr<StunUInt64Attribute>, std::vector<uint16_t>>>
|
||||
ApplyDelta(const StunByteStringAttribute& delta);
|
||||
|
||||
private:
|
||||
friend class StunDictionaryWriter;
|
||||
|
||||
const StunAttribute* GetOrNull(
|
||||
int key,
|
||||
absl::optional<StunAttributeValueType> = absl::nullopt) const;
|
||||
size_t GetLength(int key) const;
|
||||
static webrtc::RTCErrorOr<
|
||||
std::pair<uint64_t, std::deque<std::unique_ptr<StunAttribute>>>>
|
||||
ParseDelta(const StunByteStringAttribute& delta);
|
||||
|
||||
std::map<uint16_t, std::unique_ptr<StunAttribute>> attrs_;
|
||||
std::map<uint16_t, uint64_t> version_per_key_;
|
||||
|
||||
int max_bytes_stored_ = 16384;
|
||||
int bytes_stored_ = 0;
|
||||
};
|
||||
|
||||
class StunDictionaryWriter {
|
||||
public:
|
||||
StunDictionaryWriter() {
|
||||
dictionary_ = std::make_unique<StunDictionaryView>();
|
||||
}
|
||||
explicit StunDictionaryWriter(
|
||||
std::unique_ptr<StunDictionaryView> dictionary) {
|
||||
dictionary_ = std::move(dictionary);
|
||||
}
|
||||
|
||||
// A pending modification.
|
||||
template <typename T>
|
||||
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<T> attr)
|
||||
: writer_(writer), attr_(std::move(attr)) {}
|
||||
StunDictionaryWriter* writer_;
|
||||
std::unique_ptr<T> attr_;
|
||||
|
||||
Modification(const Modification<T>&) =
|
||||
delete; // not copyable (but movable).
|
||||
Modification& operator=(Modification<T>&) =
|
||||
delete; // not copyable (but movable).
|
||||
};
|
||||
|
||||
// Record a modification.
|
||||
Modification<StunAddressAttribute> SetAddress(int key) {
|
||||
return Modification<StunAddressAttribute>(
|
||||
this, StunAttribute::CreateAddress(key));
|
||||
}
|
||||
Modification<StunUInt32Attribute> SetUInt32(int key) {
|
||||
return Modification<StunUInt32Attribute>(this,
|
||||
StunAttribute::CreateUInt32(key));
|
||||
}
|
||||
Modification<StunUInt64Attribute> SetUInt64(int key) {
|
||||
return Modification<StunUInt64Attribute>(this,
|
||||
StunAttribute::CreateUInt64(key));
|
||||
}
|
||||
Modification<StunByteStringAttribute> SetByteString(int key) {
|
||||
return Modification<StunByteStringAttribute>(
|
||||
this, StunAttribute::CreateByteString(key));
|
||||
}
|
||||
Modification<StunUInt16ListAttribute> SetUInt16List(int key) {
|
||||
return Modification<StunUInt16ListAttribute>(
|
||||
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<StunByteStringAttribute> 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<StunAttribute> attr);
|
||||
|
||||
bool disabled_ = false;
|
||||
|
||||
// version of modification.
|
||||
int64_t version_ = 1;
|
||||
|
||||
// (optional) StunDictionaryView.
|
||||
std::unique_ptr<StunDictionaryView> dictionary_;
|
||||
|
||||
// sorted list of changes that has not been yet been ack:ed.
|
||||
std::vector<std::pair<uint64_t, const StunAttribute*>> pending_;
|
||||
|
||||
// tombstones, i.e values that has been deleted but not yet acked.
|
||||
std::map<uint16_t, std::unique_ptr<StunAttribute>> tombstones_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // P2P_BASE_STUN_DICTIONARY_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue