Always try next Address when an outgoing connection fails to authenticate.
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.
This commit is contained in:
parent
28a1501b9a
commit
80e15d8b96
4 changed files with 42 additions and 29 deletions
|
@ -60,44 +60,54 @@ connection_t *new_connection(void) {
|
|||
return c;
|
||||
}
|
||||
|
||||
void free_connection(connection_t *c) {
|
||||
if(c->name)
|
||||
free(c->name);
|
||||
void free_connection_partially(connection_t *c) {
|
||||
free(c->inkey);
|
||||
free(c->outkey);
|
||||
free(c->mychallenge);
|
||||
free(c->hischallenge);
|
||||
free(c->outbuf);
|
||||
|
||||
if(c->hostname)
|
||||
free(c->hostname);
|
||||
c->inkey = NULL;
|
||||
c->outkey = NULL;
|
||||
c->mychallenge = NULL;
|
||||
c->hischallenge = NULL;
|
||||
c->outbuf = NULL;
|
||||
|
||||
if(c->inkey)
|
||||
free(c->inkey);
|
||||
|
||||
if(c->outkey)
|
||||
free(c->outkey);
|
||||
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->mychallenge)
|
||||
free(c->mychallenge);
|
||||
if(c->rsa_key) {
|
||||
RSA_free(c->rsa_key);
|
||||
c->rsa_key = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(c->hischallenge)
|
||||
free(c->hischallenge);
|
||||
void free_connection(connection_t *c) {
|
||||
free_connection_partially(c);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -107,6 +107,7 @@ extern void init_connections(void);
|
|||
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);
|
||||
|
|
12
src/net.c
12
src/net.c
|
@ -204,18 +204,14 @@ void terminate_connection(connection_t *c, bool report) {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -111,8 +111,14 @@ bool pong_h(connection_t *c) {
|
|||
|
||||
/* 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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue