Commit 9483a20a authored by Kevin Cernekee's avatar Kevin Cernekee

library: Add protect_socket callback

In some situations (e.g. Android VpnService) it isn't possible to add a
routing table entry for the VPN gateway's IP.  Instead, it is necessary
to bind each individual file descriptor used for the tunnel to the default
interface before passing traffic on it.  Add an optional protect_socket
callback for this purpose.
Signed-off-by: default avatarKevin Cernekee <>
parent 723bcb4e
......@@ -486,6 +486,8 @@ int connect_dtls_socket(struct openconnect_info *vpninfo)
perror(_("Open UDP socket for DTLS:"));
return -EINVAL;
if (vpninfo->protect_socket)
vpninfo->protect_socket(vpninfo->cbdata, dtls_fd);
sndbuf = vpninfo->ip_info.mtu * 2;
setsockopt(dtls_fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
......@@ -48,6 +48,7 @@ OPENCONNECT_3.1 {
......@@ -527,3 +527,9 @@ int openconnect_set_stoken_mode(struct openconnect_info *vpninfo,
return openconnect_set_token_mode(vpninfo, token_mode, token_str);
void openconnect_set_protect_socket_handler(struct openconnect_info *vpninfo,
openconnect_protect_socket_vfn protect_socket)
vpninfo->protect_socket = protect_socket;
......@@ -301,6 +301,7 @@ struct openconnect_info {
openconnect_write_new_config_vfn write_new_config;
openconnect_process_auth_form_vfn process_auth_form;
openconnect_progress_vfn progress;
openconnect_protect_socket_vfn protect_socket;
#if (defined(DTLS_OPENSSL) && defined(SSL_OP_CISCO_ANYCONNECT)) || \
......@@ -366,6 +366,13 @@ struct openconnect_info *openconnect_vpninfo_new(char *useragent,
void *privdata);
void openconnect_vpninfo_free(struct openconnect_info *vpninfo);
/* Callback to allow binding a newly created socket's file descriptor to
a specific interface, e.g. with SO_BINDTODEVICE. This tells the kernel
not to route the traffic in question over the VPN tunnel. */
typedef void (*openconnect_protect_socket_vfn) (void *privdata, int fd);
void openconnect_set_protect_socket_handler(struct openconnect_info *vpninfo,
openconnect_protect_socket_vfn protect_socket);
/* SSL certificate capabilities. openconnect_has_pkcs11_support() means that we
can accept PKCS#11 URLs in place of filenames, for the certificate and key. */
int openconnect_has_pkcs11_support(void);
......@@ -66,6 +66,8 @@ static int cancellable_connect(struct openconnect_info *vpninfo, int sockfd,
int maxfd = sockfd;
fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK);
if (vpninfo->protect_socket)
vpninfo->protect_socket(vpninfo->cbdata, sockfd);
if (connect(sockfd, addr, addrlen) < 0 && errno != EINPROGRESS)
return -1;
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