A remote user could telnet to the tinc daemon and type only this line:
61 6
00000000/
00000000:28f
This would deny any packets to be sent to other tinc networks (except
for to the hosts that run tincd's themselves). Solution is to skip
hosts in lookup_conn() that have not been activated yet.
Fixed potential conn_list table corruption:
If a new connection is accepted but a connection with the same subnet
would already exist in the connection list, the OLD connection is
terminated.
if(cl->status.outgoing)
{
if(cl->status.outgoing)
{
signal(SIGALRM, sigalrm_handler);
signal(SIGALRM, sigalrm_handler);
syslog(LOG_NOTICE, "Try to re-establish outgoing connection in 5 seconds.");
}
syslog(LOG_NOTICE, "Try to re-establish outgoing connection in 5 seconds.");
}
/*
look for a connection associated with the given vpn ip,
/*
look for a connection associated with the given vpn ip,
- return its connection structure
+ return its connection structure.
+ Skips connections that are not activated!
*/
conn_list_t *lookup_conn(ip_t ip)
{
*/
conn_list_t *lookup_conn(ip_t ip)
{
cp
/* Exact match suggested by James B. MacLean */
for(p = conn_list; p != NULL; p = p->next)
cp
/* Exact match suggested by James B. MacLean */
for(p = conn_list; p != NULL; p = p->next)
+ if((ip == p->vpn_ip) && p->active)
return p;
for(p = conn_list; p != NULL; p = p->next)
return p;
for(p = conn_list; p != NULL; p = p->next)
- if((ip & p->vpn_mask) == (p->vpn_ip & p->vpn_mask))
+ if(((ip & p->vpn_mask) == (p->vpn_ip & p->vpn_mask)) && p->active)
return p;
cp
return NULL;
return p;
cp
return NULL;
conn_list_t *p;
cp
for(p = conn_list; p != NULL; p = p->next)
conn_list_t *p;
cp
for(p = conn_list; p != NULL; p = p->next)
- if(p->status.meta && p->protocol_version > PROT_3)
+ if(p->status.meta && p->active)
send_key_changed(p, myself);
cp
}
send_key_changed(p, myself);
cp
}
conn_list_t *p;
cp
for(p = conn_list; p != NULL; p = p->next)
conn_list_t *p;
cp
for(p = conn_list; p != NULL; p = p->next)
- if(p != new && p != source && p->status.meta)
+ if(p != new && p != source && p->status.meta && p->active)
function(p, new);
cp
return 0;
function(p, new);
cp
return 0;
conn_list_t *p;
cp
for(p = conn_list; p != NULL; p = p->next)
conn_list_t *p;
cp
for(p = conn_list; p != NULL; p = p->next)
- if(p != new && p->protocol_version > PROT_3)
+ if(p != new && p->active)
send_add_host(new, p);
cp
return 0;
send_add_host(new, p);
cp
return 0;
return -1;
send_passphrase(cl);
}
return -1;
send_passphrase(cl);
}
-
- cl->status.active = 0;
int public_key_h(conn_list_t *cl)
{
char *g_n;
int public_key_h(conn_list_t *cl)
{
char *g_n;
cp
if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
{
cp
if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
{
+ /* Okay, before we active the connection, we check if there is another entry
+ in the connection list with the same vpn_ip. If so, it presumably is an
+ old connection that has timed out but we don't know it yet. Because our
+ conn_list entry is not active, lookup_conn will skip ourself. */
+
+ if(old=lookup_conn(cl->vpn_ip))
+ terminate_connection(old);
+
cl->status.active = 1;
notify_others(cl, NULL, send_add_host);
notify_one(cl);
cl->status.active = 1;
notify_others(cl, NULL, send_add_host);
notify_one(cl);