mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-19 19:52:15 +02:00
Buffer: Prepare to decouple allocated buffer / RC
Rename BufferAllocated --> BufferAllocatedRc Buffer: split RC from BufferAllocated Also make changes as needed where BufferAllocated is used Buffer: Split allocation flags into own struct Leaving flags in template causes each alias to have identical flags by different names, which requires each type to pointlessly use the nested name. Make RC: Clean up headers buffer.hpp, make_rc.hpp Signed-off-by: Charlie Vigue <charlie.vigue@openvpn.com>
This commit is contained in:
parent
5ce80fc300
commit
ef8da98bd4
@ -442,7 +442,7 @@ Here is a brief set of guidelines:
|
|||||||
rather than a :code:`char *`.
|
rather than a :code:`char *`.
|
||||||
|
|
||||||
* When dealing with binary data or buffers, always try to use a
|
* When dealing with binary data or buffers, always try to use a
|
||||||
:code:`Buffer`, :code:`ConstBuffer`, :code:`BufferAllocated`, or
|
:code:`Buffer`, :code:`ConstBuffer`, :code:`BufferAllocatedRc`, or
|
||||||
:code:`BufferPtr` object to provide managed access to the buffer, to
|
:code:`BufferPtr` object to provide managed access to the buffer, to
|
||||||
protect against security bugs that arise when using raw buffer pointers.
|
protect against security bugs that arise when using raw buffer pointers.
|
||||||
See `<openvpn/buffer/buffer.hpp>`_ for the OpenVPN :code:`Buffer` classes.
|
See `<openvpn/buffer/buffer.hpp>`_ for the OpenVPN :code:`Buffer` classes.
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
namespace openvpn::CF {
|
namespace openvpn::CF {
|
||||||
|
|
||||||
// essentially a vector of void *, used as source for array and dictionary constructors
|
// essentially a vector of void *, used as source for array and dictionary constructors
|
||||||
typedef BufferAllocatedType<CFTypeRef, thread_unsafe_refcount> SrcList;
|
typedef BufferAllocatedType<CFTypeRef> SrcList;
|
||||||
|
|
||||||
inline Array array(const SrcList &values)
|
inline Array array(const SrcList &values)
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
// Buffer : a simple buffer of unsigned char without ownership semantics
|
// Buffer : a simple buffer of unsigned char without ownership semantics
|
||||||
// ConstBuffer : like buffer but where the data pointed to by the buffer is read-only
|
// ConstBuffer : like buffer but where the data pointed to by the buffer is read-only
|
||||||
// BufferAllocated : an allocated Buffer with ownership semantics
|
// BufferAllocated : an allocated Buffer with ownership semantics
|
||||||
// BufferPtr : a smart, reference-counted pointer to a BufferAllocated
|
// BufferPtr : a smart, reference-counted pointer to a BufferAllocatedRc
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
@ -63,6 +63,7 @@
|
|||||||
#include <openvpn/common/exception.hpp>
|
#include <openvpn/common/exception.hpp>
|
||||||
#include <openvpn/common/rc.hpp>
|
#include <openvpn/common/rc.hpp>
|
||||||
#include <openvpn/buffer/bufclamp.hpp>
|
#include <openvpn/buffer/bufclamp.hpp>
|
||||||
|
#include <openvpn/common/make_rc.hpp>
|
||||||
|
|
||||||
#ifdef OPENVPN_BUFFER_ABORT
|
#ifdef OPENVPN_BUFFER_ABORT
|
||||||
#define OPENVPN_BUFFER_THROW(exc) \
|
#define OPENVPN_BUFFER_THROW(exc) \
|
||||||
@ -204,7 +205,7 @@ class BufferException : public std::exception
|
|||||||
// ===============================================================================================
|
// ===============================================================================================
|
||||||
// ===============================================================================================
|
// ===============================================================================================
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
class BufferAllocatedType;
|
class BufferAllocatedType;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -868,12 +869,24 @@ class BufferType : public ConstBufferType<T>
|
|||||||
// class BufferAllocatedType
|
// class BufferAllocatedType
|
||||||
// ===============================================================================================
|
// ===============================================================================================
|
||||||
|
|
||||||
template <typename T, typename R>
|
// Allocation and security for the buffer
|
||||||
class BufferAllocatedType : public BufferType<T>, public RC<R>
|
struct BufAllocFlags
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CONSTRUCT_ZERO = (1 << 0), ///< if enabled, constructors/init will zero allocated space
|
||||||
|
DESTRUCT_ZERO = (1 << 1), ///< if enabled, destructor will zero data before deletion
|
||||||
|
GROW = (1 << 2), ///< if enabled, buffer will grow (otherwise buffer_full exception will be thrown)
|
||||||
|
ARRAY = (1 << 3), ///< if enabled, use as array
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class BufferAllocatedType : public BufferType<T>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Friend to all specializations of this template allows access to other.data_
|
// Friend to all specializations of this template allows access to other.data_
|
||||||
template <typename, typename>
|
template <typename>
|
||||||
friend class BufferAllocatedType;
|
friend class BufferAllocatedType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -888,14 +901,6 @@ class BufferAllocatedType : public BufferType<T>, public RC<R>
|
|||||||
using BufferType<T>::c_data;
|
using BufferType<T>::c_data;
|
||||||
using BufferType<T>::swap;
|
using BufferType<T>::swap;
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
CONSTRUCT_ZERO = (1 << 0), ///< if enabled, constructors/init will zero allocated space
|
|
||||||
DESTRUCT_ZERO = (1 << 1), ///< if enabled, destructor will zero data before deletion
|
|
||||||
GROW = (1 << 2), ///< if enabled, buffer will grow (otherwise buffer_full exception will be thrown)
|
|
||||||
ARRAY = (1 << 3), ///< if enabled, use as array
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Default constructor.
|
* @brief Default constructor.
|
||||||
*/
|
*/
|
||||||
@ -979,14 +984,8 @@ class BufferAllocatedType : public BufferType<T>, public RC<R>
|
|||||||
* @tparam R_ The template parameter type of the other BufferAllocatedType object.
|
* @tparam R_ The template parameter type of the other BufferAllocatedType object.
|
||||||
* @param other The other BufferAllocatedType object to move from.
|
* @param other The other BufferAllocatedType object to move from.
|
||||||
*/
|
*/
|
||||||
template <typename T_, typename R_>
|
template <typename T_>
|
||||||
void move(BufferAllocatedType<T_, R_> &other);
|
void move(BufferAllocatedType<T_> &other);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Moves the contents of this BufferAllocatedType object into a new RCPtr object.
|
|
||||||
* @return A new RCPtr object containing the contents of this BufferAllocatedType object.
|
|
||||||
*/
|
|
||||||
RCPtr<BufferAllocatedType<T, R>> move_to_ptr();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Swaps the contents of this BufferAllocatedType object with another BufferAllocatedType object.
|
* @brief Swaps the contents of this BufferAllocatedType object with another BufferAllocatedType object.
|
||||||
@ -994,8 +993,8 @@ class BufferAllocatedType : public BufferType<T>, public RC<R>
|
|||||||
* @tparam R_ The template parameter type of the other BufferAllocatedType object.
|
* @tparam R_ The template parameter type of the other BufferAllocatedType object.
|
||||||
* @param other The other BufferAllocatedType object to swap with.
|
* @param other The other BufferAllocatedType object to swap with.
|
||||||
*/
|
*/
|
||||||
template <typename T_, typename R_>
|
template <typename T_>
|
||||||
void swap(BufferAllocatedType<T_, R_> &other);
|
void swap(BufferAllocatedType<T_> &other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Move constructor.
|
* @brief Move constructor.
|
||||||
@ -1003,8 +1002,8 @@ class BufferAllocatedType : public BufferType<T>, public RC<R>
|
|||||||
* @tparam R_ The template parameter type of the other BufferAllocatedType object.
|
* @tparam R_ The template parameter type of the other BufferAllocatedType object.
|
||||||
* @param other The other BufferAllocatedType object to move from.
|
* @param other The other BufferAllocatedType object to move from.
|
||||||
*/
|
*/
|
||||||
template <typename T_, typename R_>
|
template <typename T_>
|
||||||
BufferAllocatedType(BufferAllocatedType<T_, R_> &&other) noexcept;
|
BufferAllocatedType(BufferAllocatedType<T_> &&other) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Move assignment operator.
|
* @brief Move assignment operator.
|
||||||
@ -1641,48 +1640,48 @@ ConstBufferType<T>::ConstBufferType(const U *data, const size_t offset, const si
|
|||||||
: ConstBufferType(const_cast<U *>(data), offset, size, capacity){};
|
: ConstBufferType(const_cast<U *>(data), offset, size, capacity){};
|
||||||
|
|
||||||
// ===============================================================================================
|
// ===============================================================================================
|
||||||
// BufferAllocatedType<T, R> member function definitions
|
// BufferAllocatedType<T> member function definitions
|
||||||
// ===============================================================================================
|
// ===============================================================================================
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
BufferAllocatedType<T, R>::BufferAllocatedType(const size_t offset, const size_t size, const size_t capacity, const unsigned int flags)
|
BufferAllocatedType<T>::BufferAllocatedType(const size_t offset, const size_t size, const size_t capacity, const unsigned int flags)
|
||||||
: BufferType<T>(capacity ? new T[capacity] : nullptr, offset, size, capacity), flags_(flags)
|
: BufferType<T>(capacity ? new T[capacity] : nullptr, offset, size, capacity), flags_(flags)
|
||||||
{
|
{
|
||||||
if (flags & CONSTRUCT_ZERO)
|
if (flags & BufAllocFlags::CONSTRUCT_ZERO)
|
||||||
std::memset(data_raw(), 0, capacity * sizeof(T));
|
std::memset(data_raw(), 0, capacity * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
BufferAllocatedType<T, R>::BufferAllocatedType()
|
BufferAllocatedType<T>::BufferAllocatedType()
|
||||||
: BufferAllocatedType(0, 0, 0, 0)
|
: BufferAllocatedType(0, 0, 0, 0)
|
||||||
{
|
{
|
||||||
static_assert(std::is_nothrow_move_constructible_v<BufferAllocatedType>,
|
static_assert(std::is_nothrow_move_constructible_v<BufferAllocatedType>,
|
||||||
"class BufferAllocatedType not noexcept move constructable");
|
"class BufferAllocatedType not noexcept move constructable");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
BufferAllocatedType<T, R>::BufferAllocatedType(const size_t capacity, const unsigned int flags)
|
BufferAllocatedType<T>::BufferAllocatedType(const size_t capacity, const unsigned int flags)
|
||||||
: BufferAllocatedType(0, flags & ARRAY ? capacity : 0, capacity, flags){};
|
: BufferAllocatedType(0, flags & BufAllocFlags::ARRAY ? capacity : 0, capacity, flags){};
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
BufferAllocatedType<T, R>::BufferAllocatedType(const T *data, const size_t size, const unsigned int flags)
|
BufferAllocatedType<T>::BufferAllocatedType(const T *data, const size_t size, const unsigned int flags)
|
||||||
: BufferAllocatedType(0, size, size, flags)
|
: BufferAllocatedType(0, size, size, flags)
|
||||||
{
|
{
|
||||||
if (size)
|
if (size && data)
|
||||||
std::memcpy(data_raw(), data, size * sizeof(T));
|
std::memcpy(data_raw(), data, size * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
BufferAllocatedType<T, R>::BufferAllocatedType(const BufferAllocatedType &other)
|
BufferAllocatedType<T>::BufferAllocatedType(const BufferAllocatedType &other)
|
||||||
: BufferAllocatedType(other.offset(), other.size(), other.capacity(), other.flags_)
|
: BufferAllocatedType(other.offset(), other.size(), other.capacity(), other.flags_)
|
||||||
{
|
{
|
||||||
if (size())
|
if (size())
|
||||||
std::memcpy(data(), other.c_data(), size() * sizeof(T));
|
std::memcpy(data(), other.c_data(), size() * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
template <typename T_>
|
template <typename T_>
|
||||||
BufferAllocatedType<T, R>::BufferAllocatedType(const BufferType<T_> &other, const unsigned int flags)
|
BufferAllocatedType<T>::BufferAllocatedType(const BufferType<T_> &other, const unsigned int flags)
|
||||||
: BufferAllocatedType(other.offset(), other.size(), other.capacity(), flags)
|
: BufferAllocatedType(other.offset(), other.size(), other.capacity(), flags)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) == sizeof(T_), "size inconsistency");
|
static_assert(sizeof(T) == sizeof(T_), "size inconsistency");
|
||||||
@ -1690,8 +1689,8 @@ BufferAllocatedType<T, R>::BufferAllocatedType(const BufferType<T_> &other, cons
|
|||||||
std::memcpy(data(), other.c_data(), size() * sizeof(T));
|
std::memcpy(data(), other.c_data(), size() * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::operator=(const BufferAllocatedType &other)
|
void BufferAllocatedType<T>::operator=(const BufferAllocatedType &other)
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
@ -1702,74 +1701,68 @@ void BufferAllocatedType<T, R>::operator=(const BufferAllocatedType &other)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::init(const size_t capacity, const unsigned int flags)
|
void BufferAllocatedType<T>::init(const size_t capacity, const unsigned int flags)
|
||||||
{
|
{
|
||||||
auto tempBuffer = BufferAllocatedType(capacity, flags);
|
auto tempBuffer = BufferAllocatedType(capacity, flags);
|
||||||
swap(tempBuffer);
|
swap(tempBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::init(const T *data, const size_t size, const unsigned int flags)
|
void BufferAllocatedType<T>::init(const T *data, const size_t size, const unsigned int flags)
|
||||||
{
|
{
|
||||||
auto tempBuffer = BufferAllocatedType(data, size, flags);
|
auto tempBuffer = BufferAllocatedType(data, size, flags);
|
||||||
swap(tempBuffer);
|
swap(tempBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::realloc(const size_t newcap)
|
void BufferAllocatedType<T>::realloc(const size_t newcap)
|
||||||
{
|
{
|
||||||
if (newcap > capacity())
|
if (newcap > capacity())
|
||||||
realloc_(newcap);
|
realloc_(newcap);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::reset(const size_t min_capacity, const unsigned int flags)
|
void BufferAllocatedType<T>::reset(const size_t min_capacity, const unsigned int flags)
|
||||||
{
|
{
|
||||||
if (min_capacity > capacity())
|
if (min_capacity > capacity())
|
||||||
init(min_capacity, flags);
|
init(min_capacity, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::reset(const size_t headroom, const size_t min_capacity, const unsigned int flags)
|
void BufferAllocatedType<T>::reset(const size_t headroom, const size_t min_capacity, const unsigned int flags)
|
||||||
{
|
{
|
||||||
reset(min_capacity, flags);
|
reset(min_capacity, flags);
|
||||||
init_headroom(headroom);
|
init_headroom(headroom);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
template <typename T_, typename R_>
|
template <typename T_>
|
||||||
void BufferAllocatedType<T, R>::move(BufferAllocatedType<T_, R_> &other)
|
void BufferAllocatedType<T>::move(BufferAllocatedType<T_> &other)
|
||||||
{
|
{
|
||||||
auto temp = BufferAllocatedType();
|
auto temp = BufferAllocatedType();
|
||||||
swap(other);
|
swap(other);
|
||||||
other.swap(temp);
|
other.swap(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
RCPtr<BufferAllocatedType<T, R>> BufferAllocatedType<T, R>::move_to_ptr()
|
template <typename T_>
|
||||||
{
|
void BufferAllocatedType<T>::swap(BufferAllocatedType<T_> &other)
|
||||||
return RCPtr<BufferAllocatedType<T, R>>(new BufferAllocatedType<T, R>(std::move(*this)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename R>
|
|
||||||
template <typename T_, typename R_>
|
|
||||||
void BufferAllocatedType<T, R>::swap(BufferAllocatedType<T_, R_> &other)
|
|
||||||
{
|
{
|
||||||
BufferType<T>::swap(other);
|
BufferType<T>::swap(other);
|
||||||
std::swap(flags_, other.flags_);
|
std::swap(flags_, other.flags_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
template <typename T_, typename R_>
|
template <typename T_>
|
||||||
BufferAllocatedType<T, R>::BufferAllocatedType(BufferAllocatedType<T_, R_> &&other) noexcept
|
BufferAllocatedType<T>::BufferAllocatedType(BufferAllocatedType<T_> &&other) noexcept
|
||||||
: BufferAllocatedType()
|
: BufferAllocatedType()
|
||||||
{
|
{
|
||||||
move(other);
|
move(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
BufferAllocatedType<T, R> &BufferAllocatedType<T, R>::operator=(BufferAllocatedType &&other) noexcept
|
BufferAllocatedType<T> &BufferAllocatedType<T>::operator=(BufferAllocatedType &&other) noexcept
|
||||||
{
|
{
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
@ -1778,53 +1771,53 @@ BufferAllocatedType<T, R> &BufferAllocatedType<T, R>::operator=(BufferAllocatedT
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::clear()
|
void BufferAllocatedType<T>::clear()
|
||||||
{
|
{
|
||||||
auto tempBuffer = BufferAllocatedType(0, 0, 0, 0);
|
auto tempBuffer = BufferAllocatedType(0, 0, 0, 0);
|
||||||
swap(tempBuffer);
|
swap(tempBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::or_flags(const unsigned int flags)
|
void BufferAllocatedType<T>::or_flags(const unsigned int flags)
|
||||||
{
|
{
|
||||||
flags_ |= flags;
|
flags_ |= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::and_flags(const unsigned int flags)
|
void BufferAllocatedType<T>::and_flags(const unsigned int flags)
|
||||||
{
|
{
|
||||||
flags_ &= flags;
|
flags_ &= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
BufferAllocatedType<T, R>::~BufferAllocatedType()
|
BufferAllocatedType<T>::~BufferAllocatedType()
|
||||||
{
|
{
|
||||||
if (data_raw())
|
if (data_raw())
|
||||||
free_data();
|
free_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::reset_impl(const size_t min_capacity, const unsigned int flags)
|
void BufferAllocatedType<T>::reset_impl(const size_t min_capacity, const unsigned int flags)
|
||||||
{
|
{
|
||||||
init(min_capacity, flags);
|
init(min_capacity, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::resize(const size_t new_capacity)
|
void BufferAllocatedType<T>::resize(const size_t new_capacity)
|
||||||
{
|
{
|
||||||
const size_t newcap = std::max(new_capacity, capacity() * 2);
|
const size_t newcap = std::max(new_capacity, capacity() * 2);
|
||||||
if (newcap > capacity())
|
if (newcap > capacity())
|
||||||
{
|
{
|
||||||
if (flags_ & GROW)
|
if (flags_ & BufAllocFlags::GROW)
|
||||||
realloc_(newcap);
|
realloc_(newcap);
|
||||||
else
|
else
|
||||||
buffer_full_error(newcap, true);
|
buffer_full_error(newcap, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::realloc_(const size_t newcap)
|
void BufferAllocatedType<T>::realloc_(const size_t newcap)
|
||||||
{
|
{
|
||||||
auto tempBuffer = BufferAllocatedType(offset(), size(), newcap, flags_);
|
auto tempBuffer = BufferAllocatedType(offset(), size(), newcap, flags_);
|
||||||
if (size())
|
if (size())
|
||||||
@ -1832,10 +1825,10 @@ void BufferAllocatedType<T, R>::realloc_(const size_t newcap)
|
|||||||
swap(tempBuffer);
|
swap(tempBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename R>
|
template <typename T>
|
||||||
void BufferAllocatedType<T, R>::free_data()
|
void BufferAllocatedType<T>::free_data()
|
||||||
{
|
{
|
||||||
if (size() && (flags_ & DESTRUCT_ZERO))
|
if (size() && (flags_ & BufAllocFlags::DESTRUCT_ZERO))
|
||||||
std::memset(data_raw(), 0, capacity() * sizeof(T));
|
std::memset(data_raw(), 0, capacity() * sizeof(T));
|
||||||
delete[] data_raw();
|
delete[] data_raw();
|
||||||
}
|
}
|
||||||
@ -1844,17 +1837,18 @@ void BufferAllocatedType<T, R>::free_data()
|
|||||||
// specializations of BufferType for unsigned char
|
// specializations of BufferType for unsigned char
|
||||||
// ===============================================================================================
|
// ===============================================================================================
|
||||||
|
|
||||||
typedef BufferType<unsigned char> Buffer;
|
using Buffer = BufferType<unsigned char>;
|
||||||
typedef ConstBufferType<unsigned char> ConstBuffer;
|
using ConstBuffer = ConstBufferType<unsigned char>;
|
||||||
typedef BufferAllocatedType<unsigned char, thread_unsafe_refcount> BufferAllocated;
|
using BufferAllocated = BufferAllocatedType<unsigned char>;
|
||||||
typedef RCPtr<BufferAllocated> BufferPtr;
|
using BufferAllocatedRc = RcEnable<BufferAllocated, RC<thread_unsafe_refcount>>;
|
||||||
|
using BufferPtr = RCPtr<BufferAllocatedRc>;
|
||||||
|
|
||||||
// ===============================================================================================
|
// ===============================================================================================
|
||||||
// BufferAllocated with thread-safe refcount
|
// BufferAllocated + RC with thread-safe refcount
|
||||||
// ===============================================================================================
|
// ===============================================================================================
|
||||||
|
|
||||||
typedef BufferAllocatedType<unsigned char, thread_safe_refcount> BufferAllocatedTS;
|
using BufferAllocatedTS = RcEnable<BufferAllocated, RC<thread_safe_refcount>>;
|
||||||
typedef RCPtr<BufferAllocatedTS> BufferPtrTS;
|
using BufferPtrTS = RCPtr<BufferAllocatedTS>;
|
||||||
|
|
||||||
// ===============================================================================================
|
// ===============================================================================================
|
||||||
// cast BufferType<T> to ConstBufferType<T>
|
// cast BufferType<T> to ConstBufferType<T>
|
||||||
|
@ -56,7 +56,7 @@ struct BufferCollection : public COLLECTION<BufferPtr>
|
|||||||
const size_t size = join_size();
|
const size_t size = join_size();
|
||||||
|
|
||||||
// allocate buffer
|
// allocate buffer
|
||||||
BufferPtr big = new BufferAllocated(size + headroom + tailroom, 0);
|
auto big = BufferAllocatedRc::Create(size + headroom + tailroom, 0);
|
||||||
big->init_headroom(headroom);
|
big->init_headroom(headroom);
|
||||||
|
|
||||||
// second pass -- copy data
|
// second pass -- copy data
|
||||||
@ -89,7 +89,7 @@ struct BufferCollection : public COLLECTION<BufferPtr>
|
|||||||
{
|
{
|
||||||
BufferCollection ret;
|
BufferCollection ret;
|
||||||
for (auto &b : *this)
|
for (auto &b : *this)
|
||||||
ret.emplace_back(new BufferAllocated(*b));
|
ret.emplace_back(BufferAllocatedRc::Create(*b));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ struct BufferCollection : public COLLECTION<BufferPtr>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emplace_back(new BufferAllocated(std::move(buf)));
|
emplace_back(BufferAllocatedRc::Create(std::move(buf)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ inline void buf_write_string(Buffer &buf, const char *str)
|
|||||||
inline BufferPtr buf_from_string(const std::string &str)
|
inline BufferPtr buf_from_string(const std::string &str)
|
||||||
{
|
{
|
||||||
const size_t len = str.length();
|
const size_t len = str.length();
|
||||||
BufferPtr buf(new BufferAllocated(len, 0));
|
BufferPtr buf = BufferAllocatedRc::Create(len, 0);
|
||||||
buf->write((unsigned char *)str.c_str(), len);
|
buf->write((unsigned char *)str.c_str(), len);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ inline BufferPtr buf_from_string(const std::string &str)
|
|||||||
inline BufferPtr buf_from_string(const char *str)
|
inline BufferPtr buf_from_string(const char *str)
|
||||||
{
|
{
|
||||||
const size_t len = std::strlen(str);
|
const size_t len = std::strlen(str);
|
||||||
BufferPtr buf(new BufferAllocated(len, 0));
|
BufferPtr buf = BufferAllocatedRc::Create(len, 0);
|
||||||
buf->write((unsigned char *)str, len);
|
buf->write((unsigned char *)str, len);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ inline BufferPtr compress(const ConstBuffer &src,
|
|||||||
OPENVPN_THROW(lz4_error, "compress buffer size=" << src.size() << " exceeds LZ4_MAX_INPUT_SIZE=" << LZ4_MAX_INPUT_SIZE);
|
OPENVPN_THROW(lz4_error, "compress buffer size=" << src.size() << " exceeds LZ4_MAX_INPUT_SIZE=" << LZ4_MAX_INPUT_SIZE);
|
||||||
|
|
||||||
// allocate dest buffer
|
// allocate dest buffer
|
||||||
BufferPtr dest = new BufferAllocated(sizeof(std::uint32_t) + headroom + tailroom + LZ4_COMPRESSBOUND(src.size()), 0);
|
auto dest = BufferAllocatedRc::Create(sizeof(std::uint32_t) + headroom + tailroom + LZ4_COMPRESSBOUND(src.size()), 0);
|
||||||
dest->init_headroom(headroom);
|
dest->init_headroom(headroom);
|
||||||
|
|
||||||
// as a hint to receiver, write the decompressed size
|
// as a hint to receiver, write the decompressed size
|
||||||
@ -83,7 +83,7 @@ inline BufferPtr decompress(const ConstBuffer &source,
|
|||||||
OPENVPN_THROW(lz4_error, "decompress expansion size=" << size << " is too large (must be <= " << max_decompressed_size << ')');
|
OPENVPN_THROW(lz4_error, "decompress expansion size=" << size << " is too large (must be <= " << max_decompressed_size << ')');
|
||||||
|
|
||||||
// allocate dest buffer
|
// allocate dest buffer
|
||||||
BufferPtr dest = new BufferAllocated(headroom + tailroom + size, 0);
|
auto dest = BufferAllocatedRc::Create(headroom + tailroom + size, 0);
|
||||||
dest->init_headroom(headroom);
|
dest->init_headroom(headroom);
|
||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
|
@ -30,10 +30,13 @@
|
|||||||
#include <openvpn/buffer/bufstr.hpp>
|
#include <openvpn/buffer/bufstr.hpp>
|
||||||
|
|
||||||
namespace openvpn {
|
namespace openvpn {
|
||||||
|
/**
|
||||||
|
@brief A string-like type that clears the buffer contents on delete
|
||||||
|
*/
|
||||||
class SafeString
|
class SafeString
|
||||||
{
|
{
|
||||||
static constexpr size_t INITIAL_CAPACITY = 32;
|
static constexpr size_t INITIAL_CAPACITY = 32;
|
||||||
static constexpr unsigned int BUF_FLAGS = BufferAllocated::DESTRUCT_ZERO | BufferAllocated::GROW;
|
static constexpr unsigned int BUF_FLAGS = BufAllocFlags::DESTRUCT_ZERO | BufAllocFlags::GROW;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SafeString()
|
SafeString()
|
||||||
|
@ -90,7 +90,7 @@ inline BufferPtr compress_gzip(BufferPtr src,
|
|||||||
if (status != Z_OK)
|
if (status != Z_OK)
|
||||||
OPENVPN_THROW(zlib_error, "zlib deflateinit2 failed, error=" << status);
|
OPENVPN_THROW(zlib_error, "zlib deflateinit2 failed, error=" << status);
|
||||||
const uLong outcap = ::deflateBound(&zs.s, src->size());
|
const uLong outcap = ::deflateBound(&zs.s, src->size());
|
||||||
BufferPtr b = new BufferAllocated(outcap + headroom + tailroom, 0);
|
auto b = BufferAllocatedRc::Create(outcap + headroom + tailroom, 0);
|
||||||
b->init_headroom(headroom);
|
b->init_headroom(headroom);
|
||||||
zs.s.next_out = b->data();
|
zs.s.next_out = b->data();
|
||||||
zs.s.avail_out = numeric_cast<decltype(zs.s.avail_out)>(outcap);
|
zs.s.avail_out = numeric_cast<decltype(zs.s.avail_out)>(outcap);
|
||||||
@ -138,7 +138,7 @@ inline BufferPtr decompress_gzip(BufferPtr src,
|
|||||||
{
|
{
|
||||||
// use headroom/tailroom on first block to take advantage
|
// use headroom/tailroom on first block to take advantage
|
||||||
// of BufferList::join() optimization for one-block lists
|
// of BufferList::join() optimization for one-block lists
|
||||||
BufferPtr b = new BufferAllocated(block_size + hr + tr, 0);
|
auto b = BufferAllocatedRc::Create(block_size + hr + tr, 0);
|
||||||
b->init_headroom(hr);
|
b->init_headroom(hr);
|
||||||
const size_t avail = b->remaining(tr);
|
const size_t avail = b->remaining(tr);
|
||||||
zs.s.next_out = b->data();
|
zs.s.next_out = b->data();
|
||||||
|
@ -132,9 +132,9 @@ inline AccHandshaker::MsgT AccHandshaker::process_msg(const MsgT &msg)
|
|||||||
auto &api = mSslApi->get();
|
auto &api = mSslApi->get();
|
||||||
if (msg)
|
if (msg)
|
||||||
{
|
{
|
||||||
api.write_ciphertext(new BufferAllocated(reinterpret_cast<const unsigned char *>(msg->c_str()),
|
api.write_ciphertext(BufferAllocatedRc::Create(reinterpret_cast<const unsigned char *>(msg->c_str()),
|
||||||
msg->size(),
|
msg->size(),
|
||||||
0));
|
0));
|
||||||
|
|
||||||
// Won't handshake without this even though there is no data available.
|
// Won't handshake without this even though there is no data available.
|
||||||
uint8_t cleartext[8];
|
uint8_t cleartext[8];
|
||||||
|
@ -416,7 +416,7 @@ struct InfoJSON : public Base
|
|||||||
|
|
||||||
virtual std::string render() const
|
virtual std::string render() const
|
||||||
{
|
{
|
||||||
BufferAllocated buf(512, BufferAllocated::GROW);
|
BufferAllocated buf(512, BufAllocFlags::GROW);
|
||||||
buf_append_string(buf, msg_type);
|
buf_append_string(buf, msg_type);
|
||||||
buf_append_string(buf, ":");
|
buf_append_string(buf, ":");
|
||||||
json::format_compact(jdata, buf);
|
json::format_compact(jdata, buf);
|
||||||
|
@ -86,7 +86,7 @@ inline BufferPtr read_binary(const std::string &filename,
|
|||||||
ifs.seekg(0, std::ios::beg);
|
ifs.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
// allocate buffer
|
// allocate buffer
|
||||||
BufferPtr b = new BufferAllocated(size_t(length), buffer_flags | BufferAllocated::ARRAY);
|
auto b = BufferAllocatedRc::Create(size_t(length), buffer_flags | BufAllocFlags::ARRAY);
|
||||||
|
|
||||||
// read data
|
// read data
|
||||||
ifs.read((char *)b->data(), length);
|
ifs.read((char *)b->data(), length);
|
||||||
@ -114,7 +114,7 @@ inline BufferPtr read_binary_linear(const std::string &filename,
|
|||||||
std::streamsize total_size = 0;
|
std::streamsize total_size = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
BufferPtr b = new BufferAllocated(block_size, 0);
|
auto b = BufferAllocatedRc::Create(block_size, 0);
|
||||||
ifs.read((char *)b->data(), b->remaining());
|
ifs.read((char *)b->data(), b->remaining());
|
||||||
const std::streamsize size = ifs.gcount();
|
const std::streamsize size = ifs.gcount();
|
||||||
if (size)
|
if (size)
|
||||||
|
@ -161,7 +161,7 @@ inline BufferPtr read_binary_unix(const std::string &fn,
|
|||||||
throw file_unix_error(fn + " : file too large [" + std::to_string(length) + '/' + std::to_string(max_size) + ']');
|
throw file_unix_error(fn + " : file too large [" + std::to_string(length) + '/' + std::to_string(max_size) + ']');
|
||||||
|
|
||||||
// allocate buffer
|
// allocate buffer
|
||||||
BufferPtr bp = new BufferAllocated(size_t(length), buffer_flags);
|
auto bp = BufferAllocatedRc::Create(size_t(length), buffer_flags);
|
||||||
|
|
||||||
// read file content into buffer
|
// read file content into buffer
|
||||||
while (buf_read(fd(), *bp, fn))
|
while (buf_read(fd(), *bp, fn))
|
||||||
|
@ -56,7 +56,7 @@ inline void write_atomic(const std::string &fn,
|
|||||||
const size_t size_hint,
|
const size_t size_hint,
|
||||||
StrongRandomAPI &rng)
|
StrongRandomAPI &rng)
|
||||||
{
|
{
|
||||||
BufferPtr bp = new BufferAllocated(size_hint, BufferAllocated::GROW);
|
auto bp = BufferAllocatedRc::Create(size_hint, BufAllocFlags::GROW);
|
||||||
format_compact(root, *bp);
|
format_compact(root, *bp);
|
||||||
write_binary_atomic(fn, tmpdir, mode, mtime_ns, *bp, rng);
|
write_binary_atomic(fn, tmpdir, mode, mtime_ns, *bp, rng);
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ inline void write_fast(const std::string &fn,
|
|||||||
const Json::Value &root,
|
const Json::Value &root,
|
||||||
const size_t size_hint)
|
const size_t size_hint)
|
||||||
{
|
{
|
||||||
BufferPtr bp = new BufferAllocated(size_hint, BufferAllocated::GROW);
|
auto bp = BufferAllocatedRc::Create(size_hint, BufAllocFlags::GROW);
|
||||||
format_compact(root, *bp);
|
format_compact(root, *bp);
|
||||||
write_binary_unix(fn, mode, mtime_ns, *bp);
|
write_binary_unix(fn, mode, mtime_ns, *bp);
|
||||||
}
|
}
|
||||||
|
@ -853,7 +853,7 @@ inline void to_uchar(const Json::Value &root,
|
|||||||
auto temp = get_int(root, name, title);
|
auto temp = get_int(root, name, title);
|
||||||
dest = clamp_notify<unsigned char>(temp,
|
dest = clamp_notify<unsigned char>(temp,
|
||||||
[](decltype(temp) temp) -> unsigned char
|
[](decltype(temp) temp) -> unsigned char
|
||||||
{
|
{
|
||||||
auto why = std::string("Conversion error [" + std::to_string(temp) + "] to unsigned char");
|
auto why = std::string("Conversion error [" + std::to_string(temp) + "] to unsigned char");
|
||||||
throw json_parse(std::move(why)); });
|
throw json_parse(std::move(why)); });
|
||||||
}
|
}
|
||||||
@ -911,9 +911,9 @@ inline void format_compact(const Json::Value &root, Buffer &buf)
|
|||||||
inline std::string format_compact(const Json::Value &root,
|
inline std::string format_compact(const Json::Value &root,
|
||||||
const size_t size_hint = 256)
|
const size_t size_hint = 256)
|
||||||
{
|
{
|
||||||
BufferPtr bp = new BufferAllocated(size_hint, BufferAllocated::GROW);
|
auto bp = BufferAllocated(size_hint, BufAllocFlags::GROW);
|
||||||
format_compact(root, *bp);
|
format_compact(root, bp);
|
||||||
return buf_to_string(*bp);
|
return buf_to_string(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void format(const Json::Value &root, Buffer &buf)
|
inline void format(const Json::Value &root, Buffer &buf)
|
||||||
|
91
openvpn/common/make_rc.hpp
Normal file
91
openvpn/common/make_rc.hpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
// OpenVPN -- An application to securely tunnel IP networks
|
||||||
|
// over a single port, with support for SSL/TLS-based
|
||||||
|
// session authentication and key exchange,
|
||||||
|
// packet encryption, packet authentication, and
|
||||||
|
// packet compression.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2024- OpenVPN Inc.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License Version 3
|
||||||
|
// as published by the Free Software Foundation.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program in the COPYING file.
|
||||||
|
// If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <openvpn/common/rc.hpp>
|
||||||
|
|
||||||
|
namespace openvpn {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A class template that enables reference counting for a given type.
|
||||||
|
* @details This class inherits from both the TypeT and RcT (Reference Counting)
|
||||||
|
* classes. It provides a convenient way to create reference-counted
|
||||||
|
* objects of TypeT.
|
||||||
|
* @tparam TypeT The base type to be reference-counted.
|
||||||
|
* @tparam RcT The reference counting class, defaulting to RC<thread_unsafe_refcount>.
|
||||||
|
*/
|
||||||
|
template <typename TypeT, typename RcT = RC<thread_unsafe_refcount>>
|
||||||
|
class RcEnable : public TypeT, public RcT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Ptr = RCPtr<RcEnable>; ///< Alias for the pointer type used by the reference counting class.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a new instance of RcEnable with the given arguments.
|
||||||
|
* @details This function creates a new RcEnable object using the provided arguments
|
||||||
|
* and returns a smart pointer (Ptr) to the created object.
|
||||||
|
* @tparam ArgsT The parameter pack types for the arguments to be forwarded
|
||||||
|
* to the RcEnable constructor.
|
||||||
|
* @param args The arguments to be forwarded to the RcEnable constructor.
|
||||||
|
* @return A smart pointer (Ptr) to the newly created RcEnable object with intrusive ref count.
|
||||||
|
*/
|
||||||
|
template <typename... ArgsT>
|
||||||
|
[[nodiscard]] static Ptr Create(ArgsT &&...args)
|
||||||
|
{
|
||||||
|
return Ptr(new RcEnable(std::forward<ArgsT>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Private constructor for RcEnable.
|
||||||
|
* @details This constructor is used to create a new instance of RcEnable with the
|
||||||
|
* provided arguments. It initializes the base classes TypeT and RcT with
|
||||||
|
* the forwarded arguments.
|
||||||
|
* @tparam ArgsT The parameter pack types for the arguments to be forwarded
|
||||||
|
* to the base class constructors.
|
||||||
|
* @param args The arguments to be forwarded to the base class constructors.
|
||||||
|
* @note This constructor is private and should not be called directly.
|
||||||
|
* Use the Create() function to create instances of RcEnable.
|
||||||
|
*/
|
||||||
|
template <typename... ArgsT>
|
||||||
|
RcEnable(ArgsT &&...args)
|
||||||
|
: TypeT(std::forward<ArgsT>(args)...),
|
||||||
|
RcT(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper function to create a reference-counted object with the default thread-unsafe reference counting policy.
|
||||||
|
* @tparam TypeT The type of the object to be created.
|
||||||
|
* @tparam RcT The RC type that shall be used, defaults to RC<thread_unsafe_refcount>
|
||||||
|
* @tparam ArgsT The types of the arguments to be forwarded to the constructor of TypeT.
|
||||||
|
* @param args The arguments to be forwarded to the constructor of TypeT.
|
||||||
|
* @return A reference-counted object of type TypeT, using the default thread-unsafe reference counting policy.
|
||||||
|
* @note This function is a convenience wrapper around make_rc_impl, using the default RC<thread_unsafe_refcount>
|
||||||
|
* as the reference counting policy.
|
||||||
|
*/
|
||||||
|
template <typename TypeT, typename RcT = RC<thread_unsafe_refcount>, typename... ArgsT>
|
||||||
|
auto make_rc(ArgsT &&...args)
|
||||||
|
{
|
||||||
|
return RcEnable<TypeT, RcT>::Create(std::forward<ArgsT>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace openvpn
|
@ -231,7 +231,7 @@ inline BufferPtr string_to_utf16(const STRING &str)
|
|||||||
dest + str.length(),
|
dest + str.length(),
|
||||||
lenientConversion);
|
lenientConversion);
|
||||||
conversion_result_throw(res);
|
conversion_result_throw(res);
|
||||||
BufferPtr ret(new BufferAllocated((dest - utf16_dest.get()) * 2, BufferAllocated::ARRAY));
|
auto ret = BufferAllocatedRc::Create((dest - utf16_dest.get()) * 2, BufAllocFlags::ARRAY);
|
||||||
UTF8 *d = ret->data();
|
UTF8 *d = ret->data();
|
||||||
for (const UTF16 *s = utf16_dest.get(); s < dest; ++s)
|
for (const UTF16 *s = utf16_dest.get(); s < dest; ++s)
|
||||||
{
|
{
|
||||||
|
@ -51,7 +51,7 @@ class CompressLZO : public Compress
|
|||||||
asym(asym_arg)
|
asym(asym_arg)
|
||||||
{
|
{
|
||||||
OVPN_LOG_INFO("LZO init swap=" << support_swap_arg << " asym=" << asym_arg);
|
OVPN_LOG_INFO("LZO init swap=" << support_swap_arg << " asym=" << asym_arg);
|
||||||
lzo_workspace.init(LZO1X_1_15_MEM_COMPRESS, BufferAllocated::ARRAY);
|
lzo_workspace.init(LZO1X_1_15_MEM_COMPRESS, BufAllocFlags::ARRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_static()
|
static void init_static()
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#ifndef OPENVPN_COMPRESS_LZOASYM_H
|
#ifndef OPENVPN_COMPRESS_LZOASYM_H
|
||||||
#define OPENVPN_COMPRESS_LZOASYM_H
|
#define OPENVPN_COMPRESS_LZOASYM_H
|
||||||
|
|
||||||
|
#include <openvpn/buffer/buffer.hpp>
|
||||||
#include <openvpn/compress/lzoasym_impl.hpp>
|
#include <openvpn/compress/lzoasym_impl.hpp>
|
||||||
|
|
||||||
// Implement asymmetrical LZO compression (only uncompress, don't compress)
|
// Implement asymmetrical LZO compression (only uncompress, don't compress)
|
||||||
|
@ -61,7 +61,7 @@ class HashString
|
|||||||
|
|
||||||
BufferPtr final()
|
BufferPtr final()
|
||||||
{
|
{
|
||||||
BufferPtr ret(new BufferAllocated(ctx->size(), BufferAllocated::ARRAY));
|
auto ret = BufferAllocatedRc::Create(ctx->size(), BufAllocFlags::ARRAY);
|
||||||
ctx->final(ret->data());
|
ctx->final(ret->data());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class StaticKey
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
StaticKey(const unsigned char *key_data, const size_t key_size)
|
StaticKey(const unsigned char *key_data, const size_t key_size)
|
||||||
: key_data_(key_data, key_size, key_t::DESTRUCT_ZERO)
|
: key_data_(key_data, key_size, BufAllocFlags::DESTRUCT_ZERO)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ class StaticKey
|
|||||||
|
|
||||||
void parse_from_base64(const std::string &b64, const size_t capacity)
|
void parse_from_base64(const std::string &b64, const size_t capacity)
|
||||||
{
|
{
|
||||||
key_data_.reset(capacity, key_t::DESTRUCT_ZERO);
|
key_data_.reset(capacity, BufAllocFlags::DESTRUCT_ZERO);
|
||||||
base64->decode(key_data_, b64);
|
base64->decode(key_data_, b64);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ class StaticKey
|
|||||||
|
|
||||||
void init_from_rng(StrongRandomAPI &rng, const size_t key_size)
|
void init_from_rng(StrongRandomAPI &rng, const size_t key_size)
|
||||||
{
|
{
|
||||||
key_data_.init(key_size, key_t::DESTRUCT_ZERO);
|
key_data_.init(key_size, BufAllocFlags::DESTRUCT_ZERO);
|
||||||
rng.rand_bytes(key_data_.data(), key_size);
|
rng.rand_bytes(key_data_.data(), key_size);
|
||||||
key_data_.set_size(key_size);
|
key_data_.set_size(key_size);
|
||||||
}
|
}
|
||||||
@ -151,7 +151,7 @@ class OpenVPNStaticKey
|
|||||||
void parse(const std::string &key_text)
|
void parse(const std::string &key_text)
|
||||||
{
|
{
|
||||||
SplitLines in(key_text, 0);
|
SplitLines in(key_text, 0);
|
||||||
key_t data(KEY_SIZE, key_t::DESTRUCT_ZERO);
|
key_t data(KEY_SIZE, BufAllocFlags::DESTRUCT_ZERO);
|
||||||
bool in_body = false;
|
bool in_body = false;
|
||||||
while (in(true))
|
while (in(true))
|
||||||
{
|
{
|
||||||
@ -182,7 +182,7 @@ class OpenVPNStaticKey
|
|||||||
|
|
||||||
unsigned char *raw_alloc()
|
unsigned char *raw_alloc()
|
||||||
{
|
{
|
||||||
key_data_.init(KEY_SIZE, key_t::DESTRUCT_ZERO | key_t::ARRAY);
|
key_data_.init(KEY_SIZE, BufAllocFlags::DESTRUCT_ZERO | BufAllocFlags::ARRAY);
|
||||||
return key_data_.data();
|
return key_data_.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class TLSCryptV2ServerKey
|
|||||||
|
|
||||||
TLSCryptV2ServerKey()
|
TLSCryptV2ServerKey()
|
||||||
: key_size(128),
|
: key_size(128),
|
||||||
key(key_size, BufferAllocated::DESTRUCT_ZERO)
|
key(key_size, BufAllocFlags::DESTRUCT_ZERO)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ class TLSCryptV2ClientKey
|
|||||||
|
|
||||||
void parse(const std::string &key_text)
|
void parse(const std::string &key_text)
|
||||||
{
|
{
|
||||||
BufferAllocated data(key_size + WKC_MAX_SIZE, BufferAllocated::DESTRUCT_ZERO);
|
BufferAllocated data(key_size + WKC_MAX_SIZE, BufAllocFlags::DESTRUCT_ZERO);
|
||||||
|
|
||||||
if (!SSLLib::PEMAPI::pem_decode(data, key_text.c_str(), key_text.length(), tls_crypt_v2_client_key_name))
|
if (!SSLLib::PEMAPI::pem_decode(data, key_text.c_str(), key_text.length(), tls_crypt_v2_client_key_name))
|
||||||
throw tls_crypt_v2_client_key_parse_error();
|
throw tls_crypt_v2_client_key_parse_error();
|
||||||
@ -119,8 +119,8 @@ class TLSCryptV2ClientKey
|
|||||||
if (data.size() < (tag_size + key_size))
|
if (data.size() < (tag_size + key_size))
|
||||||
throw tls_crypt_v2_client_key_bad_size();
|
throw tls_crypt_v2_client_key_bad_size();
|
||||||
|
|
||||||
key.init(data.data(), key_size, BufferAllocated::DESTRUCT_ZERO);
|
key.init(data.data(), key_size, BufAllocFlags::DESTRUCT_ZERO);
|
||||||
wkc.init(data.data() + key_size, data.size() - key_size, BufferAllocated::DESTRUCT_ZERO);
|
wkc.init(data.data() + key_size, data.size() - key_size, BufAllocFlags::DESTRUCT_ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void extract_key(OpenVPNStaticKey &tls_key)
|
void extract_key(OpenVPNStaticKey &tls_key)
|
||||||
@ -131,7 +131,7 @@ class TLSCryptV2ClientKey
|
|||||||
std::string render() const
|
std::string render() const
|
||||||
{
|
{
|
||||||
BufferAllocated data(32 + 2 * (key.size() + wkc.size()), 0);
|
BufferAllocated data(32 + 2 * (key.size() + wkc.size()), 0);
|
||||||
BufferAllocated in(key, BufferAllocated::GROW);
|
BufferAllocated in(key, BufAllocFlags::GROW);
|
||||||
in.append(wkc);
|
in.append(wkc);
|
||||||
|
|
||||||
if (!SSLLib::PEMAPI::pem_encode(data, in.c_data(), in.size(), tls_crypt_v2_client_key_name))
|
if (!SSLLib::PEMAPI::pem_encode(data, in.c_data(), in.size(), tls_crypt_v2_client_key_name))
|
||||||
|
@ -643,7 +643,7 @@ class OvpnDcoClient : public Client,
|
|||||||
// good enough values for control channel packets
|
// good enough values for control channel packets
|
||||||
pkt->buf.reset(512,
|
pkt->buf.reset(512,
|
||||||
3072,
|
3072,
|
||||||
BufferAllocated::GROW | BufferAllocated::CONSTRUCT_ZERO | BufferAllocated::DESTRUCT_ZERO);
|
BufAllocFlags::GROW | BufAllocFlags::CONSTRUCT_ZERO | BufAllocFlags::DESTRUCT_ZERO);
|
||||||
pipe->async_read_some(
|
pipe->async_read_some(
|
||||||
pkt->buf.mutable_buffer(),
|
pkt->buf.mutable_buffer(),
|
||||||
[self = Ptr(this),
|
[self = Ptr(this),
|
||||||
|
@ -84,7 +84,7 @@ class Frame : public RC<thread_unsafe_refcount>
|
|||||||
const size_t tailroom,
|
const size_t tailroom,
|
||||||
const size_t align_adjust, // length of leading prefix data before the data that needs to be aligned on a size_t boundary
|
const size_t align_adjust, // length of leading prefix data before the data that needs to be aligned on a size_t boundary
|
||||||
const size_t align_block, // size of alignment block, usually sizeof(size_t) but sometimes the cipher block size
|
const size_t align_block, // size of alignment block, usually sizeof(size_t) but sometimes the cipher block size
|
||||||
const unsigned int buffer_flags) // flags passed to BufferAllocated constructor
|
const unsigned int buffer_flags) // flags passed to BufferAllocatedRc constructor
|
||||||
{
|
{
|
||||||
headroom_ = headroom;
|
headroom_ = headroom;
|
||||||
payload_ = payload;
|
payload_ = payload;
|
||||||
@ -144,11 +144,11 @@ class Frame : public RC<thread_unsafe_refcount>
|
|||||||
buf.realign(actual_headroom(buf.c_data_raw()));
|
buf.realign(actual_headroom(buf.c_data_raw()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a new BufferAllocated object initialized with the given data.
|
// Return a new BufferAllocatedRc object initialized with the given data.
|
||||||
BufferPtr copy(const unsigned char *data, const size_t size) const
|
BufferPtr copy(const unsigned char *data, const size_t size) const
|
||||||
{
|
{
|
||||||
const size_t cap = size + headroom() + tailroom();
|
const size_t cap = size + headroom() + tailroom();
|
||||||
BufferPtr b = new BufferAllocated(cap, buffer_flags());
|
auto b = BufferAllocatedRc::Create(cap, buffer_flags());
|
||||||
b->init_headroom(actual_headroom(b->c_data_raw()));
|
b->init_headroom(actual_headroom(b->c_data_raw()));
|
||||||
b->write(data, size);
|
b->write(data, size);
|
||||||
return b;
|
return b;
|
||||||
@ -164,13 +164,13 @@ class Frame : public RC<thread_unsafe_refcount>
|
|||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a new BufferAllocated object initialized with
|
// Return a new BufferAllocatedRc object initialized with
|
||||||
// the data in given buffer. buf may be empty or undefined.
|
// the data in given buffer. buf may be empty or undefined.
|
||||||
BufferPtr copy(const BufferPtr &buf) const
|
BufferPtr copy(const BufferPtr &buf) const
|
||||||
{
|
{
|
||||||
const size_t size = buf ? buf->size() : 0;
|
const size_t size = buf ? buf->size() : 0;
|
||||||
const size_t cap = size + headroom() + tailroom();
|
const size_t cap = size + headroom() + tailroom();
|
||||||
BufferPtr b = new BufferAllocated(cap, buffer_flags());
|
auto b = BufferAllocatedRc::Create(cap, buffer_flags());
|
||||||
b->init_headroom(actual_headroom(b->c_data_raw()));
|
b->init_headroom(actual_headroom(b->c_data_raw()));
|
||||||
if (size)
|
if (size)
|
||||||
b->write(buf->c_data(), size);
|
b->write(buf->c_data(), size);
|
||||||
@ -280,7 +280,7 @@ class Frame : public RC<thread_unsafe_refcount>
|
|||||||
|
|
||||||
BufferPtr prepare(const unsigned int context) const
|
BufferPtr prepare(const unsigned int context) const
|
||||||
{
|
{
|
||||||
BufferPtr buf(new BufferAllocated());
|
auto buf = BufferAllocatedRc::Create();
|
||||||
prepare(context, *buf);
|
prepare(context, *buf);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ inline Frame::Ptr frame_init(const bool align_adjust_3_1,
|
|||||||
tailroom,
|
tailroom,
|
||||||
0,
|
0,
|
||||||
align_block,
|
align_block,
|
||||||
BufferAllocated::GROW);
|
BufAllocFlags::GROW);
|
||||||
frame->standardize_capacity(~0);
|
frame->standardize_capacity(~0);
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
|
@ -77,7 +77,7 @@ class MemQStream : public MemQBase
|
|||||||
// Start a new buffer
|
// Start a new buffer
|
||||||
while (b.size())
|
while (b.size())
|
||||||
{
|
{
|
||||||
BufferPtr newbuf(new BufferAllocated);
|
auto newbuf = BufferAllocatedRc::Create();
|
||||||
fc.prepare(*newbuf);
|
fc.prepare(*newbuf);
|
||||||
const size_t write_size = std::min(b.size(), fc.payload());
|
const size_t write_size = std::min(b.size(), fc.payload());
|
||||||
const unsigned char *from = b.read_alloc(write_size);
|
const unsigned char *from = b.read_alloc(write_size);
|
||||||
|
@ -80,7 +80,7 @@ class MbedTLSPEM
|
|||||||
{
|
{
|
||||||
size_t buflen = 0;
|
size_t buflen = 0;
|
||||||
const uint8_t *bufptr = mbedtls_pem_get_buffer(&ctx, &buflen);
|
const uint8_t *bufptr = mbedtls_pem_get_buffer(&ctx, &buflen);
|
||||||
dst.init(bufptr, buflen, BufferAllocated::DESTRUCT_ZERO);
|
dst.init(bufptr, buflen, BufAllocFlags::DESTRUCT_ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_pem_free(&ctx);
|
mbedtls_pem_free(&ctx);
|
||||||
|
@ -930,7 +930,7 @@ class OMICore : public Acceptor::ListenerBase
|
|||||||
{
|
{
|
||||||
if (!is_sock_open() || recv_queued)
|
if (!is_sock_open() || recv_queued)
|
||||||
return;
|
return;
|
||||||
BufferPtr buf(new BufferAllocated(256, 0));
|
BufferPtr buf = BufferAllocatedRc::Create(256, 0);
|
||||||
socket->async_receive(buf->mutable_buffer_clamp(),
|
socket->async_receive(buf->mutable_buffer_clamp(),
|
||||||
[self = Ptr(this), sock = socket, buf](const openvpn_io::error_code &error, const size_t bytes_recvd)
|
[self = Ptr(this), sock = socket, buf](const openvpn_io::error_code &error, const size_t bytes_recvd)
|
||||||
{
|
{
|
||||||
@ -990,7 +990,7 @@ class OMICore : public Acceptor::ListenerBase
|
|||||||
{
|
{
|
||||||
if (!is_sock_open())
|
if (!is_sock_open())
|
||||||
return;
|
return;
|
||||||
BufferAllocated &buf = *content_out.front();
|
auto &buf = *content_out.front();
|
||||||
socket->async_send(buf.const_buffer_clamp(),
|
socket->async_send(buf.const_buffer_clamp(),
|
||||||
[self = Ptr(this), sock = socket](const openvpn_io::error_code &error, const size_t bytes_sent)
|
[self = Ptr(this), sock = socket](const openvpn_io::error_code &error, const size_t bytes_sent)
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,7 @@ class PushContinuationFragment : public std::vector<BufferPtr>
|
|||||||
total_size += e->size();
|
total_size += e->size();
|
||||||
|
|
||||||
// allocate return buffer
|
// allocate return buffer
|
||||||
BufferPtr ret(new BufferAllocated(total_size, 0));
|
auto ret = BufferAllocatedRc::Create(total_size, 0);
|
||||||
buf_append_string(*ret, "PUSH_REPLY");
|
buf_append_string(*ret, "PUSH_REPLY");
|
||||||
|
|
||||||
// terminators
|
// terminators
|
||||||
@ -163,7 +163,7 @@ class PushContinuationFragment : public std::vector<BufferPtr>
|
|||||||
void append_new_buffer()
|
void append_new_buffer()
|
||||||
{
|
{
|
||||||
// include extra byte for null termination
|
// include extra byte for null termination
|
||||||
BufferPtr bp = new BufferAllocated(FRAGMENT_SIZE + 1, 0);
|
auto bp = BufferAllocatedRc::Create(FRAGMENT_SIZE + 1, 0);
|
||||||
buf_append_string(*bp, "PUSH_REPLY");
|
buf_append_string(*bp, "PUSH_REPLY");
|
||||||
push_back(std::move(bp));
|
push_back(std::move(bp));
|
||||||
}
|
}
|
||||||
|
@ -459,7 +459,7 @@ class MyClientInstance : public WS::Server::Listener::Client
|
|||||||
void http_content_in(BufferAllocated &buf) override
|
void http_content_in(BufferAllocated &buf) override
|
||||||
{
|
{
|
||||||
if (buf.defined())
|
if (buf.defined())
|
||||||
in.emplace_back(new BufferAllocated(std::move(buf)));
|
in.emplace_back(BufferAllocatedRc::Create(std::move(buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferPtr http_content_out() override
|
BufferPtr http_content_out() override
|
||||||
|
@ -812,7 +812,7 @@ class MyClientInstance : public WS::Server::Listener::Client
|
|||||||
void http_content_in(BufferAllocated &buf) override
|
void http_content_in(BufferAllocated &buf) override
|
||||||
{
|
{
|
||||||
if (buf.defined())
|
if (buf.defined())
|
||||||
in.emplace_back(new BufferAllocated(std::move(buf)));
|
in.emplace_back(BufferAllocatedRc::Create(std::move(buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferPtr http_content_out() override
|
BufferPtr http_content_out() override
|
||||||
|
@ -152,7 +152,7 @@ class NTLM
|
|||||||
std::memcpy(ntlmv2_response, ntlmv2_hmacmd5, 16);
|
std::memcpy(ntlmv2_response, ntlmv2_hmacmd5, 16);
|
||||||
|
|
||||||
// start building phase3 message (what we return to caller)
|
// start building phase3 message (what we return to caller)
|
||||||
BufferAllocated phase3(0x40, BufferAllocated::ARRAY | BufferAllocated::CONSTRUCT_ZERO | BufferAllocated::GROW);
|
BufferAllocated phase3(0x40, BufAllocFlags::ARRAY | BufAllocFlags::CONSTRUCT_ZERO | BufAllocFlags::GROW);
|
||||||
std::strcpy((char *)phase3.data(), "NTLMSSP"); // signature
|
std::strcpy((char *)phase3.data(), "NTLMSSP"); // signature
|
||||||
phase3[8] = 3; // type 3
|
phase3[8] = 3; // type 3
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ class ServerProto
|
|||||||
|
|
||||||
if (proto_context.primary_defined())
|
if (proto_context.primary_defined())
|
||||||
{
|
{
|
||||||
BufferPtr buf(new BufferAllocated(64, 0));
|
auto buf = BufferAllocatedRc::Create(64, 0);
|
||||||
buf_append_string(*buf, "RELAY");
|
buf_append_string(*buf, "RELAY");
|
||||||
buf->null_terminate();
|
buf->null_terminate();
|
||||||
proto_context.control_send(std::move(buf));
|
proto_context.control_send(std::move(buf));
|
||||||
@ -465,7 +465,7 @@ class ServerProto
|
|||||||
|
|
||||||
proto_context.update_now();
|
proto_context.update_now();
|
||||||
|
|
||||||
BufferPtr buf(new BufferAllocated(128, BufferAllocated::GROW));
|
auto buf = BufferAllocatedRc::Create(128, BufAllocFlags::GROW);
|
||||||
BufferStreamOut os(*buf);
|
BufferStreamOut os(*buf);
|
||||||
|
|
||||||
std::string ts;
|
std::string ts;
|
||||||
|
@ -183,7 +183,7 @@ class AppControlMessageReceiver
|
|||||||
bool receive_message(const std::string &msg)
|
bool receive_message(const std::string &msg)
|
||||||
{
|
{
|
||||||
if (!recvbuf.defined())
|
if (!recvbuf.defined())
|
||||||
recvbuf.reset(256, BufferAllocated::GROW);
|
recvbuf.reset(256, BufAllocFlags::GROW);
|
||||||
// msg includes ACC, prefix
|
// msg includes ACC, prefix
|
||||||
auto parts = string::split(msg, ',', 4);
|
auto parts = string::split(msg, ',', 4);
|
||||||
if (parts.size() != 5 || parts[0] != "ACC")
|
if (parts.size() != 5 || parts[0] != "ACC")
|
||||||
|
@ -1595,7 +1595,7 @@ class ProtoContext : public logging::LoggingMixin<OPENVPN_DEBUG_PROTO,
|
|||||||
void write_control_string(const S &str)
|
void write_control_string(const S &str)
|
||||||
{
|
{
|
||||||
const size_t len = str.length();
|
const size_t len = str.length();
|
||||||
BufferPtr bp = new BufferAllocated(len + 1, 0);
|
auto bp = BufferAllocatedRc::Create(len + 1, 0);
|
||||||
write_control_string(str, *bp);
|
write_control_string(str, *bp);
|
||||||
control_send(std::move(bp));
|
control_send(std::move(bp));
|
||||||
}
|
}
|
||||||
@ -1623,7 +1623,7 @@ class ProtoContext : public logging::LoggingMixin<OPENVPN_DEBUG_PROTO,
|
|||||||
{
|
{
|
||||||
Packet pkt;
|
Packet pkt;
|
||||||
pkt.opcode = opcode;
|
pkt.opcode = opcode;
|
||||||
pkt.buf.reset(new BufferAllocated(*buf));
|
pkt.buf = BufferAllocatedRc::Create(*buf);
|
||||||
return pkt;
|
return pkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1636,7 +1636,7 @@ class ProtoContext : public logging::LoggingMixin<OPENVPN_DEBUG_PROTO,
|
|||||||
void frame_prepare(const Frame &frame, const unsigned int context)
|
void frame_prepare(const Frame &frame, const unsigned int context)
|
||||||
{
|
{
|
||||||
if (!buf)
|
if (!buf)
|
||||||
buf.reset(new BufferAllocated());
|
buf = BufferAllocatedRc::Create();
|
||||||
frame.prepare(context, *buf);
|
frame.prepare(context, *buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2864,7 +2864,7 @@ class ProtoContext : public logging::LoggingMixin<OPENVPN_DEBUG_PROTO,
|
|||||||
|
|
||||||
void send_auth()
|
void send_auth()
|
||||||
{
|
{
|
||||||
BufferPtr buf = new BufferAllocated();
|
auto buf = BufferAllocatedRc::Create();
|
||||||
proto.config->frame->prepare(Frame::WRITE_SSL_CLEARTEXT, *buf);
|
proto.config->frame->prepare(Frame::WRITE_SSL_CLEARTEXT, *buf);
|
||||||
buf->write(proto_context_private::auth_prefix, sizeof(proto_context_private::auth_prefix));
|
buf->write(proto_context_private::auth_prefix, sizeof(proto_context_private::auth_prefix));
|
||||||
tlsprf->self_randomize(*proto.config->rng);
|
tlsprf->self_randomize(*proto.config->rng);
|
||||||
@ -2874,7 +2874,7 @@ class ProtoContext : public logging::LoggingMixin<OPENVPN_DEBUG_PROTO,
|
|||||||
if (!proto.is_server())
|
if (!proto.is_server())
|
||||||
{
|
{
|
||||||
OVPN_LOG_INFO("Tunnel Options:" << options);
|
OVPN_LOG_INFO("Tunnel Options:" << options);
|
||||||
buf->or_flags(BufferAllocated::DESTRUCT_ZERO);
|
buf->or_flags(BufAllocFlags::DESTRUCT_ZERO);
|
||||||
if (proto.config->xmit_creds)
|
if (proto.config->xmit_creds)
|
||||||
proto.client_auth(*buf);
|
proto.client_auth(*buf);
|
||||||
else
|
else
|
||||||
@ -3223,7 +3223,7 @@ class ProtoContext : public logging::LoggingMixin<OPENVPN_DEBUG_PROTO,
|
|||||||
|
|
||||||
bool decapsulate_tls_crypt(Packet &pkt)
|
bool decapsulate_tls_crypt(Packet &pkt)
|
||||||
{
|
{
|
||||||
BufferAllocated &recv = *pkt.buf;
|
auto &recv = *pkt.buf;
|
||||||
const unsigned char *orig_data = recv.data();
|
const unsigned char *orig_data = recv.data();
|
||||||
const size_t orig_size = recv.size();
|
const size_t orig_size = recv.size();
|
||||||
|
|
||||||
@ -3357,7 +3357,7 @@ class ProtoContext : public logging::LoggingMixin<OPENVPN_DEBUG_PROTO,
|
|||||||
if ((wkc_len - sizeof(uint16_t)) != wkc_raw_size)
|
if ((wkc_len - sizeof(uint16_t)) != wkc_raw_size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BufferAllocated plaintext(wkc_len, BufferAllocated::CONSTRUCT_ZERO);
|
BufferAllocated plaintext(wkc_len, BufAllocFlags::CONSTRUCT_ZERO);
|
||||||
// plaintext will be used to compute the Auth Tag, therefore start by prepending
|
// plaintext will be used to compute the Auth Tag, therefore start by prepending
|
||||||
// the WKc length in network order
|
// the WKc length in network order
|
||||||
wkc_len = htons(wkc_len);
|
wkc_len = htons(wkc_len);
|
||||||
@ -4096,7 +4096,7 @@ class ProtoContext : public logging::LoggingMixin<OPENVPN_DEBUG_PROTO,
|
|||||||
|
|
||||||
void control_send(BufferAllocated &&app_buf)
|
void control_send(BufferAllocated &&app_buf)
|
||||||
{
|
{
|
||||||
control_send(app_buf.move_to_ptr());
|
control_send(BufferAllocatedRc::Create(std::move(app_buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate a control channel network packet
|
// validate a control channel network packet
|
||||||
@ -4109,14 +4109,14 @@ class ProtoContext : public logging::LoggingMixin<OPENVPN_DEBUG_PROTO,
|
|||||||
|
|
||||||
bool control_net_recv(const PacketType &type, BufferAllocated &&net_buf)
|
bool control_net_recv(const PacketType &type, BufferAllocated &&net_buf)
|
||||||
{
|
{
|
||||||
Packet pkt(net_buf.move_to_ptr(), type.opcode);
|
Packet pkt(BufferAllocatedRc::Create(std::move(net_buf)), type.opcode);
|
||||||
if (type.is_soft_reset() && !renegotiate_request(pkt))
|
if (type.is_soft_reset() && !renegotiate_request(pkt))
|
||||||
return false;
|
return false;
|
||||||
return select_key_context(type, true).net_recv(std::move(pkt));
|
return select_key_context(type, true).net_recv(std::move(pkt));
|
||||||
}
|
}
|
||||||
|
|
||||||
// this version only appears to support test_proto.cpp; suggest creating a
|
// this version only appears to support test_proto.cpp; suggest creating a
|
||||||
// local BufferAllocated and move the BufferPtr contents into it; then use
|
// local BufferAllocatedRc and move the BufferPtr contents into it; then use
|
||||||
// the version above
|
// the version above
|
||||||
bool control_net_recv(const PacketType &type, BufferPtr &&net_bp)
|
bool control_net_recv(const PacketType &type, BufferPtr &&net_bp)
|
||||||
{
|
{
|
||||||
|
@ -451,7 +451,7 @@ class ProtoStackBase
|
|||||||
while (ssl_->read_cleartext_ready())
|
while (ssl_->read_cleartext_ready())
|
||||||
{
|
{
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
to_app_buf.reset(new BufferAllocated());
|
to_app_buf = BufferAllocatedRc::Create();
|
||||||
frame_->prepare(Frame::READ_SSL_CLEARTEXT, *to_app_buf);
|
frame_->prepare(Frame::READ_SSL_CLEARTEXT, *to_app_buf);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -156,7 +156,7 @@ class TLSPRF
|
|||||||
+ client_seed_len
|
+ client_seed_len
|
||||||
+ server_seed_len
|
+ server_seed_len
|
||||||
+ ProtoSessionID::SIZE * 2,
|
+ ProtoSessionID::SIZE * 2,
|
||||||
BufferAllocated::DESTRUCT_ZERO);
|
BufAllocFlags::DESTRUCT_ZERO);
|
||||||
seed.write((unsigned char *)label, label_len);
|
seed.write((unsigned char *)label, label_len);
|
||||||
seed.write(client_seed, client_seed_len);
|
seed.write(client_seed, client_seed_len);
|
||||||
seed.write(server_seed, server_seed_len);
|
seed.write(server_seed, server_seed_len);
|
||||||
|
@ -203,9 +203,9 @@ class PacketStream
|
|||||||
|
|
||||||
static void validate_size(const size_t size, const Frame::Context &frame_context)
|
static void validate_size(const size_t size, const Frame::Context &frame_context)
|
||||||
{
|
{
|
||||||
// Don't validate upper bound on size if BufferAllocated::GROW is set,
|
// Don't validate upper bound on size if BufAllocFlags::GROW is set,
|
||||||
// allowing it to range up to larger sizes.
|
// allowing it to range up to larger sizes.
|
||||||
if (!size || (!(frame_context.buffer_flags() & BufferAllocated::GROW) && size > frame_context.payload()))
|
if (!size || (!(frame_context.buffer_flags() & BufAllocFlags::GROW) && size > frame_context.payload()))
|
||||||
throw embedded_packet_size_error();
|
throw embedded_packet_size_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ class LinkCommon : public LinkBase
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf.reset(new BufferAllocated());
|
buf = BufferAllocatedRc::Create();
|
||||||
}
|
}
|
||||||
buf->swap(b);
|
buf->swap(b);
|
||||||
if (!is_raw_mode_write())
|
if (!is_raw_mode_write())
|
||||||
|
@ -219,7 +219,7 @@ class UDPLink : public RC<thread_unsafe_refcount>
|
|||||||
std::unique_ptr<AsioEndpoint> ep;
|
std::unique_ptr<AsioEndpoint> ep;
|
||||||
if (endpoint)
|
if (endpoint)
|
||||||
ep.reset(new AsioEndpoint(*endpoint));
|
ep.reset(new AsioEndpoint(*endpoint));
|
||||||
gremlin->send_queue([self = Ptr(this), buf = BufferAllocated(buf, 0), ep = std::move(ep)]() mutable
|
gremlin->send_queue([self = Ptr(this), buf = BufferAllocatedRc(buf, 0), ep = std::move(ep)]() mutable
|
||||||
{
|
{
|
||||||
if (!self->halt)
|
if (!self->halt)
|
||||||
self->do_send(buf, ep.get()); });
|
self->do_send(buf, ep.get()); });
|
||||||
|
@ -755,7 +755,7 @@ class GeNL : public RC<thread_unsafe_refcount>
|
|||||||
void reset_buffer()
|
void reset_buffer()
|
||||||
{
|
{
|
||||||
// good enough values to handle control packets
|
// good enough values to handle control packets
|
||||||
buf.reset(512, 3072, BufferAllocated::GROW | BufferAllocated::CONSTRUCT_ZERO | BufferAllocated::DESTRUCT_ZERO);
|
buf.reset(512, 3072, BufAllocFlags::GROW | BufAllocFlags::CONSTRUCT_ZERO | BufAllocFlags::DESTRUCT_ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +59,7 @@ enum
|
|||||||
|
|
||||||
inline IP::Addr cvt_pnr_ip_v4(const std::string &hexaddr)
|
inline IP::Addr cvt_pnr_ip_v4(const std::string &hexaddr)
|
||||||
{
|
{
|
||||||
BufferAllocated v(4, BufferAllocated::CONSTRUCT_ZERO);
|
BufferAllocated v(4, BufAllocFlags::CONSTRUCT_ZERO);
|
||||||
parse_hex(v, hexaddr);
|
parse_hex(v, hexaddr);
|
||||||
if (v.size() != 4)
|
if (v.size() != 4)
|
||||||
throw tun_linux_error("bad hex address");
|
throw tun_linux_error("bad hex address");
|
||||||
|
@ -512,7 +512,7 @@ inline int iface_del(std::ostringstream &os, const std::string &dev)
|
|||||||
|
|
||||||
/*inline IPv4::Addr cvt_pnr_ip_v4(const std::string& hexaddr)
|
/*inline IPv4::Addr cvt_pnr_ip_v4(const std::string& hexaddr)
|
||||||
{
|
{
|
||||||
BufferAllocated v(4, BufferAllocated::CONSTRUCT_ZERO);
|
BufferAllocated v(4, BufAllocFlags::CONSTRUCT_ZERO);
|
||||||
parse_hex(v, hexaddr);
|
parse_hex(v, hexaddr);
|
||||||
if (v.size() != 4)
|
if (v.size() != 4)
|
||||||
throw tun_linux_error("bad hex address");
|
throw tun_linux_error("bad hex address");
|
||||||
|
@ -475,7 +475,7 @@ struct DeviceInstanceIdInterfaceList : public std::vector<DeviceInstanceIdInterf
|
|||||||
LONG status = RegQueryValueExA(regkey(), "NetCfgInstanceId", NULL, NULL, NULL, &size);
|
LONG status = RegQueryValueExA(regkey(), "NetCfgInstanceId", NULL, NULL, NULL, &size);
|
||||||
if (status != ERROR_SUCCESS)
|
if (status != ERROR_SUCCESS)
|
||||||
continue;
|
continue;
|
||||||
BufferAllocatedType<char, thread_unsafe_refcount> buf_net_cfg_inst_id(size, BufferAllocated::CONSTRUCT_ZERO);
|
BufferAllocatedType<char> buf_net_cfg_inst_id(size, BufAllocFlags::CONSTRUCT_ZERO);
|
||||||
|
|
||||||
status = RegQueryValueExA(regkey(), "NetCfgInstanceId", NULL, NULL, (LPBYTE)buf_net_cfg_inst_id.data(), &size);
|
status = RegQueryValueExA(regkey(), "NetCfgInstanceId", NULL, NULL, (LPBYTE)buf_net_cfg_inst_id.data(), &size);
|
||||||
if (status == ERROR_SUCCESS)
|
if (status == ERROR_SUCCESS)
|
||||||
@ -490,7 +490,7 @@ struct DeviceInstanceIdInterfaceList : public std::vector<DeviceInstanceIdInterf
|
|||||||
if (res != FALSE && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
if (res != FALSE && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BufferAllocatedType<char, thread_unsafe_refcount> buf_dev_inst_id(size, BufferAllocated::CONSTRUCT_ZERO);
|
BufferAllocatedType<char> buf_dev_inst_id(size, BufAllocFlags::CONSTRUCT_ZERO);
|
||||||
if (!SetupDiGetDeviceInstanceId(device_info_set, &dev_info_data, buf_dev_inst_id.data(), size, &size))
|
if (!SetupDiGetDeviceInstanceId(device_info_set, &dev_info_data, buf_dev_inst_id.data(), size, &size))
|
||||||
continue;
|
continue;
|
||||||
buf_dev_inst_id.set_size(size);
|
buf_dev_inst_id.set_size(size);
|
||||||
@ -504,7 +504,7 @@ struct DeviceInstanceIdInterfaceList : public std::vector<DeviceInstanceIdInterf
|
|||||||
if (cr != CR_SUCCESS)
|
if (cr != CR_SUCCESS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BufferAllocatedType<char, thread_unsafe_refcount> buf_dev_iface_list(dev_interface_list_size, BufferAllocated::CONSTRUCT_ZERO);
|
BufferAllocatedType<char> buf_dev_iface_list(dev_interface_list_size, BufAllocFlags::CONSTRUCT_ZERO);
|
||||||
cr = CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_NET,
|
cr = CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_NET,
|
||||||
buf_dev_inst_id.data(),
|
buf_dev_inst_id.data(),
|
||||||
buf_dev_iface_list.data(),
|
buf_dev_iface_list.data(),
|
||||||
|
@ -1095,7 +1095,7 @@ class HTTPCore : public Base, public TransportClientParent
|
|||||||
const Request req = http_request();
|
const Request req = http_request();
|
||||||
content_info = http_content_info();
|
content_info = http_content_info();
|
||||||
|
|
||||||
outbuf.reset(new BufferAllocated(512, BufferAllocated::GROW));
|
outbuf = BufferAllocatedRc::Create(512, BufAllocFlags::GROW);
|
||||||
BufferStreamOut os(*outbuf);
|
BufferStreamOut os(*outbuf);
|
||||||
|
|
||||||
if (content_info.websocket)
|
if (content_info.websocket)
|
||||||
|
@ -835,7 +835,7 @@ class ClientSet : public RC<thread_unsafe_refcount>
|
|||||||
{
|
{
|
||||||
if (out_iter != trans().content_out.end())
|
if (out_iter != trans().content_out.end())
|
||||||
{
|
{
|
||||||
BufferPtr ret = new BufferAllocated(**out_iter);
|
auto ret = BufferAllocatedRc::Create(**out_iter);
|
||||||
++out_iter;
|
++out_iter;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ class HTTPBase : public REFCOUNT_BASE
|
|||||||
if (ssl_sess)
|
if (ssl_sess)
|
||||||
{
|
{
|
||||||
// HTTPS
|
// HTTPS
|
||||||
BufferPtr buf(new BufferAllocated());
|
auto buf = BufferAllocatedRc::Create();
|
||||||
buf->swap(b); // take ownership
|
buf->swap(b); // take ownership
|
||||||
ssl_sess->write_ciphertext(buf);
|
ssl_sess->write_ciphertext(buf);
|
||||||
ssl_up_stack();
|
ssl_up_stack();
|
||||||
@ -252,10 +252,10 @@ class HTTPBase : public REFCOUNT_BASE
|
|||||||
// void base_http_content_out_needed();
|
// void base_http_content_out_needed();
|
||||||
// void base_http_out_eof();
|
// void base_http_out_eof();
|
||||||
// bool base_http_headers_received();
|
// bool base_http_headers_received();
|
||||||
// void base_http_content_in(BufferAllocated& buf);
|
// void base_http_content_in(BufferAllocatedRc& buf);
|
||||||
// bool base_link_send(BufferAllocated& buf);
|
// bool base_link_send(BufferAllocatedRc& buf);
|
||||||
// bool base_send_queue_empty();
|
// bool base_send_queue_empty();
|
||||||
// void base_http_done_handler(BufferAllocated& residual)
|
// void base_http_done_handler(BufferAllocatedRc& residual)
|
||||||
// void base_error_handler(const int errcode, const std::string& err);
|
// void base_error_handler(const int errcode, const std::string& err);
|
||||||
|
|
||||||
// protected member vars
|
// protected member vars
|
||||||
|
@ -306,7 +306,7 @@ class Listener : public ProxyListener
|
|||||||
|
|
||||||
content_info = std::move(ci);
|
content_info = std::move(ci);
|
||||||
|
|
||||||
outbuf.reset(new BufferAllocated(512, BufferAllocated::GROW));
|
outbuf = BufferAllocatedRc::Create(512, BufAllocFlags::GROW);
|
||||||
BufferStreamOut os(*outbuf);
|
BufferStreamOut os(*outbuf);
|
||||||
|
|
||||||
// websocket?
|
// websocket?
|
||||||
|
@ -333,7 +333,7 @@ class Receiver
|
|||||||
if (!buf.allocated())
|
if (!buf.allocated())
|
||||||
{
|
{
|
||||||
buf = std::move(inbuf);
|
buf = std::move(inbuf);
|
||||||
buf.or_flags(BufferAllocated::GROW);
|
buf.or_flags(BufAllocFlags::GROW);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
buf.append(inbuf);
|
buf.append(inbuf);
|
||||||
|
@ -533,7 +533,7 @@ class Client : public ClientBase
|
|||||||
{
|
{
|
||||||
using PKEY_CTX_unique_ptr = std::unique_ptr<::EVP_PKEY_CTX, decltype(&::EVP_PKEY_CTX_free)>;
|
using PKEY_CTX_unique_ptr = std::unique_ptr<::EVP_PKEY_CTX, decltype(&::EVP_PKEY_CTX_free)>;
|
||||||
|
|
||||||
BufferAllocated signdata(256, BufferAllocated::GROW);
|
BufferAllocated signdata(256, BufAllocFlags::GROW);
|
||||||
base64->decode(signdata, signreq.data);
|
base64->decode(signdata, signreq.data);
|
||||||
|
|
||||||
EVP_PKEY *pkey = epki_pkey.obj();
|
EVP_PKEY *pkey = epki_pkey.obj();
|
||||||
@ -572,7 +572,7 @@ class Client : public ClientBase
|
|||||||
throw Exception("epki_sign failed, error signing data: " + openssl_error());
|
throw Exception("epki_sign failed, error signing data: " + openssl_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferAllocated sig(outlen, BufferAllocated::ARRAY);
|
BufferAllocated sig(outlen, BufAllocFlags::ARRAY);
|
||||||
|
|
||||||
if ((EVP_PKEY_sign(pkey_ctx.get(), sig.data(), &outlen, signdata.c_data(), signdata.size())) < 0)
|
if ((EVP_PKEY_sign(pkey_ctx.get(), sig.data(), &outlen, signdata.c_data(), signdata.size())) < 0)
|
||||||
{
|
{
|
||||||
@ -598,7 +598,7 @@ class Client : public ClientBase
|
|||||||
void doOpenSSLDigestSignature(ClientAPI::ExternalPKISignRequest &signreq)
|
void doOpenSSLDigestSignature(ClientAPI::ExternalPKISignRequest &signreq)
|
||||||
{
|
{
|
||||||
EVP_PKEY_CTX *pkey_ctx = nullptr;
|
EVP_PKEY_CTX *pkey_ctx = nullptr;
|
||||||
BufferAllocated signdata(256, BufferAllocated::GROW);
|
BufferAllocated signdata(256, BufAllocFlags::GROW);
|
||||||
base64->decode(signdata, signreq.data);
|
base64->decode(signdata, signreq.data);
|
||||||
|
|
||||||
using MD_unique_ptr = std::unique_ptr<::EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>;
|
using MD_unique_ptr = std::unique_ptr<::EVP_MD_CTX, decltype(&::EVP_MD_CTX_free)>;
|
||||||
@ -660,7 +660,7 @@ class Client : public ClientBase
|
|||||||
throw Exception("epki_sign failed, error signing data: " + openssl_error());
|
throw Exception("epki_sign failed, error signing data: " + openssl_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferAllocated sig(outlen, BufferAllocated::ARRAY);
|
BufferAllocated sig(outlen, BufAllocFlags::ARRAY);
|
||||||
|
|
||||||
if (EVP_DigestSign(md.get(), sig.data(), &outlen, signdata.data(), signdata.size()) < 0)
|
if (EVP_DigestSign(md.get(), sig.data(), &outlen, signdata.data(), signdata.size()) < 0)
|
||||||
{
|
{
|
||||||
@ -694,7 +694,7 @@ class Client : public ClientBase
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// decode base64 sign request
|
// decode base64 sign request
|
||||||
BufferAllocated signdata(256, BufferAllocated::GROW);
|
BufferAllocated signdata(256, BufAllocFlags::GROW);
|
||||||
base64->decode(signdata, signreq.data);
|
base64->decode(signdata, signreq.data);
|
||||||
|
|
||||||
// get MD alg
|
// get MD alg
|
||||||
@ -704,7 +704,7 @@ class Client : public ClientBase
|
|||||||
OPENVPN_LOG("SIGN[" << PKCS1::DigestPrefix::MbedTLSParse::to_string(md_alg) << ',' << signdata.size() << "]: " << render_hex_generic(signdata));
|
OPENVPN_LOG("SIGN[" << PKCS1::DigestPrefix::MbedTLSParse::to_string(md_alg) << ',' << signdata.size() << "]: " << render_hex_generic(signdata));
|
||||||
|
|
||||||
// allocate buffer for signature
|
// allocate buffer for signature
|
||||||
BufferAllocated sig(mbedtls_pk_get_len(epki_ctx.get()), BufferAllocated::ARRAY);
|
BufferAllocated sig(mbedtls_pk_get_len(epki_ctx.get()), BufAllocFlags::ARRAY);
|
||||||
|
|
||||||
// sign it
|
// sign it
|
||||||
size_t sig_size = 0;
|
size_t sig_size = 0;
|
||||||
|
@ -74,6 +74,7 @@ add_executable(coreUnitTests
|
|||||||
test_statickey.cpp
|
test_statickey.cpp
|
||||||
test_streq.cpp
|
test_streq.cpp
|
||||||
test_time.cpp
|
test_time.cpp
|
||||||
|
test_make_rc.cpp
|
||||||
test_typeindex.cpp
|
test_typeindex.cpp
|
||||||
test_tun_builder.cpp
|
test_tun_builder.cpp
|
||||||
test_userpass.cpp
|
test_userpass.cpp
|
||||||
|
@ -14,7 +14,7 @@ TEST(buffer, const_buffer_ref_1)
|
|||||||
EXPECT_EQ(buf_to_string(buf), buf_to_string(cbuf));
|
EXPECT_EQ(buf_to_string(buf), buf_to_string(cbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
// test equality of BufferAllocated and ConstBuffer
|
// test equality of BufferAllocatedRc and ConstBuffer
|
||||||
TEST(buffer, const_buffer_ref_2)
|
TEST(buffer, const_buffer_ref_2)
|
||||||
{
|
{
|
||||||
BufferAllocated buf(64, 0);
|
BufferAllocated buf(64, 0);
|
||||||
@ -165,7 +165,7 @@ TEST(buffer, alloc_buffer_access1)
|
|||||||
// Test read/write access and bounds check
|
// Test read/write access and bounds check
|
||||||
TEST(buffer, alloc_buffer_access2)
|
TEST(buffer, alloc_buffer_access2)
|
||||||
{
|
{
|
||||||
BufferAllocated buf(64, BufferAllocated::CONSTRUCT_ZERO | BufferAllocated::DESTRUCT_ZERO);
|
BufferAllocated buf(64, BufAllocFlags::CONSTRUCT_ZERO | BufAllocFlags::DESTRUCT_ZERO);
|
||||||
buf_append_string(buf, "hello world");
|
buf_append_string(buf, "hello world");
|
||||||
|
|
||||||
buf[0] = 'j';
|
buf[0] = 'j';
|
||||||
|
@ -129,7 +129,7 @@ static OptionList random_optionlist(RandomAPI &prng)
|
|||||||
static void test_roundtrip(const OptionList &opt_orig)
|
static void test_roundtrip(const OptionList &opt_orig)
|
||||||
{
|
{
|
||||||
// first render to CSV
|
// first render to CSV
|
||||||
BufferAllocated buf(opt_orig.size() * 128, BufferAllocated::GROW);
|
BufferAllocated buf(opt_orig.size() * 128, BufAllocFlags::GROW);
|
||||||
buf_append_string(buf, "PUSH_REPLY,");
|
buf_append_string(buf, "PUSH_REPLY,");
|
||||||
buf_append_string(buf, opt_orig.render_csv());
|
buf_append_string(buf, opt_orig.render_csv());
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ TEST(continuation, test1)
|
|||||||
// push-list for further testing
|
// push-list for further testing
|
||||||
TEST(continuation, test2)
|
TEST(continuation, test2)
|
||||||
{
|
{
|
||||||
BufferAllocated buf(65536, BufferAllocated::GROW);
|
BufferAllocated buf(65536, BufAllocFlags::GROW);
|
||||||
buf_append_string(buf, "PUSH_REPLY,route-gateway 10.213.0.1,ifconfig 10.213.0.48 255.255.0.0,ifconfig-ipv6 fdab::48/64 fdab::1,client-ip 192.168.4.1,ping 1,ping-restart 8,reneg-sec 60,cipher AES-128-GCM,compress stub-v2,peer-id 4,topology subnet,explicit-exit-notify");
|
buf_append_string(buf, "PUSH_REPLY,route-gateway 10.213.0.1,ifconfig 10.213.0.48 255.255.0.0,ifconfig-ipv6 fdab::48/64 fdab::1,client-ip 192.168.4.1,ping 1,ping-restart 8,reneg-sec 60,cipher AES-128-GCM,compress stub-v2,peer-id 4,topology subnet,explicit-exit-notify");
|
||||||
|
|
||||||
// pack the buffers, so several reach the maximum
|
// pack the buffers, so several reach the maximum
|
||||||
|
87
test/unittests/test_make_rc.cpp
Normal file
87
test/unittests/test_make_rc.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#include <openvpn/common/make_rc.hpp>
|
||||||
|
|
||||||
|
using namespace openvpn;
|
||||||
|
|
||||||
|
// Tests the RcEnable and make_rc functionality.
|
||||||
|
|
||||||
|
struct test1
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
using rc_test1 = RcEnable<test1>;
|
||||||
|
|
||||||
|
// The `f_ptr` function checks that the reference-counted object has the expected value.
|
||||||
|
void f_ptr(rc_test1::Ptr rct1, int i)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(rct1->i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ref to base
|
||||||
|
void f_ref(test1 &t1, int i)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(t1.i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sliced value
|
||||||
|
void f_val(test1 t1, int i)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(t1.i, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The `direct_enable` test verifies that an RcEnable object can be created directly.
|
||||||
|
TEST(make_rc, direct_enable)
|
||||||
|
{
|
||||||
|
auto rct1 = RcEnable<test1>::Create();
|
||||||
|
EXPECT_EQ(rct1->i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The `simple` test verifies that a reference-counted object can be created using `make_rc`.
|
||||||
|
TEST(make_rc, simple)
|
||||||
|
{
|
||||||
|
auto rct1 = make_rc<test1>();
|
||||||
|
EXPECT_EQ(rct1->i, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The `move_init` test verifies that a reference-counted object can be created by moving an existing object.
|
||||||
|
TEST(make_rc, move_init)
|
||||||
|
{
|
||||||
|
auto t = test1();
|
||||||
|
EXPECT_EQ(t.i, 0);
|
||||||
|
t.i = 42;
|
||||||
|
auto rct1 = make_rc<test1>(std::move(t));
|
||||||
|
EXPECT_EQ(rct1->i, 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The `move_init_call` test verifies that a reference-counted object can be created by moving an existing object
|
||||||
|
// and passed to a function.
|
||||||
|
TEST(make_rc, move_init_call)
|
||||||
|
{
|
||||||
|
auto t = test1();
|
||||||
|
EXPECT_EQ(t.i, 0);
|
||||||
|
t.i = 42;
|
||||||
|
f_ptr(make_rc<test1>(std::move(t)), 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calls using ref
|
||||||
|
TEST(make_rc, call_value)
|
||||||
|
{
|
||||||
|
auto rct1 = RcEnable<test1>::Create();
|
||||||
|
f_ref(*rct1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calls using sliced value
|
||||||
|
TEST(make_rc, call_slice)
|
||||||
|
{
|
||||||
|
auto rct1 = RcEnable<test1>::Create();
|
||||||
|
f_val(*rct1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make_rc TS
|
||||||
|
TEST(make_rc, simple_ts)
|
||||||
|
{
|
||||||
|
auto rct1 = make_rc<test1, RC<thread_safe_refcount>>();
|
||||||
|
EXPECT_EQ(rct1->i, 0);
|
||||||
|
}
|
@ -44,8 +44,8 @@ static void do_test(const bool grow, const bool verbose)
|
|||||||
const int n_iter = 250000;
|
const int n_iter = 250000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const Frame::Context fc(256, 512, 256, 0, sizeof(size_t), grow ? BufferAllocated::GROW : 0);
|
const Frame::Context fc(256, 512, 256, 0, sizeof(size_t), grow ? BufAllocFlags::GROW : 0);
|
||||||
const Frame::Context fc_big(256, 4096, 256, 0, sizeof(size_t), grow ? BufferAllocated::GROW : 0);
|
const Frame::Context fc_big(256, 4096, 256, 0, sizeof(size_t), grow ? BufAllocFlags::GROW : 0);
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
@ -172,7 +172,7 @@ static void validate_size_test()
|
|||||||
const size_t tailroom = 0;
|
const size_t tailroom = 0;
|
||||||
const size_t align_block = 16;
|
const size_t align_block = 16;
|
||||||
const Frame::Context fixed(headroom, payload, tailroom, 0, align_block, 0);
|
const Frame::Context fixed(headroom, payload, tailroom, 0, align_block, 0);
|
||||||
const Frame::Context grow(headroom, payload, tailroom, 0, align_block, BufferAllocated::GROW);
|
const Frame::Context grow(headroom, payload, tailroom, 0, align_block, BufAllocFlags::GROW);
|
||||||
validate_size<PKTSTREAM>(fixed, 2048, false); // succeeds
|
validate_size<PKTSTREAM>(fixed, 2048, false); // succeeds
|
||||||
validate_size<PKTSTREAM>(fixed, 2049, true); // exceeded payload, throw
|
validate_size<PKTSTREAM>(fixed, 2049, true); // exceeded payload, throw
|
||||||
validate_size<PKTSTREAM>(grow, 2048, false); // succeeds
|
validate_size<PKTSTREAM>(grow, 2048, false); // succeeds
|
||||||
|
@ -391,7 +391,7 @@ class TestProto : public ProtoContextCallbackInterface
|
|||||||
{
|
{
|
||||||
proto_context.start();
|
proto_context.start();
|
||||||
const size_t msglen = std::strlen(msg) + 1;
|
const size_t msglen = std::strlen(msg) + 1;
|
||||||
templ.reset(new BufferAllocated((unsigned char *)msg, msglen, 0));
|
templ = BufferAllocatedRc::Create((unsigned char *)msg, msglen, 0);
|
||||||
proto_context.flush(true);
|
proto_context.flush(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ class TestProto : public ProtoContextCallbackInterface
|
|||||||
|
|
||||||
BufferPtr data_encrypt_string(const char *str)
|
BufferPtr data_encrypt_string(const char *str)
|
||||||
{
|
{
|
||||||
BufferPtr bp = new BufferAllocated();
|
BufferPtr bp = BufferAllocatedRc::Create();
|
||||||
frame->prepare(Frame::READ_LINK_UDP, *bp);
|
frame->prepare(Frame::READ_LINK_UDP, *bp);
|
||||||
bp->write((unsigned char *)str, std::strlen(str));
|
bp->write((unsigned char *)str, std::strlen(str));
|
||||||
data_encrypt(*bp);
|
data_encrypt(*bp);
|
||||||
@ -512,7 +512,7 @@ class TestProto : public ProtoContextCallbackInterface
|
|||||||
if (disable_xmit_)
|
if (disable_xmit_)
|
||||||
return;
|
return;
|
||||||
net_bytes_ += net_buf.size();
|
net_bytes_ += net_buf.size();
|
||||||
net_out.push_back(BufferPtr(new BufferAllocated(net_buf, 0)));
|
net_out.push_back(BufferAllocatedRc::Create(net_buf, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void control_recv(BufferPtr &&app_bp) override
|
void control_recv(BufferPtr &&app_bp) override
|
||||||
@ -1349,12 +1349,12 @@ TEST(proto, controlmessage_invalidchar)
|
|||||||
std::string only_whitespace{"\n\n\r\n\r\n\r\n"};
|
std::string only_whitespace{"\n\n\r\n\r\n\r\n"};
|
||||||
std::string empty{""};
|
std::string empty{""};
|
||||||
|
|
||||||
BufferAllocated valid_auth_fail_buf{reinterpret_cast<const unsigned char *>(valid_auth_fail.c_str()), valid_auth_fail.size(), BufferAllocated::GROW};
|
BufferAllocated valid_auth_fail_buf{reinterpret_cast<const unsigned char *>(valid_auth_fail.c_str()), valid_auth_fail.size(), BufAllocFlags::GROW};
|
||||||
BufferAllocated valid_auth_fail_newline_end_buf{reinterpret_cast<const unsigned char *>(valid_auth_fail_newline_end.c_str()), valid_auth_fail_newline_end.size(), BufferAllocated::GROW};
|
BufferAllocated valid_auth_fail_newline_end_buf{reinterpret_cast<const unsigned char *>(valid_auth_fail_newline_end.c_str()), valid_auth_fail_newline_end.size(), BufAllocFlags::GROW};
|
||||||
BufferAllocated invalid_auth_fail_buf{reinterpret_cast<const unsigned char *>(invalid_auth_fail.c_str()), invalid_auth_fail.size(), BufferAllocated::GROW};
|
BufferAllocated invalid_auth_fail_buf{reinterpret_cast<const unsigned char *>(invalid_auth_fail.c_str()), invalid_auth_fail.size(), BufAllocFlags::GROW};
|
||||||
BufferAllocated lot_of_whitespace_buf{reinterpret_cast<const unsigned char *>(lot_of_whitespace.c_str()), lot_of_whitespace.size(), BufferAllocated::GROW};
|
BufferAllocated lot_of_whitespace_buf{reinterpret_cast<const unsigned char *>(lot_of_whitespace.c_str()), lot_of_whitespace.size(), BufAllocFlags::GROW};
|
||||||
BufferAllocated only_whitespace_buf{reinterpret_cast<const unsigned char *>(only_whitespace.c_str()), only_whitespace.size(), BufferAllocated::GROW};
|
BufferAllocated only_whitespace_buf{reinterpret_cast<const unsigned char *>(only_whitespace.c_str()), only_whitespace.size(), BufAllocFlags::GROW};
|
||||||
BufferAllocated empty_buf{reinterpret_cast<const unsigned char *>(empty.c_str()), empty.size(), BufferAllocated::GROW};
|
BufferAllocated empty_buf{reinterpret_cast<const unsigned char *>(empty.c_str()), empty.size(), BufAllocFlags::GROW};
|
||||||
|
|
||||||
auto msg = ProtoContext::read_control_string<std::string>(valid_auth_fail_buf);
|
auto msg = ProtoContext::read_control_string<std::string>(valid_auth_fail_buf);
|
||||||
EXPECT_EQ(msg, valid_auth_fail);
|
EXPECT_EQ(msg, valid_auth_fail);
|
||||||
|
@ -248,7 +248,7 @@ void test(MTRand &rand,
|
|||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "Test packet #" << count;
|
os << "Test packet #" << count;
|
||||||
const std::string s = os.str();
|
const std::string s = os.str();
|
||||||
BufferPtr buffer(new BufferAllocated((unsigned char *)s.c_str(), s.length() + 1, 0));
|
auto buffer = BufferAllocatedRc::Create((unsigned char *)s.c_str(), s.length() + 1, 0);
|
||||||
ReliableSend::Message &m = send.send(now, Time::Duration());
|
ReliableSend::Message &m = send.send(now, Time::Duration());
|
||||||
m.packet.buf = buffer;
|
m.packet.buf = buffer;
|
||||||
Message msg;
|
Message msg;
|
||||||
|
Loading…
Reference in New Issue
Block a user