From 2165931c62f0433fd97bd3ac6aefea3627218946 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 30 Oct 2001 16:34:32 +0000 Subject: [PATCH] More updates to protocol handlers and reimplemented terminate_connection(). --- src/connection.c | 4 +-- src/connection.h | 4 +-- src/net.c | 87 +++++++++++++++++++++++++++++++++++++++++++----- src/protocol.c | 50 ++++++++++++++++++++++------ 4 files changed, 122 insertions(+), 23 deletions(-) diff --git a/src/connection.c b/src/connection.c index 1bad1182..4ee9a1b9 100644 --- a/src/connection.c +++ b/src/connection.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: connection.c,v 1.1.2.23 2001/10/28 22:42:49 guus Exp $ + $Id: connection.c,v 1.1.2.24 2001/10/30 16:34:32 guus Exp $ */ #include "config.h" @@ -54,7 +54,7 @@ cp cp } -void exit_connection(void) +void exit_connections(void) { cp avl_delete_tree(connection_tree); diff --git a/src/connection.h b/src/connection.h index 5307147a..8ab81288 100644 --- a/src/connection.h +++ b/src/connection.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: connection.h,v 1.1.2.20 2001/10/28 22:42:49 guus Exp $ + $Id: connection.h,v 1.1.2.21 2001/10/30 16:34:32 guus Exp $ */ #ifndef __TINC_CONNECTION_H__ @@ -104,7 +104,7 @@ typedef struct connection_t { extern avl_tree_t *connection_tree; extern void init_connections(void); -extern void exit_connection(void); +extern void exit_connections(void); extern connection_t *new_connection(void); extern void free_connection(connection_t *); extern void connection_add(connection_t *); diff --git a/src/net.c b/src/net.c index 1e37a798..1895bc18 100644 --- a/src/net.c +++ b/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.142 2001/10/30 12:59:12 guus Exp $ + $Id: net.c,v 1.35.4.143 2001/10/30 16:34:32 guus Exp $ */ #include "config.h" @@ -81,6 +81,8 @@ int udp_socket = -1; int keylifetime = 0; int keyexpires = 0; +int do_prune = 0; + /* VPN packet I/O */ void receive_udppacket(node_t *n, vpn_packet_t *inpkt) @@ -363,7 +365,6 @@ int setup_outgoing_socket(connection_t *c) { int flags; struct sockaddr_in a; - int option; cp if(debug_lvl >= DEBUG_CONNECTIONS) syslog(LOG_INFO, _("Trying to connect to %s (%s)"), c->name, c->hostname); @@ -804,9 +805,13 @@ cp terminate_connection(c, 0); } -// terminate_connection(myself, 0); + terminate_connection(myself->connection, 0); // destroy_trees(); + exit_edges(); + exit_subnets(); + exit_nodes(); + exit_connections(); execute_script("tinc-down"); @@ -920,15 +925,59 @@ cp /* Terminate a connection: - - Close the sockets - - Remove associated hosts and subnets + - Close the socket + - Remove associated edge and tell other connections about it if report = 1 + - Check if we need to retry making an outgoing connection - Deactivate the host - - Since it might still be referenced, put it on the prune list. - - If report == 1, then send DEL_HOST messages to the other tinc daemons. */ void terminate_connection(connection_t *c, int report) { - /* Needs a serious rewrite. */ + avl_node_t *node; + connection_t *other; +cp + if(c->status.remove) + return; + + if(debug_lvl >= DEBUG_CONNECTIONS) + syslog(LOG_NOTICE, _("Closing connection with %s (%s)"), + c->name, c->hostname); + + c->status.remove = 1; + + if(c->socket) + close(c->socket); + + if(c->edge) + { + if(report) + { + for(node = connection_tree->head; node; node = node->next) + { + other = (connection_t *)node->data; + if(other->status.active && other != c) + send_del_edge(other, c->edge); + } + } + + edge_del(c->edge); + } + + /* Check if this was our outgoing connection */ + + if(c->status.outgoing) + { + c->status.outgoing = 0; + signal(SIGALRM, try_outgoing_connections); + alarm(seconds_till_retry); + syslog(LOG_NOTICE, _("Trying to re-establish outgoing connection in %d seconds"), seconds_till_retry); + } + + /* Deactivate */ + + c->status.active = 0; + c->node->connection = NULL; + do_prune = 1; +cp } /* @@ -1104,6 +1153,22 @@ cp cp } +void prune_connections(void) +{ + connection_t *c; + avl_node_t *node, *next; +cp + for(node = connection_tree->head; node; node = next) + { + next = node->next; + c = (connection_t *)node->data; + + if(c->status.remove) + connection_del(c); + } +cp +} + /* this is where it all happens... */ @@ -1123,6 +1188,12 @@ cp tv.tv_sec = timeout; tv.tv_usec = 0; + if(do_prune) + { + prune_connections(); + do_prune = 0; + } + build_fdset(&fset); if((r = select(FD_SETSIZE, &fset, NULL, NULL, &tv)) < 0) diff --git a/src/protocol.c b/src/protocol.c index 2744592e..c8c41d9f 100644 --- a/src/protocol.c +++ b/src/protocol.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: protocol.c,v 1.28.4.113 2001/10/30 12:59:12 guus Exp $ + $Id: protocol.c,v 1.28.4.114 2001/10/30 16:34:32 guus Exp $ */ #include "config.h" @@ -606,7 +606,7 @@ cp */ - /* Create a edge_t for this connection */ + /* Create an edge_t for this connection */ c->edge = new_edge(); @@ -874,6 +874,11 @@ cp if(n) { /* Check if it matches */ + + if(n->address != address || n->port != port) + syslog(LOG_DEBUG, _("Got %s from %s (%s) for %s which does not match existing entry"), "ADD_NODE", c->name, c->hostname, n->name); + + return 0; } else { @@ -907,11 +912,12 @@ cp int del_node_h(connection_t *c) { node_t *n; + edge_t *e; char name[MAX_STRING_SIZE]; ipv4_t address; port_t port; connection_t *other; - avl_node_t *node; + avl_node_t *node, *next; cp if(sscanf(c->buffer, "%*d "MAX_STRING" %lx:%hd", name, &address, &port) != 3) { @@ -951,8 +957,7 @@ cp if(address != n->address || port != n->port) { - syslog(LOG_WARNING, _("Got %s from %s (%s) for %s which doesn't match"), "DEL_NODE", c->name, c->hostname, n->name); - return 0; + syslog(LOG_WARNING, _("Got %s from %s (%s) for %s which does not match existing entry"), "DEL_NODE", c->name, c->hostname, n->name); } /* Tell the rest about the deleted node */ @@ -964,9 +969,21 @@ cp send_del_node(other, n); } + /* Delete all edges associated with the node */ + + for(node = n->edge_tree->head; node; node = next) + { + next = node->next; + e = (edge_t *)node->data; + edge_del(e); + } + /* Delete the node */ node_del(n); + + mst_kruskal(); + sssp_bfs(); cp return 0; } @@ -1029,13 +1046,19 @@ cp return -1; } - /* Check if node already exists */ + /* Check if edge already exists */ e = lookup_edge(from, to); if(e) { - /* Check if it matches */ + if(e->weight != weight || e->options != options) + { + syslog(LOG_ERR, _("Got %s from %s (%s) which does not match existing entry"), "ADD_EDGE", c->name, c->hostname); + return -1; + } + + return 0; } else { @@ -1067,8 +1090,8 @@ cp int send_del_edge(connection_t *c, edge_t *e) { cp - return send_request(c, "%d %s %s %lx", DEL_EDGE, - e->from->name, e->to->name, e->options); + return send_request(c, "%d %s %s %lx %d", DEL_EDGE, + e->from->name, e->to->name, e->options, e->weight); } int del_edge_h(connection_t *c) @@ -1078,10 +1101,11 @@ int del_edge_h(connection_t *c) char to_name[MAX_STRING_SIZE]; node_t *from, *to; long int options; + int weight; connection_t *other; avl_node_t *node; cp - if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" %lx", from_name, to_name, &options) != 3) + if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" %lx %d", from_name, to_name, &options, &weight) != 4) { syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_EDGE", c->name, c->hostname); @@ -1126,7 +1150,11 @@ cp if(e) { - /* Check if it matches */ + if(e->weight != weight || e->options != options) + { + syslog(LOG_ERR, _("Got %s from %s (%s) which does not match existing entry"), "ADD_EDGE", c->name, c->hostname); + return -1; + } } else { -- 2.39.5