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
33 {
34 }
35 explicit MemQStream(const Frame::Ptr &frame)
36 : frame_(frame)
37 {
38 }
39 void set_frame(const Frame::Ptr &frame)
40 {
41 frame_ = frame;
42 }
43
44 size_t pending() const
45 {
46 return total_length();
47 }
48
49 void write(const unsigned char *data, size_t size)
50 {
51 if (frame_)
52 {
53 const Frame::Context &fc = (*frame_)[Frame::READ_BIO_MEMQ_STREAM];
54 if (size)
55 {
56 ConstBuffer b(data, size, true);
57 // Any residual space remaining in most recently pushed buffer?
58 if (!q.empty())
59 {
60 BufferPtr &qb = q.back();
61 const size_t write_size = std::min(b.size(), fc.remaining_payload(*qb));
62 const unsigned char *from = b.read_alloc(write_size);
63 qb->write(from, write_size);
64 length += write_size;
65 }
66
67 // Start a new buffer
68 while (b.size())
69 {
70 auto newbuf = BufferAllocatedRc::Create();
71 fc.prepare(*newbuf);
72 const size_t write_size = std::min(b.size(), fc.payload());
73 const unsigned char *from = b.read_alloc(write_size);
74 newbuf->write(from, write_size);
75 q.push_back(newbuf);
76 length += write_size;
77 }
78 }
79 }
80 else
81 throw frame_uninitialized();
82 }
83
84 size_t read(unsigned char *data, size_t len)
85 {
86 Buffer b(data, len, false);
87 while (!q.empty())
88 {
89 const size_t remaining = b.remaining();
90 if (!remaining)
91 break;
92 BufferPtr &qf = q.front();
93 const size_t read_size = std::min(remaining, qf->size());
94 unsigned char *to = b.write_alloc(read_size);
95 qf->read(to, read_size);
96 length -= read_size;
97 if (qf->empty())
98 q.pop_front();
99 }
100 return b.size();
101 }
102
103 private:
105};
106
107} // namespace openvpn
108
109#endif // OPENVPN_FRAME_MEMQ_STREAM_H
T * write_alloc(const size_t size)
Allocate space for writing data to the buffer.
Definition buffer.hpp:1587
size_t size() const
Returns the size of the buffer in T objects.
Definition buffer.hpp:1242
auto * read_alloc(const size_t size)
Allocate memory and read data from the buffer into the allocated memory.
Definition buffer.hpp:1343
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:1468
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