PERFORCE change 123045 for review

Matus Harvan mharvan at FreeBSD.org
Sat Jul 7 08:12:16 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=123045

Change 123045 by mharvan at mharvan_twoflower on 2007/07/07 08:11:45

	added prepending a dispatch value before the actual payload (ping, data,...)
	added a keep-alive/ping mechanism, UDP failure can now be detected

Affected files ...

.. //depot/projects/soc2007/mharvan-mtund/mtund.src/Makefile#4 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/tunneld.c#5 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/tunneld.h#3 edit

Differences ...

==== //depot/projects/soc2007/mharvan-mtund/mtund.src/Makefile#4 (text+ko) ====


==== //depot/projects/soc2007/mharvan-mtund/mtund.src/tunneld.c#5 (text+ko) ====

@@ -26,8 +26,17 @@
 
 #include "tunneld.h"
 
+// linux only
+#include <stdarg.h>
+#include <sys/types.h>
+
+#define min(a,b) ( (a>b) ? b : a )
+
 /* max transfered unit - capsuled packet size */
-const int mtu = 1400;
+//const int mtu = 1400;
+#define MTU 1500
+/* how many pings can fail before the plugin is declared broken */
+#define PING_FAIL 3
 
 int server = 0; /* are we a server or a client? */
 plugint *plugins = NULL; /* linked list of loaded plugins */
@@ -38,6 +47,9 @@
 int tun_fd = 0; /* tunnel device */
 struct event tun_ev;
 
+struct event timer_ev;
+uint echo_seq = 0;
+
 char *host;
 char *port = "12345";
     
@@ -178,6 +190,8 @@
     pl->next = plugins;
     plugins = pl;
 
+    pl->ping_counter = PING_FAIL;
+
     fprintf(stderr, "successfully loaded plugin %s\n", pl->name);
     return 0;
 
@@ -187,15 +201,68 @@
 	return 2;
 }
 
