PERFORCE change 125418 for review
Matus Harvan
mharvan at FreeBSD.org
Mon Aug 20 09:10:19 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125418
Change 125418 by mharvan at mharvan_bike-planet on 2007/08/20 16:10:17
code cleanup - daemon
Affected files ...
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/mtund.c#11 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/mtund.h#6 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/plugin.h#9 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/tun_dev.c#3 edit
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/tun_dev.c.freebsd#3 delete
.. //depot/projects/soc2007/mharvan-mtund/mtund.src/tun_dev.h#3 edit
Differences ...
==== //depot/projects/soc2007/mharvan-mtund/mtund.src/mtund.c#11 (text+ko) ====
@@ -1,18 +1,38 @@
-/*
- * Tunneling code idea based and tun interface handling based on the
- * ICMP tunnel described at
- * http://neworder.box.sk/newsread.php?newsid=13688
- * which had following comments:
- * > Code is ruthlessly ripped from vtun and itunnel with appropriate changes.
- * > Guys, thanks for the great stuff!
- * >
- * > itunnel - an ICMP tunnel by edi / teso
- * > VTun - Virtual Tunnel over TCP/IP network.
+/*-
+ * Copyright (c) 2007 Matus Harvan
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
+
#include <dlfcn.h>
#include <event.h>
#include <err.h>
@@ -28,92 +48,91 @@
#include "tun_dev.h"
#include "mtund.h"
-// Linux only
-//#include <stdarg.h>
-//#include <sys/types.h>
-
/* max transfered unit - encapsulated packet size */
#define MTU 1500
-/* how many pings can fail before the plugin is declared broken */
+/*
+ * probes ad keep-alive pings
+ *
+ * PING_INTERVAL - how often to send pings
+ * PING_FAIL_PLUGIN - how many can fail before the plugin is declared broken
+ * PING_FAIL_PLUGIN - how many can fail before the client is declared
+ * dead by the server and its ID reclaimed
+ *
+ * The counter for failed pings is reset whenever a ping reply is
+ * received or the plugin is changed.
+ */
#define PING_INTERVAL 5
#define PING_FAIL_PLUGIN 3
#define PING_FAIL_COMPLETE 10
-#define IDREQUEST_RETRIES 3
#define min(a,b) ( (a>b) ? b : a )
+
/* DATA TYPES */
/* fragment header */
struct frag_hdr {
u_int8_t dispatch;
- uint id; /* Id of the whole packet, same in each fragment */
- uint size; /* length of the whole packet, same in each fragment */
- uint offset; /* fragment offset (in bytes) from the beginning
- * of the packet */
+ uint id; /* ID of the packet. same in each fragment
+ * belonging to the same packet */
+ uint size; /* length of the whole packet, same in each fragment */
+ uint offset; /* fragment offset (in bytes) from the beginning
+ * of the packet */
};
/* info about a packet being reassembled from fragments */
struct frag_info {
- uint id; /* Id of the whole packet, same in each fragment */
- uint size; /* length of the whole packet, same in each fragment */
- time_t tv_sec; /* seconds after epoch when reassembly
- * of this packet started */
- u_int8_t *bitmap; /* bitmap representing already
- * received parts of the packet */
- char *buf; /* buffer into which the fragment is reassembled */
- LIST_ENTRY(frag_info) frag_infos;
+ uint id; /* ID of the packet. same in each fragment
+ * belonging to the same packet */
+ uint size; /* length of the whole packet, same
+ * in each fragment */
+ time_t tv_sec; /* seconds after epoch when reassembly
+ * of this packet started */
+ u_int8_t *bitmap; /* bitmap representing already
+ * received parts of the packet */
+ char *buf; /* buffer into which the fragment is
+ * reassembled */
+ LIST_ENTRY(frag_info) frag_infos; /* queue(3) */
};
+/* structure representing a client */
struct client {
- clientid_t clid; /* client ID */
- int used; /* client active or not */
- long reqid; /* request ID used for the client ID request */
- struct plugin* pl;
-
+ clientid_t clid; /* client ID */
+ int used; /* client active or not */
+ long reqid; /* request ID used for the client ID request */
+ struct plugin *pl;
/* tunnel device */
- char tun_dev[16];
- int tun_fd;
- struct event tun_ev;
-
+ char tun_dev[16];
+ int tun_fd;
+ struct event tun_ev;
/* ping */
- int ping_counter;
- uint8_t echo_seq;
-
+ int ping_counter;
+ uint8_t echo_seq;
/* fragmentation */
- struct frag_hdr frag_hdr;
- char frag_data[MTU+sizeof(struct frag_hdr)];
- char *frag_datap;
- int frag_data_len;
- uint frag_id; /* id for the next packet to be fragmented */
- // TODO: randomize initial value of frag_id
-
- /* fragmentat reassembly */
+ struct frag_hdr frag_hdr;
+ char frag_data[MTU+sizeof(struct frag_hdr)];
+ char *frag_datap;
+ int frag_data_len;
+ uint frag_id;/* id for the next packet to be fragmented */
+ /* fragment reassembly information */
LIST_HEAD(frag_infos_head, frag_info) frag_infos;
};
-//TODO: init: frag_datap, frag_data_len, frag_id, echo_seq, client id,
-// frag_info_list
-// pl->ping_counter = PING_FAIL;
+/* TODO: randomize initial value of frag_id */
+/* TODO: init: frag_datap, frag_data_len, frag_id, echo_seq, client id, */
+/* frag_info_list */
-struct client clients[MAXCLIENTS];
/* FUNCTION HEADERS */
-/*
- * Pass data received from the tun interface to the daemon.
- */
static int process_data_from_tun(struct client *cl, struct plugin *pl,
uint8_t dispatch, char *data, int len);
-
static int send_next_frag();
static void cleanup();
static void send_plugin_select(struct client *cl);
+
/* GLOBAL VARIABLES */
-int server = 0; /* are we a server or a client? */
-TAILQ_HEAD(plugins_head, plugin) plugins =
- TAILQ_HEAD_INITIALIZER(plugins);
-
-static struct event timer_ev;
-
+int server = 0; /* are we a server or a client? */
+TAILQ_HEAD(plugins_head, plugin) plugins = TAILQ_HEAD_INITIALIZER(plugins);
+struct client clients[MAXCLIENTS]; /* client is using clients[0] for itself */
static uint8_t myclid = 0; /* client ID of this client (client only) */
/* server host */
@@ -121,8 +140,9 @@
char *host;
char *port = "12345";
-//static int client_state;
+static struct event timer_ev;
+/* dump data in hex format */
static void
dump_data(char *data, int len)
{
@@ -133,6 +153,10 @@
printf("\n");
}
+/*
+ * not used yet - useful out, i.e., which plugins work should be
+ * produced with this function
+ */
int
mylog(const char *fmt, ...)
{
@@ -146,6 +170,9 @@
return out;
}
+/*
+ * debugging output - will be removed
+ */
int
debug(const char *fmt, ...)
{
@@ -159,6 +186,7 @@
return out;
}
+/* show and execute a command */
int
ssystem(const char *fmt, ...)
{
@@ -171,7 +199,7 @@
return system(cmd);
}
-/* lookup client by ID */
+/* lookup the client by ID */
static struct client *
lookup_clid(clientid_t clid)
{
@@ -213,8 +241,8 @@
}
/*
- * entry function if a polling plugin can send more data - if
- * fragments pending, send these; otherwise read data from the tun
+ * entry function if a polling plugin can send more data - if there
+ * are pending fragments, send these; otherwise read data from the tun
* interface and pass it to the daemon
*/
static void
@@ -246,7 +274,7 @@
} while (nread > 0 && nwrite == SEND_PKT_SENT);
}
-/* send data via the tun interface for the client */
+/* write a packet (data) to the the tun interface of a client */
static int
tun_send(struct client *cl, char *data, int len) {
int n;
@@ -278,7 +306,8 @@
request_tun_data(cl);
}
- int
+/* initialize a tun device */
+int
tun_init(struct client *cl)
{
int tun_flags;
@@ -336,19 +365,16 @@
if (cl->pl->is_ready_to_send(cl->pl, cl->clid) ==
WILL_SEND_IMMEDIATELY)
event_add(&cl->tun_ev, NULL);
- // else the tun read is timed by the plugin
+ /* else the tun read is timed by the plugin */
}
return 0;
}
+/* deinitialize a tun device */
static void
tun_deinit(struct client *cl)
{
- if (!server) {
- // TODO: fix routing table
- }
-
if (cl->tun_fd != -1) {
event_del(&cl->tun_ev);
tun_close(cl->tun_fd, cl->tun_dev);
@@ -361,42 +387,43 @@
*/
static struct plugin *
load_plugin(char *path) {
- struct plugin *pl;
- int (*plugin_register)(struct plugin*);
- void *handle;
- const char *error;
- pl = malloc(sizeof(struct plugin));
- if (!pl) {
- warnx("failed to malloc plugin: out of memory!\n");
- return NULL;
- }
+ struct plugin *pl;
+ int (*plugin_register)(struct plugin*);
+ void *handle;
+ const char *error;
- /* open the library */
- handle = dlopen (path, RTLD_NOW);
- if (!handle) {
- fputs(dlerror(), stderr);
- return NULL;
- }
- /* load the plugin */
- plugin_register = dlsym(handle, "plugin_register");
- if ((error = dlerror()) != NULL)
- goto error;
- /* prepare the plugin for registration */
- plugin_register(pl);
+ pl = malloc(sizeof(struct plugin));
+ if (!pl) {
+ warnx("failed to malloc plugin: out of memory!\n");
+ return NULL;
+ }
- /* add plugin to the list of loaded plugins */
- TAILQ_INSERT_TAIL(&plugins, pl, plugins);
+ /* open the library */
+ handle = dlopen (path, RTLD_NOW);
+ if (!handle) {
+ fputs(dlerror(), stderr);
+ return NULL;
+ }
+ /* load the plugin */
+ plugin_register = dlsym(handle, "plugin_register");
+ if ((error = dlerror()) != NULL)
+ goto error;
+ /* prepare the plugin for registration */
+ plugin_register(pl);
+
+ /* add plugin to the list of loaded plugins */
+ TAILQ_INSERT_TAIL(&plugins, pl, plugins);
+
+ debug("successfully loaded plugin %s\n", pl->name);
+ return (pl);
- fprintf(stderr, "successfully loaded plugin %s\n", pl->name);
- return pl;
-
error:
fputs(error, stderr);
free(pl);
- return NULL;
+ return (NULL);
}
-/* initialize the client datastructure */
+/* initialize a client */
static struct client *
client_init(clientid_t clid)
{
@@ -416,13 +443,26 @@
return cl;
}
-/* deinitialize the client datastructure, corresponding tun device,... */
+/* deinitialize a client datastructure, the corresponding tun device,... */
static void
client_deinit(struct client *cl)
{
- //TODO
- //TODO close conn
+ struct frag_info *np, *np_temp;
+
+ /* close the (plugin) connection */
+ if (cl->pl)
+ cl->pl->conn_close(cl->pl, cl->clid);
+ /* deinitialize the tun device */
tun_deinit(cl);
+
+ /* deallocate fragment reassembly information */
+ LIST_FOREACH_SAFE(np, &cl->frag_infos, frag_infos, np_temp) {
+ LIST_REMOVE(np, frag_infos);
+ free(np->bitmap);
+ free(np->buf);
+ free(np);
+ }
+
cl->used = 0;
}
@@ -447,13 +487,14 @@
len++;
}
+ /* dispatch */
*datap = DISPATCH_PLUGIN_SELECT;
datap++;
len++;
nwrite = cl->pl->send(cl->pl, cl->clid,
data, len, NORMAL_DATA, &consumed);
- printf("send_plugin_select(): nwrite: 0x%x\n", nwrite);
+ debug("send_plugin_select(): nwrite: 0x%x\n", nwrite);
}
}
/*
@@ -479,17 +520,19 @@
len++;
}
+ /* dispatch */
*datap = DISPATCH_ECHO_REQUEST;
datap++;
len++;
+ /* ping sequence number */
*datap = cl->echo_seq++;
datap++;
len++;
nwrite = cl->pl->send(cl->pl, cl->clid,
data, len, NORMAL_DATA, &consumed);
- printf("send_echo_request(): nwrite: 0x%x\n", nwrite);
+ debug("send_echo_request(): nwrite: 0x%x\n", nwrite);
}
}
@@ -521,8 +564,7 @@
nwrite = cl->pl->send(cl->pl, cl->clid,
data, pdata - data, NORMAL_DATA,
&consumed);
- //pl->ping_counter--;
- printf("send_id_request(): nwrite: 0x%x\n", nwrite);
+ debug("send_id_request(): nwrite: 0x%x\n", nwrite);
}
}
@@ -532,61 +574,60 @@
static void
timer_ev_handler(int fd, short ev_type, void *arg)
{
- struct timeval tv;
- struct frag_info *np, *np_temp;
- struct client *cl;
- int i;
+ struct timeval tv;
+ struct frag_info *np, *np_temp;
+ struct client *cl;
+ int i;
- /* check if too many ping requests have not failed */
- for(i = 0; i < MAXCLIENTS; i++) {
- cl = &clients[i];
- if (cl->used == 0)
- continue;
-
- printf("ping_counter: %d\n", cl->ping_counter);
- if (cl->ping_counter > PING_FAIL_COMPLETE &&
- server)
- client_deinit(cl);
- else if (cl->pl) {
- if (cl->ping_counter > PING_FAIL_PLUGIN)
- plugin_report(cl->pl, cl->clid,
- REPORT_ERROR_PING);
- send_echo_request(cl);
- }
- }
-
- /* fragment reassembly timeout */
- gettimeofday(&tv, NULL);
- for(i = 0; i < MAXCLIENTS; i++) {
- cl = &clients[i];
- if (cl->used == 0)
- continue;
-
- LIST_FOREACH_SAFE(np, &cl->frag_infos, frag_infos, np_temp) {
- if (tv.tv_sec - np->tv_sec > FRAG_TIMEOUT) {
- LIST_REMOVE(np, frag_infos);
- free(np->bitmap);
- free(np->buf);
- free(np);
- }
- }
- }
+ /* check if too many ping requests have not failed */
+ for(i = 0; i < MAXCLIENTS; i++) {
+ cl = &clients[i];
+ if (cl->used == 0)
+ continue;
+
+ printf("ping_counter: %d\n", cl->ping_counter);
+ if (cl->ping_counter > PING_FAIL_COMPLETE &&
+ server)
+ client_deinit(cl);
+ else if (cl->pl) {
+ if (cl->ping_counter > PING_FAIL_PLUGIN)
+ plugin_report(cl->pl, cl->clid,
+ REPORT_ERROR_PING);
+ send_echo_request(cl);
+ }
+ }
+
+ /* fragment reassembly timeout */
+ gettimeofday(&tv, NULL);
+ for(i = 0; i < MAXCLIENTS; i++) {
+ cl = &clients[i];
+ if (cl->used == 0)
+ continue;
+
+ LIST_FOREACH_SAFE(np, &cl->frag_infos, frag_infos, np_temp) {
+ if (tv.tv_sec - np->tv_sec > FRAG_TIMEOUT) {
+ LIST_REMOVE(np, frag_infos);
+ free(np->bitmap);
+ free(np->buf);
+ free(np);
+ }
+ }
+ }
- /* register a timer event again */
- tv.tv_sec=PING_INTERVAL;
- tv.tv_usec=0;
- evtimer_set(&timer_ev, timer_ev_handler, NULL);
- evtimer_add(&timer_ev, &tv);
+ /* register a timer event again */
+ tv.tv_sec=PING_INTERVAL;
+ 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.
- *
- * called 1st time: *conn == NULL
- * lookup client's conn by client ID and return
+ * Pass data received by the plugin to the daemon. This function is
+ * called from plugins. Before calling plugin_send, it should call
+ * plugin_conn_map().
*
- * called 2nd time: *conn != NULL
- *
+ * clid and conn_flag will be removed from the function signature as
+ * plugin_conn_map() is used now.
*/
void
process_data_from_plugin(struct plugin *pl, char *data, int len,
@@ -606,8 +647,8 @@
struct timeval tv;
int dgram_reassembled;
- printf("data from plugin: ");
- dump_data(data, len);
+/* debug("data from plugin: "); */
+/* dump_data(data, len); */
*conn_flag = CONN_DISCARD;
@@ -628,12 +669,10 @@
/* process the dispatch */
dispatch = *data;
-
- printf("clid: %hhd, dispatch: 0x%02hhx\n", *clid, dispatch);
-
+ debug("clid: %hhd, dispatch: 0x%02hhx\n", *clid, dispatch);
switch (dispatch) {
case DISPATCH_DATA:
- printf("process_data_from_plugin(): DATA\n");
+ debug("process_data_from_plugin(): DATA\n");
/* only associated clients can send DATA to the server */
if (server && *clid == 0) {
*conn_flag = CONN_DISCARD;
@@ -647,12 +686,13 @@
/* update the current plugin for this client */
set_client_pl(cl, pl);
+ /* pass data to the tun device */
tun_send(cl, data+1, len-1);
break;
case DISPATCH_PLUGIN_SELECT:
- printf("process_data_from_plugin(): PLUGIN_SELECT\n");
+ debug("process_data_from_plugin(): PLUGIN_SELECT\n");
/* only associated clients can send DATA to the server */
if (server && *clid == 0) {
*conn_flag = CONN_DISCARD;
@@ -680,7 +720,6 @@
data += sizeof(struct frag_hdr);
len -= sizeof(struct frag_hdr);
- /* debugging output */
debug("got a frag header: id %d, size %d, off %d, len %d\n",
frag_hdr->id, frag_hdr->size, frag_hdr->offset, len);
@@ -735,17 +774,26 @@
if (frag_hdr->offset + len <= p->size) {
/* copy the data */
memcpy(p->buf + frag_hdr->offset, data, len);
- /* update the bitmap */
- // TODO: we ignore overlaps, but that should be caught
- // by the upper layer checksum
+ /* update the bitmap
+ *
+ * We ignore fragment overlaps as these should
+ * be caught by the upper layer
+ * checksum. Actually, they should not happen
+ * at all.
+ */
for (i = frag_hdr->offset; i < frag_hdr->offset+len;
i++)
p->bitmap[i/8] |= (0x1 << (i%8));
} else {
- warnx("fragment outside of packet payload\n");
+ debug("fragment outside of packet payload\n");
return;
}
-
+
+ /*
+ * Fragment was processed without errors, so it was
+ * valid traffic and the plugin used by this client
+ * should be updated.
+ */
set_client_pl(cl, pl);
/* check if the complete packet has been reassembled */
@@ -766,9 +814,11 @@
if (dgram_reassembled) {
debug("frag reassembly: packet complete\n");
set_client_pl(cl, pl);
+
+ /* pass the reassembled packet to the tun device */
tun_send(cl, p->buf, p->size);
- /* remove fragment info from linked list */
+ /* fragment info for this packet no longer needed */
LIST_REMOVE(p, frag_infos);
free(p->buf);
free(p->bitmap);
@@ -778,18 +828,18 @@
break;
case DISPATCH_ECHO_REQUEST:
- printf("process_data_from_plugin(): ECHO_REQUEST\n");
- fprintf(stderr, "got echo request (plugin: %s)\n",
- pl->name);
+ debug("process_data_from_plugin(): ECHO_REQUEST\n");
+ debug("got echo request (plugin: %s)\n", pl->name);
+ /* pings are qualify for temporary connection status only */
+ *conn_flag = CONN_TEMP;
pl->conn_map(pl, *clid, CONN_TEMP);
/* generate a reply to the echo request */
- char *ndata;
- *conn_flag = CONN_TEMP;
-
*data = (u_int8_t)DISPATCH_ECHO_REPLY;
+ /* client only - prepend the client ID */
+ char *ndata;
if (!server) { /* client */
/*
* payload from the client should contain the
@@ -807,7 +857,7 @@
}
nwrite = pl->send(pl, 0, data, len, URGENT_DATA, &consumed);
- printf("sending reply, returned 0x%x\n", nwrite);
+ debug("sending reply, returned 0x%x\n", nwrite);
if (server) {
if (*clid != 0)
@@ -818,22 +868,26 @@
break;
case DISPATCH_ECHO_REPLY:
- printf("process_data_from_plugin(): ECHO_REPLY\n");
- fprintf(stderr, "got echo reply (plugin: %s)\n",
- pl->name);
+ debug("process_data_from_plugin(): ECHO_REPLY\n");
+ debug("got echo reply (plugin: %s)\n", pl->name);
+ /* pings are qualify for temporary connection status only */
pl->conn_map(pl, *clid, CONN_TEMP);
*conn_flag = CONN_TEMP;
/* update the ping counter */
cl->ping_counter = 0;
- //TODO
+ /*
+ * Receiving a ping reply indicates a working plugin.
+ * This is a good point to update the currently used
+ * plugin if none is set and to request a client ID if
+ * not associated already.
+ */
if (!server) { /* client */
- //TODO set_client_pl(0, pl);
if(cl->pl == NULL)
set_client_pl(0, pl);
-
+ /* request a client ID from the server */
if (myclid == 0)
send_id_request();
}
@@ -841,23 +895,22 @@
break;
case DISPATCH_ID_REQUEST:
- //long reqid;
- printf("process_data_from_plugin(): ID_REQUEST\n");
+ debug("process_data_from_plugin(): ID_REQUEST\n");
/* only relevant to the server */
if (!server) {
pl->conn_map(pl, *clid, CONN_DISCARD);
return;
}
- /* the client ID in a request has to be zero */
+ /* the client ID in a request has to be zero */
if (*clid != 0) {
pl->conn_map(pl, *clid, CONN_DISCARD);
return;
}
- //reqid = *(data+1);
- //TODO: assign new ID
- int i;
+ /* TODO reqid = *(data+1); */
+
+ /* assign a new client ID */
for (i = 1; i < MAXCLIENTS && clients[i].used != 0; i++);
if (i == MAXCLIENTS) {
*conn_flag = CONN_DISCARD;
@@ -865,6 +918,7 @@
return;
}
+ /* found an available ID, associate it with the client */
*clid = i;
*conn_flag = CONN_PERM;
pl->conn_map(pl, *clid, CONN_PERM);
@@ -873,46 +927,55 @@
tun_init(cl);
set_client_pl(cl, pl);
+ /* reply to the client offering the ID */
*(data) = DISPATCH_ID_OFFER;
*(data+1) = *clid;
nwrite = pl->send(pl, *clid, data, 2, URGENT_DATA, &consumed);
- fprintf(stderr, "got ID request (plugin: %s)\n",
- pl->name);
- printf("sending an offer, returned 0x%x\n", nwrite);
+ debug("got ID request (plugin: %s)\n", pl->name);
+ debug("sending an offer, returned 0x%x\n", nwrite);
break;
case DISPATCH_ID_OFFER:
- printf("process_data_from_plugin(): ID_OFFER\n");
+ debug("process_data_from_plugin(): ID_OFFER\n");
/* only relevant to the client */
if (server) {
pl->conn_map(pl, *clid, CONN_DISCARD);
return;
}
- if (myclid != 0) {
+ if (myclid != 0) { /* ID already assigned */
pl->conn_map(pl, *clid, CONN_DISCARD);
- return; /* ID already assigned */
+ return;
}
+ /* parse the reply for the client ID */
myclid = *(data+1);
cl->clid = myclid;
- printf("got an ID offer (%d)\n", myclid);
+ debug("got an ID offer (%d)\n", myclid);
+ /*
+ * We can start tunneling after a successful
+ * association with a server so initialize the tun
+ * device.
+ */
tun_init(clients);
break;
case DISPATCH_PLUGIN_DATA:
- printf("process_data_from_plugin(): PLUGIN_DATA\n");
+ /* plugin-to-plugin communication */
+ debug("process_data_from_plugin(): PLUGIN_DATA\n");
pl->conn_map(pl, *clid, CONN_TEMP);
+
+ /* pass the payload to the plugin */
pl->custom_receive(pl, 0, data + 1, len - 1);
break;
default:
- fprintf(stderr, "unknown dispatch 0x%X in data from plugin "
- "%s\n", dispatch, pl->name);
+ debug("unknown dispatch 0x%X in data from plugin "
+ "%s\n", dispatch, pl->name);
pl->conn_map(pl, *clid, CONN_DISCARD);
}
}
@@ -936,7 +999,7 @@
return SEND_ERROR;
}
- printf("process_data_from_tun: len: %d, pl->mtu: %d\n",
+ debug("process_data_from_tun: len: %d, pl->mtu: %d\n",
len, pl->mtu);
/* no need to add the fragmentation header */
if (len < pl->mtu || dispatch == DISPATCH_PLUGIN_DATA) {
@@ -959,10 +1022,15 @@
/* prepare the frag header */
cl->frag_hdr.dispatch = DISPATCH_FRAG;
cl->frag_hdr.id = cl->frag_id;
- cl->frag_id++;
cl->frag_hdr.size = len;
cl->frag_hdr.offset = 0;
+ /* increment the fragment ID */
+ if (cl->frag_id == 65535)
+ cl->frag_id = 0;
+ else
+ cl->frag_id++;
+
cl->frag_data_len = 0;
cl->frag_datap = cl->frag_data;
@@ -981,6 +1049,7 @@
}
}
+/* plugin can request sending data, used for plugin-to=plugin communication */
int
plugin_custom_send(struct plugin *pl, uint8_t clid,
char *data, int len)
@@ -1000,7 +1069,7 @@
if (server) {
while(cl->frag_data_len > sizeof(cl->frag_hdr) &&
nwrite == SEND_PKT_SENT) {
- printf("send_next_frag: sending frag "
+ debug("send_next_frag: sending frag "
"offset %d, send_len %d, frag_data_len %d\n",
cl->frag_hdr.offset,
min(cl->pl->mtu, cl->frag_data_len),
@@ -1021,7 +1090,7 @@
n = cl->frag_data_len;
nwrite = cl->pl->send(cl->pl, cl->clid,
cl->frag_datap, n, NORMAL_DATA, &consumed);
- printf("send_next_frag: consumed: %d\n", consumed);
+ debug("send_next_frag: consumed: %d\n", consumed);
switch (nwrite) {
case SEND_PKT_SENT:
case SEND_PKT_QUEUED:
@@ -1031,7 +1100,7 @@
cl->frag_data_len -= consumed;
break;
default:
- //plugin_report(current_pl, REPORT_ERROR_SEND);
+ /*plugin_report(current_pl, REPORT_ERROR_SEND);*/
return nwrite;
}
}
@@ -1039,10 +1108,11 @@
cl->frag_datap = NULL;
cl->frag_data_len = 0;
}
+
} else { /* client */
while(cl->frag_data_len > sizeof(cl->frag_hdr) + 1 &&
nwrite == SEND_PKT_SENT) {
- printf("send_next_frag: sending frag "
+ debug("send_next_frag: sending frag "
"offset %d, send_len %d, frag_data_len %d\n",
cl->frag_hdr.offset,
min(cl->pl->mtu, cl->frag_data_len),
@@ -1056,8 +1126,6 @@
sizeof(cl->frag_hdr));
/* send it */
- //TODO: maybe we should check how much data
- // was actually sent
if (cl->pl->mtu > 0)
n = min(cl->pl->mtu, cl->frag_data_len);
else
@@ -1073,7 +1141,7 @@
cl->frag_data_len -= consumed;
break;
default:
- //plugin_report(current_pl, REPORT_ERROR_SEND);
+ /*plugin_report(current_pl, REPORT_ERROR_SEND);*/
return nwrite;
}
}
@@ -1086,6 +1154,11 @@
return nwrite;
}
+/*
+ * entry function for plugins to report various things to the daemon,
+ * such as errors, availability to send mroe data (all queued data has
+ * been sent),...
+ */
void
plugin_report(struct plugin *pl, clientid_t clid, int err)
{
@@ -1105,15 +1178,18 @@
request_tun_data(cl);
return;
- //case REPORT_INIT_SUCCESS: /* initialization succeeded */
- //case REPORT_INIT_FAIL: /* initialization failed */
+ /* not used yet */
+/* case REPORT_INIT_SUCCESS: /\* initialization succeeded *\/ */
+/* case REPORT_INIT_FAIL: /\* initialization failed *\/ */
/* errors */
case REPORT_ERROR_PING: /* too many probes have failed */
case REPORT_ERROR_SEND: /* problem with sending */
case REPORT_ERROR_RECEIVE: /* problem with receiving */
pl->conn_close(pl, clid);
+
/* FALLTHROUGH */
+
case REPORT_BOOTSTRAP: /* no plugin initialized yet */
default:
if (server) {
@@ -1123,7 +1199,7 @@
} else { /* client */
if (pl) {
/* deinitialize the broken plugin */
- printf("plugin failed: %s\n", pl->name);
+ mylog("plugin failed: %s\n", pl->name);
pl->deinitialize(pl);
/* move to next plugin */
@@ -1133,22 +1209,22 @@
for (; pl; pl = TAILQ_NEXT(pl, plugins)) {
/* try to initialize plugin */
- fprintf(stderr, "initalizing plugin: %s...\n",
- pl->name);
+ debug("initalizing plugin: %s...\n",
+ pl->name);
if (((pl->initialize)(pl, server,
host, pl->name+4)) == 0) {
- fprintf(stderr, "initialized "
- "plugin %s\n", pl->name);
+ mylog("initialized plugin %s\n",
+ pl->name);
set_client_pl(cl, pl);
cl->ping_counter = 0;
send_echo_request(cl);
return;
} else {
- fprintf(stderr, "plugin %s failed to "
+ mylog("plugin %s failed to "
"initialize\n", pl->name);
}
}
- warnx("all plugins failed, giving up\n");
+ mylog("all plugins failed, giving up\n");
cleanup();
}
}
@@ -1158,27 +1234,17 @@
void
cleanup()
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list