blob: a243134222cbb30e797b52bf237bb120edfe24dd [file] [log] [blame]
// Copyright 2016 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef OPENSSL_HEADER_CRYPTO_POOL_INTERNAL_H
#define OPENSSL_HEADER_CRYPTO_POOL_INTERNAL_H
#include "../internal.h"
#include "../lhash/internal.h"
#include "../mem_internal.h"
DECLARE_OPAQUE_STRUCT(crypto_buffer_st, CryptoBuffer)
DECLARE_OPAQUE_STRUCT(crypto_buffer_pool_st, CryptoBufferPool)
BSSL_NAMESPACE_BEGIN
// A CryptoBufferPoolHandle is the portion of the pool that lasts as long as any
// live buffer or pool. This allows buffers to outlive the pool. (The pool is
// only needed as long as callers wish to create new buffers.)
class CryptoBufferPoolHandle : public RefCounted<CryptoBufferPoolHandle> {
public:
explicit CryptoBufferPoolHandle(CryptoBufferPool *pool)
: RefCounted(CheckSubClass()), pool_(pool) {}
// pool_ is protected by lock_.
Mutex lock_;
CryptoBufferPool *pool_ = nullptr;
private:
friend RefCounted;
~CryptoBufferPoolHandle() = default;
};
class CryptoBuffer : public crypto_buffer_st {
public:
CryptoBuffer() = default;
CryptoBuffer(const CryptoBuffer &) = delete;
CryptoBuffer &operator=(const CryptoBuffer &) = delete;
Span<const uint8_t> span() const { return Span(data_, len_); }
// Instead of subclassing RefCounted<T>, implement refcounting by hand.
// CryptoBuffer's refcounting must synchronize with CryptoBufferPool.
static constexpr bool kAllowRefCountedUniquePtr = true;
void UpRefInternal();
void DecRefInternal();
UniquePtr<CryptoBufferPoolHandle> pool_handle_;
uint8_t *data_ = nullptr;
size_t len_ = 0;
CRYPTO_refcount_t references_ = 1;
bool data_is_static_ = false;
private:
~CryptoBuffer();
};
DEFINE_LHASH_OF(CryptoBuffer)
class CryptoBufferPool : public crypto_buffer_pool_st {
public:
static constexpr bool kAllowUniquePtr = true;
CryptoBufferPool();
~CryptoBufferPool();
// Hash returns the hash of |data|.
uint32_t Hash(Span<const uint8_t> data) const;
// FindBufferLocked looks for a buffer with hash |hash| and contents |data|.
// It returns it if found and nullptr otherwise. |handle_->lock_| must be
// locked for reading or writing before calling this.
CryptoBuffer *FindBufferLocked(uint32_t hash, Span<const uint8_t> data);
UniquePtr<CryptoBufferPoolHandle> handle_;
LHASH_OF(CryptoBuffer) *bufs_ = nullptr;
uint64_t hash_key_[2];
};
BSSL_NAMESPACE_END
#endif // OPENSSL_HEADER_CRYPTO_POOL_INTERNAL_H