Skip to content

Latest commit

 

History

History
508 lines (441 loc) · 13.6 KB

mainloop.c

File metadata and controls

508 lines (441 loc) · 13.6 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"
Oct 6, 2008
Oct 6, 2008
22
#include <unistd.h>
Dec 5, 2015
Dec 5, 2015
23
24
25
26
27
#ifndef _WIN32
/* for setgroups() */
# include <sys/types.h>
# include <grp.h>
#endif
Sep 22, 2008
Sep 22, 2008
28
Jun 30, 2021
Jun 30, 2021
29
30
31
32
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
Sep 22, 2008
Sep 22, 2008
33
Jun 28, 2021
Jun 28, 2021
34
35
int queue_new_packet(struct openconnect_info *vpninfo,
struct pkt_q *q, void *buf, int len)
Sep 22, 2008
Sep 22, 2008
36
{
Jun 28, 2021
Jun 28, 2021
37
struct pkt *new = alloc_pkt(vpninfo, len);
Sep 22, 2008
Sep 22, 2008
38
if (!new)
Sep 22, 2008
Sep 22, 2008
39
40
return -ENOMEM;
Sep 22, 2008
Sep 22, 2008
41
42
43
44
new->len = len;
new->next = NULL;
memcpy(new->data, buf, len);
queue_packet(q, new);
Sep 22, 2008
Sep 22, 2008
45
46
47
return 0;
}
Feb 13, 2014
Feb 13, 2014
48
49
/* This is here because it's generic and hence can't live in either of the
tun*.c files for specific platforms */
Jul 1, 2021
Jul 1, 2021
50
int tun_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable, int did_work)
Feb 13, 2014
Feb 13, 2014
51
{
Jan 29, 2015
Jan 29, 2015
52
struct pkt *this;
Feb 13, 2014
Feb 13, 2014
53
54
int work_done = 0;
Apr 15, 2019
Apr 15, 2019
55
if (readable && read_fd_monitored(vpninfo, tun)) {
Jul 31, 2014
Jul 31, 2014
56
struct pkt *out_pkt = vpninfo->tun_pkt;
Feb 13, 2014
Feb 13, 2014
57
58
59
60
while (1) {
int len = vpninfo->ip_info.mtu;
if (!out_pkt) {
Jun 28, 2021
Jun 28, 2021
61
out_pkt = alloc_pkt(vpninfo, len + vpninfo->pkt_trailer);
Feb 13, 2014
Feb 13, 2014
62
if (!out_pkt) {
Jan 7, 2015
Jan 7, 2015
63
vpn_progress(vpninfo, PRG_ERR, _("Allocation failed\n"));
Feb 13, 2014
Feb 13, 2014
64
65
66
67
68
break;
}
out_pkt->len = len;
}
Mar 11, 2014
Mar 11, 2014
69
if (os_read_tun(vpninfo, out_pkt))
Feb 13, 2014
Feb 13, 2014
70
71
72
73
74
break;
vpninfo->stats.tx_pkts++;
vpninfo->stats.tx_bytes += out_pkt->len;
work_done = 1;
Jan 29, 2015
Jan 29, 2015
75
Jul 16, 2019
Jul 16, 2019
76
if (queue_packet(&vpninfo->outgoing_queue, out_pkt) +
Mar 28, 2021
Mar 28, 2021
77
vpninfo->tcp_control_queue.count >= vpninfo->max_qlen) {
Jan 29, 2015
Jan 29, 2015
78
out_pkt = NULL;
Feb 13, 2014
Feb 13, 2014
79
80
81
unmonitor_read_fd(vpninfo, tun);
break;
}
Jan 29, 2015
Jan 29, 2015
82
out_pkt = NULL;
Feb 13, 2014
Feb 13, 2014
83
}
Jul 31, 2014
Jul 31, 2014
84
vpninfo->tun_pkt = out_pkt;
Mar 28, 2021
Mar 28, 2021
85
} else if (vpninfo->outgoing_queue.count + vpninfo->tcp_control_queue.count < vpninfo->max_qlen) {
Feb 13, 2014
Feb 13, 2014
86
87
88
monitor_read_fd(vpninfo, tun);
}
Jan 29, 2015
Jan 29, 2015
89
while ((this = dequeue_packet(&vpninfo->incoming_queue))) {
Feb 13, 2014
Feb 13, 2014
90
Aug 25, 2016
Aug 25, 2016
91
92
unmonitor_write_fd(vpninfo, tun);
Jan 29, 2015
Jan 29, 2015
93
94
if (os_write_tun(vpninfo, this)) {
requeue_packet(&vpninfo->incoming_queue, this);
Feb 13, 2014
Feb 13, 2014
95
break;
Jan 29, 2015
Jan 29, 2015
96
}
Feb 13, 2014
Feb 13, 2014
97
98
99
100
vpninfo->stats.rx_pkts++;
vpninfo->stats.rx_bytes += this->len;
Jun 28, 2021
Jun 28, 2021
101
free_pkt(vpninfo, this);
Feb 13, 2014
Feb 13, 2014
102
103
104
105
106
}
/* Work is not done if we just got rid of packets off the queue */
return work_done;
}
Dec 5, 2015
Dec 5, 2015
107
108
109
110
static int setup_tun_device(struct openconnect_info *vpninfo)
{
int ret;
Mar 8, 2016
Mar 8, 2016
111
112
113
114
115
116
if (vpninfo->setup_tun) {
vpninfo->setup_tun(vpninfo->cbdata);
if (tun_is_up(vpninfo))
return 0;
}
Dec 5, 2015
Dec 5, 2015
117
118
119
120
#ifndef _WIN32
if (vpninfo->use_tun_script) {
ret = openconnect_setup_tun_script(vpninfo, vpninfo->vpnc_script);
if (ret) {
Feb 26, 2022
Feb 26, 2022
121
vpn_progress(vpninfo, PRG_ERR, _("Set up tun script failed\n"));
Dec 5, 2015
Dec 5, 2015
122
123
124
125
126
127
return ret;
}
} else
#endif
ret = openconnect_setup_tun_device(vpninfo, vpninfo->vpnc_script, vpninfo->ifname);
if (ret) {
Feb 26, 2022
Feb 26, 2022
128
vpn_progress(vpninfo, PRG_ERR, _("Set up tun device failed\n"));
Nov 16, 2020
Nov 16, 2020
129
130
if (!vpninfo->quit_reason)
vpninfo->quit_reason = "Set up tun device failed";
Dec 5, 2015
Dec 5, 2015
131
132
133
return ret;
}
Mar 8, 2016
Mar 8, 2016
134
#if !defined(_WIN32) && !defined(__native_client__)
Dec 5, 2015
Dec 5, 2015
135
if (vpninfo->uid != getuid()) {
Dec 5, 2015
Dec 5, 2015
136
if (setgid(vpninfo->gid)) {
Feb 26, 2022
Feb 26, 2022
137
vpn_progress(vpninfo, PRG_ERR, _("Failed to set gid %ld: %s\n"),
Feb 26, 2022
Feb 26, 2022
138
(long)vpninfo->gid, strerror(errno));
Dec 5, 2015
Dec 5, 2015
139
140
141
142
return -EPERM;
}
if (setgroups(1, &vpninfo->gid)) {
Feb 26, 2022
Feb 26, 2022
143
vpn_progress(vpninfo, PRG_ERR, _("Failed to set groups to %ld: %s\n"),
Feb 26, 2022
Feb 26, 2022
144
(long)vpninfo->gid, strerror(errno));
Dec 5, 2015
Dec 5, 2015
145
146
147
return -EPERM;
}
Dec 5, 2015
Dec 5, 2015
148
if (setuid(vpninfo->uid)) {
Feb 26, 2022
Feb 26, 2022
149
vpn_progress(vpninfo, PRG_ERR, _("Failed to set uid %ld: %s\n"),
Feb 26, 2022
Feb 26, 2022
150
(long)vpninfo->uid, strerror(errno));
Dec 5, 2015
Dec 5, 2015
151
152
153
154
155
156
157
return -EPERM;
}
}
#endif
return 0;
}
Jan 15, 2014
Jan 15, 2014
158
/* Return value:
Jan 15, 2014
Jan 15, 2014
159
* = 0, when successfully paused (may call again)
Jun 13, 2014
Jun 13, 2014
160
161
* = -EINTR, if aborted locally via OC_CMD_CANCEL
* = -ECONNABORTED, if aborted locally via OC_CMD_DETACH
Jan 15, 2014
Jan 15, 2014
162
163
164
165
* = -EPIPE, if the remote end explicitly terminated the session
* = -EPERM, if the gateway sent 401 Unauthorized (cookie expired)
* < 0, for any other error
*/
Jan 15, 2014
Jan 15, 2014
166
167
168
int openconnect_mainloop(struct openconnect_info *vpninfo,
int reconnect_timeout,
int reconnect_interval)
Sep 22, 2008
Sep 22, 2008
169
{
Jan 15, 2014
Jan 15, 2014
170
int ret = 0;
Apr 15, 2019
Apr 15, 2019
171
int tun_r = 1, udp_r = 1, tcp_r = 1;
Jul 1, 2021
Jul 1, 2021
172
173
174
175
#ifdef HAVE_VHOST
int vhost_r = 0;
#endif
Jan 15, 2014
Jan 15, 2014
176
177
178
vpninfo->reconnect_timeout = reconnect_timeout;
vpninfo->reconnect_interval = reconnect_interval;
Jan 15, 2014
Jan 15, 2014
179
if (vpninfo->cmd_fd != -1) {
Feb 11, 2014
Feb 11, 2014
180
181
monitor_fd_new(vpninfo, cmd);
monitor_read_fd(vpninfo, cmd);
Jan 15, 2014
Jan 15, 2014
182
}
Sep 30, 2008
Sep 30, 2008
183
Sep 30, 2008
Sep 30, 2008
184
while (!vpninfo->quit_reason) {
Sep 22, 2008
Sep 22, 2008
185
int did_work = 0;
Dec 5, 2015
Dec 5, 2015
186
int timeout;
Feb 11, 2014
Feb 11, 2014
187
188
189
190
#ifdef _WIN32
HANDLE events[4];
int nr_events = 0;
#else
Oct 15, 2008
Oct 15, 2008
191
192
struct timeval tv;
fd_set rfds, wfds, efds;
Feb 11, 2014
Feb 11, 2014
193
#endif
Sep 22, 2008
Sep 22, 2008
194
Dec 5, 2015
Dec 5, 2015
195
196
/* If tun is not up, loop more often to detect
* a DTLS timeout (due to a firewall block) as soon. */
Mar 8, 2016
Mar 8, 2016
197
if (tun_is_up(vpninfo))
Dec 5, 2015
Dec 5, 2015
198
199
200
201
timeout = INT_MAX;
else
timeout = 1000;
Nov 16, 2020
Nov 16, 2020
202
if (!tun_is_up(vpninfo)) {
Nov 16, 2020
Nov 16, 2020
203
if (vpninfo->delay_tunnel_reason) {
Nov 16, 2020
Nov 16, 2020
204
205
vpn_progress(vpninfo, PRG_TRACE, _("Delaying tunnel with reason: %s\n"),
vpninfo->delay_tunnel_reason);
Nov 16, 2020
Nov 16, 2020
206
207
208
209
210
211
/* XX: don't let this spin forever */
vpninfo->delay_tunnel_reason = NULL;
} else {
/* No DTLS, or DTLS failed; setup TUN device unconditionally */
ret = setup_tun_device(vpninfo);
if (ret)
Dec 5, 2015
Dec 5, 2015
212
213
break;
}
Nov 16, 2020
Nov 16, 2020
214
}
Dec 5, 2015
Dec 5, 2015
215
Nov 16, 2020
Nov 16, 2020
216
if (vpninfo->dtls_state > DTLS_DISABLED) {
Apr 15, 2019
Apr 15, 2019
217
ret = vpninfo->proto->udp_mainloop(vpninfo, &timeout, udp_r);
Feb 11, 2014
Feb 11, 2014
218
219
220
221
if (vpninfo->quit_reason)
break;
did_work += ret;
}
Sep 30, 2008
Sep 30, 2008
222
Apr 15, 2019
Apr 15, 2019
223
ret = vpninfo->proto->tcp_mainloop(vpninfo, &timeout, tcp_r);
Sep 30, 2008
Sep 30, 2008
224
225
if (vpninfo->quit_reason)
break;
Jan 15, 2014
Jan 15, 2014
226
did_work += ret;
Oct 26, 2008
Oct 26, 2008
227
Jul 1, 2021
Jul 1, 2021
228
Oct 26, 2008
Oct 26, 2008
229
230
/* Tun must be last because it will set/clear its bit
in the select_rfds according to the queue length */
Jul 1, 2021
Jul 1, 2021
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
if (!tun_is_up(vpninfo)) {
struct pkt *this;
/* no tun yet; clear any queued packets */
while ((this = dequeue_packet(&vpninfo->incoming_queue)))
free_pkt(vpninfo, this);
#ifdef HAVE_VHOST
} else if (vpninfo->vhost_fd != -1) {
did_work += vhost_tun_mainloop(vpninfo, &timeout, vhost_r, did_work);
/* If it returns zero *then* it will have read the eventfd
* and there's no need to do so again until we poll again. */
if (!did_work)
vhost_r = 0;
#endif
} else {
did_work += tun_mainloop(vpninfo, &timeout, tun_r, did_work);
}
Sep 30, 2008
Sep 30, 2008
247
248
249
if (vpninfo->quit_reason)
break;
Jun 28, 2021
Jun 28, 2021
250
251
252
if (vpninfo->need_poll_cmd_fd)
poll_cmd_fd(vpninfo, 0);
Jan 15, 2014
Jan 15, 2014
253
if (vpninfo->got_cancel_cmd) {
Nov 16, 2020
Nov 16, 2020
254
255
if (vpninfo->delay_close != NO_DELAY_CLOSE) {
if (vpninfo->delay_close == DELAY_CLOSE_IMMEDIATE_CALLBACK) {
Nov 16, 2020
Nov 16, 2020
256
vpn_progress(vpninfo, PRG_TRACE, _("Delaying cancel (immediate callback).\n"));
Nov 16, 2020
Nov 16, 2020
257
258
did_work++;
} else
Nov 16, 2020
Nov 16, 2020
259
vpn_progress(vpninfo, PRG_TRACE, _("Delaying cancel.\n"));
Nov 16, 2020
Nov 16, 2020
260
261
262
/* XX: don't let this spin forever */
vpninfo->delay_close = NO_DELAY_CLOSE;
} else if (vpninfo->cancel_type == OC_CMD_CANCEL) {
Jun 13, 2014
Jun 13, 2014
263
vpninfo->quit_reason = "Aborted by caller";
Nov 16, 2020
Nov 16, 2020
264
vpninfo->got_cancel_cmd = 0;
Jun 13, 2014
Jun 13, 2014
265
ret = -EINTR;
Nov 16, 2020
Nov 16, 2020
266
break;
Jun 13, 2014
Jun 13, 2014
267
} else {
Nov 16, 2020
Nov 16, 2020
268
vpninfo->got_cancel_cmd = 0;
Jun 13, 2014
Jun 13, 2014
269
ret = -ECONNABORTED;
Nov 16, 2020
Nov 16, 2020
270
break;
Jun 13, 2014
Jun 13, 2014
271
}
Sep 30, 2008
Sep 30, 2008
272
}
Dec 5, 2015
Dec 5, 2015
273
Jan 15, 2014
Jan 15, 2014
274
if (vpninfo->got_pause_cmd) {
Nov 16, 2020
Nov 16, 2020
275
276
277
if (vpninfo->delay_close != NO_DELAY_CLOSE) {
/* XX: don't let this spin forever */
if (vpninfo->delay_close == DELAY_CLOSE_IMMEDIATE_CALLBACK) {
Nov 16, 2020
Nov 16, 2020
278
vpn_progress(vpninfo, PRG_TRACE, _("Delaying pause (immediate callback).\n"));
Nov 16, 2020
Nov 16, 2020
279
280
did_work++;
} else
Nov 16, 2020
Nov 16, 2020
281
vpn_progress(vpninfo, PRG_TRACE, _("Delaying pause.\n"));
Nov 16, 2020
Nov 16, 2020
282
283
284
285
286
287
288
289
290
291
/* XX: don't let this spin forever */
vpninfo->delay_close = NO_DELAY_CLOSE;
} else {
/* close all connections and wait for the user to call
openconnect_mainloop() again */
openconnect_close_https(vpninfo, 0);
if (vpninfo->dtls_state > DTLS_DISABLED) {
vpninfo->proto->udp_close(vpninfo);
vpninfo->new_dtls_started = 0;
}
Jan 15, 2014
Jan 15, 2014
292
Nov 16, 2020
Nov 16, 2020
293
294
vpninfo->got_pause_cmd = 0;
vpn_progress(vpninfo, PRG_INFO, _("Caller paused the connection\n"));
Jul 1, 2021
Jul 1, 2021
295
296
297
298
if (vpninfo->cmd_fd >= 0)
unmonitor_fd(vpninfo, cmd);
Nov 16, 2020
Nov 16, 2020
299
300
return 0;
}
Jan 15, 2014
Jan 15, 2014
301
}
Sep 30, 2008
Sep 30, 2008
302
Sep 30, 2008
Sep 30, 2008
303
304
305
if (did_work)
continue;
Jun 27, 2011
Jun 27, 2011
306
vpn_progress(vpninfo, PRG_TRACE,
Sep 22, 2011
Sep 22, 2011
307
_("No work to do; sleeping for %d ms...\n"), timeout);
Feb 11, 2014
Feb 11, 2014
308
309
310
311
312
313
314
315
316
317
318
319
320
321
#ifdef _WIN32
if (vpninfo->dtls_monitored) {
WSAEventSelect(vpninfo->dtls_fd, vpninfo->dtls_event, vpninfo->dtls_monitored);
events[nr_events++] = vpninfo->dtls_event;
}
if (vpninfo->ssl_monitored) {
WSAEventSelect(vpninfo->ssl_fd, vpninfo->ssl_event, vpninfo->ssl_monitored);
events[nr_events++] = vpninfo->ssl_event;
}
if (vpninfo->cmd_monitored) {
WSAEventSelect(vpninfo->cmd_fd, vpninfo->cmd_event, vpninfo->cmd_monitored);
events[nr_events++] = vpninfo->cmd_event;
}
Feb 11, 2014
Feb 11, 2014
322
323
324
if (vpninfo->tun_monitored) {
events[nr_events++] = vpninfo->tun_rd_overlap.hEvent;
}
Feb 11, 2014
Feb 11, 2014
325
if (WaitForMultipleObjects(nr_events, events, FALSE, timeout) == WAIT_FAILED) {
Oct 28, 2014
Oct 28, 2014
326
char *errstr = openconnect__win32_strerror(GetLastError());
Feb 11, 2014
Feb 11, 2014
327
vpn_progress(vpninfo, PRG_ERR,
Oct 28, 2014
Oct 28, 2014
328
329
330
_("WaitForMultipleObjects failed: %s\n"),
errstr);
free(errstr);
Feb 11, 2014
Feb 11, 2014
331
332
}
#else
Jun 29, 2021
Jun 29, 2021
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
#ifdef HAVE_EPOLL
if (vpninfo->epoll_fd >= 0) {
struct epoll_event evs[5];
/* During busy periods, monitor_read_fd() and unmonitor_read_fd()
* may get called multiple times as we go round and round the
* loop and queues get full then have space again. In the past
* with the select() loop, that was only a bitflip in the fd_set
* and didn't cost much. With epoll() it's actually a system
* call, so don't do it every time. Wait until we're about to
* sleep, and *then* ensure that we call epoll_ctl() to sync the
* set of events that we care about, if it's changed. */
if (vpninfo->epoll_update) {
update_epoll_fd(vpninfo, tun);
update_epoll_fd(vpninfo, ssl);
update_epoll_fd(vpninfo, cmd);
update_epoll_fd(vpninfo, dtls);
Jul 1, 2021
Jul 1, 2021
350
351
352
#ifdef HAVE_VHOST
update_epoll_fd(vpninfo, vhost_call);
#endif
Jun 29, 2021
Jun 29, 2021
353
354
355
}
tun_r = udp_r = tcp_r = 0;
Jul 1, 2021
Jul 1, 2021
356
357
358
#ifdef HAVE_VHOST
vhost_r = 0;
#endif
Jun 29, 2021
Jun 29, 2021
359
360
361
362
363
364
365
366
367
368
369
int nfds = epoll_wait(vpninfo->epoll_fd, evs, 5, timeout);
if (nfds < 0) {
if (errno != EINTR) {
ret = -errno;
vpn_perror(vpninfo, _("Failed epoll_wait() in mainloop"));
break;
}
nfds = 0;
}
while (nfds--) {
Apr 6, 2022
Apr 6, 2022
370
if (evs[nfds].events & (EPOLLIN|EPOLLERR)) {
Jun 29, 2021
Jun 29, 2021
371
372
373
374
375
376
if (evs[nfds].data.fd == vpninfo->tun_fd)
tun_r = 1;
else if (evs[nfds].data.fd == vpninfo->ssl_fd)
tcp_r = 1;
else if (evs[nfds].data.fd == vpninfo->dtls_fd)
udp_r = 1;
Jul 1, 2021
Jul 1, 2021
377
378
379
380
#ifdef HAVE_VHOST
else if (evs[nfds].data.fd == vpninfo->vhost_call_fd)
vhost_r = 1;
#endif
Jun 29, 2021
Jun 29, 2021
381
382
383
384
385
}
}
continue;
}
#endif
Feb 11, 2014
Feb 11, 2014
386
387
388
memcpy(&rfds, &vpninfo->_select_rfds, sizeof(rfds));
memcpy(&wfds, &vpninfo->_select_wfds, sizeof(wfds));
memcpy(&efds, &vpninfo->_select_efds, sizeof(efds));
Oct 15, 2008
Oct 15, 2008
389
390
tv.tv_sec = timeout / 1000;
Dec 6, 2008
Dec 6, 2008
391
tv.tv_usec = (timeout % 1000) * 1000;
Oct 19, 2009
Oct 19, 2009
392
Oct 14, 2019
Oct 14, 2019
393
394
if (select(vpninfo->_select_nfds, &rfds, &wfds, &efds, &tv) < 0 &&
errno != EINTR) {
Oct 10, 2019
Oct 10, 2019
395
ret = -errno;
Oct 14, 2019
Oct 14, 2019
396
vpn_perror(vpninfo, _("Failed select() in mainloop"));
Oct 10, 2019
Oct 10, 2019
397
398
break;
}
Jul 1, 2021
Jul 1, 2021
399
400
401
402
#ifdef HAVE_VHOST
if (vpninfo->vhost_call_fd >= 0)
vhost_r = FD_ISSET(vpninfo->vhost_call_fd, &rfds);
#endif
Apr 15, 2019
Apr 15, 2019
403
404
405
406
407
408
if (vpninfo->tun_fd >= 0)
tun_r = FD_ISSET(vpninfo->tun_fd, &rfds);
if (vpninfo->dtls_fd >= 0)
udp_r = FD_ISSET(vpninfo->dtls_fd, &rfds);
if (vpninfo->ssl_fd >= 0)
tcp_r = FD_ISSET(vpninfo->ssl_fd, &rfds);
Feb 11, 2014
Feb 11, 2014
409
#endif
Sep 22, 2008
Sep 22, 2008
410
}
Sep 22, 2008
Sep 22, 2008
411
May 16, 2016
May 16, 2016
412
413
if (vpninfo->quit_reason && vpninfo->proto->vpn_close_session)
vpninfo->proto->vpn_close_session(vpninfo, vpninfo->quit_reason);
Sep 22, 2008
Sep 22, 2008
414
Mar 8, 2016
Mar 8, 2016
415
if (tun_is_up(vpninfo))
Jan 14, 2016
Jan 14, 2016
416
os_shutdown_tun(vpninfo);
Jul 1, 2021
Jul 1, 2021
417
418
419
420
if (vpninfo->cmd_fd >= 0)
unmonitor_fd(vpninfo, cmd);
Jan 15, 2014
Jan 15, 2014
421
return ret < 0 ? ret : -EIO;
Sep 22, 2008
Sep 22, 2008
422
}
Oct 2, 2008
Oct 2, 2008
423
May 31, 2018
May 31, 2018
424
int ka_check_deadline(int *timeout, time_t now, time_t due)
Feb 17, 2014
Feb 17, 2014
425
426
427
428
429
430
431
432
{
if (now >= due)
return 1;
if (*timeout > (due - now) * 1000)
*timeout = (due - now) * 1000;
return 0;
}
Oct 2, 2008
Oct 2, 2008
433
434
/* Called when the socket is unwritable, to get the deadline for DPD.
Returns 1 if DPD deadline has already arrived. */
Aug 3, 2012
Aug 3, 2012
435
int ka_stalled_action(struct keepalive_info *ka, int *timeout)
Oct 2, 2008
Oct 2, 2008
436
{
Feb 17, 2014
Feb 17, 2014
437
time_t now = time(NULL);
Aug 3, 2012
Aug 3, 2012
438
Feb 17, 2014
Feb 17, 2014
439
/* We only support the new-tunnel rekey method for now. */
Feb 18, 2014
Feb 18, 2014
440
441
442
if (ka->rekey_method != REKEY_NONE &&
ka_check_deadline(timeout, now, ka->last_rekey + ka->rekey)) {
ka->last_rekey = now;
Feb 17, 2014
Feb 17, 2014
443
return KA_REKEY;
Feb 18, 2014
Feb 18, 2014
444
}
Oct 2, 2008
Oct 2, 2008
445
Feb 17, 2014
Feb 17, 2014
446
447
if (ka->dpd &&
ka_check_deadline(timeout, now, ka->last_rx + (2 * ka->dpd)))
Aug 3, 2012
Aug 3, 2012
448
return KA_DPD_DEAD;
Oct 2, 2008
Oct 2, 2008
449
Aug 3, 2012
Aug 3, 2012
450
return KA_NONE;
Oct 2, 2008
Oct 2, 2008
451
452
453
}
Oct 2, 2008
Oct 2, 2008
454
int keepalive_action(struct keepalive_info *ka, int *timeout)
Oct 2, 2008
Oct 2, 2008
455
456
457
{
time_t now = time(NULL);
Feb 18, 2014
Feb 18, 2014
458
if (ka->rekey_method != REKEY_NONE &&
Feb 17, 2014
Feb 17, 2014
459
460
461
ka_check_deadline(timeout, now, ka->last_rekey + ka->rekey)) {
ka->last_rekey = now;
return KA_REKEY;
Oct 2, 2008
Oct 2, 2008
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
}
/* DPD is bidirectional -- PKT 3 out, PKT 4 back */
if (ka->dpd) {
time_t due = ka->last_rx + ka->dpd;
time_t overdue = ka->last_rx + (2 * ka->dpd);
/* Peer didn't respond */
if (now > overdue)
return KA_DPD_DEAD;
/* If we already have DPD outstanding, don't flood. Repeat by
all means, but only after half the DPD period. */
if (ka->last_dpd > ka->last_rx)
due = ka->last_dpd + ka->dpd / 2;
/* We haven't seen a packet from this host for $DPD seconds.
Prod it to see if it's still alive */
Feb 17, 2014
Feb 17, 2014
480
if (ka_check_deadline(timeout, now, due)) {
Oct 2, 2008
Oct 2, 2008
481
482
483
484
485
ka->last_dpd = now;
return KA_DPD;
}
}
Feb 17, 2014
Feb 17, 2014
486
487
488
489
490
491
/* Keepalive is just client -> server.
If we haven't sent anything for $KEEPALIVE seconds, send a
dummy packet (which the server will discard) */
if (ka->keepalive &&
ka_check_deadline(timeout, now, ka->last_tx + ka->keepalive))
return KA_KEEPALIVE;
Oct 2, 2008
Oct 2, 2008
492
493
494
return KA_NONE;
}
Oct 5, 2019
Oct 5, 2019
495
496
497
498
499
500
501
502
503
504
505
506
507
508
int trojan_check_deadline(struct openconnect_info *vpninfo, int *timeout)
{
time_t now = time(NULL);
if (vpninfo->trojan_interval &&
ka_check_deadline(timeout, now,
vpninfo->last_trojan + vpninfo->trojan_interval)) {
vpninfo->last_trojan = now;
return 1;
} else {
return 0;
}
}