Skip to content

Latest commit

 

History

History
661 lines (555 loc) · 17.5 KB

dtls.c

File metadata and controls

661 lines (555 loc) · 17.5 KB
 
Sep 22, 2008
Sep 22, 2008
1
/*
Nov 20, 2008
Nov 20, 2008
2
* OpenConnect (SSL + DTLS) VPN client
Sep 22, 2008
Sep 22, 2008
3
*
Jan 26, 2015
Jan 26, 2015
4
* Copyright © 2008-2015 Intel Corporation.
Sep 22, 2008
Sep 22, 2008
5
*
Nov 20, 2008
Nov 20, 2008
6
7
8
* Author: David Woodhouse <dwmw2@infradead.org>
*
* This program is free software; you can redistribute it and/or
Oct 4, 2008
Oct 4, 2008
9
* modify it under the terms of the GNU Lesser General Public License
Nov 20, 2008
Nov 20, 2008
10
* version 2.1, as published by the Free Software Foundation.
Sep 22, 2008
Sep 22, 2008
11
*
Nov 20, 2008
Nov 20, 2008
12
* This program is distributed in the hope that it will be useful, but
Oct 4, 2008
Oct 4, 2008
13
14
15
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
Sep 22, 2008
Sep 22, 2008
16
17
*/
Jul 1, 2014
Jul 1, 2014
18
19
#include <config.h>
Jun 30, 2021
Jun 30, 2021
20
21
#include "openconnect-internal.h"
Sep 23, 2008
Sep 23, 2008
22
#include <unistd.h>
Jun 30, 2021
Jun 30, 2021
23
#include <sys/types.h>
Sep 23, 2008
Sep 23, 2008
24
#include <fcntl.h>
May 6, 2016
May 6, 2016
25
26
27
28
#ifndef _WIN32
#include <netinet/in.h>
#include <sys/socket.h>
#endif
Sep 22, 2008
Sep 22, 2008
29
Jun 30, 2021
Jun 30, 2021
30
31
32
33
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
Sep 22, 2008
Sep 22, 2008
34
Sep 22, 2008
Sep 22, 2008
35
36
37
38
39
40
/*
* The master-secret is generated randomly by the client. The server
* responds with a DTLS Session-ID. These, done over the HTTPS
* connection, are enough to 'resume' a DTLS session, bypassing all
* the normal setup of a normal DTLS connection.
*
Sep 29, 2008
Sep 29, 2008
41
42
43
44
* Cisco use a version of the protocol which predates RFC4347, but
* isn't quite the same as the pre-RFC version of the protocol which
* was in OpenSSL 0.9.8e -- it includes backports of some later
* OpenSSL patches.
Sep 23, 2008
Sep 23, 2008
45
*
Apr 9, 2009
Apr 9, 2009
46
47
* The openssl/ directory of this source tree should contain both a
* small patch against OpenSSL 0.9.8e to make it support Cisco's
Sep 29, 2008
Sep 29, 2008
48
49
* snapshot of the protocol, and a larger patch against newer OpenSSL
* which gives us an option to use the old protocol again.
Sep 23, 2008
Sep 23, 2008
50
*
Sep 29, 2008
Sep 29, 2008
51
52
53
54
55
56
* Cisco's server also seems to respond to the official version of the
* protocol, with a change in the ChangeCipherSpec packet which implies
* that it does know the difference and isn't just repeating the version
* number seen in the ClientHello. But although I can make the handshake
* complete by hacking tls1_mac() to use the _old_ protocol version
* number when calculating the MAC, the server still seems to be ignoring
Oct 2, 2008
Oct 2, 2008
57
58
* my subsequent data packets. So we use the old protocol, which is what
* their clients use anyway.
Apr 9, 2009
Apr 9, 2009
59
*/
Sep 22, 2008
Sep 22, 2008
60
Dec 13, 2016
Dec 13, 2016
61
62
char *openconnect_bin2hex(const char *prefix, const uint8_t *data, unsigned len)
{
Dec 13, 2016
Dec 13, 2016
63
64
struct oc_text_buf *buf;
char *p = NULL;
Dec 13, 2016
Dec 13, 2016
65
Dec 13, 2016
Dec 13, 2016
66
buf = buf_alloc();
May 15, 2017
May 15, 2017
67
68
if (prefix)
buf_append(buf, "%s", prefix);
Dec 13, 2016
Dec 13, 2016
69
70
71
72
73
buf_append_hex(buf, data, len);
if (!buf_error(buf)) {
p = buf->data;
buf->data = NULL;
Dec 13, 2016
Dec 13, 2016
74
}
Dec 13, 2016
Dec 13, 2016
75
76
77
buf_free(buf);
return p;
Dec 13, 2016
Dec 13, 2016
78
79
}
May 15, 2017
May 15, 2017
80
81
82
83
84
85
86
87
char *openconnect_bin2base64(const char *prefix, const uint8_t *data, unsigned len)
{
struct oc_text_buf *buf;
char *p = NULL;
buf = buf_alloc();
if (prefix)
buf_append(buf, "%s", prefix);
May 17, 2021
May 17, 2021
88
buf_append_base64(buf, data, len, 0);
May 15, 2017
May 15, 2017
89
90
91
92
93
94
95
96
97
98
if (!buf_error(buf)) {
p = buf->data;
buf->data = NULL;
}
buf_free(buf);
return p;
}
Apr 21, 2021
Apr 21, 2021
99
static int connect_dtls_socket(struct openconnect_info *vpninfo, int *timeout)
Jun 7, 2012
Jun 7, 2012
100
{
Jan 26, 2015
Jan 26, 2015
101
int dtls_fd, ret;
Jun 7, 2012
Jun 7, 2012
102
Feb 11, 2014
Feb 11, 2014
103
104
105
106
107
108
109
/* Sanity check for the removal of new_dtls_{fd,ssl} */
if (vpninfo->dtls_fd != -1) {
vpn_progress(vpninfo, PRG_ERR, _("DTLS connection attempted with an existing fd\n"));
vpninfo->dtls_attempt_period = 0;
return -EINVAL;
}
Jun 7, 2012
Jun 7, 2012
110
111
112
113
114
115
if (!vpninfo->dtls_addr) {
vpn_progress(vpninfo, PRG_ERR, _("No DTLS address\n"));
vpninfo->dtls_attempt_period = 0;
return -EINVAL;
}
Apr 21, 2021
Apr 21, 2021
116
if (vpninfo->proto->proto == PROTO_ANYCONNECT && !vpninfo->dtls_cipher) {
Jun 7, 2012
Jun 7, 2012
117
118
119
120
121
122
123
124
125
126
127
128
129
/* We probably didn't offer it any ciphers it liked */
vpn_progress(vpninfo, PRG_ERR, _("Server offered no DTLS cipher option\n"));
vpninfo->dtls_attempt_period = 0;
return -EINVAL;
}
if (vpninfo->proxy) {
/* XXX: Theoretically, SOCKS5 proxies can do UDP too */
vpn_progress(vpninfo, PRG_ERR, _("No DTLS when connected via proxy\n"));
vpninfo->dtls_attempt_period = 0;
return -EINVAL;
}
Jan 26, 2015
Jan 26, 2015
130
131
dtls_fd = udp_connect(vpninfo);
if (dtls_fd < 0)
Jun 7, 2012
Jun 7, 2012
132
133
134
135
136
return -EINVAL;
ret = start_dtls_handshake(vpninfo, dtls_fd);
if (ret) {
Feb 6, 2014
Feb 6, 2014
137
closesocket(dtls_fd);
Jun 7, 2012
Jun 7, 2012
138
139
140
return ret;
}
Feb 11, 2014
Feb 11, 2014
141
142
vpninfo->dtls_state = DTLS_CONNECTING;
Feb 11, 2014
Feb 11, 2014
143
vpninfo->dtls_fd = dtls_fd;
Feb 11, 2014
Feb 11, 2014
144
145
146
monitor_fd_new(vpninfo, dtls);
monitor_read_fd(vpninfo, dtls);
monitor_except_fd(vpninfo, dtls);
Jun 7, 2012
Jun 7, 2012
147
148
149
time(&vpninfo->new_dtls_started);
Apr 21, 2021
Apr 21, 2021
150
return dtls_try_handshake(vpninfo, timeout);
Jun 7, 2012
Jun 7, 2012
151
152
}
Feb 11, 2014
Feb 11, 2014
153
void dtls_close(struct openconnect_info *vpninfo)
Oct 2, 2008
Oct 2, 2008
154
155
{
if (vpninfo->dtls_ssl) {
Sep 12, 2016
Sep 12, 2016
156
dtls_ssl_free(vpninfo);
Jul 1, 2021
Jul 1, 2021
157
unmonitor_fd(vpninfo, dtls);
Jun 29, 2021
Jun 29, 2021
158
closesocket(vpninfo->dtls_fd);
Oct 2, 2008
Oct 2, 2008
159
160
161
vpninfo->dtls_ssl = NULL;
vpninfo->dtls_fd = -1;
}
Aug 14, 2017
Aug 14, 2017
162
vpninfo->dtls_state = DTLS_SLEEPING;
Jan 15, 2014
Jan 15, 2014
163
}
Sep 29, 2008
Sep 29, 2008
164
Apr 21, 2021
Apr 21, 2021
165
int dtls_reconnect(struct openconnect_info *vpninfo, int *timeout)
Jan 15, 2014
Jan 15, 2014
166
{
Feb 11, 2014
Feb 11, 2014
167
dtls_close(vpninfo);
May 14, 2017
May 14, 2017
168
169
170
171
if (vpninfo->dtls_state == DTLS_DISABLED)
return -EINVAL;
Feb 11, 2014
Feb 11, 2014
172
vpninfo->dtls_state = DTLS_SLEEPING;
Apr 21, 2021
Apr 21, 2021
173
return connect_dtls_socket(vpninfo, timeout);
Sep 29, 2008
Sep 29, 2008
174
175
}
Apr 13, 2021
Apr 13, 2021
176
int dtls_setup(struct openconnect_info *vpninfo)
Sep 22, 2008
Sep 22, 2008
177
{
Apr 21, 2021
Apr 21, 2021
178
179
if (vpninfo->dtls_state == DTLS_DISABLED ||
vpninfo->dtls_state == DTLS_NOSECRET)
Jan 26, 2015
Jan 26, 2015
180
181
return -EINVAL;
Apr 13, 2021
Apr 13, 2021
182
if (!vpninfo->dtls_attempt_period)
Jan 15, 2014
Jan 15, 2014
183
184
return 0;
Apr 16, 2021
Apr 16, 2021
185
if (!vpninfo->dtls_addr) {
May 28, 2021
May 28, 2021
186
vpn_progress(vpninfo, PRG_ERR, _("No DTLS address\n"));
Jan 2, 2010
Jan 2, 2010
187
vpninfo->dtls_attempt_period = 0;
Sep 23, 2008
Sep 23, 2008
188
return -EINVAL;
Jan 2, 2010
Jan 2, 2010
189
}
Feb 17, 2014
Feb 17, 2014
190
191
if (vpninfo->dtls_times.rekey <= 0)
vpninfo->dtls_times.rekey_method = REKEY_NONE;
Jan 2, 2010
Jan 2, 2010
192
Apr 21, 2021
Apr 21, 2021
193
if (connect_dtls_socket(vpninfo, NULL))
Oct 2, 2008
Oct 2, 2008
194
return -EINVAL;
Sep 23, 2008
Sep 23, 2008
195
Jun 13, 2014
Jun 13, 2014
196
vpn_progress(vpninfo, PRG_DEBUG,
Feb 12, 2013
Feb 12, 2013
197
_("DTLS initialised. DPD %d, Keepalive %d\n"),
Sep 22, 2011
Sep 22, 2011
198
vpninfo->dtls_times.dpd, vpninfo->dtls_times.keepalive);
Sep 23, 2008
Sep 23, 2008
199
200
return 0;
Sep 22, 2008
Sep 22, 2008
201
202
}
Apr 1, 2020
Apr 1, 2020
203
204
205
206
207
208
int udp_tos_update(struct openconnect_info *vpninfo, struct pkt *pkt)
{
int tos;
/* Extract TOS field from IP header (IPv4 and IPv6 differ) */
switch(pkt->data[0] >> 4) {
Jul 19, 2021
Jul 19, 2021
209
210
211
212
213
214
215
216
217
218
219
case 4:
tos = pkt->data[1];
break;
case 6:
tos = (load_be16(pkt->data) >> 4) & 0xff;
break;
default:
vpn_progress(vpninfo, PRG_ERR,
_("Unknown packet (len %d) received: %02x %02x %02x %02x...\n"),
pkt->len, pkt->data[0], pkt->data[1], pkt->data[2], pkt->data[3]);
return -EINVAL;
Apr 1, 2020
Apr 1, 2020
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
}
/* set the actual value */
if (tos != vpninfo->dtls_tos_current) {
vpn_progress(vpninfo, PRG_DEBUG, _("TOS this: %d, TOS last: %d\n"),
tos, vpninfo->dtls_tos_current);
if (setsockopt(vpninfo->dtls_fd, vpninfo->dtls_tos_proto,
vpninfo->dtls_tos_optname, (void *)&tos, sizeof(tos)))
vpn_perror(vpninfo, _("UDP setsockopt"));
else
vpninfo->dtls_tos_current = tos;
}
return 0;
}
Apr 15, 2019
Apr 15, 2019
235
int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
Sep 22, 2008
Sep 22, 2008
236
{
Sep 23, 2008
Sep 23, 2008
237
int work_done = 0;
Oct 2, 2008
Oct 2, 2008
238
char magic_pkt;
Sep 23, 2008
Sep 23, 2008
239
Nov 18, 2014
Nov 18, 2014
240
241
if (vpninfo->dtls_need_reconnect) {
vpninfo->dtls_need_reconnect = 0;
Apr 21, 2021
Apr 21, 2021
242
dtls_reconnect(vpninfo, timeout);
Nov 18, 2014
Nov 18, 2014
243
244
245
return 1;
}
Feb 11, 2014
Feb 11, 2014
246
if (vpninfo->dtls_state == DTLS_CONNECTING) {
Apr 21, 2021
Apr 21, 2021
247
dtls_try_handshake(vpninfo, timeout);
Apr 21, 2021
Apr 21, 2021
248
249
250
251
252
if (vpninfo->dtls_state != DTLS_CONNECTED) {
vpninfo->delay_tunnel_reason = "DTLS MTU detection";
return 0;
}
return 1;
Feb 11, 2014
Feb 11, 2014
253
}
Feb 11, 2014
Feb 11, 2014
254
255
256
257
258
if (vpninfo->dtls_state == DTLS_SLEEPING) {
int when = vpninfo->new_dtls_started + vpninfo->dtls_attempt_period - time(NULL);
if (when <= 0) {
Jun 13, 2014
Jun 13, 2014
259
vpn_progress(vpninfo, PRG_DEBUG, _("Attempt new DTLS connection\n"));
Apr 21, 2021
Apr 21, 2021
260
if (connect_dtls_socket(vpninfo, timeout) < 0)
Feb 12, 2018
Feb 12, 2018
261
*timeout = 1000;
Feb 11, 2014
Feb 11, 2014
262
263
264
} else if ((when * 1000) < *timeout) {
*timeout = when * 1000;
}
Feb 11, 2014
Feb 11, 2014
265
return 0;
Feb 11, 2014
Feb 11, 2014
266
}
Feb 11, 2014
Feb 11, 2014
267
Apr 21, 2021
Apr 21, 2021
268
269
270
271
/* Nothing to do here for Cisco DTLS as it is preauthenticated */
if (vpninfo->dtls_state == DTLS_CONNECTED)
vpninfo->dtls_state = DTLS_ESTABLISHED;
Apr 15, 2019
Apr 15, 2019
272
while (readable) {
Jun 27, 2019
Jun 27, 2019
273
int len = MAX(16384, vpninfo->ip_info.mtu);
Dec 12, 2011
Dec 12, 2011
274
275
unsigned char *buf;
Jul 1, 2021
Jul 1, 2021
276
277
278
279
if (vpninfo->incoming_queue.count >= vpninfo->max_qlen) {
work_done = 1;
break;
}
Jan 6, 2015
Jan 6, 2015
280
if (!vpninfo->dtls_pkt) {
Jun 28, 2021
Jun 28, 2021
281
vpninfo->dtls_pkt = alloc_pkt(vpninfo, len);
Jan 6, 2015
Jan 6, 2015
282
if (!vpninfo->dtls_pkt) {
Jan 7, 2015
Jan 7, 2015
283
vpn_progress(vpninfo, PRG_ERR, _("Allocation failed\n"));
Dec 12, 2011
Dec 12, 2011
284
285
286
287
break;
}
}
Jan 6, 2015
Jan 6, 2015
288
buf = vpninfo->dtls_pkt->data - 1;
Apr 16, 2021
Apr 16, 2021
289
len = ssl_nonblock_read(vpninfo, 1, buf, len + 1);
Dec 12, 2011
Dec 12, 2011
290
291
if (len <= 0)
break;
Oct 5, 2008
Oct 5, 2008
292
Jun 27, 2011
Jun 27, 2011
293
vpn_progress(vpninfo, PRG_TRACE,
Sep 22, 2011
Sep 22, 2011
294
295
_("Received DTLS packet 0x%02x of %d bytes\n"),
buf[0], len);
Sep 30, 2008
Sep 30, 2008
296
Oct 2, 2008
Oct 2, 2008
297
vpninfo->dtls_times.last_rx = time(NULL);
Sep 30, 2008
Sep 30, 2008
298
Mar 10, 2013
Mar 10, 2013
299
switch (buf[0]) {
Oct 2, 2008
Oct 2, 2008
300
case AC_PKT_DATA:
Jan 6, 2015
Jan 6, 2015
301
302
303
vpninfo->dtls_pkt->len = len - 1;
queue_packet(&vpninfo->incoming_queue, vpninfo->dtls_pkt);
vpninfo->dtls_pkt = NULL;
Sep 23, 2008
Sep 23, 2008
304
305
306
work_done = 1;
break;
Oct 2, 2008
Oct 2, 2008
307
case AC_PKT_DPD_OUT:
Jun 13, 2014
Jun 13, 2014
308
vpn_progress(vpninfo, PRG_DEBUG, _("Got DTLS DPD request\n"));
Oct 2, 2008
Oct 2, 2008
309
310
311
/* FIXME: What if the packet doesn't get through? */
magic_pkt = AC_PKT_DPD_RESP;
Apr 16, 2021
Apr 16, 2021
312
if (ssl_nonblock_write(vpninfo, 1, &magic_pkt, 1) != 1)
Sep 22, 2011
Sep 22, 2011
313
314
vpn_progress(vpninfo, PRG_ERR,
_("Failed to send DPD response. Expect disconnect\n"));
Oct 2, 2008
Oct 2, 2008
315
316
continue;
Oct 2, 2008
Oct 2, 2008
317
case AC_PKT_DPD_RESP:
Jun 13, 2014
Jun 13, 2014
318
vpn_progress(vpninfo, PRG_DEBUG, _("Got DTLS DPD response\n"));
Sep 23, 2008
Sep 23, 2008
319
320
break;
Oct 2, 2008
Oct 2, 2008
321
case AC_PKT_KEEPALIVE:
Jun 13, 2014
Jun 13, 2014
322
vpn_progress(vpninfo, PRG_DEBUG, _("Got DTLS Keepalive\n"));
Oct 2, 2008
Oct 2, 2008
323
324
break;
Jan 7, 2015
Jan 7, 2015
325
326
327
328
329
330
case AC_PKT_COMPRESSED:
if (!vpninfo->dtls_compr) {
vpn_progress(vpninfo, PRG_ERR,
_("Compressed DTLS packet received when compression not enabled\n"));
goto unknown_pkt;
}
Feb 18, 2015
Feb 18, 2015
331
332
decompress_and_queue_packet(vpninfo, vpninfo->dtls_compr,
vpninfo->dtls_pkt->data, len - 1);
Jan 7, 2015
Jan 7, 2015
333
break;
Sep 23, 2008
Sep 23, 2008
334
default:
Jun 27, 2011
Jun 27, 2011
335
vpn_progress(vpninfo, PRG_ERR,
Sep 22, 2011
Sep 22, 2011
336
337
_("Unknown DTLS packet type %02x, len %d\n"),
buf[0], len);
Oct 6, 2008
Oct 6, 2008
338
339
if (1) {
/* Some versions of OpenSSL have bugs with receiving out-of-order
Apr 9, 2009
Apr 9, 2009
340
* packets. Not only do they wrongly decide to drop packets if
Oct 6, 2008
Oct 6, 2008
341
342
343
344
345
* two packets get swapped in transit, but they also _fail_ to
* drop the packet in non-blocking mode; instead they return
* the appropriate length of garbage. So don't abort... for now. */
break;
} else {
Jan 7, 2015
Jan 7, 2015
346
unknown_pkt:
Oct 6, 2008
Oct 6, 2008
347
348
349
350
vpninfo->quit_reason = "Unknown packet received";
return 1;
}
Sep 23, 2008
Sep 23, 2008
351
}
Sep 23, 2008
Sep 23, 2008
352
}
Sep 23, 2008
Sep 23, 2008
353
Oct 2, 2008
Oct 2, 2008
354
switch (keepalive_action(&vpninfo->dtls_times, timeout)) {
Jan 15, 2014
Jan 15, 2014
355
356
357
case KA_REKEY: {
int ret;
Sep 22, 2011
Sep 22, 2011
358
vpn_progress(vpninfo, PRG_INFO, _("DTLS rekey due\n"));
Aug 11, 2010
Aug 11, 2010
359
Feb 16, 2014
Feb 16, 2014
360
361
362
if (vpninfo->dtls_times.rekey_method == REKEY_SSL) {
time(&vpninfo->new_dtls_started);
vpninfo->dtls_state = DTLS_CONNECTING;
Apr 21, 2021
Apr 21, 2021
363
ret = dtls_try_handshake(vpninfo, timeout);
Feb 16, 2014
Feb 16, 2014
364
if (ret) {
Feb 18, 2014
Feb 18, 2014
365
vpn_progress(vpninfo, PRG_ERR, _("DTLS Rehandshake failed; reconnecting.\n"));
Apr 21, 2021
Apr 21, 2021
366
return connect_dtls_socket(vpninfo, timeout);
Feb 16, 2014
Feb 16, 2014
367
}
Aug 11, 2010
Aug 11, 2010
368
369
}
Dec 31, 2013
Dec 31, 2013
370
return 1;
Jan 15, 2014
Jan 15, 2014
371
}
Oct 2, 2008
Oct 2, 2008
372
373
case KA_DPD_DEAD:
Sep 22, 2011
Sep 22, 2011
374
vpn_progress(vpninfo, PRG_ERR, _("DTLS Dead Peer Detection detected dead peer!\n"));
Oct 2, 2008
Oct 2, 2008
375
/* Fall back to SSL, and start a new DTLS connection */
Apr 21, 2021
Apr 21, 2021
376
dtls_reconnect(vpninfo, timeout);
Oct 2, 2008
Oct 2, 2008
377
return 1;
Oct 2, 2008
Oct 2, 2008
378
379
case KA_DPD:
Jun 13, 2014
Jun 13, 2014
380
vpn_progress(vpninfo, PRG_DEBUG, _("Send DTLS DPD\n"));
Sep 23, 2008
Sep 23, 2008
381
Oct 2, 2008
Oct 2, 2008
382
magic_pkt = AC_PKT_DPD_OUT;
Apr 16, 2021
Apr 16, 2021
383
if (ssl_nonblock_write(vpninfo, 1, &magic_pkt, 1) != 1)
Jun 7, 2012
Jun 7, 2012
384
385
386
vpn_progress(vpninfo, PRG_ERR,
_("Failed to send DPD request. Expect disconnect\n"));
Oct 2, 2008
Oct 2, 2008
387
388
389
390
/* last_dpd will just have been set */
vpninfo->dtls_times.last_tx = vpninfo->dtls_times.last_dpd;
work_done = 1;
break;
Sep 23, 2008
Sep 23, 2008
391
Oct 2, 2008
Oct 2, 2008
392
393
394
case KA_KEEPALIVE:
/* No need to send an explicit keepalive
if we have real data to send */
Jan 29, 2015
Jan 29, 2015
395
if (vpninfo->outgoing_queue.head)
Oct 2, 2008
Oct 2, 2008
396
break;
Sep 23, 2008
Sep 23, 2008
397
Jun 13, 2014
Jun 13, 2014
398
vpn_progress(vpninfo, PRG_DEBUG, _("Send DTLS Keepalive\n"));
Oct 2, 2008
Oct 2, 2008
399
Oct 2, 2008
Oct 2, 2008
400
magic_pkt = AC_PKT_KEEPALIVE;
Apr 16, 2021
Apr 16, 2021
401
if (ssl_nonblock_write(vpninfo, 1, &magic_pkt, 1) != 1)
Jun 7, 2012
Jun 7, 2012
402
403
vpn_progress(vpninfo, PRG_ERR,
_("Failed to send keepalive request. Expect disconnect\n"));
Oct 2, 2008
Oct 2, 2008
404
405
406
time(&vpninfo->dtls_times.last_tx);
work_done = 1;
break;
Sep 23, 2008
Sep 23, 2008
407
Oct 2, 2008
Oct 2, 2008
408
409
case KA_NONE:
;
Sep 23, 2008
Sep 23, 2008
410
411
}
Oct 2, 2008
Oct 2, 2008
412
/* Service outgoing packet queue */
Feb 11, 2014
Feb 11, 2014
413
unmonitor_write_fd(vpninfo, dtls);
Jan 29, 2015
Jan 29, 2015
414
415
while (vpninfo->outgoing_queue.head) {
struct pkt *this = dequeue_packet(&vpninfo->outgoing_queue);
Jan 7, 2015
Jan 7, 2015
416
struct pkt *send_pkt = this;
Oct 2, 2008
Oct 2, 2008
417
int ret;
Sep 29, 2008
Sep 29, 2008
418
Aug 25, 2016
Aug 25, 2016
419
420
/* If TOS optname is set, we want to copy the TOS/TCLASS header
to the outer UDP packet */
Apr 1, 2020
Apr 1, 2020
421
422
if (vpninfo->dtls_tos_optname)
udp_tos_update(vpninfo, this);
Aug 25, 2016
Aug 25, 2016
423
Oct 2, 2008
Oct 2, 2008
424
/* One byte of header */
Jan 26, 2015
Jan 26, 2015
425
this->cstp.hdr[7] = AC_PKT_DATA;
Apr 9, 2009
Apr 9, 2009
426
Jan 15, 2015
Jan 15, 2015
427
428
429
430
431
432
/* We can compress into vpninfo->deflate_pkt unless CSTP
* currently has a compressed packet pending — which it
* shouldn't if DTLS is active. */
if (vpninfo->dtls_compr &&
vpninfo->current_ssl_pkt != vpninfo->deflate_pkt &&
!compress_packet(vpninfo, vpninfo->dtls_compr, this)) {
Jan 7, 2015
Jan 7, 2015
433
send_pkt = vpninfo->deflate_pkt;
Jan 26, 2015
Jan 26, 2015
434
send_pkt->cstp.hdr[7] = AC_PKT_COMPRESSED;
Jan 7, 2015
Jan 7, 2015
435
436
}
Apr 16, 2021
Apr 16, 2021
437
ret = ssl_nonblock_write(vpninfo, 1, &send_pkt->cstp.hdr[7], send_pkt->len + 1);
Oct 2, 2008
Oct 2, 2008
438
if (ret <= 0) {
Apr 16, 2021
Apr 16, 2021
439
440
441
442
443
444
/* Zero is -EAGAIN; just requeue. dtls_nonblock_write()
* will have added the socket to the poll wfd list. */
requeue_packet(&vpninfo->outgoing_queue, this);
if (ret < 0) {
/* If it's a real error, kill the DTLS connection so
the requeued packet will be sent over SSL */
Apr 21, 2021
Apr 21, 2021
445
dtls_reconnect(vpninfo, timeout);
Oct 3, 2013
Oct 3, 2013
446
work_done = 1;
Jun 7, 2012
Jun 7, 2012
447
}
Oct 3, 2013
Oct 3, 2013
448
return work_done;
Jun 7, 2012
Jun 7, 2012
449
}
Oct 2, 2008
Oct 2, 2008
450
time(&vpninfo->dtls_times.last_tx);
Jun 27, 2011
Jun 27, 2011
451
vpn_progress(vpninfo, PRG_TRACE,
Jun 7, 2012
Jun 7, 2012
452
_("Sent DTLS packet of %d bytes; DTLS send returned %d\n"),
Sep 22, 2011
Sep 22, 2011
453
this->len, ret);
Jun 28, 2021
Jun 28, 2021
454
free_pkt(vpninfo, this);
Sep 29, 2008
Sep 29, 2008
455
}
Sep 23, 2008
Sep 23, 2008
456
Sep 23, 2008
Sep 23, 2008
457
return work_done;
Sep 22, 2008
Sep 22, 2008
458
}
Dec 5, 2015
Dec 5, 2015
459
Jun 4, 2019
Jun 4, 2019
460
461
462
463
464
465
466
/* This symbol is missing in glibc < 2.22 (bug 18643). */
#if defined(__linux__) && !defined(HAVE_IPV6_PATHMTU)
# define HAVE_IPV6_PATHMTU 1
# define IPV6_PATHMTU 61
#endif
#define PKT_INTERVAL_MS 50
Sep 10, 2016
Sep 10, 2016
467
Dec 5, 2015
Dec 5, 2015
468
469
470
471
472
/* Performs a binary search to detect MTU.
* @buf: is preallocated with MTU size
*
* Returns: new MTU or 0
*/
Jun 4, 2019
Jun 4, 2019
473
static int probe_mtu(struct openconnect_info *vpninfo, unsigned char *buf)
Dec 5, 2015
Dec 5, 2015
474
{
Jun 4, 2019
Jun 4, 2019
475
int max, min, cur, ret, absolute_min, last;
Sep 14, 2016
Sep 14, 2016
476
int tries = 0; /* Number of loops in bin search - includes resends */
Jun 4, 2019
Jun 4, 2019
477
478
uint32_t id, id_len;
struct timeval start_tv, now_tv, last_tv;
Dec 5, 2015
Dec 5, 2015
479
Jun 4, 2019
Jun 4, 2019
480
481
482
absolute_min = 576;
if (vpninfo->ip_info.addr6)
absolute_min = 1280;
Dec 5, 2015
Dec 5, 2015
483
Jun 4, 2019
Jun 4, 2019
484
485
486
/* We'll assume that it is at least functional, and permits the bare
* minimum MTU for the protocol(s) it transports. All else is mad. */
min = absolute_min;
Sep 14, 2016
Sep 14, 2016
487
Jun 4, 2019
Jun 4, 2019
488
489
490
/* First send a probe at the configured maximum. Most of the time, this
one will probably work. */
last = cur = max = vpninfo->ip_info.mtu;
Dec 5, 2015
Dec 5, 2015
491
Jun 4, 2019
Jun 4, 2019
492
493
if (max <= min)
goto fail;
Dec 5, 2015
Dec 5, 2015
494
Jun 4, 2019
Jun 4, 2019
495
496
497
/* Generate unique ID */
if (openconnect_random(&id, sizeof(id)) < 0)
goto fail;
Dec 5, 2015
Dec 5, 2015
498
Jun 4, 2019
Jun 4, 2019
499
500
vpn_progress(vpninfo, PRG_DEBUG,
_("Initiating MTU detection (min=%d, max=%d)\n"), min, max);
Dec 5, 2015
Dec 5, 2015
501
Jun 4, 2019
Jun 4, 2019
502
503
gettimeofday(&start_tv, NULL);
last_tv = start_tv;
Sep 10, 2016
Sep 10, 2016
504
Jun 4, 2019
Jun 4, 2019
505
506
while (1) {
int wait_ms;
Sep 14, 2016
Sep 14, 2016
507
Jun 4, 2019
Jun 4, 2019
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
#ifdef HAVE_IPV6_PATHMTU
if (vpninfo->peer_addr->sa_family == AF_INET6) {
struct ip6_mtuinfo mtuinfo;
socklen_t len = sizeof(mtuinfo);
int newmax;
if (getsockopt(vpninfo->dtls_fd, IPPROTO_IPV6, IPV6_PATHMTU, &mtuinfo, &len) >= 0) {
newmax = mtuinfo.ip6m_mtu;
if (newmax > 0) {
newmax = dtls_set_mtu(vpninfo, newmax) - /*ipv6*/40 - /*udp*/20 - /*oc dtls*/1;
if (absolute_min > newmax)
goto fail;
if (max > newmax)
max = newmax;
if (cur > newmax)
cur = newmax;
}
Sep 14, 2016
Sep 14, 2016
525
}
Dec 5, 2015
Dec 5, 2015
526
}
May 6, 2016
May 6, 2016
527
528
#endif
Dec 5, 2015
Dec 5, 2015
529
buf[0] = AC_PKT_DPD_OUT;
Jun 4, 2019
Jun 4, 2019
530
531
id_len = id + cur;
memcpy(&buf[1], &id_len, sizeof(id_len));
Dec 5, 2015
Dec 5, 2015
532
Sep 10, 2016
Sep 10, 2016
533
vpn_progress(vpninfo, PRG_TRACE,
Jun 4, 2019
Jun 4, 2019
534
535
536
_("Sending MTU DPD probe (%u bytes)\n"), cur);
ret = openconnect_dtls_write(vpninfo, buf, cur + 1);
if (ret != cur + 1) {
Dec 5, 2015
Dec 5, 2015
537
vpn_progress(vpninfo, PRG_ERR,
Jun 4, 2019
Jun 4, 2019
538
539
540
541
542
543
544
545
546
547
548
549
550
_("Failed to send DPD request (%d %d)\n"), cur, ret);
if (cur == max) {
max = --cur;
if (cur >= absolute_min)
continue;
}
goto fail;
}
if (last == cur)
tries++;
else {
tries = 0;
last = cur;
Dec 5, 2015
Dec 5, 2015
551
552
553
}
memset(buf, 0, sizeof(id)+1);
Jun 4, 2019
Jun 4, 2019
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
keep_waiting:
gettimeofday(&now_tv, NULL);
if (now_tv.tv_sec > start_tv.tv_sec + 10) {
if (absolute_min == min) {
/* Hm, we never got *anything* back successfully? */
vpn_progress(vpninfo, PRG_ERR,
_("Too long time in MTU detect loop; assuming negotiated MTU.\n"));
goto fail;
} else {
vpn_progress(vpninfo, PRG_ERR,
_("Too long time in MTU detect loop; MTU set to %d.\n"), min);
ret = min;
goto out;
}
Sep 10, 2016
Sep 10, 2016
569
}
Dec 5, 2015
Dec 5, 2015
570
Jun 4, 2019
Jun 4, 2019
571
572
573
574
wait_ms = PKT_INTERVAL_MS -
((now_tv.tv_sec - last_tv.tv_sec) * 1000) -
((now_tv.tv_usec - last_tv.tv_usec) / 1000);
Apr 13, 2021
Apr 13, 2021
575
if (wait_ms <= 0 || wait_ms > PKT_INTERVAL_MS)
Jun 4, 2019
Jun 4, 2019
576
577
578
579
580
wait_ms = PKT_INTERVAL_MS;
ret = openconnect_dtls_read(vpninfo, buf, max+1, wait_ms);
if (ret > 0 && (buf[0] != AC_PKT_DPD_RESP || !memcpy(&id_len, &buf[1], sizeof(id_len)) ||
id_len != id + ret - 1)) {
Dec 5, 2015
Dec 5, 2015
581
vpn_progress(vpninfo, PRG_DEBUG,
Jun 4, 2019
Jun 4, 2019
582
583
_("Received unexpected packet (%.2x) in MTU detection; skipping.\n"), (unsigned)buf[0]);
goto keep_waiting;
Dec 5, 2015
Dec 5, 2015
584
585
}
Jun 4, 2019
Jun 4, 2019
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
if (ret == -ETIMEDOUT) {
if (tries >= 6) {
vpn_progress(vpninfo, PRG_DEBUG,
_("No response to size %u after %d tries; declare MTU is %u\n"),
last, tries, min);
ret = min;
goto out;
}
} else if (ret < 0) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to recv DPD request (%d)\n"), ret);
goto fail;
} else if (ret > 0) {
vpn_progress(vpninfo, PRG_TRACE,
_("Received MTU DPD probe (%u bytes)\n"), ret - 1);
ret--;
tries = 0;
}
Sep 10, 2016
Sep 10, 2016
604
Jun 4, 2019
Jun 4, 2019
605
606
if (ret == max)
goto out;
Dec 5, 2015
Dec 5, 2015
607
Jun 4, 2019
Jun 4, 2019
608
609
610
611
612
613
if (ret > min) {
min = ret;
if (min >= last) {
cur = (min + max + 1) / 2;
} else {
cur = (min + last + 1) / 2;
Dec 5, 2015
Dec 5, 2015
614
}
Jun 4, 2019
Jun 4, 2019
615
616
} else {
cur = (min + last + 1) / 2;
Dec 5, 2015
Dec 5, 2015
617
618
619
}
}
fail:
Jun 4, 2019
Jun 4, 2019
620
621
622
ret = 0;
out:
return ret;
Dec 5, 2015
Dec 5, 2015
623
}
Jun 4, 2019
Jun 4, 2019
624
625
Dec 5, 2015
Dec 5, 2015
626
Sep 10, 2016
Sep 10, 2016
627
void dtls_detect_mtu(struct openconnect_info *vpninfo)
Dec 5, 2015
Dec 5, 2015
628
{
Nov 17, 2020
Nov 17, 2020
629
int mtu;
Dec 5, 2015
Dec 5, 2015
630
631
632
int prev_mtu = vpninfo->ip_info.mtu;
unsigned char *buf;
Apr 21, 2021
Apr 21, 2021
633
634
635
if (vpninfo->proto->proto != PROTO_ANYCONNECT)
return;
Jun 4, 2019
Jun 4, 2019
636
if (vpninfo->ip_info.mtu < 1 + sizeof(uint32_t))
Dec 5, 2015
Dec 5, 2015
637
638
639
640
641
642
643
644
645
return;
/* detect MTU */
buf = calloc(1, 1 + vpninfo->ip_info.mtu);
if (!buf) {
vpn_progress(vpninfo, PRG_ERR, _("Allocation failed\n"));
return;
}
Jun 4, 2019
Jun 4, 2019
646
647
648
mtu = probe_mtu(vpninfo, buf);
if (mtu == 0)
goto skip_mtu;
Dec 5, 2015
Dec 5, 2015
649
650
651
652
653
654
655
656
657
658
659
660
661
vpninfo->ip_info.mtu = mtu;
if (prev_mtu != vpninfo->ip_info.mtu) {
vpn_progress(vpninfo, PRG_INFO,
_("Detected MTU of %d bytes (was %d)\n"), vpninfo->ip_info.mtu, prev_mtu);
} else {
vpn_progress(vpninfo, PRG_DEBUG,
_("No change in MTU after detection (was %d)\n"), prev_mtu);
}
skip_mtu:
free(buf);
}