OpenVPN
occ.c
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-2024 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#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "syshead.h"
29
30#include "occ.h"
31#include "forward.h"
32#include "memdbg.h"
33
34
35/*
36 * This random string identifies an OpenVPN
37 * Configuration Control packet.
38 * It should be of sufficient length and randomness
39 * so as not to collide with other tunnel data.
40 *
41 * The OCC protocol is as follows:
42 *
43 * occ_magic -- (16 octets)
44 *
45 * type [OCC_REQUEST | OCC_REPLY] (1 octet)
46 * null terminated options string if OCC_REPLY (variable)
47 *
48 * When encryption is used, the OCC packet
49 * is encapsulated within the encrypted
50 * envelope.
51 *
52 * OCC_STRING_SIZE must be set to sizeof (occ_magic)
53 */
54
55const uint8_t occ_magic[] = {
56 0x28, 0x7f, 0x34, 0x6b, 0xd4, 0xef, 0x7a, 0x81,
57 0x2d, 0x56, 0xb8, 0xd3, 0xaf, 0xc5, 0x45, 0x9c
58};
59
60static const struct mtu_load_test mtu_load_test_sequence[] = {
61
62 {OCC_MTU_LOAD_REQUEST, -1000},
63 {OCC_MTU_LOAD, -1000},
64 {OCC_MTU_LOAD_REQUEST, -1000},
65 {OCC_MTU_LOAD, -1000},
66 {OCC_MTU_LOAD_REQUEST, -1000},
67 {OCC_MTU_LOAD, -1000},
68
70 {OCC_MTU_LOAD, -750},
72 {OCC_MTU_LOAD, -750},
74 {OCC_MTU_LOAD, -750},
75
77 {OCC_MTU_LOAD, -500},
79 {OCC_MTU_LOAD, -500},
81 {OCC_MTU_LOAD, -500},
82
84 {OCC_MTU_LOAD, -400},
86 {OCC_MTU_LOAD, -400},
88 {OCC_MTU_LOAD, -400},
89
91 {OCC_MTU_LOAD, -300},
93 {OCC_MTU_LOAD, -300},
95 {OCC_MTU_LOAD, -300},
96
98 {OCC_MTU_LOAD, -200},
100 {OCC_MTU_LOAD, -200},
101 {OCC_MTU_LOAD_REQUEST, -200},
102 {OCC_MTU_LOAD, -200},
103
104 {OCC_MTU_LOAD_REQUEST, -150},
105 {OCC_MTU_LOAD, -150},
106 {OCC_MTU_LOAD_REQUEST, -150},
107 {OCC_MTU_LOAD, -150},
108 {OCC_MTU_LOAD_REQUEST, -150},
109 {OCC_MTU_LOAD, -150},
110
111 {OCC_MTU_LOAD_REQUEST, -100},
112 {OCC_MTU_LOAD, -100},
113 {OCC_MTU_LOAD_REQUEST, -100},
114 {OCC_MTU_LOAD, -100},
115 {OCC_MTU_LOAD_REQUEST, -100},
116 {OCC_MTU_LOAD, -100},
117
119 {OCC_MTU_LOAD, -50},
121 {OCC_MTU_LOAD, -50},
123 {OCC_MTU_LOAD, -50},
124
126 {OCC_MTU_LOAD, 0},
128 {OCC_MTU_LOAD, 0},
130 {OCC_MTU_LOAD, 0},
131
132 {OCC_MTU_REQUEST, 0},
133 {OCC_MTU_REQUEST, 0},
134 {OCC_MTU_REQUEST, 0},
135 {OCC_MTU_REQUEST, 0},
136 {OCC_MTU_REQUEST, 0},
137 {OCC_MTU_REQUEST, 0},
138 {OCC_MTU_REQUEST, 0},
139 {OCC_MTU_REQUEST, 0},
140 {OCC_MTU_REQUEST, 0},
141 {OCC_MTU_REQUEST, 0},
142
143 {-1, 0}
144};
145
146void
148{
149 if (++c->c2.occ_n_tries >= OCC_N_TRIES)
150 {
151 if (c->options.ce.remote)
152 {
153 /*
154 * No OCC_REPLY from peer after repeated attempts.
155 * Give up.
156 */
158 "NOTE: failed to obtain options consistency info from peer -- "
159 "this could occur if the remote peer is running a version of "
160 PACKAGE_NAME
161 " before 1.5-beta8 or if there is a network connectivity problem, and will not necessarily prevent "
162 PACKAGE_NAME
163 " from running (" counter_format " bytes received from peer, " counter_format
164 " bytes authenticated data channel traffic) -- you can disable the options consistency "
165 "check with --disable-occ.",
168 }
170 }
171 else
172 {
173 c->c2.occ_op = OCC_REQUEST;
174
175 /*
176 * If we don't hear back from peer, send another
177 * OCC_REQUEST in OCC_INTERVAL_SECONDS.
178 */
180 }
181}
182
183void
185{
187 {
188 const struct mtu_load_test *entry;
189
190 if (!c->c2.occ_mtu_load_n_tries)
191 {
192 msg(M_INFO,
193 "NOTE: Beginning empirical MTU test -- results should be available in 3 to 4 minutes.");
194 }
195
197 if (entry->op >= 0)
198 {
199 c->c2.occ_op = entry->op;
200 size_t payload_size = frame_calculate_payload_size(&c->c2.frame,
201 &c->options, &c->c1.ks.key_type);
202 size_t header_size = frame_calculate_protocol_header_size(&c->c1.ks.key_type, &c->options, false);
203
204 c->c2.occ_mtu_load_size = payload_size + header_size;
205 }
206 else
207 {
208 msg(M_INFO,
209 "NOTE: failed to empirically measure MTU (requires " PACKAGE_NAME " 1.5 or higher at other end of connection).");
212 }
213 }
214}
215
216void
218{
219 bool doit = false;
220
221 c->c2.buf = c->c2.buffers->aux_buf;
225
226 switch (c->c2.occ_op)
227 {
228 case OCC_REQUEST:
229 if (!buf_write_u8(&c->c2.buf, OCC_REQUEST))
230 {
231 break;
232 }
233 dmsg(D_PACKET_CONTENT, "SENT OCC_REQUEST");
234 doit = true;
235 break;
236
237 case OCC_REPLY:
238 if (!c->c2.options_string_local)
239 {
240 break;
241 }
242 if (!buf_write_u8(&c->c2.buf, OCC_REPLY))
243 {
244 break;
245 }
247 strlen(c->c2.options_string_local) + 1))
248 {
249 break;
250 }
251 dmsg(D_PACKET_CONTENT, "SENT OCC_REPLY");
252 doit = true;
253 break;
254
255 case OCC_MTU_REQUEST:
257 {
258 break;
259 }
260 dmsg(D_PACKET_CONTENT, "SENT OCC_MTU_REQUEST");
261 doit = true;
262 break;
263
264 case OCC_MTU_REPLY:
265 if (!buf_write_u8(&c->c2.buf, OCC_MTU_REPLY))
266 {
267 break;
268 }
270 {
271 break;
272 }
274 {
275 break;
276 }
277 dmsg(D_PACKET_CONTENT, "SENT OCC_MTU_REPLY");
278 doit = true;
279 break;
280
283 {
284 break;
285 }
287 {
288 break;
289 }
290 dmsg(D_PACKET_CONTENT, "SENT OCC_MTU_LOAD_REQUEST");
291 doit = true;
292 break;
293
294 case OCC_MTU_LOAD:
295 {
296 int need_to_add;
297
298 if (!buf_write_u8(&c->c2.buf, OCC_MTU_LOAD))
299 {
300 break;
301 }
302 size_t proto_hdr, payload_hdr;
303 const struct key_type *kt = &c->c1.ks.key_type;
304
305 /* OCC message have comp/fragment headers but not ethernet headers */
306 payload_hdr = frame_calculate_payload_overhead(0, &c->options, kt);
307
308 /* Since we do not know the payload size we just pass 0 as size here */
309 proto_hdr = frame_calculate_protocol_header_size(kt, &c->options, false);
310
311 need_to_add = min_int(c->c2.occ_mtu_load_size, c->c2.frame.buf.payload_size)
313 - sizeof(uint8_t) /* occ opcode */
314 - payload_hdr
315 - proto_hdr;
316
317 while (need_to_add > 0)
318 {
319 /*
320 * Fill the load test packet with pseudo-random bytes.
321 */
322 if (!buf_write_u8(&c->c2.buf, get_random() & 0xFF))
323 {
324 break;
325 }
326 --need_to_add;
327 }
328 dmsg(D_PACKET_CONTENT, "SENT OCC_MTU_LOAD min_int(%d,%d)-%d-%d-%d-%d) size=%d",
332 (int) sizeof(uint8_t),
333 (int) payload_hdr,
334 (int) proto_hdr,
335 BLEN(&c->c2.buf));
336 doit = true;
337 }
338 break;
339
340 case OCC_EXIT:
341 if (!buf_write_u8(&c->c2.buf, OCC_EXIT))
342 {
343 break;
344 }
345 dmsg(D_PACKET_CONTENT, "SENT OCC_EXIT");
346 doit = true;
347 break;
348 }
349
350 if (doit)
351 {
352 /*
353 * We will treat the packet like any other outgoing packet,
354 * compress, encrypt, sign, etc.
355 */
356 encrypt_sign(c, true);
357 }
358
359 c->c2.occ_op = -1;
360}
361
362void
364{
366 switch (buf_read_u8(&c->c2.buf))
367 {
368 case OCC_REQUEST:
369 dmsg(D_PACKET_CONTENT, "RECEIVED OCC_REQUEST");
370 c->c2.occ_op = OCC_REPLY;
371 break;
372
373 case OCC_MTU_REQUEST:
374 dmsg(D_PACKET_CONTENT, "RECEIVED OCC_MTU_REQUEST");
376 break;
377
379 dmsg(D_PACKET_CONTENT, "RECEIVED OCC_MTU_LOAD_REQUEST");
381 if (c->c2.occ_mtu_load_size >= 0)
382 {
384 }
385 break;
386
387 case OCC_REPLY:
388 dmsg(D_PACKET_CONTENT, "RECEIVED OCC_REPLY");
389 if (c->options.occ && !TLS_MODE(c) && c->c2.options_string_remote)
390 {
391 if (!options_cmp_equal_safe((char *) BPTR(&c->c2.buf),
393 c->c2.buf.len))
394 {
395 options_warning_safe((char *) BPTR(&c->c2.buf),
397 c->c2.buf.len);
398 }
399 }
401 break;
402
403 case OCC_MTU_REPLY:
404 dmsg(D_PACKET_CONTENT, "RECEIVED OCC_MTU_REPLY");
407 if (c->options.mtu_test
408 && c->c2.max_recv_size_remote > 0
409 && c->c2.max_send_size_remote > 0)
410 {
411 msg(M_INFO, "NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[%d,%d] remote->local=[%d,%d]",
416 if (!c->options.ce.fragment
421 {
422 msg(M_INFO, "NOTE: This connection is unable to accommodate a UDP packet size of %d. Consider using --fragment or --mssfix options as a workaround.",
424 }
425 }
427 break;
428
429 case OCC_EXIT:
430 dmsg(D_STREAM_ERRORS, "OCC exit message received by peer");
431 register_signal(c->sig, SIGUSR1, "remote-exit");
432 break;
433 }
434 c->c2.buf.len = 0; /* don't pass packet on */
435}
static bool buf_write_u16(struct buffer *dest, uint16_t data)
Definition buffer.h:698
#define BPTR(buf)
Definition buffer.h:124
static int buf_read_u16(struct buffer *buf)
Definition buffer.h:803
static bool buf_safe(const struct buffer *buf, size_t len)
Definition buffer.h:520
static bool buf_advance(struct buffer *buf, int size)
Definition buffer.h:618
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:668
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition buffer.h:692
static int buf_read_u8(struct buffer *buf)
Definition buffer.h:790
#define BLEN(buf)
Definition buffer.h:127
#define buf_init(buf, offset)
Definition buffer.h:209
#define counter_format
Definition common.h:31
long int get_random(void)
Definition crypto.c:1757
#define D_SHOW_OCC
Definition errlevel.h:151
#define D_PACKET_CONTENT
Definition errlevel.h:168
#define D_STREAM_ERRORS
Definition errlevel.h:63
#define M_INFO
Definition errlevel.h:55
Interface functions to the internal and external multiplexers.
static bool connection_established(struct context *c)
Definition forward.h:430
void encrypt_sign(struct context *c, bool comp_frag)
Process a data channel packet that will be sent through a VPN tunnel.
Definition forward.c:625
static int min_int(int x, int y)
Definition integer.h:102
static void event_timeout_reset(struct event_timeout *et)
Resets a timer.
Definition interval.h:189
static void event_timeout_clear(struct event_timeout *et)
Clears the timeout and reset all values to 0.
Definition interval.h:155
size_t frame_calculate_payload_size(const struct frame *frame, const struct options *options, const struct key_type *kt)
Calculates the size of the payload according to tun-mtu and tap overhead.
Definition mtu.c:142
size_t frame_calculate_protocol_header_size(const struct key_type *kt, const struct options *options, bool occ)
Calculates the size of the OpenVPN protocol header.
Definition mtu.c:63
size_t frame_calculate_payload_overhead(size_t extra_tun, const struct options *options, const struct key_type *kt)
Calculates the size of the payload overhead according to tun-mtu and tap overhead.
Definition mtu.c:101
#define TUN_MTU_MIN
Definition mtu.h:60
void process_received_occ_msg(struct context *c)
Definition occ.c:363
void check_send_occ_req_dowork(struct context *c)
Definition occ.c:147
void check_send_occ_msg_dowork(struct context *c)
Definition occ.c:217
const uint8_t occ_magic[]
Definition occ.c:55
void check_send_occ_load_test_dowork(struct context *c)
Definition occ.c:184
static const struct mtu_load_test mtu_load_test_sequence[]
Definition occ.c:60
#define OCC_N_TRIES
Definition occ.h:47
#define OCC_REQUEST
Definition occ.h:36
#define OCC_REPLY
Definition occ.h:37
#define OCC_MTU_REPLY
Definition occ.h:55
#define OCC_STRING_SIZE
Definition occ.h:30
#define OCC_MTU_LOAD_REQUEST
Definition occ.h:52
#define OCC_MTU_REQUEST
Definition occ.h:54
#define OCC_EXIT
Definition occ.h:66
#define OCC_MTU_LOAD
Definition occ.h:53
#define dmsg(flags,...)
Definition error.h:148
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define TLS_MODE(c)
Definition openvpn.h:536
bool options_cmp_equal_safe(char *actual, const char *expected, size_t actual_n)
Definition options.c:4729
void options_warning_safe(char *actual, const char *expected, size_t actual_n)
Definition options.c:4752
void register_signal(struct signal_info *si, int signum, const char *signal_text)
Register a soft signal in the signal_info struct si respecting priority.
Definition sig.c:231
static bool proto_is_dgram(int proto)
Return if the protocol is datagram (UDP)
Definition socket.h:597
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
const char * remote
Definition options.h:112
int fragment
Definition options.h:139
int proto
Definition options.h:107
struct key_schedule ks
Definition openvpn.h:163
counter_type link_read_bytes
Definition openvpn.h:266
char * options_string_local
Definition openvpn.h:296
struct event_timeout occ_mtu_load_test_interval
Definition openvpn.h:317
int max_recv_size_local
Definition openvpn.h:308
int occ_mtu_load_size
Definition openvpn.h:315
int max_recv_size_remote
Definition openvpn.h:309
char * options_string_remote
Definition openvpn.h:297
int occ_mtu_load_n_tries
Definition openvpn.h:318
int max_send_size_local
Definition openvpn.h:310
int occ_op
Definition openvpn.h:299
struct frame frame
Definition openvpn.h:248
struct event_timeout occ_interval
Definition openvpn.h:301
counter_type link_read_bytes_auth
Definition openvpn.h:268
struct buffer buf
Definition openvpn.h:375
struct context_buffers * buffers
Definition openvpn.h:367
int max_send_size_remote
Definition openvpn.h:311
int occ_n_tries
Definition openvpn.h:300
struct buffer aux_buf
Definition openvpn.h:97
Contains all state information for one tunnel.
Definition openvpn.h:474
struct signal_info * sig
Internal error signaling object.
Definition openvpn.h:500
struct context_2 c2
Level 2 context.
Definition openvpn.h:514
struct options options
Options loaded from command line or configuration file.
Definition openvpn.h:475
struct context_1 c1
Level 1 context.
Definition openvpn.h:513
int payload_size
the maximum size that a payload that our buffers can hold from either tun device or network link.
Definition mtu.h:102
int headroom
the headroom in the buffer, this is choosen to allow all potential header to be added before the pack...
Definition mtu.h:108
struct frame::@8 buf
struct key_type key_type
Definition openvpn.h:57
int op
Definition occ.h:74
struct connection_entry ce
Definition options.h:288
bool mtu_test
Definition options.h:332
bool occ
Definition options.h:443