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