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