OpenVPN
fragment.h
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2023 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifndef FRAGMENT_H
25 #define FRAGMENT_H
26 
33 #ifdef ENABLE_FRAGMENT
34 
41 #include "common.h"
42 #include "buffer.h"
43 #include "interval.h"
44 #include "mtu.h"
45 #include "shaper.h"
46 #include "error.h"
47 
48 
49 #define N_FRAG_BUF 25
50 
54 #define FRAG_TTL_SEC 10
55 
57 #define FRAG_WAKEUP_INTERVAL 5
58 
61 /**************************************************************************/
65 struct fragment {
66  bool defined;
71 #define FRAG_MAP_MASK 0xFFFFFFFF
72 
73 #define MAX_FRAGS 32
74  unsigned int map;
75 
84  time_t timestamp;
86  struct buffer buf;
88 };
89 
90 
95 struct fragment_list {
96  int seq_id;
99  int index;
115 };
116 
117 
142 #define N_SEQ_ID 256
143 
154 #define MAX_FRAG_PKT_SIZE 65536
155 
172  struct buffer outgoing;
182 };
183 
184 
185 /**************************************************************************//*************************************/
189 
190 typedef uint32_t fragment_header_type;
194 #define hton_fragment_header_type(x) htonl(x)
195 
198 #define ntoh_fragment_header_type(x) ntohl(x)
199 
202 #define FRAG_TYPE_MASK 0x00000003
203 
204 #define FRAG_TYPE_SHIFT 0
206 #define FRAG_WHOLE 0
208 #define FRAG_YES_NOTLAST 1
211 #define FRAG_YES_LAST 2
214 #define FRAG_TEST 3
219 #define FRAG_SEQ_ID_MASK 0x000000ff
220 
221 #define FRAG_SEQ_ID_SHIFT 2
223 #define FRAG_ID_MASK 0x0000001f
224 
225 #define FRAG_ID_SHIFT 10
226 
228 /*
229  * FRAG_SIZE 14 bits
230  *
231  * IF FRAG_YES_LAST (FRAG_SIZE):
232  * The max size of a %fragment. If a %fragment is not the last %fragment in the packet,
233  * then the %fragment size is guaranteed to be equal to the max %fragment size. Therefore,
234  * max_frag_size is only sent over the wire if FRAG_LAST is set. Otherwise it is assumed
235  * to be the actual %fragment size received.
236  */
237 #define FRAG_SIZE_MASK 0x00003fff
238 
239 #define FRAG_SIZE_SHIFT 15
240 
241 #define FRAG_SIZE_ROUND_SHIFT 2
242 #define FRAG_SIZE_ROUND_MASK ((1 << FRAG_SIZE_ROUND_SHIFT) - 1)
243 
245 /*
246  * FRAG_EXTRA 16 bits
247  *
248  * IF FRAG_WHOLE or FRAG_YES_NOTLAST, these 16 bits are available (not currently used)
249  */
250 #define FRAG_EXTRA_MASK 0x0000ffff
251 
252 #define FRAG_EXTRA_SHIFT 15
253 /********************************************/
256 
257 
258 /**************************************************************************//************/
260 
273 struct fragment_master *fragment_init(struct frame *frame);
274 
275 
285 void fragment_frame_init(struct fragment_master *f, const struct frame *frame);
286 
287 
293 void fragment_free(struct fragment_master *f);
294 /*******************/
296 
297 
298 /**************************************************************************/
342 void fragment_incoming(struct fragment_master *f, struct buffer *buf,
343  const struct frame *frame);
344 
348 /**************************************************************************/
393 void fragment_outgoing(struct fragment_master *f, struct buffer *buf,
394  const struct frame *frame);
395 
423 bool fragment_ready_to_send(struct fragment_master *f, struct buffer *buf,
424  const struct frame *frame);
425 
437 static inline bool
439 {
440  return f->outgoing.len > 0;
441 }
442 
446 void fragment_wakeup(struct fragment_master *f, struct frame *frame);
447 
448 
449 /**************************************************************************//******************/
451 
464 static inline void
465 fragment_housekeeping(struct fragment_master *f, struct frame *frame, struct timeval *tv)
466 {
467  if (event_timeout_trigger(&f->wakeup, tv, ETT_DEFAULT))
468  {
470  }
471 }
472 /*************************/
474 
475 /****************************************/
477 
478 
479 #endif /* ifdef ENABLE_FRAGMENT */
480 #endif /* ifndef FRAGMENT_H */
fragment_frame_init
void fragment_frame_init(struct fragment_master *f, const struct frame *frame)
Allocate internal packet buffers for a fragment_master structure.
Definition: fragment.c:122
error.h
fragment_master::received_os_mtu_hint
bool received_os_mtu_hint
Whether the operating system has explicitly recommended an MTU value.
Definition: fragment.h:140
fragment_init
struct fragment_master * fragment_init(struct frame *frame)
Allocate and initialize a fragment_master structure.
Definition: fragment.c:89
fragment_free
void fragment_free(struct fragment_master *f)
Free a fragment_master structure and its internal packet buffers.
Definition: fragment.c:113
fragment_master
Fragmentation and reassembly state for one VPN tunnel instance.
Definition: fragment.h:136
fragment_master::outgoing_seq_id
int outgoing_seq_id
Fragment sequence ID of the current fragmented packet waiting to be sent.
Definition: fragment.h:146
fragment::defined
bool defined
Whether reassembly is currently taking place in this structure.
Definition: fragment.h:66
fragment
Structure for reassembling one incoming fragmented packet.
Definition: fragment.h:65
frame
Packet geometry parameters.
Definition: mtu.h:98
shaper.h
interval.h
fragment_list::fragments
struct fragment fragments[N_FRAG_BUF]
Array of reassembly structures, each can contain one whole packet.
Definition: fragment.h:114
mtu.h
fragment_master::outgoing
struct buffer outgoing
Buffer containing the remaining parts of the fragmented packet being sent.
Definition: fragment.h:172
fragment_list
List of fragment structures for reassembling multiple incoming packets concurrently.
Definition: fragment.h:95
fragment_list::seq_id
int seq_id
Highest fragmentation sequence ID of the packets currently being reassembled.
Definition: fragment.h:96
fragment_master::wakeup
struct event_timeout wakeup
Timeout structure used by the main event loop to know when to do fragmentation housekeeping.
Definition: fragment.h:137
fragment_outgoing
void fragment_outgoing(struct fragment_master *f, struct buffer *buf, const struct frame *frame)
Process an outgoing packet, which may or may not need to be fragmented.
Definition: fragment.c:321
fragment_housekeeping
static void fragment_housekeeping(struct fragment_master *f, struct frame *frame, struct timeval *tv)
Perform housekeeping of a fragment_master structure.
Definition: fragment.h:467
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
fragment_wakeup
void fragment_wakeup(struct fragment_master *f, struct frame *frame)
Definition: fragment.c:429
fragment::max_frag_size
int max_frag_size
Maximum size of each fragment.
Definition: fragment.h:69
buffer.h
fragment_ready_to_send
bool fragment_ready_to_send(struct fragment_master *f, struct buffer *buf, const struct frame *frame)
Check whether outgoing fragments are ready to be send, and if so make one available.
Definition: fragment.c:376
fragment_header_type
uint32_t fragment_header_type
Fragmentation information is stored in a 32-bit packet header.
Definition: fragment.h:190
fragment::buf
struct buffer buf
Buffer in which received datagrams are reassembled.
Definition: fragment.h:86
common.h
ETT_DEFAULT
#define ETT_DEFAULT
Definition: interval.h:224
event_timeout_trigger
bool event_timeout_trigger(struct event_timeout *et, struct timeval *tv, const int et_const_retry)
This is the principal function for testing and triggering recurring timers.
Definition: interval.c:43
fragment_master::outgoing_return
struct buffer outgoing_return
Buffer used by fragment_ready_to_send() to return a part to send.
Definition: fragment.h:174
event_timeout
Definition: interval.h:136
fragment_list::index
int index
Index of the packet being reassembled with the highest fragmentation sequence ID into the fragment_li...
Definition: fragment.h:99
fragment_master::outgoing_frag_size
int outgoing_frag_size
Size in bytes of each part to be sent, except for the last part which may be smaller.
Definition: fragment.h:157
N_FRAG_BUF
#define N_FRAG_BUF
Number of packet buffers for reassembling incoming fragmented packets.
Definition: fragment.h:49
fragment_incoming
void fragment_incoming(struct fragment_master *f, struct buffer *buf, const struct frame *frame)
Process an incoming packet, which may or may not be fragmented.
Definition: fragment.c:136
http-client.f
string f
Definition: http-client.py:6
fragment_master::incoming
struct fragment_list incoming
List of structures for reassembling incoming packets.
Definition: fragment.h:179
fragment_master::outgoing_frag_id
int outgoing_frag_id
The fragment ID of the next part to be sent.
Definition: fragment.h:169
fragment::timestamp
time_t timestamp
Timestamp for time-to-live purposes.
Definition: fragment.h:84
fragment_outgoing_defined
static bool fragment_outgoing_defined(struct fragment_master *f)
Check whether a fragment_master structure contains fragments ready to be sent.
Definition: fragment.h:440