Use libevent for meta socket input/output buffering.

This commit is contained in:
Guus Sliepen 2007-05-19 22:23:02 +00:00
parent 59108e4e4f
commit fbf305c09d
12 changed files with 177 additions and 269 deletions

View file

@ -56,19 +56,9 @@ void exit_connections(void) {
} }
connection_t *new_connection(void) { connection_t *new_connection(void) {
connection_t *c;
cp(); cp();
c = xmalloc_and_zero(sizeof(connection_t)); return xmalloc_and_zero(sizeof(connection_t));
if(!c)
return NULL;
gettimeofday(&c->start, NULL);
event_set(&c->ev, -1, 0, NULL, NULL);
return c;
} }
void free_connection(connection_t *c) { void free_connection(connection_t *c) {
@ -95,7 +85,12 @@ void free_connection(connection_t *c) {
if(c->hischallenge) if(c->hischallenge)
free(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); free(c);
} }
@ -121,9 +116,8 @@ void dump_connections(void) {
for(node = connection_tree->head; node; node = node->next) { for(node = connection_tree->head; node; node = node->next) {
c = node->data; c = node->data;
logger(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x outbuf %d/%d/%d"), logger(LOG_DEBUG, _(" %s at %s options %lx socket %d status %04x"),
c->name, c->hostname, c->options, c->socket, c->status.value, c->name, c->hostname, c->options, c->socket, c->status.value);
c->outbufsize, c->outbufstart, c->outbuflen);
} }
logger(LOG_DEBUG, _("End of connections.")); logger(LOG_DEBUG, _("End of connections."));

View file

@ -62,7 +62,6 @@ typedef struct connection_t {
char *hostname; /* the hostname of its real ip */ char *hostname; /* the hostname of its real ip */
int protocol_version; /* used protocol */ int protocol_version; /* used protocol */
struct event ev; /* events on this metadata connection */
int socket; /* socket used for this connection */ int socket; /* socket used for this connection */
long int options; /* options for this connection */ long int options; /* options for this connection */
connection_status_t status; /* status info */ connection_status_t status; /* status info */
@ -91,18 +90,11 @@ typedef struct connection_t {
char *mychallenge; /* challenge we received from him */ char *mychallenge; /* challenge we received from him */
char *hischallenge; /* challenge we sent to him */ char *hischallenge; /* challenge we sent to him */
char buffer[MAXBUFSIZE]; /* metadata input buffer */ struct bufferevent *buffer; /* buffer events on this metadata connection */
int buflen; /* bytes read into buffer */ struct event inevent; /* input event on this metadata connection */
int reqlen; /* length of incoming request */
int tcplen; /* length of incoming TCPpacket */ int tcplen; /* length of incoming TCPpacket */
int allow_request; /* defined if there's only one request possible */ 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 */ 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 */ splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */

View file

@ -37,90 +37,34 @@
bool send_meta(connection_t *c, const char *buffer, int length) { bool send_meta(connection_t *c, const char *buffer, int length) {
int outlen; int outlen;
int result; int result;
cp(); cp();
ifdebug(META) logger(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s)"), length, ifdebug(META) logger(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s)"), length,
c->name, c->hostname); 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 */ /* Add our data to buffer */
if(c->status.encryptout) { if(c->status.encryptout) {
result = EVP_EncryptUpdate(c->outctx, (unsigned char *)c->outbuf + c->outbufstart + c->outbuflen, char outbuf[length];
&outlen, (unsigned char *)buffer, length);
if(!result || outlen < 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"), logger(LOG_ERR, _("Error while encrypting metadata to %s (%s): %s"),
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false; 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 { } else {
memcpy(c->outbuf + c->outbufstart + c->outbuflen, buffer, length); logger(LOG_DEBUG, _("Unencrypted write %p %p %p %d"), c, c->buffer, buffer, length);
c->outbuflen += length; bufferevent_write(c->buffer, (void *)buffer, length);
logger(LOG_DEBUG, _("Done."));
} }
return true; 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) { void broadcast_meta(connection_t *from, const char *buffer, int length) {
splay_node_t *node; splay_node_t *node;
connection_t *c; connection_t *c;
@ -136,10 +80,9 @@ void broadcast_meta(connection_t *from, const char *buffer, int length) {
} }
bool receive_meta(connection_t *c) { bool receive_meta(connection_t *c) {
int oldlen, i, result; int result, inlen, outlen;
int inlen, outlen, reqlen;
bool decrypted = false;
char inbuf[MAXBUFSIZE]; char inbuf[MAXBUFSIZE];
char *bufp = inbuf, *endp;
cp(); cp();
@ -152,87 +95,67 @@ bool receive_meta(connection_t *c) {
- If not, keep stuff in buffer and exit. - 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 <= 0) {
if(!inlen || !errno) { logger(LOG_ERR, _("Receive callback called for %s (%s) but no data to receive: %s"), c->name, c->hostname, strerror(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));
return false; return false;
} }
oldlen = c->buflen; do {
c->buflen += inlen; if(!c->status.decryptin) {
endp = memchr(bufp, '\n', inlen);
if(endp)
endp++;
else
endp = bufp + inlen;
while(inlen > 0) { logger(LOG_DEBUG, _("Received unencrypted %ld of %d bytes"), endp - bufp, inlen);
/* Decrypt */
if(c->status.decryptin && !decrypted) { evbuffer_add(c->buffer->input, bufp, endp - bufp);
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) { if(!result || outlen != inlen) {
logger(LOG_ERR, _("Error while decrypting metadata from %s (%s): %s"), logger(LOG_ERR, _("Error while decrypting metadata from %s (%s): %s"),
c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL)); c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
return false; return false;
} }
memcpy(c->buffer + oldlen, inbuf, inlen); c->buffer->input->off += inlen;
decrypted = true;
inlen = 0;
} }
/* Are we receiving a TCPpacket? */ while(c->buffer->input->off) {
/* Are we receiving a TCPpacket? */
if(c->tcplen) { if(c->tcplen) {
if(c->tcplen <= c->buflen) { if(c->tcplen <= c->buffer->input->off) {
receive_tcppacket(c, c->buffer, c->tcplen); receive_tcppacket(c, (char *)c->buffer->input->buffer, c->tcplen);
evbuffer_drain(c->buffer->input, c->tcplen);
c->tcplen = 0;
continue;
} else {
break;
}
}
c->buflen -= c->tcplen; /* Otherwise we are waiting for a request */
inlen -= c->tcplen - oldlen;
memmove(c->buffer, c->buffer + c->tcplen, c->buflen); char *request = evbuffer_readline(c->buffer->input);
oldlen = 0; if(request) {
c->tcplen = 0; receive_request(c, request);
free(request);
continue; continue;
} else { } else {
break; break;
} }
} }
} while(inlen);
/* 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;
}
c->last_ping_time = time(NULL); c->last_ping_time = time(NULL);

View file

@ -121,8 +121,6 @@ void terminate_connection(connection_t *c, bool report) {
if(c->socket) if(c->socket)
closesocket(c->socket); closesocket(c->socket);
event_del(&c->ev);
if(c->edge) { if(c->edge) {
if(report && !tunnelserver) if(report && !tunnelserver)
send_del_edge(broadcast, c->edge); 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 */ /* Check if this was our outgoing connection */
if(c->outgoing) if(c->outgoing)

View file

@ -349,6 +349,16 @@ begin:
return; 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) { void setup_outgoing_connection(outgoing_t *outgoing) {
connection_t *c; connection_t *c;
node_t *n; node_t *n;
@ -392,12 +402,14 @@ void setup_outgoing_connection(outgoing_t *outgoing) {
do_outgoing_connection(c); do_outgoing_connection(c);
event_set(&c->ev, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c); event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
event_set(&c->outev, c->socket, EV_WRITE | EV_PERSIST, flush_meta, c); event_add(&c->inevent, NULL);
if(event_add(&c->ev, NULL) < 0) { c->buffer = bufferevent_new(c->socket, handle_meta_connection_data, handle_meta_write, handle_meta_connection_error, c);
logger(LOG_EMERG, _("event_add failed: %s"), strerror(errno)); if(!c->buffer) {
logger(LOG_EMERG, _("bufferevent_new() failed: %s"), strerror(errno));
abort(); 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); 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->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
event_set(&c->outev, c->socket, EV_WRITE | EV_PERSIST, flush_meta, c); event_add(&c->inevent, NULL);
if(event_add(&c->ev, NULL) < 0) { c->buffer = bufferevent_new(c->socket, NULL, handle_meta_write, handle_meta_connection_error, c);
logger(LOG_ERR, _("event_add failed: %s"), strerror(errno)); if(!c->buffer) {
connection_del(c); logger(LOG_EMERG, _("bufferevent_new() failed: %s"), strerror(errno));
return; abort();
} }
bufferevent_disable(c->buffer, EV_READ);
configure_tcp(c); configure_tcp(c);

View file

@ -34,7 +34,7 @@ bool tunnelserver = false;
/* Jumptable for the request handlers */ /* 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, id_h, metakey_h, challenge_h, chal_reply_h, ack_h,
status_h, error_h, termreq_h, status_h, error_h, termreq_h,
ping_h, pong_h, ping_h, pong_h,
@ -68,8 +68,8 @@ bool check_id(const char *id) {
bool send_request(connection_t *c, const char *format, ...) { bool send_request(connection_t *c, const char *format, ...) {
va_list args; va_list args;
char buffer[MAXBUFSIZE]; char request[MAXBUFSIZE];
int len, request; int len;
cp(); cp();
@ -78,7 +78,7 @@ bool send_request(connection_t *c, const char *format, ...) {
input buffer anyway */ input buffer anyway */
va_start(args, format); va_start(args, format);
len = vsnprintf(buffer, MAXBUFSIZE, format, args); len = vsnprintf(request, MAXBUFSIZE, format, args);
va_end(args); va_end(args);
if(len < 0 || len > MAXBUFSIZE - 1) { if(len < 0 || len > MAXBUFSIZE - 1) {
@ -88,55 +88,50 @@ bool send_request(connection_t *c, const char *format, ...) {
} }
ifdebug(PROTOCOL) { ifdebug(PROTOCOL) {
sscanf(buffer, "%d", &request);
ifdebug(META) ifdebug(META)
logger(LOG_DEBUG, _("Sending %s to %s (%s): %s"), 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 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); c->name, c->hostname);
} }
buffer[len++] = '\n'; request[len++] = '\n';
if(c == broadcast) { if(c == broadcast) {
broadcast_meta(NULL, buffer, len); broadcast_meta(NULL, request, len);
return true; return true;
} else } else
return send_meta(c, buffer, len); return send_meta(c, request, len);
} }
void forward_request(connection_t *from) { void forward_request(connection_t *from, char *request) {
int request;
cp(); cp();
ifdebug(PROTOCOL) { ifdebug(PROTOCOL) {
sscanf(from->buffer, "%d", &request);
ifdebug(META) ifdebug(META)
logger(LOG_DEBUG, _("Forwarding %s from %s (%s): %s"), logger(LOG_DEBUG, _("Forwarding %s from %s (%s): %s"),
request_name[request], from->name, from->hostname, request_name[atoi(request)], from->name, from->hostname, request);
from->buffer);
else else
logger(LOG_DEBUG, _("Forwarding %s from %s (%s)"), 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'; int len = strlen(request);
request[len] = '\n';
broadcast_meta(from, from->buffer, from->reqlen); broadcast_meta(from, request, len);
} }
bool receive_request(connection_t *c) { bool receive_request(connection_t *c, char *request) {
int request; int reqno = atoi(request);
cp(); cp();
if(sscanf(c->buffer, "%d", &request) == 1) { if(reqno || *request == '0') {
if((request < 0) || (request >= LAST) || !request_handlers[request]) { if((reqno < 0) || (reqno >= LAST) || !request_handlers[reqno]) {
ifdebug(META) ifdebug(META)
logger(LOG_DEBUG, _("Unknown request from %s (%s): %s"), logger(LOG_DEBUG, _("Unknown request from %s (%s): %s"),
c->name, c->hostname, c->buffer); c->name, c->hostname, request);
else else
logger(LOG_ERR, _("Unknown request from %s (%s)"), logger(LOG_ERR, _("Unknown request from %s (%s)"),
c->name, c->hostname); c->name, c->hostname);
@ -146,25 +141,24 @@ bool receive_request(connection_t *c) {
ifdebug(PROTOCOL) { ifdebug(PROTOCOL) {
ifdebug(META) ifdebug(META)
logger(LOG_DEBUG, _("Got %s from %s (%s): %s"), logger(LOG_DEBUG, _("Got %s from %s (%s): %s"),
request_name[request], c->name, c->hostname, request_name[reqno], c->name, c->hostname, request);
c->buffer);
else else
logger(LOG_DEBUG, _("Got %s from %s (%s)"), 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, logger(LOG_ERR, _("Unauthorized request from %s (%s)"), c->name,
c->hostname); c->hostname);
return false; return false;
} }
if(!request_handlers[request](c)) { if(!request_handlers[reqno](c, request)) {
/* Something went wrong. Probably scriptkiddies. Terminate. */ /* Something went wrong. Probably scriptkiddies. Terminate. */
logger(LOG_ERR, _("Error while processing %s from %s (%s)"), 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; return false;
} }
} else { } else {

View file

@ -72,8 +72,8 @@ extern bool tunnelserver;
/* Basic functions */ /* Basic functions */
extern bool send_request(struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 2, 3))); extern bool send_request(struct connection_t *, const char *, ...) __attribute__ ((__format__(printf, 2, 3)));
extern void forward_request(struct connection_t *); extern void forward_request(struct connection_t *, char *);
extern bool receive_request(struct connection_t *); extern bool receive_request(struct connection_t *, char *);
extern bool check_id(const char *); extern bool check_id(const char *);
extern void init_requests(void); extern void init_requests(void);
@ -103,23 +103,23 @@ extern bool send_tcppacket(struct connection_t *, struct vpn_packet_t *);
/* Request handlers */ /* Request handlers */
extern bool id_h(struct connection_t *); extern bool id_h(struct connection_t *, char *);
extern bool metakey_h(struct connection_t *); extern bool metakey_h(struct connection_t *, char *);
extern bool challenge_h(struct connection_t *); extern bool challenge_h(struct connection_t *, char *);
extern bool chal_reply_h(struct connection_t *); extern bool chal_reply_h(struct connection_t *, char *);
extern bool ack_h(struct connection_t *); extern bool ack_h(struct connection_t *, char *);
extern bool status_h(struct connection_t *); extern bool status_h(struct connection_t *, char *);
extern bool error_h(struct connection_t *); extern bool error_h(struct connection_t *, char *);
extern bool termreq_h(struct connection_t *); extern bool termreq_h(struct connection_t *, char *);
extern bool ping_h(struct connection_t *); extern bool ping_h(struct connection_t *, char *);
extern bool pong_h(struct connection_t *); extern bool pong_h(struct connection_t *, char *);
extern bool add_subnet_h(struct connection_t *); extern bool add_subnet_h(struct connection_t *, char *);
extern bool del_subnet_h(struct connection_t *); extern bool del_subnet_h(struct connection_t *, char *);
extern bool add_edge_h(struct connection_t *); extern bool add_edge_h(struct connection_t *, char *);
extern bool del_edge_h(struct connection_t *); extern bool del_edge_h(struct connection_t *, char *);
extern bool key_changed_h(struct connection_t *); extern bool key_changed_h(struct connection_t *, char *);
extern bool req_key_h(struct connection_t *); extern bool req_key_h(struct connection_t *, char *);
extern bool ans_key_h(struct connection_t *); extern bool ans_key_h(struct connection_t *, char *);
extern bool tcppacket_h(struct connection_t *); extern bool tcppacket_h(struct connection_t *, char *);
#endif /* __TINC_PROTOCOL_H__ */ #endif /* __TINC_PROTOCOL_H__ */

View file

@ -47,12 +47,12 @@ bool send_id(connection_t *c) {
myself->connection->protocol_version); myself->connection->protocol_version);
} }
bool id_h(connection_t *c) { bool id_h(connection_t *c, char *request) {
char name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE];
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ID", c->name,
c->hostname); c->hostname);
return false; return false;
@ -199,14 +199,14 @@ bool send_metakey(connection_t *c) {
return x; return x;
} }
bool metakey_h(connection_t *c) { bool metakey_h(connection_t *c, char *request) {
char buffer[MAX_STRING_SIZE]; char buffer[MAX_STRING_SIZE];
int cipher, digest, maclength, compression; int cipher, digest, maclength, compression;
int len; int len;
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "METAKEY", c->name,
c->hostname); c->hostname);
return false; return false;
@ -329,13 +329,13 @@ bool send_challenge(connection_t *c) {
return send_request(c, "%d %s", CHALLENGE, buffer); 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]; char buffer[MAX_STRING_SIZE];
int len; int len;
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "CHALLENGE", c->name,
c->hostname); c->hostname);
return false; return false;
@ -393,14 +393,14 @@ bool send_chal_reply(connection_t *c) {
return send_request(c, "%d %s", CHAL_REPLY, hash); 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 hishash[MAX_STRING_SIZE];
char myhash[EVP_MAX_MD_SIZE]; char myhash[EVP_MAX_MD_SIZE];
EVP_MD_CTX ctx; EVP_MD_CTX ctx;
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "CHAL_REPLY", c->name,
c->hostname); c->hostname);
return false; 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 hisport[MAX_STRING_SIZE];
char *hisaddress, *dummy; char *hisaddress, *dummy;
int weight, mtu; int weight, mtu;
@ -523,7 +523,7 @@ bool ack_h(connection_t *c) {
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ACK", c->name,
c->hostname); c->hostname);
return false; return false;

View file

@ -53,7 +53,7 @@ bool send_add_edge(connection_t *c, const edge_t *e) {
return x; return x;
} }
bool add_edge_h(connection_t *c) { bool add_edge_h(connection_t *c, char *request) {
edge_t *e; edge_t *e;
node_t *from, *to; node_t *from, *to;
char from_name[MAX_STRING_SIZE]; char from_name[MAX_STRING_SIZE];
@ -66,7 +66,7 @@ bool add_edge_h(connection_t *c) {
cp(); 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) { from_name, to_name, to_address, to_port, &options, &weight) != 6) {
logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_EDGE", c->name, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_EDGE", c->name,
c->hostname); c->hostname);
@ -87,7 +87,7 @@ bool add_edge_h(connection_t *c) {
return false; return false;
} }
if(seen_request(c->buffer)) if(seen_request(request))
return true; return true;
/* Lookup nodes */ /* Lookup nodes */
@ -156,7 +156,7 @@ bool add_edge_h(connection_t *c) {
/* Tell the rest about the new edge */ /* Tell the rest about the new edge */
if(!tunnelserver) if(!tunnelserver)
forward_request(c); forward_request(c, request);
/* Run MST before or after we tell the rest? */ /* 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); 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; edge_t *e;
char from_name[MAX_STRING_SIZE]; char from_name[MAX_STRING_SIZE];
char to_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE];
@ -180,7 +180,7 @@ bool del_edge_h(connection_t *c) {
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_EDGE", c->name,
c->hostname); c->hostname);
return false; return false;
@ -200,7 +200,7 @@ bool del_edge_h(connection_t *c) {
return false; return false;
} }
if(seen_request(c->buffer)) if(seen_request(request))
return true; return true;
/* Lookup nodes */ /* Lookup nodes */
@ -244,7 +244,7 @@ bool del_edge_h(connection_t *c) {
/* Tell the rest about the deleted edge */ /* Tell the rest about the deleted edge */
if(!tunnelserver) if(!tunnelserver)
forward_request(c); forward_request(c, request);
/* Delete the edge */ /* Delete the edge */

View 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); 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]; char name[MAX_STRING_SIZE];
node_t *n; node_t *n;
cp(); 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", logger(LOG_ERR, _("Got bad %s from %s (%s)"), "KEY_CHANGED",
c->name, c->hostname); c->name, c->hostname);
return false; return false;
} }
if(seen_request(c->buffer)) if(seen_request(request))
return true; return true;
n = lookup_node(name); n = lookup_node(name);
@ -79,7 +79,7 @@ bool key_changed_h(connection_t *c) {
/* Tell the others */ /* Tell the others */
if(!tunnelserver) if(!tunnelserver)
forward_request(c); forward_request(c, request);
return true; 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); 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 from_name[MAX_STRING_SIZE];
char to_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE];
node_t *from, *to; node_t *from, *to;
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "REQ_KEY", c->name,
c->hostname); c->hostname);
return false; return false;
@ -152,7 +152,7 @@ bool send_ans_key(connection_t *c, const node_t *from, const node_t *to) {
from->compression); 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 from_name[MAX_STRING_SIZE];
char to_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE];
char key[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE];
@ -161,7 +161,7 @@ bool ans_key_h(connection_t *c) {
cp(); 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, from_name, to_name, key, &cipher, &digest, &maclength,
&compression) != 7) { &compression) != 7) {
logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ANS_KEY", c->name, 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) if(tunnelserver)
return false; 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 */ /* Update our copy of the origin's packet key */

View 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); 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; int statusno;
char statusstring[MAX_STRING_SIZE]; char statusstring[MAX_STRING_SIZE];
cp(); 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", logger(LOG_ERR, _("Got bad %s from %s (%s)"), "STATUS",
c->name, c->hostname); c->name, c->hostname);
return false; 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); 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; int err;
char errorstring[MAX_STRING_SIZE]; char errorstring[MAX_STRING_SIZE];
cp(); 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", logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ERROR",
c->name, c->hostname); c->name, c->hostname);
return false; return false;
@ -100,7 +100,7 @@ bool send_termreq(connection_t *c)
return send_request(c, "%d", TERMREQ); return send_request(c, "%d", TERMREQ);
} }
bool termreq_h(connection_t *c) bool termreq_h(connection_t *c, char *request)
{ {
cp(); cp();
@ -117,7 +117,7 @@ bool send_ping(connection_t *c)
return send_request(c, "%d", PING); return send_request(c, "%d", PING);
} }
bool ping_h(connection_t *c) bool ping_h(connection_t *c, char *request)
{ {
cp(); cp();
@ -131,7 +131,7 @@ bool send_pong(connection_t *c)
return send_request(c, "%d", PONG); return send_request(c, "%d", PONG);
} }
bool pong_h(connection_t *c) bool pong_h(connection_t *c, char *request)
{ {
cp(); 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 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; return true;
if(!send_request(c, "%d %hd", PACKET, packet->len)) 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); 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; short int len;
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "PACKET", c->name,
c->hostname); c->hostname);
return false; return false;

View 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); 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 subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE];
@ -54,7 +54,7 @@ bool add_subnet_h(connection_t *c)
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_SUBNET", c->name,
c->hostname); c->hostname);
return false; return false;
@ -76,7 +76,7 @@ bool add_subnet_h(connection_t *c)
return false; return false;
} }
if(seen_request(c->buffer)) if(seen_request(request))
return true; return true;
/* Check if the owner of the new subnet is in the connection list */ /* 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 */ /* Tell the rest */
if(!tunnelserver) if(!tunnelserver)
forward_request(c); forward_request(c, request);
return true; 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); 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 subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE];
@ -166,7 +166,7 @@ bool del_subnet_h(connection_t *c)
cp(); 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, logger(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_SUBNET", c->name,
c->hostname); c->hostname);
return false; return false;
@ -201,7 +201,7 @@ bool del_subnet_h(connection_t *c)
return false; return false;
} }
if(seen_request(c->buffer)) if(seen_request(request))
return true; return true;
/* If everything is correct, delete the subnet from the list of the owner */ /* 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 */ /* Tell the rest */
if(!tunnelserver) if(!tunnelserver)
forward_request(c); forward_request(c, request);
/* Finally, delete it. */ /* Finally, delete it. */