From 18370601baf25c4bf1dcd7d5f8bf6b89b8ff1551 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Wed, 4 May 2016 21:40:05 -0700 Subject: [PATCH] library: Add reconnected() callback Currently, library callers can pause the connection and then re-enter the mainloop later on, reusing the same cookie they obtained during the initial login. But they do not have an easy way to tell when the VPN has successfully reconnected and is able to pass traffic. This could be useful for informing the host OS (and/or UI) that the VPN has transitioned back from Reconnecting->Connected. A callback is only needed on reconnection, not initial connection, because for the latter case CSTP is started through the openconnect_make_cstp_connection() API call before entering the mainloop. Signed-off-by: Kevin Cernekee Signed-off-by: David Woodhouse --- .../infradead/libopenconnect/LibOpenConnect.java | 1 + jni.c | 16 ++++++++++++++++ libopenconnect.map.in | 1 + library.c | 6 ++++++ openconnect-internal.h | 1 + openconnect.h | 6 ++++++ ssl.c | 4 ++++ 7 files changed, 35 insertions(+) diff --git a/java/src/org/infradead/libopenconnect/LibOpenConnect.java b/java/src/org/infradead/libopenconnect/LibOpenConnect.java index bf545b51..8dc74526 100644 --- a/java/src/org/infradead/libopenconnect/LibOpenConnect.java +++ b/java/src/org/infradead/libopenconnect/LibOpenConnect.java @@ -63,6 +63,7 @@ public void onStatsUpdate(VPNStats stats) { } public int onTokenLock() { return 0; } public int onTokenUnlock(String newToken) { return 0; } public void onSetupTun() { } + public void onReconnected() { } /* create/destroy library instances */ diff --git a/jni.c b/jni.c index bb843a40..b5aa92d9 100644 --- a/jni.c +++ b/jni.c @@ -309,6 +309,21 @@ static void setup_tun_cb(void *privdata) (*ctx->jenv)->PopLocalFrame(ctx->jenv, NULL); } +static void reconnected_cb(void *privdata) +{ + struct libctx *ctx = privdata; + jmethodID mid; + + if ((*ctx->jenv)->PushLocalFrame(ctx->jenv, 256) < 0) + return; + + mid = get_obj_mid(ctx, ctx->jobj, "onReconnected", "()V"); + if (mid) + (*ctx->jenv)->CallVoidMethod(ctx->jenv, ctx->jobj, mid); + + (*ctx->jenv)->PopLocalFrame(ctx->jenv, NULL); +} + static jobject new_auth_form(struct libctx *ctx, struct oc_auth_form *form) { jmethodID mid; @@ -625,6 +640,7 @@ JNIEXPORT jlong JNICALL Java_org_infradead_libopenconnect_LibOpenConnect_init( openconnect_set_protect_socket_handler(ctx->vpninfo, protect_socket_cb); openconnect_set_stats_handler(ctx->vpninfo, stats_cb); openconnect_set_setup_tun_handler(ctx->vpninfo, setup_tun_cb); + openconnect_set_reconnected_handler(ctx->vpninfo, reconnected_cb); ctx->cmd_fd = openconnect_setup_cmd_pipe(ctx->vpninfo); if (ctx->cmd_fd < 0) diff --git a/libopenconnect.map.in b/libopenconnect.map.in index 7c99c86a..49c2b145 100644 --- a/libopenconnect.map.in +++ b/libopenconnect.map.in @@ -81,6 +81,7 @@ OPENCONNECT_5_3 { openconnect_get_dtls_compression; openconnect_disable_ipv6; openconnect_set_localname; + openconnect_set_reconnected_handler; } OPENCONNECT_5_2; OPENCONNECT_PRIVATE { diff --git a/library.c b/library.c index 5c4028bf..97be3103 100644 --- a/library.c +++ b/library.c @@ -786,6 +786,12 @@ void openconnect_set_setup_tun_handler(struct openconnect_info *vpninfo, vpninfo->setup_tun = setup_tun; } +void openconnect_set_reconnected_handler(struct openconnect_info *vpninfo, + openconnect_reconnected_vfn reconnected) +{ + vpninfo->reconnected = reconnected; +} + void openconnect_set_stats_handler(struct openconnect_info *vpninfo, openconnect_stats_vfn stats_handler) { diff --git a/openconnect-internal.h b/openconnect-internal.h index fa729d21..b339ef6e 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -611,6 +611,7 @@ struct openconnect_info { openconnect_protect_socket_vfn protect_socket; openconnect_getaddrinfo_vfn getaddrinfo_override; openconnect_setup_tun_vfn setup_tun; + openconnect_reconnected_vfn reconnected; int (*ssl_read)(struct openconnect_info *vpninfo, char *buf, size_t len); int (*ssl_gets)(struct openconnect_info *vpninfo, char *buf, size_t len); diff --git a/openconnect.h b/openconnect.h index 23a8fb31..22f7c5e1 100644 --- a/openconnect.h +++ b/openconnect.h @@ -44,6 +44,7 @@ extern "C" { * - Add openconnect_disable_ipv6(). * - Add ip_info->gateway_addr. * - Add openconnect_set_setup_tun_handler(). + * - Add openconnect_set_reconnected_handler(). * * API version 5.2 (v7.05; 2015-03-10): * - Add openconnect_set_http_auth(), openconnect_set_protocol(). @@ -615,6 +616,11 @@ typedef void (*openconnect_setup_tun_vfn) (void *privdata); void openconnect_set_setup_tun_handler(struct openconnect_info *vpninfo, openconnect_setup_tun_vfn setup_tun); +/* Callback for indicating that a TCP reconnection succeeded. */ +typedef void (*openconnect_reconnected_vfn) (void *privdata); +void openconnect_set_reconnected_handler(struct openconnect_info *vpninfo, + openconnect_reconnected_vfn reconnected_fn); + #ifdef __cplusplus } #endif diff --git a/ssl.c b/ssl.c index c82a22ee..118fb2de 100644 --- a/ssl.c +++ b/ssl.c @@ -1024,6 +1024,10 @@ int ssl_reconnect(struct openconnect_info *vpninfo) if (interval > RECONNECT_INTERVAL_MAX) interval = RECONNECT_INTERVAL_MAX; } + script_config_tun(vpninfo, "reconnect"); + if (vpninfo->reconnected) + vpninfo->reconnected(vpninfo->cbdata); + return 0; }