OpenVPN 3 Core Library
Loading...
Searching...
No Matches
action.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
13#ifndef OPENVPN_COMMON_ACTION_H
14#define OPENVPN_COMMON_ACTION_H
15
16#include <vector>
17#include <string>
18#include <ostream>
19#include <sstream>
20#include <unordered_set>
21
23#include <openvpn/common/rc.hpp>
27
28namespace openvpn {
29
30struct Action : public RC<thread_unsafe_refcount>
31{
33
34 virtual void execute(std::ostream &os) = 0;
35 virtual std::string to_string() const = 0;
36#ifdef HAVE_JSON
37 virtual Json::Value to_json() const
38 {
39 throw Exception("Action::to_json() virtual method not implemented");
40 }
41#endif
42 virtual ~Action() = default;
43
44 std::string mark;
45};
46
47class ActionList : public std::vector<Action::Ptr>, public DestructorBase
48{
49 public:
51
53 {
54 reserve(16);
55 }
56
57 void add(Action *action)
58 {
59 if (action)
60 emplace_back(action);
61 }
62
63 void add(const Action::Ptr &action)
64 {
65 if (action)
66 push_back(action);
67 }
68
69 void add(const ActionList &other)
70 {
71 insert(end(), other.begin(), other.end());
72 }
73
74 bool exists(const Action::Ptr &action) const
75 {
76 if (action)
77 {
78 const std::string cmp = action->to_string();
79 for (auto &a : *this)
80 {
81 if (a->to_string() == cmp)
82 return true;
83 }
84 }
85 return false;
86 }
87
98 virtual std::unordered_set<std::string> execute(std::ostream &os)
99 {
100 std::unordered_set<std::string> failed_actions;
101
102 Iter i(size(), reverse_);
103 while (i())
104 {
105 if (is_halt())
106 return failed_actions;
107 auto &action = this->at(i.index());
108 try
109 {
110 action->execute(os);
111 }
112 catch (const std::exception &e)
113 {
114 os << "action exception: " << e.what() << '\n';
115 failed_actions.insert(action->mark);
116 }
117 }
118
119 return failed_actions;
120 }
121
123 {
124 std::ostringstream os;
125 execute(os);
126 OPENVPN_LOG_STRING(os.str());
127 }
128
129 std::string to_string() const
130 {
131 std::string ret;
132 Iter i(size(), reverse_);
133 while (i())
134 {
135 ret += (*this)[i.index()]->to_string();
136 ret += '\n';
137 }
138 return ret;
139 }
140
141 void enable_destroy(const bool state)
142 {
143 enable_destroy_ = state;
144 }
145
146 void halt()
147 {
148 halt_ = true;
149 }
150
151 void destroy(std::ostream &os) override // defined by DestructorBase
152 {
153 if (enable_destroy_)
154 {
155 execute(os);
156 enable_destroy_ = false;
157 }
158 }
159
160 bool is_halt() const
161 {
162 return halt_;
163 }
164
175 void remove_marked(const std::unordered_set<std::string> &marks, std::ostream &os)
176 {
177 std::erase_if(*this, [&](const Action::Ptr &a) mutable
178 {
179 auto remove = !a->mark.empty() && marks.count(a->mark) > 0;
180 if (remove)
181 {
182 os << "Action '" << a->to_string() << "' will be removed\n";
183 }
184 return remove; });
185 }
186
187 protected:
188 class Iter
189 {
190 public:
191 Iter(size_t size, const bool reverse)
192 {
193 if (reverse)
194 {
195 idx = size;
196 end = -1;
197 delta = -1;
198 }
199 else
200 {
201 idx = -1;
202 end = size;
203 delta = 1;
204 }
205 }
206
208 {
209 return (idx += delta) != end;
210 }
211
212 size_t index() const
213 {
214 return idx;
215 }
216
217 private:
218 size_t idx;
219 size_t end;
220 size_t delta;
221 };
222
223 bool reverse_ = false;
224 bool enable_destroy_ = false;
225 volatile bool halt_ = false;
226};
227
229{
231 {
232 reverse_ = true;
233 }
234};
235
236struct ActionListFactory : public RC<thread_unsafe_refcount>
237{
239
241};
242} // namespace openvpn
243
244#endif
size_t index() const
Definition action.hpp:212
Iter(size_t size, const bool reverse)
Definition action.hpp:191
void destroy(std::ostream &os) override
Definition action.hpp:151
void add(Action *action)
Definition action.hpp:57
volatile bool halt_
Definition action.hpp:225
bool exists(const Action::Ptr &action) const
Definition action.hpp:74
void add(const Action::Ptr &action)
Definition action.hpp:63
virtual std::unordered_set< std::string > execute(std::ostream &os)
Executes a sequence of actions and returns marks of failed actions.
Definition action.hpp:98
void remove_marked(const std::unordered_set< std::string > &marks, std::ostream &os)
Removes actions with specified marks and logs the removals.
Definition action.hpp:175
void add(const ActionList &other)
Definition action.hpp:69
void enable_destroy(const bool state)
Definition action.hpp:141
std::string to_string() const
Definition action.hpp:129
bool is_halt() const
Definition action.hpp:160
The smart pointer class.
Definition rc.hpp:119
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:908
#define OPENVPN_LOG_STRING(str)
virtual ActionList::Ptr new_action_list()=0
virtual std::string to_string() const =0
virtual void execute(std::ostream &os)=0
virtual ~Action()=default
virtual Json::Value to_json() const
Definition action.hpp:37
std::string mark
Definition action.hpp:44
server addresses push_back(address)
std::string ret
std::ostringstream os