OpenVPN 3 Core Library
Loading...
Searching...
No Matches
lzo.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#ifndef OPENVPN_COMPRESS_LZO_H
13#define OPENVPN_COMPRESS_LZO_H
14
15// Implement LZO compression.
16// Should only be included by lzoselect.hpp
17
18#include "lzo/lzoutil.h"
19#include "lzo/lzo1x.h"
20
21namespace openvpn {
22
23class CompressLZO : public Compress
24{
25 public:
26 // magic number for LZO compression
27 enum
28 {
31 };
32
33 OPENVPN_SIMPLE_EXCEPTION(lzo_init_failed);
34
37 const bool support_swap_arg,
38 const bool asym_arg)
40 support_swap(support_swap_arg),
41 asym(asym_arg)
42 {
43 OVPN_LOG_INFO("LZO init swap=" << support_swap_arg << " asym=" << asym_arg);
44 lzo_workspace.init(LZO1X_1_15_MEM_COMPRESS, BufAllocFlags::ARRAY);
45 }
46
47 static void init_static()
48 {
49 if (::lzo_init() != LZO_E_OK)
50 throw lzo_init_failed();
51 }
52
53 const char *name() const override
54 {
55 return "lzo";
56 }
57
59 {
60 // initialize work buffer
61 lzo_uint zlen = frame->prepare(Frame::DECOMPRESS_WORK, work);
62
63 // do uncompress
64 const int err = lzo1x_decompress_safe(buf.c_data(), buf.size(), work.data(), &zlen, lzo_workspace.data());
65 if (err != LZO_E_OK)
66 {
67 error(buf);
68 return;
69 }
70 OVPN_LOG_VERBOSE("LZO uncompress " << buf.size() << " -> " << zlen);
71 work.set_size(zlen);
72 buf.swap(work);
73 }
74
75 void compress(BufferAllocated &buf, const bool hint) override
76 {
77 // skip null packets
78 if (!buf.size())
79 return;
80
81 if (hint && !asym)
82 {
83 // initialize work buffer
85
86 // verify that input data length is not too large
87 if (lzo_extra_buffer(buf.size()) > work.max_size())
88 {
89 error(buf);
90 return;
91 }
92
93 // do compress
94 lzo_uint zlen = 0;
95 const int err = ::lzo1x_1_15_compress(buf.c_data(), buf.size(), work.data(), &zlen, lzo_workspace.data());
96
97 // check for errors
98 if (err != LZO_E_OK)
99 {
100 error(buf);
101 return;
102 }
103
104 // did compression actually reduce data length?
105 if (zlen < buf.size())
106 {
107 OVPN_LOG_VERBOSE("LZO compress " << buf.size() << " -> " << zlen);
108 work.set_size(zlen);
109 if (support_swap)
111 else
113 buf.swap(work);
114 return;
115 }
116 }
117
118 // indicate that we didn't compress
119 if (support_swap)
121 else
123 }
124
125 void decompress(BufferAllocated &buf) override
126 {
127 // skip null packets
128 if (!buf.size())
129 return;
130
131 const unsigned char c = buf.pop_front();
132 switch (c)
133 {
134 case NO_COMPRESS_SWAP:
135 do_unswap(buf);
136 [[fallthrough]];
137 case NO_COMPRESS:
138 break;
140 do_unswap(buf);
141 [[fallthrough]];
142 case LZO_COMPRESS:
143 decompress_work(buf);
144 break;
145 default:
146 error(buf); // unknown op
147 }
148 }
149
150 private:
151 // worst case size expansion on compress
152 size_t lzo_extra_buffer(const size_t len)
153 {
154 return len + len / 8 + 128 + 3;
155 }
156
157 const bool support_swap;
158 const bool asym;
161};
162
163} // namespace openvpn
164
165#endif // OPENVPN_COMPRESS_LZO_H
void init(const size_t capacity, const BufferFlags flags=BufAllocFlags::NO_FLAGS)
Initializes the buffer with the specified capacity and flags.
Definition buffer.hpp:1739
void swap(BufferAllocatedType< T_ > &other)
Swaps the contents of this BufferAllocatedType object with another BufferAllocatedType object.
Definition buffer.hpp:1799
CompressLZO(const Frame::Ptr &frame, const SessionStats::Ptr &stats, const bool support_swap_arg, const bool asym_arg)
Definition lzo.hpp:35
BufferAllocated lzo_workspace
Definition lzo.hpp:160
BufferAllocated work
Definition lzo.hpp:159
static void init_static()
Definition lzo.hpp:47
void decompress_work(BufferAllocated &buf)
Definition lzo.hpp:58
void compress(BufferAllocated &buf, const bool hint) override
Definition lzo.hpp:75
size_t lzo_extra_buffer(const size_t len)
Definition lzo.hpp:152
OPENVPN_SIMPLE_EXCEPTION(lzo_init_failed)
const bool asym
Definition lzo.hpp:158
const bool support_swap
Definition lzo.hpp:157
const char * name() const override
Definition lzo.hpp:53
void decompress(BufferAllocated &buf) override
Definition lzo.hpp:125
void do_swap(Buffer &buf, unsigned char op)
Definition compress.hpp:82
void error(BufferAllocated &buf)
Definition compress.hpp:76
void do_unswap(Buffer &buf)
Definition compress.hpp:93
Frame::Ptr frame
Definition compress.hpp:127
SessionStats::Ptr stats
Definition compress.hpp:128
const T * c_data() const
Returns a const pointer to the start of the buffer.
Definition buffer.hpp:1194
size_t max_size() const
Return the maximum allowable size value in T objects given the current offset (without considering re...
Definition buffer.hpp:1377
size_t size() const
Returns the size of the buffer in T objects.
Definition buffer.hpp:1242
T * data()
Get a mutable pointer to the start of the array.
Definition buffer.hpp:1450
T pop_front()
Removes and returns the first element from the buffer.
Definition buffer.hpp:1256
void push_front(const T &value)
Append a T object to the array, with possible resize.
Definition buffer.hpp:1490
void set_size(const size_t size)
After an external method, operating on the array as a mutable unsigned char buffer,...
Definition buffer.hpp:1384
#define OVPN_LOG_INFO(args)
Definition logger.hpp:224
#define OVPN_LOG_VERBOSE(args)
Definition logger.hpp:225
constexpr BufferFlags ARRAY(1u<< 3)
if enabled, use as array