summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
469fa31)
When we got a key request for or from a node we don't know, we disconnected the
node that forwarded us that request. However, especially in TunnelServer mode,
disconnecting does not help. We now ignore such requests, but since there is no
way of telling the original sender that the request was dropped, we now retry
sending REQ_KEY requests when we don't get an ANS_KEY back.
/* TODO: only clear status.validkey if node is unreachable? */
n->status.validkey = false;
/* TODO: only clear status.validkey if node is unreachable? */
n->status.validkey = false;
- n->status.waitingforkey = false;
n->maxmtu = MTU;
n->minmtu = 0;
n->maxmtu = MTU;
n->minmtu = 0;
"No valid key known yet for %s (%s), forwarding via TCP",
n->name, n->hostname);
"No valid key known yet for %s (%s), forwarding via TCP",
n->name, n->hostname);
- if(!n->status.waitingforkey)
+ if(n->last_req_key + 10 < now) {
-
- n->status.waitingforkey = true;
+ n->last_req_key = now;
+ }
send_tcppacket(n->nexthop->connection, origpkt);
send_tcppacket(n->nexthop->connection, origpkt);
typedef struct node_status_t {
int unused_active:1; /* 1 if active (not used for nodes) */
int validkey:1; /* 1 if we currently have a valid key for him */
typedef struct node_status_t {
int unused_active:1; /* 1 if active (not used for nodes) */
int validkey:1; /* 1 if we currently have a valid key for him */
- int waitingforkey:1; /* 1 if we already sent out a request */
+ int unused_waitingforkey:1; /* 1 if we already sent out a request */
int visited:1; /* 1 if this node has been visited by one of the graph algorithms */
int reachable:1; /* 1 if this node is reachable in the graph */
int indirect:1; /* 1 if this node is not directly reachable by us */
int visited:1; /* 1 if this node has been visited by one of the graph algorithms */
int reachable:1; /* 1 if this node is reachable in the graph */
int indirect:1; /* 1 if this node is not directly reachable by us */
char *hostname; /* the hostname of its real ip */
node_status_t status;
char *hostname; /* the hostname of its real ip */
node_status_t status;
const EVP_CIPHER *incipher; /* Cipher type for UDP packets received from him */
char *inkey; /* Cipher key and iv */
const EVP_CIPHER *incipher; /* Cipher type for UDP packets received from him */
char *inkey; /* Cipher key and iv */
+ if(!check_id(name)) {
+ logger(LOG_ERR, "Got bad %s from %s (%s): %s", "KEY_CHANGED", c->name, c->hostname, "invalid name");
+ return false;
+ }
+
if(seen_request(c->buffer))
return true;
if(seen_request(c->buffer))
return true;
if(!n) {
logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
"KEY_CHANGED", c->name, c->hostname, name);
if(!n) {
logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist",
"KEY_CHANGED", c->name, c->hostname, name);
}
n->status.validkey = false;
}
n->status.validkey = false;
- n->status.waitingforkey = false;
+ if(!check_id(from_name) || !check_id(to_name)) {
+ logger(LOG_ERR, "Got bad %s from %s (%s): %s", "REQ_KEY", c->name, c->hostname, "invalid name");
+ return false;
+ }
+
from = lookup_node(from_name);
if(!from) {
logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
"REQ_KEY", c->name, c->hostname, from_name);
from = lookup_node(from_name);
if(!from) {
logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
"REQ_KEY", c->name, c->hostname, from_name);
}
to = lookup_node(to_name);
}
to = lookup_node(to_name);
if(!to) {
logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
"REQ_KEY", c->name, c->hostname, to_name);
if(!to) {
logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
"REQ_KEY", c->name, c->hostname, to_name);
}
/* Check if this key request is for us */
}
/* Check if this key request is for us */
send_ans_key(from);
} else {
if(tunnelserver)
send_ans_key(from);
} else {
if(tunnelserver)
if(!to->status.reachable) {
logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
if(!to->status.reachable) {
logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
+ if(!check_id(from_name) || !check_id(to_name)) {
+ logger(LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_KEY", c->name, c->hostname, "invalid name");
+ return false;
+ }
+
from = lookup_node(from_name);
if(!from) {
logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
"ANS_KEY", c->name, c->hostname, from_name);
from = lookup_node(from_name);
if(!from) {
logger(LOG_ERR, "Got %s from %s (%s) origin %s which does not exist in our connection list",
"ANS_KEY", c->name, c->hostname, from_name);
}
to = lookup_node(to_name);
}
to = lookup_node(to_name);
if(!to) {
logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
"ANS_KEY", c->name, c->hostname, to_name);
if(!to) {
logger(LOG_ERR, "Got %s from %s (%s) destination %s which does not exist in our connection list",
"ANS_KEY", c->name, c->hostname, to_name);
}
/* Forward it if necessary */
if(to != myself) {
if(tunnelserver)
}
/* Forward it if necessary */
if(to != myself) {
if(tunnelserver)
if(!to->status.reachable) {
logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
if(!to->status.reachable) {
logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
from->outkeylength = strlen(key) / 2;
hex2bin(key, from->outkey, from->outkeylength);
from->outkeylength = strlen(key) / 2;
hex2bin(key, from->outkey, from->outkeylength);
- from->status.waitingforkey = false;
/* Check and lookup cipher and digest algorithms */
if(cipher) {
/* Check and lookup cipher and digest algorithms */
if(cipher) {
if(!from->outcipher) {
logger(LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name,
from->hostname);
if(!from->outcipher) {
logger(LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name,
from->hostname);
}
if(from->outkeylength != from->outcipher->key_len + from->outcipher->iv_len) {
logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name,
from->hostname);
}
if(from->outkeylength != from->outcipher->key_len + from->outcipher->iv_len) {
logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name,
from->hostname);
}
} else {
from->outcipher = NULL;
}
} else {
from->outcipher = NULL;
if(!from->outdigest) {
logger(LOG_ERR, "Node %s (%s) uses unknown digest!", from->name,
from->hostname);
if(!from->outdigest) {
logger(LOG_ERR, "Node %s (%s) uses unknown digest!", from->name,
from->hostname);
}
if(from->outmaclength > from->outdigest->md_size || from->outmaclength < 0) {
logger(LOG_ERR, "Node %s (%s) uses bogus MAC length!",
from->name, from->hostname);
}
if(from->outmaclength > from->outdigest->md_size || from->outmaclength < 0) {
logger(LOG_ERR, "Node %s (%s) uses bogus MAC length!",
from->name, from->hostname);
}
} else {
from->outdigest = NULL;
}
} else {
from->outdigest = NULL;
if(compression < 0 || compression > 11) {
logger(LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
if(compression < 0 || compression > 11) {
logger(LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
}
from->outcompression = compression;
}
from->outcompression = compression;
if(!EVP_EncryptInit_ex(&from->outctx, from->outcipher, NULL, (unsigned char *)from->outkey, (unsigned char *)from->outkey + from->outcipher->key_len)) {
logger(LOG_ERR, "Error during initialisation of key from %s (%s): %s",
from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL));
if(!EVP_EncryptInit_ex(&from->outctx, from->outcipher, NULL, (unsigned char *)from->outkey, (unsigned char *)from->outkey + from->outcipher->key_len)) {
logger(LOG_ERR, "Error during initialisation of key from %s (%s): %s",
from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL));
}
from->status.validkey = true;
}
from->status.validkey = true;