OpenVPN 3 Core Library
Loading...
Searching...
No Matches
memq_stream.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// A queue of buffers for handling streamed data such as data received
13// from or to be sent to a TCP socket
14
15#ifndef OPENVPN_FRAME_MEMQ_STREAM_H
16#define OPENVPN_FRAME_MEMQ_STREAM_H
17
18#include <algorithm>
19
24
25namespace openvpn {
26
27class MemQStream : public MemQBase
28{
29 public:
30 OPENVPN_SIMPLE_EXCEPTION(frame_uninitialized);
31
32 MemQStream() = default;
33
34 explicit MemQStream(const Frame::Ptr &frame)
35 : frame_(frame)
36 {
37 }
38 void set_frame(const Frame::Ptr &frame)
39 {
40 frame_ = frame;
41 }
42
43 size_t pending() const
44 {
45 return total_length();
46 }
47
48 void write(const unsigned char *data, size_t size)
49 {
50 if (frame_)
51 {
52 const Frame::Context &fc = (*frame_)[Frame::READ_BIO_MEMQ_STREAM];
53 if (size)
54 {
55 ConstBuffer b(data, size, true);
56 // Any residual space remaining in most recently pushed buffer?
57 if (!q.empty())
58 {
59 const BufferPtr &qb = q.back();
60 const size_t write_size = std::min(b.size(), fc.remaining_payload(*qb));
61 const unsigned char *from = b.read_alloc(write_size);
62 qb->write(from, write_size);
63 length += write_size;
64 }
65
66 // Start a new buffer
67 while (!b.empty())
68 {
69 auto newbuf = BufferAllocatedRc::Create();
70 fc.prepare(*newbuf);
71 const size_t write_size = std::min(b.size(), fc.payload());
72 const unsigned char *from = b.read_alloc(write_size);
73 newbuf->write(from, write_size);
74 q.push_back(newbuf);
75 length += write_size;
76 }
77 }
78 }
79 else
80 throw frame_uninitialized();
81 }
82
83 size_t read(unsigned char *data, size_t len)
84 {
85 Buffer b(data, len, false);
86 while (!q.empty())
87 {
88 const size_t remaining = b.remaining();
89 if (!remaining)
90 break;
91 const BufferPtr &qf = q.front();
92 const size_t read_size = std::min(remaining, qf->size());
93 unsigned char *to = b.write_alloc(read_size);
94 qf->read(to, read_size);
95 length -= read_size;
96 if (qf->empty())
97 q.pop_front();
98 }
99 return b.size();
100 }
101
102 private:
104};
105
106} // namespace openvpn
107
108#endif // OPENVPN_FRAME_MEMQ_STREAM_H
T * write_alloc(const size_t size)
Allocate space for writing data to the buffer.
Definition buffer.hpp:1584
size_t size() const
Returns the size of the buffer in T objects.
Definition buffer.hpp:1241
bool empty() const
Returns true if the buffer is empty.
Definition buffer.hpp:1235
auto * read_alloc(const size_t size)
Allocate memory and read data from the buffer into the allocated memory.
Definition buffer.hpp:1342
size_t remaining(const size_t tailroom=0) const
Return the number of additional T objects that can be added before capacity is reached (without consi...
Definition buffer.hpp:1465
size_t payload() const
Definition frame.hpp:97
size_t prepare(Buffer &buf) const
Definition frame.hpp:116
size_t remaining_payload(const Buffer &buf) const
Definition frame.hpp:171
@ READ_BIO_MEMQ_STREAM
Definition frame.hpp:41
size_t total_length() const
Definition memq.hpp:42
size_t size() const
Definition memq.hpp:32
size_t length
Definition memq.hpp:86
void set_frame(const Frame::Ptr &frame)
void write(const unsigned char *data, size_t size)
size_t read(unsigned char *data, size_t len)
OPENVPN_SIMPLE_EXCEPTION(frame_uninitialized)
MemQStream(const Frame::Ptr &frame)
size_t pending() const
static Ptr Create(ArgsT &&...args)
Creates a new instance of RcEnable with the given arguments.
Definition make_rc.hpp:43