From owner-p4-projects@FreeBSD.ORG Mon Aug 20 16:10:18 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 9D2D316A46D; Mon, 20 Aug 2007 16:10:18 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7154116A469 for ; Mon, 20 Aug 2007 16:10:18 +0000 (UTC) (envelope-from mharvan@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 5EEB413C4F4 for ; Mon, 20 Aug 2007 16:10:18 +0000 (UTC) (envelope-from mharvan@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l7KGAIve011542 for ; Mon, 20 Aug 2007 16:10:18 GMT (envelope-from mharvan@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l7KGAI1V011532 for perforce@freebsd.org; Mon, 20 Aug 2007 16:10:18 GMT (envelope-from mharvan@FreeBSD.org) Date: Mon, 20 Aug 2007 16:10:18 GMT Message-Id: <200708201610.l7KGAI1V011532@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mharvan@FreeBSD.org using -f From: Matus Harvan To: Perforce Change Reviews Cc: Subject: PERFORCE change 125418 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Aug 2007 16:10:19 -0000 http://perforce.freebsd.org/chv.cgi?CH=125418 Change 125418 by mharvan@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 #include #include + #include #include #include @@ -28,92 +48,91 @@ #include "tun_dev.h" #include "mtund.h" -// Linux only -//#include -//#include - /* 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) <<<