From 5e4048b96a393aa9cb1f3efd288f5159ddb3e59b Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Wed, 7 Aug 2013 12:42:29 -0700 Subject: [PATCH] library: Add new openconnect_setup_cmd_pipe() call Most callers will use a simple nonblocking UNIX pipe as their cmd_fd, so provide a convenience function for creating it. Also, libopenconnect will take care of cleaning up pipes created in this manner when the library instance is freed. Pipes created through this function will be able to send new commands, such as "reconnect". Pipes passed in via openconnect_set_cancel_fd() can only be used to cancel the connection, for backward compatibility. Signed-off-by: Kevin Cernekee --- libopenconnect.map.in | 5 +++++ library.c | 24 ++++++++++++++++++++++++ openconnect-internal.h | 2 ++ openconnect.h | 6 ++++++ 4 files changed, 37 insertions(+) diff --git a/libopenconnect.map.in b/libopenconnect.map.in index 2c988ac5..233e245f 100644 --- a/libopenconnect.map.in +++ b/libopenconnect.map.in @@ -35,6 +35,11 @@ OPENCONNECT_3.0 { openconnect_set_token_mode; }; +OPENCONNECT_3.1 { + global: + openconnect_setup_cmd_pipe; +} OPENCONNECT_3.0; + OPENCONNECT_PRIVATE { global: @SYMVER_TIME@ @SYMVER_ASPRINTF@ @SYMVER_GETLINE@ @SYMVER_PRINT_ERR@ openconnect_SSL_gets; diff --git a/library.c b/library.c index 9011d746..6562dc2b 100644 --- a/library.c +++ b/library.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #ifdef HAVE_LIBSTOKEN #include @@ -57,6 +59,7 @@ struct openconnect_info *openconnect_vpninfo_new(char *useragent, vpninfo->progress = progress; vpninfo->cbdata = privdata ? : vpninfo; vpninfo->cmd_fd = -1; + vpninfo->cmd_fd_write = -1; vpninfo->xmlpost = 1; openconnect_set_reported_os(vpninfo, NULL); @@ -106,6 +109,10 @@ static void free_optlist(struct vpn_option *opt) void openconnect_vpninfo_free(struct openconnect_info *vpninfo) { openconnect_close_https(vpninfo, 1); + if (vpninfo->cmd_fd_write != -1) { + close(vpninfo->cmd_fd); + close(vpninfo->cmd_fd_write); + } free(vpninfo->peer_addr); free_optlist(vpninfo->cookies); free_optlist(vpninfo->cstp_options); @@ -282,6 +289,23 @@ void openconnect_set_cancel_fd(struct openconnect_info *vpninfo, int fd) vpninfo->cmd_fd = fd; } +int openconnect_setup_cmd_pipe(struct openconnect_info *vpninfo) +{ + int pipefd[2]; + + if (pipe(pipefd) < 0) + return -EIO; + if (fcntl(pipefd[0], F_SETFL, O_NONBLOCK) || + fcntl(pipefd[1], F_SETFL, O_NONBLOCK)) { + close(pipefd[0]); + close(pipefd[1]); + return -EIO; + } + vpninfo->cmd_fd = pipefd[0]; + vpninfo->cmd_fd_write = pipefd[1]; + return vpninfo->cmd_fd_write; +} + const char *openconnect_get_version(void) { return openconnect_version_str; diff --git a/openconnect-internal.h b/openconnect-internal.h index b59638e1..91c6b6ee 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -295,7 +295,9 @@ struct openconnect_info { int ssl_fd; int dtls_fd; int new_dtls_fd; + int cmd_fd; + int cmd_fd_write; struct pkt *incoming_queue; struct pkt *outgoing_queue; diff --git a/openconnect.h b/openconnect.h index 8d49a920..b05640ca 100644 --- a/openconnect.h +++ b/openconnect.h @@ -246,6 +246,12 @@ void openconnect_set_cert_expiry_warning(struct openconnect_info *vpninfo, cancellation mechanism inactive. */ void openconnect_set_cancel_fd(struct openconnect_info *vpninfo, int fd); +/* Create a nonblocking pipe used to send cancellations and other commands + to the library. This returns a file descriptor to the write side of + the pipe. Both sides will be closed by openconnect_vpninfo_free(). + This replaces openconnect_set_cancel_fd(). */ +int openconnect_setup_cmd_pipe(struct openconnect_info *vpninfo); + const char *openconnect_get_version(void); /* The first (privdata) argument to each of these functions is either