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