[PATCH V2 11/11] library: Add setup_tun() callback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux