From 60d4e1804b30ec3d902c2f7fab0a9a4fda052e68 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Wed, 4 Dec 2013 20:11:52 -0800 Subject: [PATCH] Add new helper functions to support cmd_fd feature Signed-off-by: Kevin Cernekee --- openconnect-internal.h | 3 +++ openconnect.h | 3 +++ ssl.c | 37 ++++++++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/openconnect-internal.h b/openconnect-internal.h index 91c6b6ee..eee5c857 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -298,6 +298,7 @@ struct openconnect_info { int cmd_fd; int cmd_fd_write; + int got_cancel_cmd; struct pkt *incoming_queue; struct pkt *outgoing_queue; @@ -403,7 +404,9 @@ const char *keystore_strerror(int err); int keystore_fetch(const char *key, unsigned char **result); #endif void cmd_fd_set(struct openconnect_info *vpninfo, fd_set *fds, int *maxfd); +void check_cmd_fd(struct openconnect_info *vpninfo, fd_set *fds); int is_cancel_pending(struct openconnect_info *vpninfo, fd_set *fds); +void poll_cmd_fd(struct openconnect_info *vpninfo, int timeout); /* ${SSL_LIBRARY}.c */ int openconnect_SSL_gets(struct openconnect_info *vpninfo, char *buf, size_t len); diff --git a/openconnect.h b/openconnect.h index b05640ca..6e3a46a1 100644 --- a/openconnect.h +++ b/openconnect.h @@ -167,6 +167,9 @@ struct oc_auth_form { #define PRG_DEBUG 2 #define PRG_TRACE 3 +/* byte commands to write into the cmd_fd */ +#define OC_CMD_CANCEL 'x' + struct openconnect_info; #define OPENCONNECT_X509 void diff --git a/ssl.c b/ssl.c index 72c7b268..b9fef08a 100644 --- a/ssl.c +++ b/ssl.c @@ -530,7 +530,42 @@ void cmd_fd_set(struct openconnect_info *vpninfo, fd_set *fds, int *maxfd) } } +void check_cmd_fd(struct openconnect_info *vpninfo, fd_set *fds) +{ + char cmd; + + if (vpninfo->cmd_fd == -1 || !FD_ISSET(vpninfo->cmd_fd, fds)) + return; + if (vpninfo->cmd_fd_write == -1) { + /* legacy openconnect_set_cancel_fd() users */ + vpninfo->got_cancel_cmd = 1; + return; + } + + if (read(vpninfo->cmd_fd, &cmd, 1) != 1) + return; + + switch (cmd) { + case OC_CMD_CANCEL: + vpninfo->got_cancel_cmd = 1; + break; + } +} + int is_cancel_pending(struct openconnect_info *vpninfo, fd_set *fds) { - return vpninfo->cmd_fd != -1 && FD_ISSET(vpninfo->cmd_fd, fds); + check_cmd_fd(vpninfo, fds); + return vpninfo->got_cancel_cmd; +} + +void poll_cmd_fd(struct openconnect_info *vpninfo, int timeout) +{ + fd_set rd_set; + int maxfd = 0; + struct timeval tv = { timeout, 0 }; + + FD_ZERO(&rd_set); + cmd_fd_set(vpninfo, &rd_set, &maxfd); + select(maxfd + 1, &rd_set, NULL, NULL, &tv); + check_cmd_fd(vpninfo, &rd_set); }