+void send_echo_request()
+{
+    char data[10];
+    plugint *pl = current_pl;
+    if (pl) {
+	*data = DISPATCH_ECHO_REQUEST;
+	*(data+1) = echo_seq++;
+	(void) pl->send(pl, data, sizeof(data));
+	pl->ping_counter--;
+    }
+}
+
+void timer_ev_handler(int fd, short ev_type, void *arg)
+{
+    struct timeval tv;
+    plugint *pl = current_pl;
+
+    fprintf(stderr, "timer fired\n");
+
+    if (pl) {
+	if (! pl->ping_counter) {
+	    report_plugin_error(pl, PLUGIN_ERROR_PING);
+	} else {
+	    send_echo_request();
+	}
+    }
+
+    /* register a timer event */
+    tv.tv_sec=1;
+    tv.tv_usec=0;
+    evtimer_set(&timer_ev, timer_ev_handler, NULL);
+    evtimer_add(&timer_ev, &tv);
+}
+
 /*
  * Pass data received by the plugin to the daemon.
  */
 void process_data_from_plugin(plugint *pl, char *data, int len)
 {
-    if (len > 0) {
-	current_pl = pl;
+    u_int8_t dispatch = *data;
+    switch (dispatch) {
+    case DISPATCH_DATA:
+	if (len > 0) {
+	    current_pl = pl;
+	}
+	tun_send(data+1, len-1);
+	break;
+    case DISPATCH_ECHO_REQUEST:
+	*data = (u_int8_t) DISPATCH_ECHO_REPLY;
+	pl->send(pl, data, len);
+	fprintf(stderr, "got echo request (plugin: %s)\n",
+		pl->name);
+	break;
+    case DISPATCH_ECHO_REPLY:
+	fprintf(stderr, "got echo reply (plugin: %s)\n",
+		pl->name);
+	pl->ping_counter++;
+	break;
+    default:
+	fprintf(stderr, "unknown dispatch 0x%X in data from plugin %s\n",
+		dispatch, pl->name);
     }
-    tun_send(data, len);
 }
 
 /*
@@ -204,14 +271,17 @@
 void process_data_from_tun(char *data, int len)
 {
     int n;
+    char ldata[MTU+1];
 
     if (current_pl == NULL) {
 	fprintf(stderr, "no plugin connected yet, discarding tun data\n");
 	report_plugin_error(NULL, PLUGIN_ERROR_BOOTSTRAP);
     } else {
-	n = current_pl->send(current_pl, data, len);
+	*ldata = DISPATCH_DATA;
+	memcpy(ldata+1, data, min(sizeof(ldata)-1, len));
+	n = current_pl->send(current_pl, ldata, min(sizeof(ldata), len+1));
 
-	if (n < len) {
+	if (n < min(sizeof(ldata), len+1)) {
 	    fprintf(stderr, "process_data_from_tun: plugind sent less "
 		    "bytes (%d) than requested (%d)\n", n, len);
 	}
@@ -224,11 +294,22 @@
 	return;
     }
 
-    if (!server) {
+    if (server) {
+	if (pl) {
+	    /* reinitialize the broken plugin */
+	    fprintf(stderr, "plugin %s failed, reinitializing...\n", pl->name);
+	    // TODO: pl->reinitialize(pl);
+	    //pl->deinitialize(pl);
+	    //(void) pl->initialize(pl, server, host, 1234);
+	}
+    } else {
 	if (pl) {
 	    /* deinitialize the broken plugin */
 	    fprintf(stderr, "plugin failed: %s\n", pl->name);
 	    pl->deinitialize(pl);
+
+	    /* move to next plugin */
+	    pl = pl->next;
 	}
 	
 	/* scan - find a working plugin */
@@ -253,6 +334,8 @@
 {
     plugint *pl;
 
+    event_del(&timer_ev);
+
     event_del(&tun_ev);
     tun_close(tun_fd, tun_dev);
 
@@ -337,7 +420,11 @@
     if (server) {
 	system("ifconfig tun0 mtu 1400 192.168.0.1 192.168.0.2");
     } else {
-	system("ifconfig tun0 mtu 1400 192.168.0.2 192.168.0.1");
+	/* FeeBSD */
+	//system("ifconfig tun0 mtu 1400 192.168.0.2 192.168.0.1");
+	/* Linux */
+	system("ifconfig tun0 mtu 1400 192.168.0.2");
+	system("route add 192.168.0.1 tun0");
     }
 
     signal(SIGHUP, sigcb);
@@ -346,7 +433,11 @@
     
     /* load plugins */
     load_plugin("./plugin_udp.so");
+    plugins->name = "udp_1111";
+    load_plugin("./plugin_udp.so");
     plugins->name = "udp_2222";
+    load_plugin("./plugin_udp.so");
+    plugins->name = "udp_3333";
     load_plugin("./plugin_tcp.so");
     plugins->name = "tcp_1111";
     load_plugin("./plugin_tcp.so");
@@ -366,6 +457,8 @@
 	report_plugin_error(NULL, PLUGIN_ERROR_BOOTSTRAP);
     }
 
+    timer_ev_handler(-1, 0, NULL);
+
     /* start tunneling */
     event_dispatch();
     

==== //depot/projects/soc2007/mharvan-mtund/mtund.src/tunneld.h#3 (text+ko) ====

@@ -15,6 +15,7 @@
 /* structure representing a plugin in the main tunnel daemon */
 typedef struct _plugint {
     char *name;
+    int ping_counter;
     int (*initialize)(struct _plugint*, int, char*, char*);
     void (*deinitialize)(struct _plugint*);
     int (*send)(struct _plugint*, char*, int);
@@ -28,7 +29,14 @@
     PLUGIN_ERROR_BOOTSTRAP,
     PLUGIN_ERROR_SEND,
     PLUGIN_ERROR_RECEIVE,
-    PLUGIN_ERROR_TIMEOUT
+    PLUGIN_ERROR_TIMEOUT,
+    PLUGIN_ERROR_PING,
+};
+
+enum {
+    DISPATCH_ECHO_REQUEST = 1,
+    DISPATCH_ECHO_REPLY   = 2,
+    DISPATCH_DATA         = 0x42
 };
 
 /* --- select() --- */


More information about the p4-projects mailing list