- New semantics for BASIC_INFO, ADD_HOST and DEL_HOST requests. This will
improve connection list consistency, ensures the tree property, and allows for recovery from situations where track of connections is lost.
This commit is contained in:
parent
e8e7379311
commit
18c85caac3
6 changed files with 153 additions and 95 deletions
30
src/net.c
30
src/net.c
|
|
@ -17,7 +17,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: net.c,v 1.35.4.13 2000/06/29 13:04:14 guus Exp $
|
||||
$Id: net.c,v 1.35.4.14 2000/06/29 17:09:05 guus Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
|
@ -921,32 +921,37 @@ cp
|
|||
|
||||
cl->status.remove = 1;
|
||||
|
||||
/* If this cl isn't active, don't send any DEL_HOSTs and don't bother
|
||||
checking for other lost connections. */
|
||||
/* If this cl isn't active, don't send any DEL_HOSTs. */
|
||||
if(!cl->status.active)
|
||||
return;
|
||||
|
||||
cl->status.active = 0;
|
||||
|
||||
notify_others(cl,NULL,send_del_host);
|
||||
|
||||
cp
|
||||
/* Find all connections that were lost because they were behind cl
|
||||
(the connection that was dropped). */
|
||||
for(p = conn_list; p != NULL; p = p->next)
|
||||
if(p->nexthop == cl)
|
||||
if(cl->status.meta)
|
||||
for(p = conn_list; p != NULL; p = p->next)
|
||||
{
|
||||
p->status.active = 0;
|
||||
p->status.remove = 1;
|
||||
if(p->nexthop == cl)
|
||||
{
|
||||
if(p->status.active)
|
||||
notify_others(p,cl,send_del_host);
|
||||
p->status.active = 0;
|
||||
p->status.remove = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cp
|
||||
/* Then send a notification about all these connections to all hosts
|
||||
that are still connected to us. */
|
||||
that are still connected to us.
|
||||
for(p = conn_list; p != NULL; p = p->next)
|
||||
if(p->status.active && p->status.meta)
|
||||
for(q = conn_list; q != NULL; q = q->next)
|
||||
if(q->status.remove)
|
||||
send_del_host(p, q);
|
||||
|
||||
*/
|
||||
cp
|
||||
}
|
||||
|
||||
|
|
@ -1146,7 +1151,8 @@ cp
|
|||
I've once got here when it said `No route to host'.
|
||||
*/
|
||||
getsockopt(p->socket, SOL_SOCKET, SO_ERROR, &x, &l);
|
||||
syslog(LOG_ERR, _("Outgoing data socket error: %s"), sys_errlist[x]);
|
||||
syslog(LOG_ERR, _("Outgoing data socket error for %s (%s): %s"),
|
||||
p->vpn_hostname, p->real_hostname, sys_errlist[x]);
|
||||
terminate_connection(p);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: netutl.c,v 1.12.4.5 2000/06/29 13:04:15 guus Exp $
|
||||
$Id: netutl.c,v 1.12.4.6 2000/06/29 17:09:06 guus Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
|
@ -192,7 +192,7 @@ cp
|
|||
}
|
||||
else
|
||||
{
|
||||
name = xmalloc(strlen(host->h_name));
|
||||
name = xmalloc(strlen(host->h_name)+1);
|
||||
sprintf(name, "%s", host->h_name);
|
||||
}
|
||||
cp
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: protocol.c,v 1.28.4.15 2000/06/29 13:04:15 guus Exp $
|
||||
$Id: protocol.c,v 1.28.4.16 2000/06/29 17:09:06 guus Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
|
@ -419,6 +419,19 @@ cp
|
|||
}
|
||||
else
|
||||
{
|
||||
/* First check if the host we connected to is already in our
|
||||
connection list. If so, we are probably making a loop, which
|
||||
is not desirable. It should not happen though.
|
||||
*/
|
||||
|
||||
if(lookup_conn(cl->vpn_ip))
|
||||
{
|
||||
if(debug_lvl>0)
|
||||
syslog(LOG_NOTICE, _("Uplink %s (%s) is already in our connection list, aborting connect"),
|
||||
cl->vpn_hostname, cl->real_hostname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(setup_vpn_connection(cl) < 0)
|
||||
return -1;
|
||||
send_passphrase(cl);
|
||||
|
|
@ -471,7 +484,8 @@ cp
|
|||
if(verify_passphrase(cl, g_n))
|
||||
{
|
||||
/* intruder! */
|
||||
syslog(LOG_ERR, _("Intruder: passphrase does not match!"));
|
||||
syslog(LOG_ERR, _("Intruder from %s: passphrase for %s does not match!"),
|
||||
cl->real_hostname, cl->vpn_hostname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -483,12 +497,17 @@ cp
|
|||
|
||||
/* 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. */
|
||||
old connection that has timed out but we don't know it yet.
|
||||
*/
|
||||
|
||||
while(old = lookup_conn(cl->vpn_ip))
|
||||
terminate_connection(old);
|
||||
|
||||
{
|
||||
syslog(LOG_NOTICE, _("Removing old entry for %s at %s in favour of new connection from %s"),
|
||||
cl->vpn_hostname, old->real_hostname, cl->real_hostname);
|
||||
old->status.active = 0;
|
||||
terminate_connection(old);
|
||||
}
|
||||
|
||||
cl->status.active = 1;
|
||||
|
||||
if(debug_lvl > 0)
|
||||
|
|
@ -538,11 +557,6 @@ cp
|
|||
|
||||
cl->status.termreq = 1;
|
||||
|
||||
if(cl->status.active)
|
||||
notify_others(cl, NULL, send_del_host);
|
||||
|
||||
cl->status.active = 0;
|
||||
|
||||
terminate_connection(cl);
|
||||
cp
|
||||
return 0;
|
||||
|
|
@ -672,8 +686,24 @@ cp
|
|||
return -1;
|
||||
}
|
||||
|
||||
while(old = lookup_conn(vpn_ip))
|
||||
terminate_connection(old);
|
||||
if(old = lookup_conn(vpn_ip))
|
||||
{
|
||||
if((real_ip==old->real_ip) && (vpn_mask==old->vpn_mask) && (port==old->port))
|
||||
{
|
||||
if(debug_lvl>1)
|
||||
syslog(LOG_NOTICE, _("Got duplicate ADD_HOST for %s (%s) from %s (%s)"),
|
||||
old->vpn_hostname, old->real_hostname, cl->vpn_hostname, cl->real_hostname);
|
||||
goto skip_add_host; /* One goto a day keeps the deeply nested if constructions away. */
|
||||
}
|
||||
else
|
||||
{
|
||||
if(debug_lvl>1)
|
||||
syslog(LOG_NOTICE, _("Removing old entry for %s (%s)"),
|
||||
old->vpn_hostname, old->real_hostname);
|
||||
old->status.active = 0;
|
||||
terminate_connection(old);
|
||||
}
|
||||
}
|
||||
|
||||
ncn = new_conn_list();
|
||||
ncn->real_ip = real_ip;
|
||||
|
|
@ -692,6 +722,8 @@ cp
|
|||
syslog(LOG_DEBUG, _("Got ADD_HOST for %s (%s) from %s (%s)"),
|
||||
ncn->vpn_hostname, ncn->real_hostname, cl->vpn_hostname, cl->real_hostname);
|
||||
|
||||
skip_add_host:
|
||||
|
||||
notify_others(ncn, cl, send_add_host);
|
||||
cp
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: protocol.h,v 1.5.4.2 2000/06/25 15:22:16 guus Exp $
|
||||
$Id: protocol.h,v 1.5.4.3 2000/06/29 17:09:08 guus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TINC_PROTOCOL_H__
|
||||
|
|
@ -72,6 +72,7 @@ extern int send_termreq(conn_list_t *);
|
|||
extern int send_timeout(conn_list_t *);
|
||||
extern int send_key_request(ip_t);
|
||||
extern void send_key_changed_all(void);
|
||||
extern int send_del_host(conn_list_t *, conn_list_t *);
|
||||
|
||||
#endif /* __TINC_PROTOCOL_H__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
$Id: tincd.c,v 1.10.4.3 2000/06/28 14:34:40 guus Exp $
|
||||
$Id: tincd.c,v 1.10.4.4 2000/06/29 17:09:08 guus Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
|
@ -485,11 +485,10 @@ setup_signals(void)
|
|||
signal(SIGINT, sigint_handler);
|
||||
signal(SIGUSR1, sigusr1_handler);
|
||||
signal(SIGUSR2, sigusr2_handler);
|
||||
signal(SIGCHLD, parent_exit);
|
||||
// signal(SIGCHLD, parent_exit);
|
||||
}
|
||||
|
||||
RETSIGTYPE parent_exit(int a)
|
||||
{
|
||||
syslog(LOG_NOTICE, _("Got SIGCHLD: exitting immediately"));
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue