The tree functions were never used on the connection_tree, a list is more appropriate.
Also be more paranoid about connections disappearing while traversing the list.
#include "system.h"
-#include "splay_tree.h"
+#include "list.h"
#include "cipher.h"
#include "conf.h"
#include "control_common.h"
#include "utils.h"
#include "xalloc.h"
-splay_tree_t *connection_tree; /* Meta connections */
+list_t *connection_list; /* Meta connections */
connection_t *everyone;
-static int connection_compare(const connection_t *a, const connection_t *b) {
- return a < b ? -1 : a == b ? 0 : 1;
-}
-
void init_connections(void) {
- connection_tree = splay_alloc_tree((splay_compare_t) connection_compare, (splay_action_t) free_connection);
+ connection_list = list_alloc((list_action_t) free_connection);
everyone = new_connection();
everyone->name = xstrdup("everyone");
everyone->hostname = xstrdup("BROADCAST");
}
void exit_connections(void) {
- splay_delete_tree(connection_tree);
+ list_delete_list(connection_list);
free_connection(everyone);
}
}
void connection_add(connection_t *c) {
- splay_insert(connection_tree, c);
+ list_insert_tail(connection_list, c);
}
void connection_del(connection_t *c) {
- splay_delete(connection_tree, c);
+ for(list_node_t *node = connection_list->head; node; node = node->next) {
+ if(node->data == c) {
+ list_delete_node(connection_list, node);
+ return;
+ }
+ }
}
bool dump_connections(connection_t *cdump) {
- splay_node_t *node;
- connection_t *c;
-
- for(node = connection_tree->head; node; node = node->next) {
- c = node->data;
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ next = node->next;
+ connection_t *c = node->data;
send_request(cdump, "%d %d %s %s %x %d %x",
CONTROL, REQ_DUMP_CONNECTIONS,
c->name, c->hostname, c->options, c->socket,
#include "cipher.h"
#include "digest.h"
#include "rsa.h"
-#include "splay_tree.h"
+#include "list.h"
#include "sptps.h"
#define OPTION_INDIRECT 0x0001
splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */
} connection_t;
-extern splay_tree_t *connection_tree;
+extern list_t *connection_list;
extern connection_t *everyone;
extern void init_connections(void);
case REQ_DISCONNECT: {
char name[MAX_STRING_SIZE];
connection_t *other;
- splay_node_t *node, *next;
bool found = false;
if(sscanf(request, "%*d %*d " MAX_STRING, name) != 1)
return control_return(c, REQ_DISCONNECT, -1);
- for(node = connection_tree->head; node; node = next) {
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
next = node->next;
other = node->data;
if(strcmp(other->name, name))
#include "system.h"
-#include "splay_tree.h"
#include "config.h"
#include "connection.h"
#include "device.h"
#include "edge.h"
#include "graph.h"
+#include "list.h"
#include "logger.h"
#include "netutl.h"
#include "node.h"
*/
static void mst_kruskal(void) {
- splay_node_t *node, *next;
- edge_t *e;
- node_t *n;
- connection_t *c;
-
/* Clear MST status on connections */
- for(node = connection_tree->head; node; node = node->next) {
- c = node->data;
+ for(list_node_t *node = connection_list->head; node; node = node->next) {
+ connection_t *c = node->data;
c->status.mst = false;
}
/* Clear visited status on nodes */
- for(node = node_tree->head; node; node = node->next) {
- n = node->data;
+ for(splay_node_t *node = node_tree->head; node; node = node->next) {
+ node_t *n = node->data;
n->status.visited = false;
}
/* Add safe edges */
- for(node = edge_weight_tree->head; node; node = next) {
+ for(splay_node_t *node = edge_weight_tree->head, *next; node; node = next) {
next = node->next;
- e = node->data;
+ edge_t *e = node->data;
if(!e->reverse || (e->from->status.visited && e->to->status.visited))
continue;
if(logcontrol) {
suppress = true;
logcontrol = false;
- for(splay_node_t *node = connection_tree->head; node; node = node->next) {
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ next = node->next;
connection_t *c = node->data;
if(!c->status.log)
continue;
#include "system.h"
-#include "splay_tree.h"
#include "cipher.h"
#include "connection.h"
#include "logger.h"
}
void broadcast_meta(connection_t *from, const char *buffer, int length) {
- splay_node_t *node;
- connection_t *c;
-
- for(node = connection_tree->head; node; node = node->next) {
- c = node->data;
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ next = node->next;
+ connection_t *c = node->data;
if(c != from && c->status.active)
send_meta(c, buffer, length);
#include "system.h"
#include "utils.h"
-#include "splay_tree.h"
#include "conf.h"
#include "connection.h"
#include "device.h"
and close the connection.
*/
static void timeout_handler(int fd, short events, void *event) {
- splay_node_t *node, *next;
- connection_t *c;
time_t now = time(NULL);
- for(node = connection_tree->head; node; node = next) {
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
next = node->next;
- c = node->data;
+ connection_t *c = node->data;
if(c->status.control)
continue;
}
int reload_configuration(void) {
- connection_t *c;
- splay_node_t *node, *next;
char *fname;
- struct stat s;
/* Reread our own configuration file */
/* If StrictSubnet is set, expire deleted Subnets and read new ones in */
if(strictsubnets) {
- subnet_t *subnet;
-
- for(node = subnet_tree->head; node; node = node->next) {
- subnet = node->data;
+ for(splay_node_t *node = subnet_tree->head; node; node = node->next) {
+ subnet_t *subnet = node->data;
subnet->expires = 1;
}
load_all_subnets();
- for(node = subnet_tree->head; node; node = next) {
+ for(splay_node_t *node = subnet_tree->head, *next; node; node = next) {
next = node->next;
- subnet = node->data;
+ subnet_t *subnet = node->data;
if(subnet->expires == 1) {
send_del_subnet(everyone, subnet);
if(subnet->owner->status.reachable)
}
}
} else { /* Only read our own subnets back in */
- subnet_t *subnet, *s2;
-
- for(node = myself->subnet_tree->head; node; node = node->next) {
+ for(splay_node_t *node = myself->subnet_tree->head; node; node = node->next) {
subnet_t *subnet = node->data;
if(!subnet->expires)
subnet->expires = 1;
config_t *cfg = lookup_config(config_tree, "Subnet");
while(cfg) {
+ subnet_t *subnet, *s2;
+
if(!get_config_subnet(cfg, &subnet))
continue;
cfg = lookup_config_next(config_tree, cfg);
}
- for(node = myself->subnet_tree->head; node; node = next) {
+ for(splay_node_t *node = myself->subnet_tree->head, *next; node; node = next) {
next = node->next;
subnet_t *subnet = node->data;
if(subnet->expires == 1) {
/* Close connections to hosts that have a changed or deleted host config file */
- for(node = connection_tree->head; node; node = next) {
- c = node->data;
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ connection_t *c = node->data;
next = node->next;
if(c->status.control)
continue;
xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, c->name);
+ struct stat s;
if(stat(fname, &s) || s.st_mtime > last_config_check) {
logger(DEBUG_CONNECTIONS, LOG_INFO, "Host config file of %s has been changed", c->name);
terminate_connection(c, c->status.active);
}
void retry(void) {
- connection_t *c;
- splay_node_t *node, *next;
-
- for(node = connection_tree->head; node; node = next) {
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
next = node->next;
- c = node->data;
+ connection_t *c = node->data;
if(c->outgoing && !c->node) {
if(timeout_initialized(&c->outgoing->ev))
#include LZO1X_H
#endif
-#include "splay_tree.h"
#include "cipher.h"
#include "conf.h"
#include "connection.h"
/* Broadcast a packet using the minimum spanning tree */
void broadcast_packet(const node_t *from, vpn_packet_t *packet) {
- splay_node_t *node;
- connection_t *c;
- node_t *n;
-
// Always give ourself a copy of the packet.
if(from != myself)
send_packet(myself, packet);
// This guarantees all nodes receive the broadcast packet, and
// usually distributes the sending of broadcast packets over all nodes.
case BMODE_MST:
- for(node = connection_tree->head; node; node = node->next) {
- c = node->data;
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ next = node->next;
+ connection_t *c = node->data;
if(c->status.active && c->status.mst && c != from->nexthop->connection)
send_packet(c->node, packet);
if(from != myself)
break;
- for(node = node_tree->head; node; node = node->next) {
- n = node->data;
+ for(splay_node_t *node = node_tree->head; node; node = node->next) {
+ node_t *n = node->data;
if(n->status.reachable && ((n->via == myself && n->nexthop == n) || n->via == n))
send_packet(n, packet);
#include "system.h"
-#include "splay_tree.h"
#include "cipher.h"
#include "conf.h"
#include "connection.h"
close all open network connections
*/
void close_network_connections(void) {
- splay_node_t *node, *next;
- connection_t *c;
- char *envp[5];
- int i;
-
- for(node = connection_tree->head; node; node = next) {
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
next = node->next;
- c = node->data;
+ connection_t *c = node->data;
/* Keep control connections open until the end, so they know when we really terminated */
if(c->status.control)
c->socket = -1;
free_connection(myself->connection);
}
- for(i = 0; i < listen_sockets; i++) {
+ for(int i = 0; i < listen_sockets; i++) {
event_del(&listen_socket[i].ev_tcp);
event_del(&listen_socket[i].ev_udp);
close(listen_socket[i].tcp);
close(listen_socket[i].udp);
}
+ char *envp[5];
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
if(myport) free(myport);
- for(i = 0; i < 4; i++)
+ for(int i = 0; i < 4; i++)
free(envp[i]);
devops.close();
#include "system.h"
-#include "splay_tree.h"
#include "conf.h"
#include "connection.h"
#include "logger.h"
/* Terminate any connections whose outgoing_t is to be deleted. */
- for(splay_node_t *n = connection_tree->head, *next; n; n = next) {
- next = n->next;
- connection_t *c = n->data;
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ next = node->next;
+ connection_t *c = node->data;
if(c->outgoing && c->outgoing->timeout == -1) {
c->outgoing = NULL;
logger(DEBUG_CONNECTIONS, LOG_INFO, "No more outgoing connection to %s", c->name);
/* Delete outgoing_ts for which there is no ConnectTo. */
- for(list_node_t *i = outgoing_list->head, *next; i; i = next) {
- next = i->next;
- outgoing = i->data;
+ for(list_node_t *node = outgoing_list->head, *next; node; node = next) {
+ next = node->next;
+ outgoing = node->data;
if(outgoing->timeout == -1)
- list_delete_node(outgoing_list, i);
+ list_delete_node(outgoing_list, node);
}
}
#include "system.h"
-#include "splay_tree.h"
#include "conf.h"
#include "connection.h"
#include "control.h"
#include "system.h"
-#include "splay_tree.h"
#include "conf.h"
#include "connection.h"
#include "edge.h"
#include "system.h"
-#include "splay_tree.h"
#include "cipher.h"
#include "connection.h"
#include "crypto.h"
static bool mykeyused = false;
void send_key_changed(void) {
- splay_node_t *node;
- connection_t *c;
-
send_request(everyone, "%d %x %s", KEY_CHANGED, rand(), myself->name);
/* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
- for(node = connection_tree->head; node; node = node->next) {
- c = node->data;
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ next = node->next;
+ connection_t *c = node->data;
if(c->status.active && c->node && c->node->status.reachable) {
if(!c->node->status.sptps)
send_ans_key(c->node);
/* Force key exchange for connections using SPTPS */
if(experimental) {
- for(node = node_tree->head; node; node = node->next) {
+ for(splay_node_t *node = node_tree->head; node; node = node->next) {
node_t *n = node->data;
if(n->status.reachable && n->status.validkey && n->status.sptps)
sptps_force_kex(&n->sptps);
#include "system.h"
-#include "splay_tree.h"
#include "connection.h"
#include "control_common.h"
#include "ethernet.h"
}
static void age_subnets(int fd, short events, void *data) {
- subnet_t *s;
- connection_t *c;
- splay_node_t *node, *next, *node2;
bool left = false;
time_t now = time(NULL);
- for(node = myself->subnet_tree->head; node; node = next) {
+ for(splay_node_t *node = myself->subnet_tree->head, *next; node; node = next) {
next = node->next;
- s = node->data;
+ subnet_t *s = node->data;
if(s->expires && s->expires < now) {
if(debug_level >= DEBUG_TRAFFIC) {
char netstr[MAXNETSTR];
logger(DEBUG_TRAFFIC, LOG_INFO, "Subnet %s expired", netstr);
}
- for(node2 = connection_tree->head; node2; node2 = node2->next) {
- c = node2->data;
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ next = node->next;
+ connection_t *c = node->data;
if(c->status.active)
send_del_subnet(c, s);
}
}
static void learn_mac(mac_t *address) {
- subnet_t *subnet;
- splay_node_t *node;
- connection_t *c;
-
- subnet = lookup_subnet_mac(myself, address);
+ subnet_t *subnet = lookup_subnet_mac(myself, address);
/* If we don't know this MAC address yet, store it */
/* And tell all other tinc daemons it's our MAC */
- for(node = connection_tree->head; node; node = node->next) {
- c = node->data;
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ next = node->next;
+ connection_t *c = node->data;
if(c->status.active)
send_add_subnet(c, subnet);
}
static void send_pcap(vpn_packet_t *packet) {
pcap = false;
- for(splay_node_t *node = connection_tree->head; node; node = node->next) {
+ for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ next = node->next;
connection_t *c = node->data;
if(!c->status.pcap)
continue;
// Symbols necessary to link with logger.o
bool send_request(void *c, const char *msg, ...) { return false; }
-struct splay_tree_t *connection_tree = NULL;
+struct list_t *connection_list = NULL;
bool send_meta(void *c, const char *msg , int len) { return false; }
char *logfilename = NULL;