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-2021 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 #elif defined(_MSC_VER)
27 #include "config-msvc.h"
28 #endif
29 
30 #include "syshead.h"
31 
32 #include "occ.h"
33 #include "forward.h"
34 #include "memdbg.h"
35 
36 
37 /*
38  * This random string identifies an OpenVPN
39  * Configuration Control packet.
40  * It should be of sufficient length and randomness
41  * so as not to collide with other tunnel data.
42  *
43  * The OCC protocol is as follows:
44  *
45  * occ_magic -- (16 octets)
46  *
47  * type [OCC_REQUEST | OCC_REPLY] (1 octet)
48  * null terminated options string if OCC_REPLY (variable)
49  *
50  * When encryption is used, the OCC packet
51  * is encapsulated within the encrypted
52  * envelope.
53  *
54  * OCC_STRING_SIZE must be set to sizeof (occ_magic)
55  */
56 
57 const uint8_t occ_magic[] = {
58  0x28, 0x7f, 0x34, 0x6b, 0xd4, 0xef, 0x7a, 0x81,
59  0x2d, 0x56, 0xb8, 0xd3, 0xaf, 0xc5, 0x45, 0x9c
60 };
61 
62 static const struct mtu_load_test mtu_load_test_sequence[] = {
63 
64  {OCC_MTU_LOAD_REQUEST, -1000},
65  {OCC_MTU_LOAD, -1000},
66  {OCC_MTU_LOAD_REQUEST, -1000},
67  {OCC_MTU_LOAD, -1000},
68  {OCC_MTU_LOAD_REQUEST, -1000},
69  {OCC_MTU_LOAD, -1000},
70 
71  {OCC_MTU_LOAD_REQUEST, -750},
72  {OCC_MTU_LOAD, -750},
73  {OCC_MTU_LOAD_REQUEST, -750},
74  {OCC_MTU_LOAD, -750},
75  {OCC_MTU_LOAD_REQUEST, -750},
76  {OCC_MTU_LOAD, -750},
77 
78  {OCC_MTU_LOAD_REQUEST, -500},
79  {OCC_MTU_LOAD, -500},
80  {OCC_MTU_LOAD_REQUEST, -500},
81  {OCC_MTU_LOAD, -500},
82  {OCC_MTU_LOAD_REQUEST, -500},
83  {OCC_MTU_LOAD, -500},
84 
85  {OCC_MTU_LOAD_REQUEST, -400},
86  {OCC_MTU_LOAD, -400},
87  {OCC_MTU_LOAD_REQUEST, -400},
88  {OCC_MTU_LOAD, -400},
89  {OCC_MTU_LOAD_REQUEST, -400},
90  {OCC_MTU_LOAD, -400},
91 
92  {OCC_MTU_LOAD_REQUEST, -300},
93  {OCC_MTU_LOAD, -300},
94  {OCC_MTU_LOAD_REQUEST, -300},
95  {OCC_MTU_LOAD, -300},
96  {OCC_MTU_LOAD_REQUEST, -300},
97  {OCC_MTU_LOAD, -300},
98 
99  {OCC_MTU_LOAD_REQUEST, -200},
100  {OCC_MTU_LOAD, -200},
101  {OCC_MTU_LOAD_REQUEST, -200},
102  {OCC_MTU_LOAD, -200},
103  {OCC_MTU_LOAD_REQUEST, -200},
104  {OCC_MTU_LOAD, -200},
105 
106  {OCC_MTU_LOAD_REQUEST, -150},
107  {OCC_MTU_LOAD, -150},
108  {OCC_MTU_LOAD_REQUEST, -150},
109  {OCC_MTU_LOAD, -150},
110  {OCC_MTU_LOAD_REQUEST, -150},
111  {OCC_MTU_LOAD, -150},
112 
113  {OCC_MTU_LOAD_REQUEST, -100},
114  {OCC_MTU_LOAD, -100},
115  {OCC_MTU_LOAD_REQUEST, -100},
116  {OCC_MTU_LOAD, -100},
117  {OCC_MTU_LOAD_REQUEST, -100},
118  {OCC_MTU_LOAD, -100},
119 
120  {OCC_MTU_LOAD_REQUEST, -50},
121  {OCC_MTU_LOAD, -50},
122  {OCC_MTU_LOAD_REQUEST, -50},
123  {OCC_MTU_LOAD, -50},
124  {OCC_MTU_LOAD_REQUEST, -50},
125  {OCC_MTU_LOAD, -50},
126 
128  {OCC_MTU_LOAD, 0},
130  {OCC_MTU_LOAD, 0},
132  {OCC_MTU_LOAD, 0},
133 
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  {OCC_MTU_REQUEST, 0},
143  {OCC_MTU_REQUEST, 0},
144 
145  {-1, 0}
146 };
147 
148 void
150 {
151  if (++c->c2.occ_n_tries >= OCC_N_TRIES)
152  {
153  if (c->options.ce.remote)
154  {
155  /*
156  * No OCC_REPLY from peer after repeated attempts.
157  * Give up.
158  */
159  msg(D_SHOW_OCC,
160  "NOTE: failed to obtain options consistency info from peer -- "
161  "this could occur if the remote peer is running a version of "
163  " before 1.5-beta8 or if there is a network connectivity problem, and will not necessarily prevent "
165  " from running (" counter_format " bytes received from peer, " counter_format
166  " bytes authenticated data channel traffic) -- you can disable the options consistency "
167  "check with --disable-occ.",
168  c->c2.link_read_bytes,
170  }
172  }
173  else
174  {
175  c->c2.occ_op = OCC_REQUEST;
176 
177  /*
178  * If we don't hear back from peer, send another
179  * OCC_REQUEST in OCC_INTERVAL_SECONDS.
180  */
182  }
183 }
184 
185 void
187 {
188  if (connection_established(c))
189  {
190  const struct mtu_load_test *entry;
191 
192  if (!c->c2.occ_mtu_load_n_tries)
193  {
194  msg(M_INFO,
195  "NOTE: Beginning empirical MTU test -- results should be available in 3 to 4 minutes.");
196  }
197 
198  entry = &mtu_load_test_sequence[c->c2.occ_mtu_load_n_tries++];
199  if (entry->op >= 0)
200  {
201  c->c2.occ_op = entry->op;
202  c->c2.occ_mtu_load_size =
203  EXPANDED_SIZE(&c->c2.frame) + entry->delta;
204  }
205  else
206  {
207  msg(M_INFO,
208  "NOTE: failed to empirically measure MTU (requires " PACKAGE_NAME " 1.5 or higher at other end of connection).");
210  c->c2.occ_mtu_load_n_tries = 0;
211  }
212  }
213 }
214 
215 void
217 {
218  bool doit = false;
219 
220  c->c2.buf = c->c2.buffers->aux_buf;
224 
225  switch (c->c2.occ_op)
226  {
227  case OCC_REQUEST:
228  if (!buf_write_u8(&c->c2.buf, OCC_REQUEST))
229  {
230  break;
231  }
232  dmsg(D_PACKET_CONTENT, "SENT OCC_REQUEST");
233  doit = true;
234  break;
235 
236  case OCC_REPLY:
237  if (!c->c2.options_string_local)
238  {
239  break;
240  }
241  if (!buf_write_u8(&c->c2.buf, OCC_REPLY))
242  {
243  break;
244  }
245  if (!buf_write(&c->c2.buf, c->c2.options_string_local,
246  strlen(c->c2.options_string_local) + 1))
247  {
248  break;
249  }
250  dmsg(D_PACKET_CONTENT, "SENT OCC_REPLY");
251  doit = true;
252  break;
253 
254  case OCC_MTU_REQUEST:
255  if (!buf_write_u8(&c->c2.buf, OCC_MTU_REQUEST))
256  {
257  break;
258  }
259  dmsg(D_PACKET_CONTENT, "SENT OCC_MTU_REQUEST");
260  doit = true;
261  break;
262 
263  case OCC_MTU_REPLY:
264  if (!buf_write_u8(&c->c2.buf, OCC_MTU_REPLY))
265  {
266  break;
267  }
268  if (!buf_write_u16(&c->c2.buf, c->c2.max_recv_size_local))
269  {
270  break;
271  }
272  if (!buf_write_u16(&c->c2.buf, c->c2.max_send_size_local))
273  {
274  break;
275  }
276  dmsg(D_PACKET_CONTENT, "SENT OCC_MTU_REPLY");
277  doit = true;
278  break;
279 
282  {
283  break;
284  }
285  if (!buf_write_u16(&c->c2.buf, c->c2.occ_mtu_load_size))
286  {
287  break;
288  }
289  dmsg(D_PACKET_CONTENT, "SENT OCC_MTU_LOAD_REQUEST");
290  doit = true;
291  break;
292 
293  case OCC_MTU_LOAD:
294  {
295  int need_to_add;
296 
297  if (!buf_write_u8(&c->c2.buf, OCC_MTU_LOAD))
298  {
299  break;
300  }
301  need_to_add = min_int(c->c2.occ_mtu_load_size, EXPANDED_SIZE(&c->c2.frame))
303  - sizeof(uint8_t)
304  - EXTRA_FRAME(&c->c2.frame);
305 
306  while (need_to_add > 0)
307  {
308  /*
309  * Fill the load test packet with pseudo-random bytes.
310  */
311  if (!buf_write_u8(&c->c2.buf, get_random() & 0xFF))
312  {
313  break;
314  }
315  --need_to_add;
316  }
317  dmsg(D_PACKET_CONTENT, "SENT OCC_MTU_LOAD min_int(%d-%d-%d-%d,%d) size=%d",
320  (int) sizeof(uint8_t),
321  EXTRA_FRAME(&c->c2.frame),
322  MAX_RW_SIZE_TUN(&c->c2.frame),
323  BLEN(&c->c2.buf));
324  doit = true;
325  }
326  break;
327 
328  case OCC_EXIT:
329  if (!buf_write_u8(&c->c2.buf, OCC_EXIT))
330  {
331  break;
332  }
333  dmsg(D_PACKET_CONTENT, "SENT OCC_EXIT");
334  doit = true;
335  break;
336  }
337 
338  if (doit)
339  {
340  /*
341  * We will treat the packet like any other outgoing packet,
342  * compress, encrypt, sign, etc.
343  */
344  encrypt_sign(c, true);
345  }
346 
347  c->c2.occ_op = -1;
348 }
349 
350 void
352 {
354  switch (buf_read_u8(&c->c2.buf))
355  {
356  case OCC_REQUEST:
357  dmsg(D_PACKET_CONTENT, "RECEIVED OCC_REQUEST");
358  c->c2.occ_op = OCC_REPLY;
359  break;
360 
361  case OCC_MTU_REQUEST:
362  dmsg(D_PACKET_CONTENT, "RECEIVED OCC_MTU_REQUEST");
363  c->c2.occ_op = OCC_MTU_REPLY;
364  break;
365 
367  dmsg(D_PACKET_CONTENT, "RECEIVED OCC_MTU_LOAD_REQUEST");
369  if (c->c2.occ_mtu_load_size >= 0)
370  {
371  c->c2.occ_op = OCC_MTU_LOAD;
372  }
373  break;
374 
375  case OCC_REPLY:
376  dmsg(D_PACKET_CONTENT, "RECEIVED OCC_REPLY");
377  if (c->options.occ && !TLS_MODE(c) && c->c2.options_string_remote)
378  {
379  if (!options_cmp_equal_safe((char *) BPTR(&c->c2.buf),
381  c->c2.buf.len))
382  {
383  options_warning_safe((char *) BPTR(&c->c2.buf),
385  c->c2.buf.len);
386  }
387  }
389  break;
390 
391  case OCC_MTU_REPLY:
392  dmsg(D_PACKET_CONTENT, "RECEIVED OCC_MTU_REPLY");
395  if (c->options.mtu_test
396  && c->c2.max_recv_size_remote > 0
397  && c->c2.max_send_size_remote > 0)
398  {
399  msg(M_INFO, "NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[%d,%d] remote->local=[%d,%d]",
404  if (!c->options.ce.fragment
405  && (proto_is_dgram(c->options.ce.proto))
409  {
410  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.",
412  }
413  }
415  break;
416 
417  case OCC_EXIT:
418  dmsg(D_PACKET_CONTENT, "RECEIVED OCC_EXIT");
420  c->sig->signal_text = "remote-exit";
421  break;
422  }
423  c->c2.buf.len = 0; /* don't pass packet on */
424 }
static bool buf_write_u8(struct buffer *dest, int data)
Definition: buffer.h:713
static bool connection_established(struct context *c)
Definition: forward.h:415
struct options options
Options loaded from command line or configuration file.
Definition: openvpn.h:463
bool options_cmp_equal_safe(char *actual, const char *expected, size_t actual_n)
Definition: options.c:4176
#define OCC_EXIT
Definition: occ.h:67
static bool buf_advance(struct buffer *buf, int size)
Definition: buffer.h:639
#define M_INFO
Definition: errlevel.h:55
Contains all state information for one tunnel.
Definition: openvpn.h:461
int occ_mtu_load_size
Definition: openvpn.h:311
void options_warning_safe(char *actual, const char *expected, size_t actual_n)
Definition: options.c:4199
struct buffer buf
Definition: openvpn.h:365
int occ_mtu_load_n_tries
Definition: openvpn.h:314
struct context_buffers * buffers
Definition: openvpn.h:357
static bool proto_is_dgram(int proto)
Return if the protocol is datagram (UDP)
Definition: socket.h:551
void process_received_occ_msg(struct context *c)
Definition: occ.c:351
static void event_timeout_clear(struct event_timeout *et)
Definition: interval.h:150
static int buf_read_u8(struct buffer *buf)
Definition: buffer.h:812
#define dmsg(flags,...)
Definition: error.h:157
struct signal_info * sig
Internal error signaling object.
Definition: openvpn.h:488
#define OCC_MTU_REPLY
Definition: occ.h:56
#define EXTRA_FRAME(f)
Definition: mtu.h:145
int max_recv_size_local
Definition: openvpn.h:304
#define SIGTERM
Definition: config-msvc.h:117
int occ_n_tries
Definition: openvpn.h:296
#define TLS_MODE(c)
Definition: openvpn.h:524
#define ASSERT(x)
Definition: error.h:204
#define OCC_REQUEST
Definition: occ.h:36
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:527
int len
Length in bytes of the actual content within the allocated memory.
Definition: buffer.h:66
#define OCC_MTU_LOAD
Definition: occ.h:53
#define BPTR(buf)
Definition: buffer.h:124
static void event_timeout_reset(struct event_timeout *et)
Definition: interval.h:174
int proto
Definition: options.h:98
counter_type link_read_bytes
Definition: openvpn.h:269
#define counter_format
Definition: common.h:31
bool occ
Definition: options.h:394
static const struct mtu_load_test mtu_load_test_sequence[]
Definition: occ.c:62
struct event_timeout occ_interval
Definition: openvpn.h:297
#define PACKAGE_NAME
Definition: config.h:730
#define FRAME_HEADROOM(f)
Definition: mtu.h:187
struct frame frame
Definition: openvpn.h:248
static bool buf_write_u16(struct buffer *dest, int data)
Definition: buffer.h:720
void check_send_occ_req_dowork(struct context *c)
Definition: occ.c:149
#define EXPANDED_SIZE(f)
Definition: mtu.h:172
void check_send_occ_msg_dowork(struct context *c)
Definition: occ.c:216
bool mtu_test
Definition: options.h:285
const uint8_t occ_magic[]
Definition: occ.c:57
Interface functions to the internal and external multiplexers.
#define OCC_REPLY
Definition: occ.h:37
int delta
Definition: occ.h:76
const char * remote
Definition: options.h:104
struct connection_entry ce
Definition: options.h:252
struct context_2 c2
Level 2 context.
Definition: openvpn.h:502
#define OCC_STRING_SIZE
Definition: occ.h:30
#define OCC_MTU_REQUEST
Definition: occ.h:54
#define OCC_MTU_LOAD_REQUEST
Definition: occ.h:52
#define BLEN(buf)
Definition: buffer.h:127
struct buffer aux_buf
Definition: openvpn.h:94
#define TUN_MTU_MIN
Definition: mtu.h:60
#define msg(flags,...)
Definition: error.h:153
int max_recv_size_remote
Definition: openvpn.h:305
void check_send_occ_load_test_dowork(struct context *c)
Definition: occ.c:186
struct event_timeout occ_mtu_load_test_interval
Definition: openvpn.h:313
volatile int signal_received
Definition: sig.h:45
int max_send_size_remote
Definition: openvpn.h:307
char * options_string_remote
Definition: openvpn.h:293
static bool buf_safe(const struct buffer *buf, size_t len)
Definition: buffer.h:541
#define buf_init(buf, offset)
Definition: buffer.h:196
int op
Definition: occ.h:75
#define MAX_RW_SIZE_TUN(f)
Definition: mtu.h:180
static int min_int(int x, int y)
Definition: integer.h:82
char * options_string_local
Definition: openvpn.h:292
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition: buffer.h:689
static int buf_read_u16(struct buffer *buf)
Definition: buffer.h:825
long int get_random(void)
Definition: crypto.c:1775
#define OCC_N_TRIES
Definition: occ.h:47
#define D_SHOW_OCC
Definition: errlevel.h:96
int max_send_size_local
Definition: openvpn.h:306
int occ_op
Definition: openvpn.h:295
const char * signal_text
Definition: sig.h:47
int fragment
Definition: options.h:127
counter_type link_read_bytes_auth
Definition: openvpn.h:270
#define D_PACKET_CONTENT
Definition: errlevel.h:162