Use libevent for meta socket input/output buffering.
This commit is contained in:
parent
59108e4e4f
commit
fbf305c09d
12 changed files with 177 additions and 269 deletions
|
@ -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."));
|
||||
|
|
|
@ -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 */
|
||||
|
|
163
src/meta.c
163
src/meta.c
|
@ -37,90 +37,34 @@
|
|||
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,48 +95,48 @@ 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;
|
||||
|
||||
while(inlen > 0) {
|
||||
/* Decrypt */
|
||||
logger(LOG_DEBUG, _("Received unencrypted %ld of %d bytes"), endp - bufp, inlen);
|
||||
|
||||
if(c->status.decryptin && !decrypted) {
|
||||
result = EVP_DecryptUpdate(c->inctx, (unsigned char *)inbuf, &outlen, (unsigned char *)c->buffer + oldlen, inlen);
|
||||
evbuffer_add(c->buffer->input, bufp, endp - bufp);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
while(c->buffer->input->off) {
|
||||
/* Are we receiving a TCPpacket? */
|
||||
|
||||
if(c->tcplen) {
|
||||
if(c->tcplen <= c->buflen) {
|
||||
receive_tcppacket(c, c->buffer, c->tcplen);
|
||||
|
||||
c->buflen -= c->tcplen;
|
||||
inlen -= c->tcplen - oldlen;
|
||||
memmove(c->buffer, c->buffer + c->tcplen, c->buflen);
|
||||
oldlen = 0;
|
||||
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 {
|
||||
|
@ -203,36 +146,16 @@ bool receive_meta(connection_t *c) {
|
|||
|
||||
/* 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;
|
||||
char *request = evbuffer_readline(c->buffer->input);
|
||||
if(request) {
|
||||
receive_request(c, request);
|
||||
free(request);
|
||||
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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
Loading…
Reference in a new issue