OpenVPN 3 Core Library
Loading...
Searching...
No Matches
msgwin.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_COMMON_MSGWIN_H
13#define OPENVPN_COMMON_MSGWIN_H
14
15#include <deque>
16
19
20// Fundamental, lowest-level object of OpenVPN protocol reliability layer
21
22namespace openvpn {
23
24// MessageWindow --
25// On receiving side: used to order packets which may be received out-of-order
26// On sending side: used to buffer unacknowledged packets
27// M : message class, must define default constructor, defined(), and erase() methods
28// id_t : sequence number object, usually unsigned int
29template <typename M, typename id_t>
31{
32 public:
33 OPENVPN_SIMPLE_EXCEPTION(message_window_ref_by_id);
34 OPENVPN_SIMPLE_EXCEPTION(message_window_rm_head);
35
37 : head_id_(0), span_(0)
38 {
39 }
40
41 MessageWindow(const id_t starting_head_id, const id_t span)
42 : head_id_(starting_head_id), span_(span)
43 {
44 }
45
46 void init(const id_t starting_head_id, const id_t span)
47 {
48 head_id_ = starting_head_id;
49 span_ = span;
50 q_.clear();
51 }
52
53 // Return true if id is within current window
54 bool in_window(const id_t id) const
55 {
56 return id >= head_id_ && id < head_id_ + span_;
57 }
58
59 // Return true if id is before current window
60 bool pre_window(const id_t id) const
61 {
62 return id < head_id_;
63 }
64
65 // Return a reference to M object at id, throw exception
66 // if id is not in current window
67 M &ref_by_id(const id_t id)
68 {
69 if (in_window(id))
70 {
71 grow(id);
72 return q_[id - head_id_];
73 }
74 else
75 throw message_window_ref_by_id();
76 }
77
78 // Remove the M object at id, is a no-op if
79 // id not in window. Do a purge() as a last
80 // step to advance the head_id_ if it's now
81 // pointing at undefined M objects.
82 void rm_by_id(const id_t id)
83 {
84 if (in_window(id))
85 {
86 grow(id);
87 M &m = q_[id - head_id_];
88 m.erase();
89 }
90 purge();
91 }
92
93 // Return true if an object at head of queue is defined
94 bool head_defined() const
95 {
96 return (!q_.empty() && q_.front().defined());
97 }
98
99 // Return the id that the object at the head of the queue
100 // would have (even if it isn't defined yet).
101 id_t head_id() const
102 {
103 return head_id_;
104 }
105
106 // Return the id of one past the end of the window
107 id_t tail_id() const
108 {
109 return head_id_ + span_;
110 }
111
112 // Return the window size
113 id_t span() const
114 {
115 return span_;
116 }
117
118 // Return a reference to the object at the front of the queue
120 {
121 return q_.front();
122 }
123
124 // Remove the object at head of queue, throw an exception if undefined
125 void rm_head()
126 {
127 if (head_defined())
129 else
130 throw message_window_rm_head();
131 }
132
133 // Remove the object at head of queue without error checking (other than
134 // that provided by std::deque object). Don't call this method unless
135 // head_defined() returns true.
137 {
138 q_.front().erase();
139 q_.pop_front();
140 ++head_id_;
141 }
142
143 private:
144 // Expand the queue if necessary so that id maps
145 // to an object in the queue
146 void grow(const id_t id)
147 {
148 const size_t needed_index = id - head_id_;
149 while (q_.size() <= needed_index)
150 q_.push_back(M());
151 }
152
153 // Purge all undefined objects at the head of
154 // the queue, advancing the head_id_
155 void purge()
156 {
157 while (!q_.empty() && q_.front().erased())
158 {
159 q_.pop_front();
160 ++head_id_;
161 }
162 }
163
164 id_t head_id_; // id of msgs[0]
165 id_t span_;
166 std::deque<M> q_;
167};
168
169} // namespace openvpn
170
171#endif // OPENVPN_COMMON_MSGWIN_H
bool in_window(const id_t id) const
Definition msgwin.hpp:54
OPENVPN_SIMPLE_EXCEPTION(message_window_rm_head)
bool pre_window(const id_t id) const
Definition msgwin.hpp:60
void rm_by_id(const id_t id)
Definition msgwin.hpp:82
std::deque< M > q_
Definition msgwin.hpp:166
M & ref_by_id(const id_t id)
Definition msgwin.hpp:67
MessageWindow(const id_t starting_head_id, const id_t span)
Definition msgwin.hpp:41
id_t span() const
Definition msgwin.hpp:113
id_t head_id() const
Definition msgwin.hpp:101
bool head_defined() const
Definition msgwin.hpp:94
void grow(const id_t id)
Definition msgwin.hpp:146
void init(const id_t starting_head_id, const id_t span)
Definition msgwin.hpp:46
OPENVPN_SIMPLE_EXCEPTION(message_window_ref_by_id)
id_t tail_id() const
Definition msgwin.hpp:107
Support deferred server-side state creation when client connects.
Definition ovpncli.cpp:95