}
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) {
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);
}
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."));
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 */
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 */
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;
}
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();
- 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);
if(c->socket)
closesocket(c->socket);
- event_del(&c->ev);
-
if(c->edge) {
if(report && !tunnelserver)
send_del_edge(broadcast, c->edge);
}
}
- 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)
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;
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);
}
/*
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);
/* 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,
bool send_request(connection_t *c, const char *format, ...) {
va_list args;
- char buffer[MAXBUFSIZE];
- int len, request;
+ char request[MAXBUFSIZE];
+ int len;
cp();
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) {
}
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);
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 {
/* 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);
/* 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__ */
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;
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;
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;
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;
}
}
-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;
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;
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];
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);
return false;
}
- if(seen_request(c->buffer))
+ if(seen_request(request))
return true;
/* Lookup nodes */
/* 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? */
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];
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;
return false;
}
- if(seen_request(c->buffer))
+ if(seen_request(request))
return true;
/* Lookup nodes */
/* Tell the rest about the deleted edge */
if(!tunnelserver)
- forward_request(c);
+ forward_request(c, request);
/* Delete the edge */
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);
/* Tell the others */
if(!tunnelserver)
- forward_request(c);
+ forward_request(c, request);
return true;
}
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;
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];
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,
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 */
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;
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;
return send_request(c, "%d", TERMREQ);
}
-bool termreq_h(connection_t *c)
+bool termreq_h(connection_t *c, char *request)
{
cp();
return send_request(c, "%d", PING);
}
-bool ping_h(connection_t *c)
+bool ping_h(connection_t *c, char *request)
{
cp();
return send_request(c, "%d", PONG);
}
-bool pong_h(connection_t *c)
+bool pong_h(connection_t *c, char *request)
{
cp();
/* 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))
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;
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];
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;
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 */
/* Tell the rest */
if(!tunnelserver)
- forward_request(c);
+ forward_request(c, request);
return true;
}
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];
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;
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 */
/* Tell the rest */
if(!tunnelserver)
- forward_request(c);
+ forward_request(c, request);
/* Finally, delete it. */