When making outgoing connections, tinc goes through the list of Addresses and
tries all of them until one succeeds. However, before it would consider
establishing a TCP connection a success, even when the authentication failed.
This would be a problem if the first Address would point to a hostname and port
combination that belongs to the wrong tinc node, or perhaps even to a non-tinc
service, causing tinc to endlessly try this Address instead of moving to the
next one.
Problem found by Delf Eldkraft.
return c;
}
-void free_connection(connection_t *c) {
- if(c->name)
- free(c->name);
-
- if(c->hostname)
- free(c->hostname);
-
- if(c->inkey)
- free(c->inkey);
-
- if(c->outkey)
- free(c->outkey);
+void free_connection_partially(connection_t *c) {
+ free(c->inkey);
+ free(c->outkey);
+ free(c->mychallenge);
+ free(c->hischallenge);
+ free(c->outbuf);
+
+ c->inkey = NULL;
+ c->outkey = NULL;
+ c->mychallenge = NULL;
+ c->hischallenge = NULL;
+ c->outbuf = NULL;
+
+ c->buflen = 0;
+ c->reqlen = 0;
+ c->tcplen = 0;
+ c->allow_request = 0;
+ c->outbuflen = 0;
+ c->outbufsize = 0;
+ c->outbufstart = 0;
if(c->inctx) {
EVP_CIPHER_CTX_cleanup(c->inctx);
free(c->inctx);
+ c->inctx = NULL;
}
if(c->outctx) {
EVP_CIPHER_CTX_cleanup(c->outctx);
free(c->outctx);
+ c->outctx = NULL;
+ }
+
+ if(c->rsa_key) {
+ RSA_free(c->rsa_key);
+ c->rsa_key = NULL;
}
+}
- if(c->mychallenge)
- free(c->mychallenge);
+void free_connection(connection_t *c) {
+ free_connection_partially(c);
- if(c->hischallenge)
- free(c->hischallenge);
+ free(c->name);
+ free(c->hostname);
if(c->config_tree)
exit_configuration(&c->config_tree);
- if(c->outbuf)
- free(c->outbuf);
-
- if(c->rsa_key)
- RSA_free(c->rsa_key);
-
free(c);
}
extern void exit_connections(void);
extern connection_t *new_connection(void) __attribute__ ((__malloc__));
extern void free_connection(connection_t *);
+extern void free_connection_partially(connection_t *);
extern void connection_add(connection_t *);
extern void connection_del(connection_t *);
extern void dump_connections(void);
}
}
+ free_connection_partially(c);
+
/* Check if this was our outgoing connection */
if(c->outgoing) {
- retry_outgoing(c->outgoing);
- c->outgoing = NULL;
+ c->status.remove = false;
+ do_outgoing_connection(c);
}
-
- free(c->outbuf);
- c->outbuf = NULL;
- c->outbuflen = 0;
- c->outbufsize = 0;
- c->outbufstart = 0;
}
/*
/* Succesful connection, reset timeout if this is an outgoing connection. */
- if(c->outgoing)
+ if(c->outgoing) {
c->outgoing->timeout = 0;
+ c->outgoing->cfg = NULL;
+ if(c->outgoing->ai)
+ freeaddrinfo(c->outgoing->ai);
+ c->outgoing->ai = NULL;
+ c->outgoing->aip = NULL;
+ }
return true;
}