OpenVPN
mtu.h
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/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-2018 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 MTU_H
25 #define MTU_H
26 
27 #include "buffer.h"
28 
29 /*
30  *
31  * Packet maninipulation routes such as encrypt, decrypt, compress, decompress
32  * are passed a frame buffer that looks like this:
33  *
34  * [extra_frame bytes] [mtu bytes] [extra_frame_bytes] [compression overflow bytes]
35  * ^
36  * Pointer passed to function points here so that routine
37  * can make use of extra_frame bytes before pointer
38  * to prepend headers, etc.
39  *
40  * extra_frame bytes is large enough for all encryption related overhead.
41  *
42  * mtu bytes will be the MTU size set in the ifconfig statement that configures
43  * the TUN or TAP device such as:
44  *
45  * ifconfig $1 10.1.0.2 pointopoint 10.1.0.1 mtu 1450
46  *
47  * Compression overflow bytes is the worst-case size expansion that would be
48  * expected if we tried to compress mtu + extra_frame bytes of uncompressible data.
49  */
50 
51 /*
52  * Standard ethernet MTU
53  */
54 #define ETHERNET_MTU 1500
55 
56 /*
57  * It is a fatal error if mtu is less than
58  * this value for tun device.
59  */
60 #define TUN_MTU_MIN 100
61 
62 /*
63  * Default MTU of network over which tunnel data will pass by TCP/UDP.
64  */
65 #define LINK_MTU_DEFAULT 1500
66 
67 /*
68  * Default MTU of tunnel device.
69  */
70 #define TUN_MTU_DEFAULT 1500
71 
72 /*
73  * MTU Defaults for TAP devices
74  */
75 #define TAP_MTU_EXTRA_DEFAULT 32
76 
77 /*
78  * Default MSSFIX value, used for reducing TCP MTU size
79  */
80 #define MSSFIX_DEFAULT 1450
81 
82 /*
83  * Alignment of payload data such as IP packet or
84  * ethernet frame.
85  */
86 #define PAYLOAD_ALIGN 4
87 
88 
89 /**************************************************************************/
93 struct frame {
94  int link_mtu;
117  int extra_tun;
126  /*
127  * Alignment control
128  */
129 #define FRAME_HEADROOM_MARKER_DECRYPT (1<<0)
130 #define FRAME_HEADROOM_MARKER_FRAGMENT (1<<1)
131 #define FRAME_HEADROOM_MARKER_READ_LINK (1<<2)
132 #define FRAME_HEADROOM_MARKER_READ_STREAM (1<<3)
133  unsigned int align_flags;
135 };
136 
137 /* Forward declarations, to prevent includes */
138 struct options;
139 
140 /* Routines which read struct frame should use the macros below */
141 
142 /*
143  * Overhead added to packet payload due to encapsulation
144  */
145 #define EXTRA_FRAME(f) ((f)->extra_frame)
146 
147 /*
148  * Delta between tun payload size and final TCP/UDP datagram size
149  * (not including extra_link additions)
150  */
151 #define TUN_LINK_DELTA(f) ((f)->extra_frame + (f)->extra_tun)
152 
153 /*
154  * This is the size to "ifconfig" the tun or tap device.
155  */
156 #define TUN_MTU_SIZE(f) ((f)->link_mtu - TUN_LINK_DELTA(f))
157 #define TUN_MTU_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic - TUN_LINK_DELTA(f))
158 
159 /*
160  * This is the maximum packet size that we need to be able to
161  * read from or write to a tun or tap device. For example,
162  * a tap device ifconfiged to an MTU of 1200 might actually want
163  * to return a packet size of 1214 on a read().
164  */
165 #define PAYLOAD_SIZE(f) ((f)->link_mtu - (f)->extra_frame)
166 #define PAYLOAD_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic - (f)->extra_frame)
167 
168 /*
169  * Max size of a payload packet after encryption, compression, etc.
170  * overhead is added.
171  */
172 #define EXPANDED_SIZE(f) ((f)->link_mtu)
173 #define EXPANDED_SIZE_DYNAMIC(f) ((f)->link_mtu_dynamic)
174 #define EXPANDED_SIZE_MIN(f) (TUN_MTU_MIN + TUN_LINK_DELTA(f))
175 
176 /*
177  * These values are used as maximum size constraints
178  * on read() or write() from TUN/TAP device or TCP/UDP port.
179  */
180 #define MAX_RW_SIZE_TUN(f) (PAYLOAD_SIZE(f))
181 #define MAX_RW_SIZE_LINK(f) (EXPANDED_SIZE(f) + (f)->extra_link)
182 
183 /*
184  * Control buffer headroom allocations to allow for efficient prepending.
185  */
186 #define FRAME_HEADROOM_BASE(f) (TUN_LINK_DELTA(f) + (f)->extra_buffer + (f)->extra_link)
187 #define FRAME_HEADROOM(f) frame_headroom(f, 0)
188 #define FRAME_HEADROOM_ADJ(f, fm) frame_headroom(f, fm)
189 
190 /*
191  * Max size of a buffer used to build a packet for output to
192  * the TCP/UDP port.
193  */
194 #define BUF_SIZE(f) (TUN_MTU_SIZE(f) + FRAME_HEADROOM_BASE(f) * 2)
195 
196 /*
197  * Function prototypes.
198  */
199 
200 void frame_finalize(struct frame *frame,
201  bool link_mtu_defined,
202  int link_mtu,
203  bool tun_mtu_defined,
204  int tun_mtu);
205 
206 void frame_subtract_extra(struct frame *frame, const struct frame *src);
207 
208 void frame_print(const struct frame *frame,
209  int level,
210  const char *prefix);
211 
212 void set_mtu_discover_type(int sd, int mtu_type, sa_family_t proto_af);
213 
214 int translate_mtu_discover_type_name(const char *name);
215 
216 /*
217  * frame_set_mtu_dynamic and flags
218  */
219 
220 #define SET_MTU_TUN (1<<0) /* use tun/tap rather than link sizing */
221 #define SET_MTU_UPPER_BOUND (1<<1) /* only decrease dynamic MTU */
222 
223 void frame_set_mtu_dynamic(struct frame *frame, int mtu, unsigned int flags);
224 
225 /*
226  * allocate a buffer for socket or tun layer
227  */
228 void alloc_buf_sock_tun(struct buffer *buf,
229  const struct frame *frame,
230  const bool tuntap_buffer,
231  const unsigned int align_mask);
232 
234 void frame_init_mssfix(struct frame *frame, const struct options *options);
235 
236 /*
237  * EXTENDED_SOCKET_ERROR_CAPABILITY functions -- print extra error info
238  * on socket errors, such as PMTU size. As of 2003.05.11, only works
239  * on Linux 2.4+.
240  */
241 
242 #if EXTENDED_SOCKET_ERROR_CAPABILITY
243 
244 void set_sock_extended_error_passing(int sd);
245 
246 const char *format_extended_socket_error(int fd, int *mtu, struct gc_arena *gc);
247 
248 #endif
249 
250 /*
251  * Calculate a starting offset into a buffer object, dealing with
252  * headroom and alignment issues.
253  */
254 static inline int
255 frame_headroom(const struct frame *f, const unsigned int flag_mask)
256 {
257  const int offset = FRAME_HEADROOM_BASE(f);
258  const int adjust = (flag_mask & f->align_flags) ? f->align_adjust : 0;
259  const int delta = ((PAYLOAD_ALIGN << 24) - (offset + adjust)) & (PAYLOAD_ALIGN - 1);
260  return offset + delta;
261 }
262 
263 /*
264  * frame member adjustment functions
265  */
266 
267 static inline void
268 frame_add_to_link_mtu(struct frame *frame, const int increment)
269 {
270  frame->link_mtu += increment;
271 }
272 
273 static inline void
274 frame_add_to_extra_frame(struct frame *frame, const unsigned int increment)
275 {
276  frame->extra_frame += increment;
277 }
278 
279 static inline void
280 frame_remove_from_extra_frame(struct frame *frame, const unsigned int decrement)
281 {
282  frame->extra_frame -= decrement;
283 }
284 
285 static inline void
286 frame_add_to_extra_tun(struct frame *frame, const int increment)
287 {
288  frame->extra_tun += increment;
289 }
290 
291 static inline void
292 frame_add_to_extra_link(struct frame *frame, const int increment)
293 {
294  frame->extra_link += increment;
295 }
296 
297 static inline void
298 frame_add_to_extra_buffer(struct frame *frame, const int increment)
299 {
300  frame->extra_buffer += increment;
301 }
302 
303 static inline void
304 frame_add_to_align_adjust(struct frame *frame, const int increment)
305 {
306  frame->align_adjust += increment;
307 }
308 
309 static inline void
311 {
312  frame->align_adjust = frame->extra_frame + frame->extra_link;
313 }
314 
315 static inline void
316 frame_or_align_flags(struct frame *frame, const unsigned int flag_mask)
317 {
318  frame->align_flags |= flag_mask;
319 }
320 
321 static inline bool
322 frame_defined(const struct frame *frame)
323 {
324  return frame->link_mtu > 0;
325 }
326 
327 #endif /* ifndef MTU_H */
static void frame_add_to_extra_buffer(struct frame *frame, const int increment)
Definition: mtu.h:298
void frame_init_mssfix(struct frame *frame, const struct options *options)
Set the –mssfix option.
Definition: mtu.c:130
static void frame_or_align_flags(struct frame *frame, const unsigned int flag_mask)
Definition: mtu.h:316
Packet geometry parameters.
Definition: mtu.h:93
#define PAYLOAD_ALIGN
Definition: mtu.h:86
static void frame_add_to_extra_frame(struct frame *frame, const unsigned int increment)
Definition: mtu.h:274
unsigned short sa_family_t
Definition: syshead.h:447
static void frame_add_to_extra_link(struct frame *frame, const int increment)
Definition: mtu.h:292
list flags
static void frame_add_to_extra_tun(struct frame *frame, const int increment)
Definition: mtu.h:286
static void frame_add_to_link_mtu(struct frame *frame, const int increment)
Definition: mtu.h:268
string f
Definition: http-client.py:6
int extra_buffer
Maximum number of bytes that processing steps could expand the internal work buffer.
Definition: mtu.h:107
int extra_link
Maximum number of bytes in excess of external network interface&#39;s MTU that might be read from or writ...
Definition: mtu.h:122
int extra_tun
Maximum number of bytes in excess of the tun/tap MTU that might be read from or written to the virtua...
Definition: mtu.h:117
static void frame_add_to_align_adjust(struct frame *frame, const int increment)
Definition: mtu.h:304
#define FRAME_HEADROOM_BASE(f)
Definition: mtu.h:186
void alloc_buf_sock_tun(struct buffer *buf, const struct frame *frame, const bool tuntap_buffer, const unsigned int align_mask)
Definition: mtu.c:43
int align_adjust
Definition: mtu.h:134
int translate_mtu_discover_type_name(const char *name)
Definition: mtu.c:205
void frame_set_mtu_dynamic(struct frame *frame, int mtu, unsigned int flags)
Definition: mtu.c:87
static void frame_align_to_extra_frame(struct frame *frame)
Definition: mtu.h:310
int extra_frame
Maximum number of bytes that all processing steps together could add.
Definition: mtu.h:100
static bool frame_defined(const struct frame *frame)
Definition: mtu.h:322
void frame_print(const struct frame *frame, int level, const char *prefix)
Definition: mtu.c:139
unsigned int align_flags
Definition: mtu.h:133
void frame_subtract_extra(struct frame *frame, const struct frame *src)
Definition: mtu.c:123
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
static int frame_headroom(const struct frame *f, const unsigned int flag_mask)
Definition: mtu.h:255
void frame_finalize(struct frame *frame, bool link_mtu_defined, int link_mtu, bool tun_mtu_defined, int tun_mtu)
Definition: mtu.c:56
int link_mtu
Maximum packet size to be sent over the external network interface.
Definition: mtu.h:94
static void frame_remove_from_extra_frame(struct frame *frame, const unsigned int decrement)
Definition: mtu.h:280
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
void set_mtu_discover_type(int sd, int mtu_type, sa_family_t proto_af)
Definition: mtu.c:169
struct gc_arena gc
Definition: options.h:183
int link_mtu_dynamic
Dynamic MTU value for the external network interface.
Definition: mtu.h:97