-int ans_key_h(connection_t *c)
-{
- char from_name[MAX_STRING_SIZE];
- char to_name[MAX_STRING_SIZE];
- char key[MAX_STRING_SIZE];
- int cipher, digest, maclength, compression;
- node_t *from, *to;
- cp();
- if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d", from_name, to_name, key, &cipher, &digest, &maclength, &compression) != 7)
- {
- syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ANS_KEY",
- c->name, c->hostname);
- return -1;
- }
-
- from = lookup_node(from_name);
-
- if(!from)
- {
- syslog(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);
- return -1;
- }
-
- to = lookup_node(to_name);
-
- if(!to)
- {
- syslog(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);
- return -1;
- }
-
- /* Forward it if necessary */
-
- if(to != myself)
- {
- return send_request(to->nexthop->connection, "%s", c->buffer);
- }
-
- /* Update our copy of the origin's packet key */
-
- if(from->key)
- free(from->key);
-
- from->key = xstrdup(key);
- from->keylength = strlen(key) / 2;
- hex2bin(from->key, from->key, from->keylength);
- from->key[from->keylength] = '\0';
-
- from->status.validkey = 1;
- from->status.waitingforkey = 0;
- from->sent_seqno = 0;
-
- /* Check and lookup cipher and digest algorithms */
-
- if(cipher)
- {
- from->cipher = EVP_get_cipherbynid(cipher);
- if(!from->cipher)
- {
- syslog(LOG_ERR, _("Node %s (%s) uses unknown cipher!"), from->name, from->hostname);
- return -1;
+bool ans_key_h(connection_t *c) {
+ char from_name[MAX_STRING_SIZE];
+ char to_name[MAX_STRING_SIZE];
+ char key[MAX_STRING_SIZE];
+ char address[MAX_STRING_SIZE] = "";
+ char port[MAX_STRING_SIZE] = "";
+ int cipher, digest, maclength, compression;
+ node_t *from, *to;
+
+ if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d "MAX_STRING" "MAX_STRING,
+ from_name, to_name, key, &cipher, &digest, &maclength,
+ &compression, address, port) < 7) {
+ logger(LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
+ c->hostname);
+ return false;
+ }
+
+ 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);
+ return true;
+ }
+
+ 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);
+ return true;
+ }
+
+ /* Forward it if necessary */
+
+ if(to != myself) {
+ if(tunnelserver)
+ return true;
+
+ if(!to->status.reachable) {
+ logger(LOG_WARNING, "Got %s from %s (%s) destination %s which is not reachable",
+ "ANS_KEY", c->name, c->hostname, to_name);
+ return true;
+ }
+
+ if(!*address && from->address.sa.sa_family != AF_UNSPEC && to->minmtu) {
+ char *address, *port;
+ ifdebug(PROTOCOL) logger(LOG_DEBUG, "Appending reflexive UDP address to ANS_KEY from %s to %s", from->name, to->name);
+ sockaddr2str(&from->address, &address, &port);
+ send_request(to->nexthop->connection, "%s %s %s", c->buffer, address, port);
+ free(address);
+ free(port);
+ return true;
+ }
+
+ return send_request(to->nexthop->connection, "%s", c->buffer);