%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/quic/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/src/quic/cid.cc |
#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC #include "cid.h" #include <crypto/crypto_util.h> #include <memory_tracker-inl.h> #include <node_mutex.h> #include <string_bytes.h> namespace node { namespace quic { // ============================================================================ // CID CID::CID() : ptr_(&cid_) { cid_.datalen = 0; } CID::CID(const ngtcp2_cid& cid) : CID(cid.data, cid.datalen) {} CID::CID(const uint8_t* data, size_t len) : CID() { DCHECK_GE(len, kMinLength); DCHECK_LE(len, kMaxLength); ngtcp2_cid_init(&cid_, data, len); } CID::CID(const ngtcp2_cid* cid) : ptr_(cid) { CHECK_NOT_NULL(cid); DCHECK_GE(cid->datalen, kMinLength); DCHECK_LE(cid->datalen, kMaxLength); } CID::CID(const CID& other) : ptr_(&cid_) { CHECK_NOT_NULL(other.ptr_); ngtcp2_cid_init(&cid_, other.ptr_->data, other.ptr_->datalen); } CID& CID::operator=(const CID& other) { CHECK_NOT_NULL(other.ptr_); ptr_ = &cid_; ngtcp2_cid_init(&cid_, other.ptr_->data, other.ptr_->datalen); return *this; } bool CID::operator==(const CID& other) const noexcept { if (this == &other || (length() == 0 && other.length() == 0)) return true; if (length() != other.length()) return false; return memcmp(ptr_->data, other.ptr_->data, ptr_->datalen) == 0; } bool CID::operator!=(const CID& other) const noexcept { return !(*this == other); } CID::operator const uint8_t*() const { return ptr_->data; } CID::operator const ngtcp2_cid&() const { return *ptr_; } CID::operator const ngtcp2_cid*() const { return ptr_; } CID::operator bool() const { return ptr_->datalen >= kMinLength; } size_t CID::length() const { return ptr_->datalen; } std::string CID::ToString() const { char dest[kMaxLength * 2]; size_t written = StringBytes::hex_encode(reinterpret_cast<const char*>(ptr_->data), ptr_->datalen, dest, arraysize(dest)); return std::string(dest, written); } CID CID::kInvalid{}; // ============================================================================ // CID::Hash size_t CID::Hash::operator()(const CID& cid) const { size_t hash = 0; for (size_t n = 0; n < cid.length(); n++) { hash ^= std::hash<uint8_t>{}(cid.ptr_->data[n] + 0x9e3779b9 + (hash << 6) + (hash >> 2)); } return hash; } // ============================================================================ // CID::Factory namespace { class RandomCIDFactory : public CID::Factory { public: RandomCIDFactory() = default; RandomCIDFactory(const RandomCIDFactory&) = delete; RandomCIDFactory(RandomCIDFactory&&) = delete; RandomCIDFactory& operator=(const RandomCIDFactory&) = delete; RandomCIDFactory& operator=(RandomCIDFactory&&) = delete; CID Generate(size_t length_hint) const override { DCHECK_GE(length_hint, CID::kMinLength); DCHECK_LE(length_hint, CID::kMaxLength); Mutex::ScopedLock lock(mutex_); maybe_refresh_pool(length_hint); auto start = pool_ + pos_; pos_ += length_hint; return CID(start, length_hint); } void GenerateInto(ngtcp2_cid* cid, size_t length_hint = CID::kMaxLength) const override { DCHECK_GE(length_hint, CID::kMinLength); DCHECK_LE(length_hint, CID::kMaxLength); Mutex::ScopedLock lock(mutex_); maybe_refresh_pool(length_hint); auto start = pool_ + pos_; pos_ += length_hint; ngtcp2_cid_init(cid, start, length_hint); } private: void maybe_refresh_pool(size_t length_hint) const { // We generate a pool of random data kPoolSize in length // and pull our random CID from that. If we don't have // enough random random remaining in the pool to generate // a CID of the requested size, we regenerate the pool // and reset it to zero. if (pos_ + length_hint > kPoolSize) { CHECK(crypto::CSPRNG(pool_, kPoolSize).is_ok()); pos_ = 0; } } static constexpr int kPoolSize = 4096; mutable int pos_ = kPoolSize; mutable uint8_t pool_[kPoolSize]; mutable Mutex mutex_; }; } // namespace const CID::Factory& CID::Factory::random() { static RandomCIDFactory instance; return instance; } } // namespace quic } // namespace node #endif // HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC