Skip to content

Commit

Permalink
library: Add protect_socket callback
Browse files Browse the repository at this point in the history
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: Kevin Cernekee <cernekee@gmail.com>
  • Loading branch information
cernekee committed Jan 15, 2014
1 parent 723bcb4 commit 9483a20
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 0 deletions.
2 changes: 2 additions & 0 deletions dtls.c
Expand Up @@ -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));
Expand Down
1 change: 1 addition & 0 deletions libopenconnect.map.in
Expand Up @@ -48,6 +48,7 @@ OPENCONNECT_3.1 {
openconnect_get_ifname;
openconnect_set_reqmtu;
openconnect_get_ip_info;
openconnect_set_protect_socket_handler;
} OPENCONNECT_3.0;

OPENCONNECT_PRIVATE {
Expand Down
6 changes: 6 additions & 0 deletions library.c
Expand Up @@ -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;
}
1 change: 1 addition & 0 deletions openconnect-internal.h
Expand Up @@ -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)) || \
Expand Down
7 changes: 7 additions & 0 deletions openconnect.h
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions ssl.c
Expand Up @@ -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;
Expand Down

0 comments on commit 9483a20

Please sign in to comment.