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
8 * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
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.
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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "forward-inline.h"
34 #include "occ-inline.h"
37 * This random string identifies an OpenVPN
38 * Configuration Control packet.
39 * It should be of sufficient length and randomness
40 * so as not to collide with other tunnel data.
42 * The OCC protocol is as follows:
44 * occ_magic -- (16 octets)
46 * type [OCC_REQUEST | OCC_REPLY] (1 octet)
47 * null terminated options string if OCC_REPLY (variable)
49 * When encryption is used, the OCC packet
50 * is encapsulated within the encrypted
53 * OCC_STRING_SIZE must be set to sizeof (occ_magic)
56 const uint8_t occ_magic
[] = {
57 0x28, 0x7f, 0x34, 0x6b, 0xd4, 0xef, 0x7a, 0x81,
58 0x2d, 0x56, 0xb8, 0xd3, 0xaf, 0xc5, 0x45, 0x9c
61 static const struct mtu_load_test mtu_load_test_sequence
[] = {
63 {OCC_MTU_LOAD_REQUEST
, -1000},
64 {OCC_MTU_LOAD
, -1000},
65 {OCC_MTU_LOAD_REQUEST
, -1000},
66 {OCC_MTU_LOAD
, -1000},
67 {OCC_MTU_LOAD_REQUEST
, -1000},
68 {OCC_MTU_LOAD
, -1000},
70 {OCC_MTU_LOAD_REQUEST
, -750},
72 {OCC_MTU_LOAD_REQUEST
, -750},
74 {OCC_MTU_LOAD_REQUEST
, -750},
77 {OCC_MTU_LOAD_REQUEST
, -500},
79 {OCC_MTU_LOAD_REQUEST
, -500},
81 {OCC_MTU_LOAD_REQUEST
, -500},
84 {OCC_MTU_LOAD_REQUEST
, -400},
86 {OCC_MTU_LOAD_REQUEST
, -400},
88 {OCC_MTU_LOAD_REQUEST
, -400},
91 {OCC_MTU_LOAD_REQUEST
, -300},
93 {OCC_MTU_LOAD_REQUEST
, -300},
95 {OCC_MTU_LOAD_REQUEST
, -300},
98 {OCC_MTU_LOAD_REQUEST
, -200},
100 {OCC_MTU_LOAD_REQUEST
, -200},
101 {OCC_MTU_LOAD
, -200},
102 {OCC_MTU_LOAD_REQUEST
, -200},
103 {OCC_MTU_LOAD
, -200},
105 {OCC_MTU_LOAD_REQUEST
, -150},
106 {OCC_MTU_LOAD
, -150},
107 {OCC_MTU_LOAD_REQUEST
, -150},
108 {OCC_MTU_LOAD
, -150},
109 {OCC_MTU_LOAD_REQUEST
, -150},
110 {OCC_MTU_LOAD
, -150},
112 {OCC_MTU_LOAD_REQUEST
, -100},
113 {OCC_MTU_LOAD
, -100},
114 {OCC_MTU_LOAD_REQUEST
, -100},
115 {OCC_MTU_LOAD
, -100},
116 {OCC_MTU_LOAD_REQUEST
, -100},
117 {OCC_MTU_LOAD
, -100},
119 {OCC_MTU_LOAD_REQUEST
, -50},
121 {OCC_MTU_LOAD_REQUEST
, -50},
123 {OCC_MTU_LOAD_REQUEST
, -50},
126 {OCC_MTU_LOAD_REQUEST
, 0},
128 {OCC_MTU_LOAD_REQUEST
, 0},
130 {OCC_MTU_LOAD_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 {OCC_MTU_REQUEST
, 0},
148 check_send_occ_req_dowork (struct context
*c
)
150 if (++c
->c2
.occ_n_tries
>= OCC_N_TRIES
)
152 if (c
->options
.ce
.remote
)
154 * No OCC_REPLY from peer after repeated attempts.
158 "NOTE: failed to obtain options consistency info from peer -- "
159 "this could occur if the remote peer is running a version of "
161 " before 1.5-beta8 or if there is a network connectivity problem, and will not necessarily prevent "
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.",
166 c
->c2
.link_read_bytes
,
167 c
->c2
.link_read_bytes_auth
);
168 event_timeout_clear (&c
->c2
.occ_interval
);
172 c
->c2
.occ_op
= OCC_REQUEST
;
175 * If we don't hear back from peer, send another
176 * OCC_REQUEST in OCC_INTERVAL_SECONDS.
178 event_timeout_reset (&c
->c2
.occ_interval
);
183 check_send_occ_load_test_dowork (struct context
*c
)
185 if (CONNECTION_ESTABLISHED (c
))
187 const struct mtu_load_test
*entry
;
189 if (!c
->c2
.occ_mtu_load_n_tries
)
191 "NOTE: Beginning empirical MTU test -- results should be available in 3 to 4 minutes.");
193 entry
= &mtu_load_test_sequence
[c
->c2
.occ_mtu_load_n_tries
++];
196 c
->c2
.occ_op
= entry
->op
;
197 c
->c2
.occ_mtu_load_size
=
198 EXPANDED_SIZE (&c
->c2
.frame
) + entry
->delta
;
203 "NOTE: failed to empirically measure MTU (requires " PACKAGE_NAME
" 1.5 or higher at other end of connection).");
204 event_timeout_clear (&c
->c2
.occ_mtu_load_test_interval
);
205 c
->c2
.occ_mtu_load_n_tries
= 0;
211 check_send_occ_msg_dowork (struct context
*c
)
215 c
->c2
.buf
= c
->c2
.buffers
->aux_buf
;
216 ASSERT (buf_init (&c
->c2
.buf
, FRAME_HEADROOM (&c
->c2
.frame
)));
217 ASSERT (buf_safe (&c
->c2
.buf
, MAX_RW_SIZE_TUN (&c
->c2
.frame
)));
218 ASSERT (buf_write (&c
->c2
.buf
, occ_magic
, OCC_STRING_SIZE
));
220 switch (c
->c2
.occ_op
)
223 if (!buf_write_u8 (&c
->c2
.buf
, OCC_REQUEST
))
225 dmsg (D_PACKET_CONTENT
, "SENT OCC_REQUEST");
230 if (!c
->c2
.options_string_local
)
232 if (!buf_write_u8 (&c
->c2
.buf
, OCC_REPLY
))
234 if (!buf_write (&c
->c2
.buf
, c
->c2
.options_string_local
,
235 strlen (c
->c2
.options_string_local
) + 1))
237 dmsg (D_PACKET_CONTENT
, "SENT OCC_REPLY");
241 case OCC_MTU_REQUEST
:
242 if (!buf_write_u8 (&c
->c2
.buf
, OCC_MTU_REQUEST
))
244 dmsg (D_PACKET_CONTENT
, "SENT OCC_MTU_REQUEST");
249 if (!buf_write_u8 (&c
->c2
.buf
, OCC_MTU_REPLY
))
251 if (!buf_write_u16 (&c
->c2
.buf
, c
->c2
.max_recv_size_local
))
253 if (!buf_write_u16 (&c
->c2
.buf
, c
->c2
.max_send_size_local
))
255 dmsg (D_PACKET_CONTENT
, "SENT OCC_MTU_REPLY");
259 case OCC_MTU_LOAD_REQUEST
:
260 if (!buf_write_u8 (&c
->c2
.buf
, OCC_MTU_LOAD_REQUEST
))
262 if (!buf_write_u16 (&c
->c2
.buf
, c
->c2
.occ_mtu_load_size
))
264 dmsg (D_PACKET_CONTENT
, "SENT OCC_MTU_LOAD_REQUEST");
272 if (!buf_write_u8 (&c
->c2
.buf
, OCC_MTU_LOAD
))
274 need_to_add
= min_int (c
->c2
.occ_mtu_load_size
, EXPANDED_SIZE (&c
->c2
.frame
))
277 - EXTRA_FRAME (&c
->c2
.frame
);
279 while (need_to_add
> 0)
282 * Fill the load test packet with pseudo-random bytes.
284 if (!buf_write_u8 (&c
->c2
.buf
, get_random () & 0xFF))
288 dmsg (D_PACKET_CONTENT
, "SENT OCC_MTU_LOAD min_int(%d-%d-%d-%d,%d) size=%d",
289 c
->c2
.occ_mtu_load_size
,
291 (int) sizeof (uint8_t),
292 EXTRA_FRAME (&c
->c2
.frame
),
293 MAX_RW_SIZE_TUN (&c
->c2
.frame
),
300 if (!buf_write_u8 (&c
->c2
.buf
, OCC_EXIT
))
302 dmsg (D_PACKET_CONTENT
, "SENT OCC_EXIT");
310 * We will treat the packet like any other outgoing packet,
311 * compress, encrypt, sign, etc.
313 encrypt_sign (c
, true);
320 process_received_occ_msg (struct context
*c
)
322 ASSERT (buf_advance (&c
->c2
.buf
, OCC_STRING_SIZE
));
323 switch (buf_read_u8 (&c
->c2
.buf
))
326 dmsg (D_PACKET_CONTENT
, "RECEIVED OCC_REQUEST");
327 c
->c2
.occ_op
= OCC_REPLY
;
330 case OCC_MTU_REQUEST
:
331 dmsg (D_PACKET_CONTENT
, "RECEIVED OCC_MTU_REQUEST");
332 c
->c2
.occ_op
= OCC_MTU_REPLY
;
335 case OCC_MTU_LOAD_REQUEST
:
336 dmsg (D_PACKET_CONTENT
, "RECEIVED OCC_MTU_LOAD_REQUEST");
337 c
->c2
.occ_mtu_load_size
= buf_read_u16 (&c
->c2
.buf
);
338 if (c
->c2
.occ_mtu_load_size
>= 0)
339 c
->c2
.occ_op
= OCC_MTU_LOAD
;
343 dmsg (D_PACKET_CONTENT
, "RECEIVED OCC_REPLY");
344 if (c
->options
.occ
&& !TLS_MODE (c
) && c
->c2
.options_string_remote
)
346 if (!options_cmp_equal_safe ((char *) BPTR (&c
->c2
.buf
),
347 c
->c2
.options_string_remote
,
350 options_warning_safe ((char *) BPTR (&c
->c2
.buf
),
351 c
->c2
.options_string_remote
,
355 event_timeout_clear (&c
->c2
.occ_interval
);
359 dmsg (D_PACKET_CONTENT
, "RECEIVED OCC_MTU_REPLY");
360 c
->c2
.max_recv_size_remote
= buf_read_u16 (&c
->c2
.buf
);
361 c
->c2
.max_send_size_remote
= buf_read_u16 (&c
->c2
.buf
);
362 if (c
->options
.mtu_test
363 && c
->c2
.max_recv_size_remote
> 0
364 && c
->c2
.max_send_size_remote
> 0)
366 msg (M_INFO
, "NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[%d,%d] remote->local=[%d,%d]",
367 c
->c2
.max_send_size_local
,
368 c
->c2
.max_recv_size_remote
,
369 c
->c2
.max_send_size_remote
,
370 c
->c2
.max_recv_size_local
);
371 if (!c
->options
.fragment
372 && c
->options
.ce
.proto
== PROTO_UDPv4
373 && c
->c2
.max_send_size_local
> TUN_MTU_MIN
374 && (c
->c2
.max_recv_size_remote
< c
->c2
.max_send_size_local
375 || c
->c2
.max_recv_size_local
< c
->c2
.max_send_size_remote
))
376 msg (M_INFO
, "NOTE: This connection is unable to accomodate a UDP packet size of %d. Consider using --fragment or --mssfix options as a workaround.",
377 c
->c2
.max_send_size_local
);
379 event_timeout_clear (&c
->c2
.occ_mtu_load_test_interval
);
383 dmsg (D_PACKET_CONTENT
, "RECEIVED OCC_EXIT");
384 c
->sig
->signal_received
= SIGTERM
;
385 c
->sig
->signal_text
= "remote-exit";
388 c
->c2
.buf
.len
= 0; /* don't pass packet on */
392 static void dummy(void) {}