Commit 654d565f authored by Kevin Cernekee's avatar Kevin Cernekee

mainloop: Add OC_CMD_PAUSE operation

This forces the connection to immediately drop, and
openconnect_mainloop() to return with status 1.  The caller may
re-invoke the mainloop when he wants to re-establish the connection,
assuming the idle/session timeouts have not expired.
Signed-off-by: default avatarKevin Cernekee <cernekee@gmail.com>
parent 2f67ef5d
......@@ -569,6 +569,8 @@ int cstp_reconnect(struct openconnect_info *vpninfo)
poll_cmd_fd(vpninfo, interval);
if (vpninfo->got_cancel_cmd)
return -EINTR;
if (vpninfo->got_pause_cmd)
return 0;
timeout -= interval;
interval += vpninfo->reconnect_interval;
if (interval > RECONNECT_INTERVAL_MAX)
......@@ -709,6 +711,9 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout)
int len, ret;
int work_done = 0;
if (vpninfo->ssl_fd == -1)
goto do_reconnect;
/* FIXME: The poll() handling here is fairly simplistic. Actually,
if the SSL connection stalls it could return a WANT_WRITE error
on _either_ of the SSL_read() or SSL_write() calls. In that case,
......
......@@ -55,6 +55,7 @@ int queue_new_packet(struct pkt **q, void *buf, int len)
}
/* Return value:
* = 0, when successfully paused (may call again)
* = -EINTR, if aborted locally via cmd_fd
* = -EPIPE, if the remote end explicitly terminated the session
* = -EPERM, if the gateway sent 401 Unauthorized (cookie expired)
......@@ -86,7 +87,8 @@ int openconnect_mainloop(struct openconnect_info *vpninfo,
dtls_try_handshake(vpninfo);
if (vpninfo->dtls_attempt_period && !vpninfo->dtls_ssl && !vpninfo->new_dtls_ssl &&
vpninfo->new_dtls_started + vpninfo->dtls_attempt_period < time(NULL)) {
vpninfo->new_dtls_started + vpninfo->dtls_attempt_period < time(NULL) &&
vpninfo->ssl_fd != -1) {
vpn_progress(vpninfo, PRG_TRACE, _("Attempt new DTLS connection\n"));
connect_dtls_socket(vpninfo);
}
......@@ -115,6 +117,17 @@ int openconnect_mainloop(struct openconnect_info *vpninfo,
ret = -EINTR;
break;
}
if (vpninfo->got_pause_cmd) {
/* close all connections and wait for the user to call
openconnect_mainloop() again */
openconnect_close_https(vpninfo, 0);
dtls_close(vpninfo, 1);
vpninfo->new_dtls_started = 0;
vpninfo->got_pause_cmd = 0;
vpn_progress(vpninfo, PRG_INFO, _("Caller paused the connection\n"));
return 0;
}
if (did_work)
continue;
......
......@@ -299,6 +299,7 @@ struct openconnect_info {
int cmd_fd;
int cmd_fd_write;
int got_cancel_cmd;
int got_pause_cmd;
struct pkt *incoming_queue;
struct pkt *outgoing_queue;
......
......@@ -168,7 +168,8 @@ struct oc_auth_form {
#define PRG_TRACE 3
/* byte commands to write into the cmd_fd */
#define OC_CMD_CANCEL 'x'
#define OC_CMD_CANCEL 'x'
#define OC_CMD_PAUSE 'p'
#define RECONNECT_INTERVAL_MIN 10
#define RECONNECT_INTERVAL_MAX 100
......
......@@ -549,6 +549,9 @@ void check_cmd_fd(struct openconnect_info *vpninfo, fd_set *fds)
case OC_CMD_CANCEL:
vpninfo->got_cancel_cmd = 1;
break;
case OC_CMD_PAUSE:
vpninfo->got_pause_cmd = 1;
break;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment