Library users used to do something like: openconnect_obtain_cookie() openconnect_make_cstp_connection() openconnect_setup_dtls() openconnect_get_ip_info() # ask the OS to create the tun interface openconnect_setup_tun_fd() openconnect_mainloop() But now that MTU is calculated a few seconds after the mainloop starts up, it is necessary to provide a callback so that the calling application can create a tun interface with the correct MTU. (Bonus: Android and Chrome OS currently do not allow the MTU, IP address, or other parameters to be adjusted after the initial settings were sent to the OS.) Signed-off-by: Kevin Cernekee <cernekee at gmail.com> --- java/src/com/example/LibTest.java | 12 ++++++++---- .../src/org/infradead/libopenconnect/LibOpenConnect.java | 1 + jni.c | 16 ++++++++++++++++ libopenconnect.map.in | 1 + library.c | 6 ++++++ mainloop.c | 6 ++++++ openconnect-internal.h | 1 + openconnect.h | 6 ++++++ 8 files changed, 45 insertions(+), 4 deletions(-) diff --git a/java/src/com/example/LibTest.java b/java/src/com/example/LibTest.java index 1219d938639e..da073b7bbe5a 100644 --- a/java/src/com/example/LibTest.java +++ b/java/src/com/example/LibTest.java @@ -163,6 +163,14 @@ public final class LibTest { break; } } + + @Override + public void onSetupTun() { + System.out.println("SETUP_TUN"); + if (setupTunDevice("/etc/vpnc/vpnc-script", null) != 0 && + setupTunScript("ocproxy") != 0) + die("Error setting up tunnel"); + } } private static void printList(String pfx, List<String> ss) { @@ -233,10 +241,6 @@ public final class LibTest { printIPInfo(lib.getIPInfo()); - if (lib.setupTunDevice("/etc/vpnc/vpnc-script", null) != 0 && - lib.setupTunScript("ocproxy") != 0) - die("Error setting up tunnel"); - if (lib.setupDTLS(60) != 0) die("Error setting up DTLS"); diff --git a/java/src/org/infradead/libopenconnect/LibOpenConnect.java b/java/src/org/infradead/libopenconnect/LibOpenConnect.java index b65f15b4feb8..dfad626136a4 100644 --- a/java/src/org/infradead/libopenconnect/LibOpenConnect.java +++ b/java/src/org/infradead/libopenconnect/LibOpenConnect.java @@ -62,6 +62,7 @@ public abstract class LibOpenConnect { public void onStatsUpdate(VPNStats stats) { } public int onTokenLock() { return 0; } public int onTokenUnlock(String newToken) { return 0; } + public void onSetupTun() { } /* create/destroy library instances */ diff --git a/jni.c b/jni.c index f806a1b995e8..a3e1006a2119 100644 --- a/jni.c +++ b/jni.c @@ -294,6 +294,21 @@ out: (*ctx->jenv)->PopLocalFrame(ctx->jenv, NULL); } +static void setup_tun_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, "onSetupTun", "()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; @@ -609,6 +624,7 @@ JNIEXPORT jlong JNICALL Java_org_infradead_libopenconnect_LibOpenConnect_init( unlock_token_cb); 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); 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 550cbd2747c5..827468295c7f 100644 --- a/libopenconnect.map.in +++ b/libopenconnect.map.in @@ -43,6 +43,7 @@ OPENCONNECT_5.0 { openconnect_set_proxy_auth; openconnect_set_reported_os; openconnect_set_reqmtu; + openconnect_set_setup_tun_handler; openconnect_set_stats_handler; openconnect_set_stoken_mode; openconnect_set_system_trust; diff --git a/library.c b/library.c index 3970ba0a0e64..fec293c5e882 100644 --- a/library.c +++ b/library.c @@ -771,6 +771,12 @@ void openconnect_override_getaddrinfo(struct openconnect_info *vpninfo, openconn vpninfo->getaddrinfo_override = gai_fn; } +void openconnect_set_setup_tun_handler(struct openconnect_info *vpninfo, + openconnect_setup_tun_vfn setup_tun) +{ + vpninfo->setup_tun = setup_tun; +} + void openconnect_set_stats_handler(struct openconnect_info *vpninfo, openconnect_stats_vfn stats_handler) { diff --git a/mainloop.c b/mainloop.c index 60a2356b993a..c1a7eb9b1f01 100644 --- a/mainloop.c +++ b/mainloop.c @@ -110,6 +110,12 @@ static int setup_tun_device(struct openconnect_info *vpninfo) { int ret; + if (vpninfo->setup_tun) { + vpninfo->setup_tun(vpninfo->cbdata); + if (tun_is_up(vpninfo)) + return 0; + } + #ifndef _WIN32 if (vpninfo->use_tun_script) { ret = openconnect_setup_tun_script(vpninfo, vpninfo->vpnc_script); diff --git a/openconnect-internal.h b/openconnect-internal.h index c39042778cb2..fa729d211b3d 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -610,6 +610,7 @@ struct openconnect_info { openconnect_progress_vfn progress; openconnect_protect_socket_vfn protect_socket; openconnect_getaddrinfo_vfn getaddrinfo_override; + openconnect_setup_tun_vfn setup_tun; 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 7d0f0342f71f..edd2c55ab4f0 100644 --- a/openconnect.h +++ b/openconnect.h @@ -42,6 +42,7 @@ extern "C" { * - Add openconnect_get_dtls_compression(). * - Add openconnect_disable_ipv6(). * - Add ip_info->gateway_addr. + * - Add openconnect_set_setup_tun_handler(). * * API version 5.2 (v7.05; 2015-03-10): * - Add openconnect_set_http_auth(), openconnect_set_protocol(). @@ -607,6 +608,11 @@ typedef int (*openconnect_getaddrinfo_vfn) (void *privdata, const char *node, co const struct addrinfo *hints, struct addrinfo **res); void openconnect_override_getaddrinfo(struct openconnect_info *vpninfo, openconnect_getaddrinfo_vfn gai_fn); +/* Callback for configuring the interface after MTU detection finishes. */ +typedef void (*openconnect_setup_tun_vfn) (void *privdata); +void openconnect_set_setup_tun_handler(struct openconnect_info *vpninfo, + openconnect_setup_tun_vfn setup_tun); + #ifdef __cplusplus } #endif -- 2.7.0