Date: Sat, 7 Jul 2007 08:12:15 GMT From: Matus Harvan <mharvan@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 123045 for review Message-ID: <200707070812.l678CFA4061622@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=123045 Change 123045 by mharvan@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() --- */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707070812.l678CFA4061622>