big svn cleanup
[anytun.git] / src / openvpn / occ.c
blob6b136dc331dc65839eb243a47e8ab33db044d4a8
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.
8 * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@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
25 #ifdef WIN32
26 #include "config-win32.h"
27 #else
28 #include "config.h"
29 #endif
31 #include "syshead.h"
33 #ifdef ENABLE_OCC
35 #include "occ.h"
37 #include "memdbg.h"
39 #include "forward-inline.h"
40 #include "occ-inline.h"
43 * This random string identifies an OpenVPN
44 * Configuration Control packet.
45 * It should be of sufficient length and randomness
46 * so as not to collide with other tunnel data.
48 * The OCC protocol is as follows:
50 * occ_magic -- (16 octets)
52 * type [OCC_REQUEST | OCC_REPLY] (1 octet)
53 * null terminated options string if OCC_REPLY (variable)
55 * When encryption is used, the OCC packet
56 * is encapsulated within the encrypted
57 * envelope.
59 * OCC_STRING_SIZE must be set to sizeof (occ_magic)
62 const uint8_t occ_magic[] = {
63 0x28, 0x7f, 0x34, 0x6b, 0xd4, 0xef, 0x7a, 0x81,
64 0x2d, 0x56, 0xb8, 0xd3, 0xaf, 0xc5, 0x45, 0x9c
67 static const struct mtu_load_test mtu_load_test_sequence[] = {
69 {OCC_MTU_LOAD_REQUEST, -1000},
70 {OCC_MTU_LOAD, -1000},
71 {OCC_MTU_LOAD_REQUEST, -1000},
72 {OCC_MTU_LOAD, -1000},
73 {OCC_MTU_LOAD_REQUEST, -1000},
74 {OCC_MTU_LOAD, -1000},
76 {OCC_MTU_LOAD_REQUEST, -750},
77 {OCC_MTU_LOAD, -750},
78 {OCC_MTU_LOAD_REQUEST, -750},
79 {OCC_MTU_LOAD, -750},
80 {OCC_MTU_LOAD_REQUEST, -750},
81 {OCC_MTU_LOAD, -750},
83 {OCC_MTU_LOAD_REQUEST, -500},
84 {OCC_MTU_LOAD, -500},
85 {OCC_MTU_LOAD_REQUEST, -500},
86 {OCC_MTU_LOAD, -500},
87 {OCC_MTU_LOAD_REQUEST, -500},
88 {OCC_MTU_LOAD, -500},
90 {OCC_MTU_LOAD_REQUEST, -400},
91 {OCC_MTU_LOAD, -400},
92 {OCC_MTU_LOAD_REQUEST, -400},
93 {OCC_MTU_LOAD, -400},
94 {OCC_MTU_LOAD_REQUEST, -400},
95 {OCC_MTU_LOAD, -400},
97 {OCC_MTU_LOAD_REQUEST, -300},
98 {OCC_MTU_LOAD, -300},
99 {OCC_MTU_LOAD_REQUEST, -300},
100 {OCC_MTU_LOAD, -300},
101 {OCC_MTU_LOAD_REQUEST, -300},
102 {OCC_MTU_LOAD, -300},
104 {OCC_MTU_LOAD_REQUEST, -200},
105 {OCC_MTU_LOAD, -200},
106 {OCC_MTU_LOAD_REQUEST, -200},
107 {OCC_MTU_LOAD, -200},
108 {OCC_MTU_LOAD_REQUEST, -200},
109 {OCC_MTU_LOAD, -200},
111 {OCC_MTU_LOAD_REQUEST, -150},
112 {OCC_MTU_LOAD, -150},
113 {OCC_MTU_LOAD_REQUEST, -150},
114 {OCC_MTU_LOAD, -150},
115 {OCC_MTU_LOAD_REQUEST, -150},
116 {OCC_MTU_LOAD, -150},
118 {OCC_MTU_LOAD_REQUEST, -100},
119 {OCC_MTU_LOAD, -100},
120 {OCC_MTU_LOAD_REQUEST, -100},
121 {OCC_MTU_LOAD, -100},
122 {OCC_MTU_LOAD_REQUEST, -100},
123 {OCC_MTU_LOAD, -100},
125 {OCC_MTU_LOAD_REQUEST, -50},
126 {OCC_MTU_LOAD, -50},
127 {OCC_MTU_LOAD_REQUEST, -50},
128 {OCC_MTU_LOAD, -50},
129 {OCC_MTU_LOAD_REQUEST, -50},
130 {OCC_MTU_LOAD, -50},
132 {OCC_MTU_LOAD_REQUEST, 0},
133 {OCC_MTU_LOAD, 0},
134 {OCC_MTU_LOAD_REQUEST, 0},
135 {OCC_MTU_LOAD, 0},
136 {OCC_MTU_LOAD_REQUEST, 0},
137 {OCC_MTU_LOAD, 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 {OCC_MTU_REQUEST, 0},
150 {-1, 0}
153 void
154 check_send_occ_req_dowork (struct context *c)
156 if (++c->c2.occ_n_tries >= OCC_N_TRIES)
158 if (c->options.remote_list)
160 * No OCC_REPLY from peer after repeated attempts.
161 * Give up.
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,
173 c->c2.link_read_bytes_auth);
174 event_timeout_clear (&c->c2.occ_interval);
176 else
178 c->c2.occ_op = OCC_REQUEST;
181 * If we don't hear back from peer, send another
182 * OCC_REQUEST in OCC_INTERVAL_SECONDS.
184 event_timeout_reset (&c->c2.occ_interval);
188 void
189 check_send_occ_load_test_dowork (struct context *c)
191 if (CONNECTION_ESTABLISHED (c))
193 const struct mtu_load_test *entry;
195 if (!c->c2.occ_mtu_load_n_tries)
196 msg (M_INFO,
197 "NOTE: Beginning empirical MTU test -- results should be available in 3 to 4 minutes.");
199 entry = &mtu_load_test_sequence[c->c2.occ_mtu_load_n_tries++];
200 if (entry->op >= 0)
202 c->c2.occ_op = entry->op;
203 c->c2.occ_mtu_load_size =
204 EXPANDED_SIZE (&c->c2.frame) + entry->delta;
206 else
208 msg (M_INFO,
209 "NOTE: failed to empirically measure MTU (requires " PACKAGE_NAME " 1.5 or higher at other end of connection).");
210 event_timeout_clear (&c->c2.occ_mtu_load_test_interval);
211 c->c2.occ_mtu_load_n_tries = 0;
216 void
217 check_send_occ_msg_dowork (struct context *c)
219 bool doit = false;
221 c->c2.buf = c->c2.buffers->aux_buf;
222 ASSERT (buf_init (&c->c2.buf, FRAME_HEADROOM (&c->c2.frame)));
223 ASSERT (buf_safe (&c->c2.buf, MAX_RW_SIZE_TUN (&c->c2.frame)));
224 ASSERT (buf_write (&c->c2.buf, occ_magic, OCC_STRING_SIZE));
226 switch (c->c2.occ_op)
228 case OCC_REQUEST:
229 if (!buf_write_u8 (&c->c2.buf, OCC_REQUEST))
230 break;
231 dmsg (D_PACKET_CONTENT, "SENT OCC_REQUEST");
232 doit = true;
233 break;
235 case OCC_REPLY:
236 if (!c->c2.options_string_local)
237 break;
238 if (!buf_write_u8 (&c->c2.buf, OCC_REPLY))
239 break;
240 if (!buf_write (&c->c2.buf, c->c2.options_string_local,
241 strlen (c->c2.options_string_local) + 1))
242 break;
243 dmsg (D_PACKET_CONTENT, "SENT OCC_REPLY");
244 doit = true;
245 break;
247 case OCC_MTU_REQUEST:
248 if (!buf_write_u8 (&c->c2.buf, OCC_MTU_REQUEST))
249 break;
250 dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_REQUEST");
251 doit = true;
252 break;
254 case OCC_MTU_REPLY:
255 if (!buf_write_u8 (&c->c2.buf, OCC_MTU_REPLY))
256 break;
257 if (!buf_write_u16 (&c->c2.buf, c->c2.max_recv_size_local))
258 break;
259 if (!buf_write_u16 (&c->c2.buf, c->c2.max_send_size_local))
260 break;
261 dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_REPLY");
262 doit = true;
263 break;
265 case OCC_MTU_LOAD_REQUEST:
266 if (!buf_write_u8 (&c->c2.buf, OCC_MTU_LOAD_REQUEST))
267 break;
268 if (!buf_write_u16 (&c->c2.buf, c->c2.occ_mtu_load_size))
269 break;
270 dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_LOAD_REQUEST");
271 doit = true;
272 break;
274 case OCC_MTU_LOAD:
276 int need_to_add;
278 if (!buf_write_u8 (&c->c2.buf, OCC_MTU_LOAD))
279 break;
280 need_to_add = min_int (c->c2.occ_mtu_load_size, EXPANDED_SIZE (&c->c2.frame))
281 - OCC_STRING_SIZE
282 - sizeof (uint8_t)
283 - EXTRA_FRAME (&c->c2.frame);
285 while (need_to_add > 0)
288 * Fill the load test packet with pseudo-random bytes.
290 if (!buf_write_u8 (&c->c2.buf, get_random () & 0xFF))
291 break;
292 --need_to_add;
294 dmsg (D_PACKET_CONTENT, "SENT OCC_MTU_LOAD min_int(%d-%d-%d-%d,%d) size=%d",
295 c->c2.occ_mtu_load_size,
296 OCC_STRING_SIZE,
297 (int) sizeof (uint8_t),
298 EXTRA_FRAME (&c->c2.frame),
299 MAX_RW_SIZE_TUN (&c->c2.frame),
300 BLEN (&c->c2.buf));
301 doit = true;
303 break;
305 case OCC_EXIT:
306 if (!buf_write_u8 (&c->c2.buf, OCC_EXIT))
307 break;
308 dmsg (D_PACKET_CONTENT, "SENT OCC_EXIT");
309 doit = true;
310 break;
313 if (doit)
316 * We will treat the packet like any other outgoing packet,
317 * compress, encrypt, sign, etc.
319 encrypt_sign (c, true);
322 c->c2.occ_op = -1;
325 void
326 process_received_occ_msg (struct context *c)
328 ASSERT (buf_advance (&c->c2.buf, OCC_STRING_SIZE));
329 switch (buf_read_u8 (&c->c2.buf))
331 case OCC_REQUEST:
332 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_REQUEST");
333 c->c2.occ_op = OCC_REPLY;
334 break;
336 case OCC_MTU_REQUEST:
337 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_REQUEST");
338 c->c2.occ_op = OCC_MTU_REPLY;
339 break;
341 case OCC_MTU_LOAD_REQUEST:
342 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_LOAD_REQUEST");
343 c->c2.occ_mtu_load_size = buf_read_u16 (&c->c2.buf);
344 if (c->c2.occ_mtu_load_size >= 0)
345 c->c2.occ_op = OCC_MTU_LOAD;
346 break;
348 case OCC_REPLY:
349 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_REPLY");
350 if (c->options.occ && !TLS_MODE (c) && c->c2.options_string_remote)
352 if (!options_cmp_equal_safe ((char *) BPTR (&c->c2.buf),
353 c->c2.options_string_remote,
354 c->c2.buf.len))
356 options_warning_safe ((char *) BPTR (&c->c2.buf),
357 c->c2.options_string_remote,
358 c->c2.buf.len);
361 event_timeout_clear (&c->c2.occ_interval);
362 break;
364 case OCC_MTU_REPLY:
365 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_REPLY");
366 c->c2.max_recv_size_remote = buf_read_u16 (&c->c2.buf);
367 c->c2.max_send_size_remote = buf_read_u16 (&c->c2.buf);
368 if (c->options.mtu_test
369 && c->c2.max_recv_size_remote > 0
370 && c->c2.max_send_size_remote > 0)
372 msg (M_INFO, "NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[%d,%d] remote->local=[%d,%d]",
373 c->c2.max_send_size_local,
374 c->c2.max_recv_size_remote,
375 c->c2.max_send_size_remote,
376 c->c2.max_recv_size_local);
377 if (!c->options.fragment
378 && c->options.proto == PROTO_UDPv4
379 && c->c2.max_send_size_local > TUN_MTU_MIN
380 && (c->c2.max_recv_size_remote < c->c2.max_send_size_local
381 || c->c2.max_recv_size_local < c->c2.max_send_size_remote))
382 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.",
383 c->c2.max_send_size_local);
385 event_timeout_clear (&c->c2.occ_mtu_load_test_interval);
386 break;
388 case OCC_EXIT:
389 dmsg (D_PACKET_CONTENT, "RECEIVED OCC_EXIT");
390 c->sig->signal_received = SIGTERM;
391 c->sig->signal_text = "remote-exit";
392 break;
394 c->c2.buf.len = 0; /* don't pass packet on */
397 #else
398 static void dummy(void) {}
399 #endif