Use libevent for meta socket input/output buffering.
authorGuus Sliepen <guus@tinc-vpn.org>
Sat, 19 May 2007 22:23:02 +0000 (22:23 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Sat, 19 May 2007 22:23:02 +0000 (22:23 +0000)
12 files changed:
src/connection.c
src/connection.h
src/meta.c
src/net.c
src/net_socket.c
src/protocol.c
src/protocol.h
src/protocol_auth.c
src/protocol_edge.c
src/protocol_key.c
src/protocol_misc.c
src/protocol_subnet.c

index 408ef6c..21cb6aa 100644 (file)
@@ -56,19 +56,9 @@ void exit_connections(void) {
 }
 
 connection_t *new_connection(void) {
-       connection_t *c;
-
        cp();
 
-       c = xmalloc_and_zero(sizeof(connection_t));
-
-       if(!c)
-               return NULL;
-
-       gettimeofday(&c->start, NULL);
-       event_set(&c->ev, -1, 0, NULL, NULL);
-
-       return c;
+       return xmalloc_and_zero(sizeof(connection_t));
 }
 
 void free_connection(connection_t *c) {
@@ -95,7 +85,12 @@ void free_connection(connection_t *c) {
        if(c->hischallenge)
                free(c->hischallenge);
 
-       event_del(&c->ev);
+       if(c->buffer)
+               bufferevent_free(c->buffer);
+       
+       if(event_initialized(&c->inevent))
+               event_del(&c->inevent);
+
        free(c);
 }
 
@@ -121,9 +116,8 @@ void dump_connections(void) {
 
        for(node = connection_tree->head; node; node = node->next) {
                c = node->data;
-               logger(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x outbuf %d/%d/%d"),
-                          c->name, c->hostname, c->options, c->socket, c->status.value,
-                          c->outbufsize, c->outbufstart, c->outbuflen);
+               logger(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x"),
+                          c->name, c->hostname, c->options, c->socket, c->status.value);
        }
 
        logger(LOG_DEBUG, _("End of connections."));
index ec6c063..2426a22 100644 (file)
@@ -62,7 +62,6 @@ typedef struct connection_t {
        char *hostname;                         /* the hostname of its real ip */
        int protocol_version;           /* used protocol */
 
-       struct event ev;                        /* events on this metadata connection */
        int socket;                                     /* socket used for this connection */
        long int options;                       /* options for this connection */
        connection_status_t status;     /* status info */
@@ -91,18 +90,11 @@ typedef struct connection_t {
        char *mychallenge;                      /* challenge we received from him */
        char *hischallenge;                     /* challenge we sent to him */
 
-       char buffer[MAXBUFSIZE];        /* metadata input buffer */
-       int buflen;                                     /* bytes read into buffer */
-       int reqlen;                                     /* length of incoming request */
+       struct bufferevent *buffer;                     /* buffer events on this metadata connection */
+       struct event inevent;                           /* input event on this metadata connection */
        int tcplen;                                     /* length of incoming TCPpacket */
        int allow_request;                      /* defined if there's only one request possible */
 
-       char *outbuf;                           /* metadata output buffer */
-       int outbufstart;                        /* index of first meaningful byte in output buffer */
-       int outbuflen;                          /* number of meaningful bytes in output buffer */
-       int outbufsize;                         /* number of bytes allocated to output buffer */
-       struct event outev;                     /* events on this metadata connection */
-
        time_t last_ping_time;          /* last time we saw some activity from the other end or pinged them */
 
        splay_tree_t *config_tree;      /* Pointer to configuration tree belonging to him */
index 78b8160..7951411 100644 (file)
 bool send_meta(connection_t *c, const char *buffer, int length) {
        int outlen;
        int result;
-
        cp();
 
        ifdebug(META) logger(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s)"), length,
                           c->name, c->hostname);
 
-       if(!c->outbuflen) {
-               if(event_add(&c->outev, NULL) < 0) {
-                       logger(LOG_EMERG, _("event_add failed: %s"), strerror(errno));
-                       abort();
-               }
-       }
-
-       /* Find room in connection's buffer */
-       if(length + c->outbuflen > c->outbufsize) {
-               c->outbufsize = length + c->outbuflen;
-               c->outbuf = xrealloc(c->outbuf, c->outbufsize);
-       }
-
-       if(length + c->outbuflen + c->outbufstart > c->outbufsize) {
-               memmove(c->outbuf, c->outbuf + c->outbufstart, c->outbuflen);
-               c->outbufstart = 0;
-       }
-
        /* Add our data to buffer */
        if(c->status.encryptout) {
-               result = EVP_EncryptUpdate(c->outctx, (unsigned char *)c->outbuf + c->outbufstart + c->outbuflen,
-                               &outlen, (unsigned char *)buffer, length);
-               if(!result || outlen < length) {
+               char outbuf[length];
+
+               result = EVP_EncryptUpdate(c->outctx, (unsigned char *)outbuf, &outlen, (unsigned char *)buffer, length);
+               if(!result || outlen != length) {
                        logger(LOG_ERR, _("Error while encrypting metadata to %s (%s): %s"),
                                        c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
                        return false;
-               } else if(outlen > length) {
-                       logger(LOG_EMERG, _("Encrypted data too long! Heap corrupted!"));
-                       abort();
                }
-               c->outbuflen += outlen;
+               
+               logger(LOG_DEBUG, _("Encrypted write %p %p %p %d"), c, c->buffer, outbuf, length);
+               bufferevent_write(c->buffer, (void *)outbuf, length);
+               logger(LOG_DEBUG, _("Done."));
        } else {
-               memcpy(c->outbuf + c->outbufstart + c->outbuflen, buffer, length);
-               c->outbuflen += length;
+               logger(LOG_DEBUG, _("Unencrypted write %p %p %p %d"), c, c->buffer, buffer, length);
+               bufferevent_write(c->buffer, (void *)buffer, length);
+               logger(LOG_DEBUG, _("Done."));
        }
 
        return true;
 }
 
-void flush_meta(int fd, short events, void *data) {
-       connection_t *c = data;
-       int result;
-       
-       ifdebug(META) logger(LOG_DEBUG, _("Flushing %d bytes to %s (%s)"),
-                        c->outbuflen, c->name, c->hostname);
-
-       while(c->outbuflen) {
-               result = send(c->socket, c->outbuf + c->outbufstart, c->outbuflen, 0);
-               if(result <= 0) {
-                       if(!errno || errno == EPIPE) {
-                               ifdebug(CONNECTIONS) logger(LOG_NOTICE, _("Connection closed by %s (%s)"),
-                                                  c->name, c->hostname);
-                       } else if(errno == EINTR) {
-                               continue;
-#ifdef EWOULDBLOCK
-                       } else if(errno == EWOULDBLOCK) {
-                               ifdebug(CONNECTIONS) logger(LOG_DEBUG, _("Flushing %d bytes to %s (%s) would block"),
-                                               c->outbuflen, c->name, c->hostname);
-                               return;
-#endif
-                       } else {
-                               logger(LOG_ERR, _("Flushing meta data to %s (%s) failed: %s"), c->name,
-                                          c->hostname, strerror(errno));
-                       }
-
-                       terminate_connection(c, c->status.active);
-                       return;
-               }
-
-               c->outbufstart += result;
-               c->outbuflen -= result;
-       }
-
-       event_del(&c->outev);
-
-       c->outbufstart = 0; /* avoid unnecessary memmoves */
-}
-
 void broadcast_meta(connection_t *from, const char *buffer, int length) {
        splay_node_t *node;
        connection_t *c;
@@ -136,10 +80,9 @@ void broadcast_meta(connection_t *from, const char *buffer, int length) {
 }
 
 bool receive_meta(connection_t *c) {
-       int oldlen, i, result;
-       int inlen, outlen, reqlen;
-       bool decrypted = false;
+       int result, inlen, outlen;
        char inbuf[MAXBUFSIZE];
+       char *bufp = inbuf, *endp;
 
        cp();
 
@@ -152,87 +95,67 @@ bool receive_meta(connection_t *c) {
           - If not, keep stuff in buffer and exit.
         */
 
-       inlen = recv(c->socket, c->buffer + c->buflen, MAXBUFSIZE - c->buflen, 0);
+       inlen = recv(c->socket, inbuf, sizeof inbuf, 0);
 
        if(inlen <= 0) {
-               if(!inlen || !errno) {
-                       ifdebug(CONNECTIONS) logger(LOG_NOTICE, _("Connection closed by %s (%s)"),
-                                          c->name, c->hostname);
-               } else if(errno == EINTR)
-                       return true;
-               else
-                       logger(LOG_ERR, _("Metadata socket read error for %s (%s): %s"),
-                                  c->name, c->hostname, strerror(errno));
-
+               logger(LOG_ERR, _("Receive callback called for %s (%s) but no data to receive: %s"), c->name, c->hostname, strerror(errno));
                return false;
        }
 
-       oldlen = c->buflen;
-       c->buflen += inlen;
+       do {
+               if(!c->status.decryptin) {
+                       endp = memchr(bufp, '\n', inlen);
+                       if(endp)
+                               endp++;
+                       else
+                               endp = bufp + inlen;
+
+                       logger(LOG_DEBUG, _("Received unencrypted %ld of %d bytes"), endp - bufp, inlen);
 
-       while(inlen > 0) {
-               /* Decrypt */
+                       evbuffer_add(c->buffer->input, bufp, endp - bufp);
 
-               if(c->status.decryptin && !decrypted) {
-                       result = EVP_DecryptUpdate(c->inctx, (unsigned char *)inbuf, &outlen, (unsigned char *)c->buffer + oldlen, inlen);
+                       inlen -= endp - bufp;
+                       bufp = endp;
+               } else {
+                       logger(LOG_DEBUG, _("Received encrypted %d bytes"), inlen);
+                       evbuffer_expand(c->buffer->input, inlen);
+                       result = EVP_DecryptUpdate(c->inctx, (unsigned char *)c->buffer->input->buffer, &outlen, (unsigned char *)bufp, inlen);
                        if(!result || outlen != inlen) {
                                logger(LOG_ERR, _("Error while decrypting metadata from %s (%s): %s"),
                                                c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
                                return false;
                        }
-                       memcpy(c->buffer + oldlen, inbuf, inlen);
-                       decrypted = true;
+                       c->buffer->input->off += inlen;
+
+                       inlen = 0;
                }
 
-               /* Are we receiving a TCPpacket? */
+               while(c->buffer->input->off) {
+                       /* Are we receiving a TCPpacket? */
+
+                       if(c->tcplen) {
+                               if(c->tcplen <= c->buffer->input->off) {
+                                       receive_tcppacket(c, (char *)c->buffer->input->buffer, c->tcplen);
+                                       evbuffer_drain(c->buffer->input, c->tcplen);
+                                       c->tcplen = 0;
+                                       continue;
+                               } else {
+                                       break;
+                               }
+                       }
 
-               if(c->tcplen) {
-                       if(c->tcplen <= c->buflen) {
-                               receive_tcppacket(c, c->buffer, c->tcplen);
+                       /* Otherwise we are waiting for a request */
 
-                               c->buflen -= c->tcplen;
-                               inlen -= c->tcplen - oldlen;
-                               memmove(c->buffer, c->buffer + c->tcplen, c->buflen);
-                               oldlen = 0;
-                               c->tcplen = 0;
+                       char *request = evbuffer_readline(c->buffer->input);
+                       if(request) {
+                               receive_request(c, request);
+                               free(request);
                                continue;
                        } else {
                                break;
                        }
                }
-
-               /* Otherwise we are waiting for a request */
-
-               reqlen = 0;
-
-               for(i = oldlen; i < c->buflen; i++) {
-                       if(c->buffer[i] == '\n') {
-                               c->buffer[i] = '\0';    /* replace end-of-line by end-of-string so we can use sscanf */
-                               reqlen = i + 1;
-                               break;
-                       }
-               }
-
-               if(reqlen) {
-                       c->reqlen = reqlen;
-                       if(!receive_request(c))
-                               return false;
-
-                       c->buflen -= reqlen;
-                       inlen -= reqlen - oldlen;
-                       memmove(c->buffer, c->buffer + reqlen, c->buflen);
-                       oldlen = 0;
-                       continue;
-               } else {
-                       break;
-               }
-       }
-
-       if(c->buflen >= MAXBUFSIZE) {
-               logger(LOG_ERR, _("Metadata read buffer overflow for %s (%s)"),
-                          c->name, c->hostname);
-               return false;
-       }
+       } while(inlen);
 
        c->last_ping_time = time(NULL);
 
index 2c7cc55..1b5bb16 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -121,8 +121,6 @@ void terminate_connection(connection_t *c, bool report) {
        if(c->socket)
                closesocket(c->socket);
 
-       event_del(&c->ev);
-
        if(c->edge) {
                if(report && !tunnelserver)
                        send_del_edge(broadcast, c->edge);
@@ -146,12 +144,6 @@ void terminate_connection(connection_t *c, bool report) {
                }
        }
 
-       free(c->outbuf);
-       c->outbuf = NULL;
-       c->outbuflen = 0;
-       c->outbufsize = 0;
-       c->outbufstart = 0;
-
        /* Check if this was our outgoing connection */
 
        if(c->outgoing)
index 7ef8193..1686c60 100644 (file)
@@ -349,6 +349,16 @@ begin:
        return;
 }
 
+void handle_meta_write(struct bufferevent *event, void *data) {
+       logger(LOG_EMERG, _("handle_meta_write() called"));
+}
+
+void handle_meta_connection_error(struct bufferevent *event, short what, void *data) {
+       connection_t *c = data;
+       logger(LOG_EMERG, _("handle_meta_connection_error() called: %d: %s"), what, strerror(errno));
+       terminate_connection(c, c->status.active);
+}
+
 void setup_outgoing_connection(outgoing_t *outgoing) {
        connection_t *c;
        node_t *n;
@@ -392,12 +402,14 @@ void setup_outgoing_connection(outgoing_t *outgoing) {
 
        do_outgoing_connection(c);
 
-       event_set(&c->ev, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
-       event_set(&c->outev, c->socket, EV_WRITE | EV_PERSIST, flush_meta, c);
-       if(event_add(&c->ev, NULL) < 0) {
-               logger(LOG_EMERG, _("event_add failed: %s"), strerror(errno));
+       event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
+       event_add(&c->inevent, NULL);
+       c->buffer = bufferevent_new(c->socket, handle_meta_connection_data, handle_meta_write, handle_meta_connection_error, c);
+       if(!c->buffer) {
+               logger(LOG_EMERG, _("bufferevent_new() failed: %s"), strerror(errno));
                abort();
        }
+       bufferevent_disable(c->buffer, EV_READ);
 }
 
 /*
@@ -435,13 +447,14 @@ void handle_new_meta_connection(int sock, short events, void *data) {
 
        ifdebug(CONNECTIONS) logger(LOG_NOTICE, _("Connection from %s"), c->hostname);
 
-       event_set(&c->ev, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
-       event_set(&c->outev, c->socket, EV_WRITE | EV_PERSIST, flush_meta, c);
-       if(event_add(&c->ev, NULL) < 0) {
-               logger(LOG_ERR, _("event_add failed: %s"), strerror(errno));
-               connection_del(c);
-               return;
+       event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
+       event_add(&c->inevent, NULL);
+       c->buffer = bufferevent_new(c->socket, NULL, handle_meta_write, handle_meta_connection_error, c);
+       if(!c->buffer) {
+               logger(LOG_EMERG, _("bufferevent_new() failed: %s"), strerror(errno));
+               abort();
        }
+       bufferevent_disable(c->buffer, EV_READ);
                
        configure_tcp(c);
 
index c3fe6f3..cae3a0f 100644 (file)
@@ -34,7 +34,7 @@ bool tunnelserver = false;
 
 /* Jumptable for the request handlers */
 
-static bool (*request_handlers[])(connection_t *) = {
+static bool (*request_handlers[])(connection_t *, char *) = {
                id_h, metakey_h, challenge_h, chal_reply_h, ack_h,
                status_h, error_h, termreq_h,
                ping_h, pong_h,
@@ -68,8 +68,8 @@ bool check_id(const char *id) {
 
 bool send_request(connection_t *c, const char *format, ...) {
        va_list args;
-       char buffer[MAXBUFSIZE];
-       int len, request;
+       char request[MAXBUFSIZE];
+       int len;
 
        cp();
 
@@ -78,7 +78,7 @@ bool send_request(connection_t *c, const char *format, ...) {
           input buffer anyway */
 
        va_start(args, format);
-       len = vsnprintf(buffer, MAXBUFSIZE, format, args);
+       len = vsnprintf(request, MAXBUFSIZE, format, args);
        va_end(args);
 
        if(len < 0 || len > MAXBUFSIZE - 1) {
@@ -88,55 +88,50 @@ bool send_request(connection_t *c, const char *format, ...) {
        }
 
        ifdebug(PROTOCOL) {
-               sscanf(buffer, "%d", &request);
                ifdebug(META)
                        logger(LOG_DEBUG, _("Sending %s to %s (%s): %s"),
-                                  request_name[request], c->name, c->hostname, buffer);
+                                  request_name[atoi(request)], c->name, c->hostname, request);
                else
-                       logger(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[request],
+                       logger(LOG_DEBUG, _("Sending %s to %s (%s)"), request_name[atoi(request)],
                                   c->name, c->hostname);
        }
 
-       buffer[len++] = '\n';
+       request[len++] = '\n';
 
        if(c == broadcast) {
-               broadcast_meta(NULL, buffer, len);
+               broadcast_meta(NULL, request, len);
                return true;
        } else
-               return send_meta(c, buffer, len);
+               return send_meta(c, request, len);
 }
 
-void forward_request(connection_t *from) {
-       int request;
-
+void forward_request(connection_t *from, char *request) {
        cp();
 
        ifdebug(PROTOCOL) {
-               sscanf(from->buffer, "%d", &request);
                ifdebug(META)
                        logger(LOG_DEBUG, _("Forwarding %s from %s (%s): %s"),
-                                  request_name[request], from->name, from->hostname,
-                                  from->buffer);
+                                  request_name[atoi(request)], from->name, from->hostname, request);
                else
                        logger(LOG_DEBUG, _("Forwarding %s from %s (%s)"),
-                                  request_name[request], from->name, from->hostname);
+                                  request_name[atoi(request)], from->name, from->hostname);
        }
 
-       from->buffer[from->reqlen - 1] = '\n';
-
-       broadcast_meta(from, from->buffer, from->reqlen);
+       int len = strlen(request);
+       request[len] = '\n';
+       broadcast_meta(from, request, len);
 }
 
-bool receive_request(connection_t *c) {
-       int request;
+bool receive_request(connection_t *c, char *request) {
+       int reqno = atoi(request);
 
        cp();
 
-       if(sscanf(c->buffer, "%d", &request) == 1) {
-               if((request < 0) || (request >= LAST) || !request_handlers[request]) {
+       if(reqno || *request == '0') {
+               if((reqno < 0) || (reqno >= LAST) || !request_handlers[reqno]) {
                        ifdebug(META)
                                logger(LOG_DEBUG, _("Unknown request from %s (%s): %s"),
-                                          c->name, c->hostname, c->buffer);
+                                          c->name, c->hostname, request);
                        else
                                logger(LOG_ERR, _("Unknown request from %s (%s)"),
                                           c->name, c->hostname);
@@ -146,25 +141,24 @@ bool receive_request(connection_t *c) {
                        ifdebug(PROTOCOL) {
                                ifdebug(META)
                                        logger(LOG_DEBUG, _("Got %s from %s (%s): %s"),
-                                                  request_name[request], c->name, c->hostname,
-                                                  c->buffer);
+                                                  request_name[reqno], c->name, c->hostname, request);
                                else
                                        logger(LOG_DEBUG, _("Got %s from %s (%s)"),
-                                                  request_name[request], c->name, c->hostname);
+                                                  request_name[reqno], c->name, c->hostname);
                        }
                }
 
-               if((c->allow_request != ALL) && (c->allow_request != request)) {
+               if((c->allow_request != ALL) && (c->allow_request != reqno)) {
                        logger(LOG_ERR, _("Unauthorized request from %s (%s)"), c->name,
                                   c->hostname);
                        return false;
                }
 
-               if(!request_handlers[request](c)) {
+               if(!request_handlers[reqno](c, request)) {
                        /* Something went wrong. Probably scriptkiddies. Terminate. */
 
                        logger(LOG_ERR, _("Error while processing %s from %s (%s)"),
-                                  request_name[request], c->name, c->hostname);
+                                  request_name[reqno], c->name, c->hostname);
                        return false;
                }
        } else {
index ab4ed78..cecc580 100644 (file)
@@ -72,8 +72,8 @@ extern bool tunnelserver;
 /* Basic functions */
 
 extern bool send_request(struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 2, 3)));
-extern void forward_request(struct connection_t *);
-extern bool receive_request(struct connection_t *);
+extern void forward_request(struct connection_t *, char *);
+extern bool receive_request(struct connection_t *, char *);
 extern bool check_id(const char *);
 
 extern void init_requests(void);
@@ -103,23 +103,23 @@ extern bool send_tcppacket(struct connection_t *, struct vpn_packet_t *);
 
 /* Request handlers  */
 
-extern bool id_h(struct connection_t *);
-extern bool metakey_h(struct connection_t *);
-extern bool challenge_h(struct connection_t *);
-extern bool chal_reply_h(struct connection_t *);
-extern bool ack_h(struct connection_t *);
-extern bool status_h(struct connection_t *);
-extern bool error_h(struct connection_t *);
-extern bool termreq_h(struct connection_t *);
-extern bool ping_h(struct connection_t *);
-extern bool pong_h(struct connection_t *);
-extern bool add_subnet_h(struct connection_t *);
-extern bool del_subnet_h(struct connection_t *);
-extern bool add_edge_h(struct connection_t *);
-extern bool del_edge_h(struct connection_t *);
-extern bool key_changed_h(struct connection_t *);
-extern bool req_key_h(struct connection_t *);
-extern bool ans_key_h(struct connection_t *);
-extern bool tcppacket_h(struct connection_t *);
+extern bool id_h(struct connection_t *, char *);
+extern bool metakey_h(struct connection_t *, char *);
+extern bool challenge_h(struct connection_t *, char *);
+extern bool chal_reply_h(struct connection_t *, char *);
+extern bool ack_h(struct connection_t *, char *);
+extern bool status_h(struct connection_t *, char *);
+extern bool error_h(struct connection_t *, char *);
+extern bool termreq_h(struct connection_t *, char *);
+extern bool ping_h(struct connection_t *, char *);
+extern bool pong_h(struct connection_t *, char *);
+extern bool add_subnet_h(struct connection_t *, char *);
+extern bool del_subnet_h(struct connection_t *, char *);
+extern bool add_edge_h(struct connection_t *, char *);
+extern bool del_edge_h(struct connection_t *, char *);
+extern bool key_changed_h(struct connection_t *, char *);
+extern bool req_key_h(struct connection_t *, char *);
+extern bool ans_key_h(struct connection_t *, char *);
+extern bool tcppacket_h(struct connection_t *, char *);
 
 #endif                                                 /* __TINC_PROTOCOL_H__ */
index 18fbb64..31dae67 100644 (file)
@@ -47,12 +47,12 @@ bool send_id(connection_t *c) {
                                                myself->connection->protocol_version);
 }
 
-bool id_h(connection_t *c) {
+bool id_h(connection_t *c, char *request) {
        char name[MAX_STRING_SIZE];
 
        cp();
 
-       if(sscanf(c->buffer, "%*d " MAX_STRING " %d", name, &c->protocol_version) != 2) {
+       if(sscanf(request, "%*d " MAX_STRING " %d", name, &c->protocol_version) != 2) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ID", c->name,
                           c->hostname);
                return false;
@@ -199,14 +199,14 @@ bool send_metakey(connection_t *c) {
        return x;
 }
 
-bool metakey_h(connection_t *c) {
+bool metakey_h(connection_t *c, char *request) {
        char buffer[MAX_STRING_SIZE];
        int cipher, digest, maclength, compression;
        int len;
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, buffer) != 5) {
+       if(sscanf(request, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, buffer) != 5) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "METAKEY", c->name,
                           c->hostname);
                return false;
@@ -329,13 +329,13 @@ bool send_challenge(connection_t *c) {
        return send_request(c, "%d %s", CHALLENGE, buffer);
 }
 
-bool challenge_h(connection_t *c) {
+bool challenge_h(connection_t *c, char *request) {
        char buffer[MAX_STRING_SIZE];
        int len;
 
        cp();
 
-       if(sscanf(c->buffer, "%*d " MAX_STRING, buffer) != 1) {
+       if(sscanf(request, "%*d " MAX_STRING, buffer) != 1) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "CHALLENGE", c->name,
                           c->hostname);
                return false;
@@ -393,14 +393,14 @@ bool send_chal_reply(connection_t *c) {
        return send_request(c, "%d %s", CHAL_REPLY, hash);
 }
 
-bool chal_reply_h(connection_t *c) {
+bool chal_reply_h(connection_t *c, char *request) {
        char hishash[MAX_STRING_SIZE];
        char myhash[EVP_MAX_MD_SIZE];
        EVP_MD_CTX ctx;
 
        cp();
 
-       if(sscanf(c->buffer, "%*d " MAX_STRING, hishash) != 1) {
+       if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "CHAL_REPLY", c->name,
                           c->hostname);
                return false;
@@ -514,7 +514,7 @@ static void send_everything(connection_t *c) {
        }
 }
 
-bool ack_h(connection_t *c) {
+bool ack_h(connection_t *c, char *request) {
        char hisport[MAX_STRING_SIZE];
        char *hisaddress, *dummy;
        int weight, mtu;
@@ -523,7 +523,7 @@ bool ack_h(connection_t *c) {
 
        cp();
 
-       if(sscanf(c->buffer, "%*d " MAX_STRING " %d %lx", hisport, &weight, &options) != 3) {
+       if(sscanf(request, "%*d " MAX_STRING " %d %lx", hisport, &weight, &options) != 3) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ACK", c->name,
                           c->hostname);
                return false;
index 8f8d092..f515eee 100644 (file)
@@ -53,7 +53,7 @@ bool send_add_edge(connection_t *c, const edge_t *e) {
        return x;
 }
 
-bool add_edge_h(connection_t *c) {
+bool add_edge_h(connection_t *c, char *request) {
        edge_t *e;
        node_t *from, *to;
        char from_name[MAX_STRING_SIZE];
@@ -66,7 +66,7 @@ bool add_edge_h(connection_t *c) {
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d",
+       if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d",
                          from_name, to_name, to_address, to_port, &options, &weight) != 6) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_EDGE", c->name,
                           c->hostname);
@@ -87,7 +87,7 @@ bool add_edge_h(connection_t *c) {
                return false;
        }
 
-       if(seen_request(c->buffer))
+       if(seen_request(request))
                return true;
 
        /* Lookup nodes */
@@ -156,7 +156,7 @@ bool add_edge_h(connection_t *c) {
        /* Tell the rest about the new edge */
 
        if(!tunnelserver)
-               forward_request(c);
+               forward_request(c, request);
 
        /* Run MST before or after we tell the rest? */
 
@@ -172,7 +172,7 @@ bool send_del_edge(connection_t *c, const edge_t *e) {
                                                e->from->name, e->to->name);
 }
 
-bool del_edge_h(connection_t *c) {
+bool del_edge_h(connection_t *c, char *request) {
        edge_t *e;
        char from_name[MAX_STRING_SIZE];
        char to_name[MAX_STRING_SIZE];
@@ -180,7 +180,7 @@ bool del_edge_h(connection_t *c) {
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) {
+       if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING, from_name, to_name) != 2) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_EDGE", c->name,
                           c->hostname);
                return false;
@@ -200,7 +200,7 @@ bool del_edge_h(connection_t *c) {
                return false;
        }
 
-       if(seen_request(c->buffer))
+       if(seen_request(request))
                return true;
 
        /* Lookup nodes */
@@ -244,7 +244,7 @@ bool del_edge_h(connection_t *c) {
        /* Tell the rest about the deleted edge */
 
        if(!tunnelserver)
-               forward_request(c);
+               forward_request(c, request);
 
        /* Delete the edge */
 
index 9ab1743..05bc97b 100644 (file)
@@ -50,19 +50,19 @@ bool send_key_changed(connection_t *c, const node_t *n) {
        return send_request(c, "%d %lx %s", KEY_CHANGED, random(), n->name);
 }
 
-bool key_changed_h(connection_t *c) {
+bool key_changed_h(connection_t *c, char *request) {
        char name[MAX_STRING_SIZE];
        node_t *n;
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %*x " MAX_STRING, name) != 1) {
+       if(sscanf(request, "%*d %*x " MAX_STRING, name) != 1) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "KEY_CHANGED",
                           c->name, c->hostname);
                return false;
        }
 
-       if(seen_request(c->buffer))
+       if(seen_request(request))
                return true;
 
        n = lookup_node(name);
@@ -79,7 +79,7 @@ bool key_changed_h(connection_t *c) {
        /* Tell the others */
 
        if(!tunnelserver)
-               forward_request(c);
+               forward_request(c, request);
 
        return true;
 }
@@ -90,14 +90,14 @@ bool send_req_key(connection_t *c, const node_t *from, const node_t *to) {
        return send_request(c, "%d %s %s", REQ_KEY, from->name, to->name);
 }
 
-bool req_key_h(connection_t *c) {
+bool req_key_h(connection_t *c, char *request) {
        char from_name[MAX_STRING_SIZE];
        char to_name[MAX_STRING_SIZE];
        node_t *from, *to;
 
        cp();
 
-       if(sscanf(c->buffer, "%*d " MAX_STRING " " MAX_STRING, from_name, to_name) != 2) {
+       if(sscanf(request, "%*d " MAX_STRING " " MAX_STRING, from_name, to_name) != 2) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "REQ_KEY", c->name,
                           c->hostname);
                return false;
@@ -152,7 +152,7 @@ bool send_ans_key(connection_t *c, const node_t *from, const node_t *to) {
                                                from->compression);
 }
 
-bool ans_key_h(connection_t *c) {
+bool ans_key_h(connection_t *c, char *request) {
        char from_name[MAX_STRING_SIZE];
        char to_name[MAX_STRING_SIZE];
        char key[MAX_STRING_SIZE];
@@ -161,7 +161,7 @@ bool ans_key_h(connection_t *c) {
 
        cp();
 
-       if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d",
+       if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d",
                from_name, to_name, key, &cipher, &digest, &maclength,
                &compression) != 7) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ANS_KEY", c->name,
@@ -191,7 +191,7 @@ bool ans_key_h(connection_t *c) {
                if(tunnelserver)
                        return false;
 
-               return send_request(to->nexthop->connection, "%s", c->buffer);
+               return send_request(to->nexthop->connection, "%s", request);
        }
 
        /* Update our copy of the origin's packet key */
index 1e0bc50..95a240e 100644 (file)
@@ -45,14 +45,14 @@ bool send_status(connection_t *c, int statusno, const char *statusstring)
        return send_request(c, "%d %d %s", STATUS, statusno, statusstring);
 }
 
-bool status_h(connection_t *c)
+bool status_h(connection_t *c, char *request)
 {
        int statusno;
        char statusstring[MAX_STRING_SIZE];
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) {
+       if(sscanf(request, "%*d %d " MAX_STRING, &statusno, statusstring) != 2) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "STATUS",
                           c->name, c->hostname);
                return false;
@@ -74,14 +74,14 @@ bool send_error(connection_t *c, int err, const char *errstring)
        return send_request(c, "%d %d %s", ERROR, err, errstring);
 }
 
-bool error_h(connection_t *c)
+bool error_h(connection_t *c, char *request)
 {
        int err;
        char errorstring[MAX_STRING_SIZE];
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %d " MAX_STRING, &err, errorstring) != 2) {
+       if(sscanf(request, "%*d %d " MAX_STRING, &err, errorstring) != 2) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ERROR",
                           c->name, c->hostname);
                return false;
@@ -100,7 +100,7 @@ bool send_termreq(connection_t *c)
        return send_request(c, "%d", TERMREQ);
 }
 
-bool termreq_h(connection_t *c)
+bool termreq_h(connection_t *c, char *request)
 {
        cp();
 
@@ -117,7 +117,7 @@ bool send_ping(connection_t *c)
        return send_request(c, "%d", PING);
 }
 
-bool ping_h(connection_t *c)
+bool ping_h(connection_t *c, char *request)
 {
        cp();
 
@@ -131,7 +131,7 @@ bool send_pong(connection_t *c)
        return send_request(c, "%d", PONG);
 }
 
-bool pong_h(connection_t *c)
+bool pong_h(connection_t *c, char *request)
 {
        cp();
 
@@ -153,7 +153,7 @@ bool send_tcppacket(connection_t *c, vpn_packet_t *packet)
 
        /* If there already is a lot of data in the outbuf buffer, discard this packet. */
 
-       if(c->outbuflen > maxoutbufsize)
+       if(c->buffer->output->off > maxoutbufsize)
                return true;
 
        if(!send_request(c, "%d %hd", PACKET, packet->len))
@@ -162,13 +162,13 @@ bool send_tcppacket(connection_t *c, vpn_packet_t *packet)
        return send_meta(c, (char *)packet->data, packet->len);
 }
 
-bool tcppacket_h(connection_t *c)
+bool tcppacket_h(connection_t *c, char *request)
 {
        short int len;
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %hd", &len) != 1) {
+       if(sscanf(request, "%*d %hd", &len) != 1) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "PACKET", c->name,
                           c->hostname);
                return false;
index e3600bd..b1d71ab 100644 (file)
@@ -45,7 +45,7 @@ bool send_add_subnet(connection_t *c, const subnet_t *subnet)
        return send_request(c, "%d %lx %s %s", ADD_SUBNET, random(), subnet->owner->name, netstr);
 }
 
-bool add_subnet_h(connection_t *c)
+bool add_subnet_h(connection_t *c, char *request)
 {
        char subnetstr[MAX_STRING_SIZE];
        char name[MAX_STRING_SIZE];
@@ -54,7 +54,7 @@ bool add_subnet_h(connection_t *c)
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
+       if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_SUBNET", c->name,
                           c->hostname);
                return false;
@@ -76,7 +76,7 @@ bool add_subnet_h(connection_t *c)
                return false;
        }
 
-       if(seen_request(c->buffer))
+       if(seen_request(request))
                return true;
 
        /* Check if the owner of the new subnet is in the connection list */
@@ -140,7 +140,7 @@ bool add_subnet_h(connection_t *c)
        /* Tell the rest */
 
        if(!tunnelserver)
-               forward_request(c);
+               forward_request(c, request);
 
        return true;
 }
@@ -157,7 +157,7 @@ bool send_del_subnet(connection_t *c, const subnet_t *s)
        return send_request(c, "%d %lx %s %s", DEL_SUBNET, random(), s->owner->name, netstr);
 }
 
-bool del_subnet_h(connection_t *c)
+bool del_subnet_h(connection_t *c, char *request)
 {
        char subnetstr[MAX_STRING_SIZE];
        char name[MAX_STRING_SIZE];
@@ -166,7 +166,7 @@ bool del_subnet_h(connection_t *c)
 
        cp();
 
-       if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
+       if(sscanf(request, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
                logger(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_SUBNET", c->name,
                           c->hostname);
                return false;
@@ -201,7 +201,7 @@ bool del_subnet_h(connection_t *c)
                return false;
        }
 
-       if(seen_request(c->buffer))
+       if(seen_request(request))
                return true;
 
        /* If everything is correct, delete the subnet from the list of the owner */
@@ -228,7 +228,7 @@ bool del_subnet_h(connection_t *c)
        /* Tell the rest */
 
        if(!tunnelserver)
-               forward_request(c);
+               forward_request(c, request);
 
        /* Finally, delete it. */