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