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() << std::endl;
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 erase(std::remove_if(
178 begin(), end(), [&](const Action::Ptr &a) mutable
179 {
180 auto remove = !a->mark.empty() && marks.count(a->mark) > 0;
181 if (remove)
182 {
183 os << "Action '" << a->to_string() << "' will be removed\n";
184 }
185 return remove; }),
186 end());
187 }
188
189 protected:
190 class Iter
191 {
192 public:
193 Iter(size_t size, const bool reverse)
194 {
195 if (reverse)
196 {
197 idx = size;
198 end = -1;
199 delta = -1;
200 }
201 else
202 {
203 idx = -1;
204 end = size;
205 delta = 1;
206 }
207 }
208
210 {
211 return (idx += delta) != end;
212 }
213
214 size_t index() const
215 {
216 return idx;
217 }
218
219 private:
220 size_t idx;
221 size_t end;
222 size_t delta;
223 };
224
225 bool reverse_ = false;
226 bool enable_destroy_ = false;
227 volatile bool halt_ = false;
228};
229
231{
233 {
234 reverse_ = true;
235 }
236};
237
238struct ActionListFactory : public RC<thread_unsafe_refcount>
239{
241
243};
244} // namespace openvpn
245
246#endif
size_t index() const
Definition action.hpp:214
Iter(size_t size, const bool reverse)
Definition action.hpp:193
void destroy(std::ostream &os) override
Definition action.hpp:151
void add(Action *action)
Definition action.hpp:57
volatile bool halt_
Definition action.hpp:227
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
RCPtr< ActionList > Ptr
Definition action.hpp:50
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:912
#define OPENVPN_LOG_STRING(str)
virtual ActionList::Ptr new_action_list()=0
RCPtr< ActionListFactory > Ptr
Definition action.hpp:240
virtual std::string to_string() const =0
virtual void execute(std::ostream &os)=0
virtual ~Action()=default
RCPtr< Action > Ptr
Definition action.hpp:32
virtual Json::Value to_json() const
Definition action.hpp:37
std::string mark
Definition action.hpp:44
server addresses push_back({address, port})
std::string ret
std::ostringstream os