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 incompressible 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 /**************************************************************************/
90 /**
91 * Packet geometry parameters.
92 */
93 struct frame {
94 int link_mtu; /**< Maximum packet size to be sent over
95 * the external network interface. */
96
97 int link_mtu_dynamic; /**< Dynamic MTU value for the external
98 * network interface. */
99
100 int extra_frame; /**< Maximum number of bytes that all
101 * processing steps together could add.
102 * @code
103 * frame.link_mtu = "socket MTU" - extra_frame;
104 * @endcode
105 */
106
107 int extra_buffer; /**< Maximum number of bytes that
108 * processing steps could expand the
109 * internal work buffer.
110 *
111 * This is used by the \link compression
112 * Data Channel Compression
113 * module\endlink to give enough working
114 * space for worst-case expansion of
115 * incompressible content. */
116
117 int extra_tun; /**< Maximum number of bytes in excess of
118 * the tun/tap MTU that might be read
119 * from or written to the virtual
120 * tun/tap network interface. */
121
122 int extra_link; /**< Maximum number of bytes in excess of
123 * external network interface's MTU that
124 * might be read from or written to it. */
125
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;
134 int align_adjust;
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(socket_descriptor_t 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
233 /** Set the --mssfix option. */
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
frame_headroom(const struct frame * f,const unsigned int flag_mask)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
frame_add_to_link_mtu(struct frame * frame,const int increment)268 frame_add_to_link_mtu(struct frame *frame, const int increment)
269 {
270 frame->link_mtu += increment;
271 }
272
273 static inline void
frame_add_to_extra_frame(struct frame * frame,const unsigned int increment)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
frame_remove_from_extra_frame(struct frame * frame,const unsigned int decrement)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
frame_add_to_extra_tun(struct frame * frame,const int increment)286 frame_add_to_extra_tun(struct frame *frame, const int increment)
287 {
288 frame->extra_tun += increment;
289 }
290
291 static inline void
frame_add_to_extra_link(struct frame * frame,const int increment)292 frame_add_to_extra_link(struct frame *frame, const int increment)
293 {
294 frame->extra_link += increment;
295 }
296
297 static inline void
frame_add_to_extra_buffer(struct frame * frame,const int increment)298 frame_add_to_extra_buffer(struct frame *frame, const int increment)
299 {
300 frame->extra_buffer += increment;
301 }
302
303 static inline void
frame_align_to_extra_frame(struct frame * frame)304 frame_align_to_extra_frame(struct frame *frame)
305 {
306 frame->align_adjust = frame->extra_frame + frame->extra_link;
307 }
308
309 static inline void
frame_or_align_flags(struct frame * frame,const unsigned int flag_mask)310 frame_or_align_flags(struct frame *frame, const unsigned int flag_mask)
311 {
312 frame->align_flags |= flag_mask;
313 }
314
315 static inline bool
frame_defined(const struct frame * frame)316 frame_defined(const struct frame *frame)
317 {
318 return frame->link_mtu > 0;
319 }
320
321 #endif /* ifndef MTU_H */
322