bool found = false;
- for list_each(outgoing_t, outgoing, outgoing_list) {
+ for list_each(outgoing_t, outgoing, &outgoing_list) {
if(outgoing->node == n) {
found = true;
break;
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
outgoing->node = n;
- list_insert_tail(outgoing_list, outgoing);
+ list_insert_tail(&outgoing_list, outgoing);
setup_outgoing_connection(outgoing, false);
}
}
/* Are we already trying to make an outgoing connection to it? If so, return. */
- for list_each(outgoing_t, outgoing, outgoing_list) {
+ for list_each(outgoing_t, outgoing, &outgoing_list) {
if(outgoing->node == n) {
return;
}
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autoconnecting to %s", n->name);
outgoing_t *outgoing = xzalloc(sizeof(*outgoing));
outgoing->node = n;
- list_insert_tail(outgoing_list, outgoing);
+ list_insert_tail(&outgoing_list, outgoing);
setup_outgoing_connection(outgoing, false);
return;
/* Choose a random outgoing connection to a node that has at least one other connection. */
int count = 0;
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) {
continue;
}
int r = rand() % count;
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
if(!c->edge || !c->outgoing || !c->node || c->node->edge_tree->count < 2) {
continue;
}
}
logger(DEBUG_CONNECTIONS, LOG_INFO, "Autodisconnecting from %s", c->name);
- list_delete(outgoing_list, c->outgoing);
+ list_delete(&outgoing_list, c->outgoing);
c->outgoing = NULL;
terminate_connection(c, c->edge);
break;
}
static void drop_superfluous_pending_connections() {
- for list_each(outgoing_t, o, outgoing_list) {
+ for list_each(outgoing_t, o, &outgoing_list) {
/* Only look for connections that are waiting to be retried later. */
bool found = false;
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
if(c->outgoing == o) {
found = true;
break;
}
logger(DEBUG_CONNECTIONS, LOG_INFO, "Cancelled outgoing connection to %s", o->node->name);
- list_delete_node(outgoing_list, node);
+ list_delete_node(&outgoing_list, node);
}
}
/* Count number of active connections. */
int nc = 0;
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
if(c->edge) {
nc++;
}
int pinginterval = 0; /* seconds between pings */
int pingtimeout = 0; /* seconds to wait for response */
-list_t *cmdline_conf = NULL; /* global/host configuration values given at the command line */
+
+/* global/host configuration values given at the command line */
+list_t cmdline_conf = {
+ .head = NULL,
+ .tail = NULL,
+ .count = 0,
+ .delete = (list_action_t)free_config,
+};
static int config_compare(const config_t *a, const config_t *b) {
int result;
}
void read_config_options(splay_tree_t *config_tree, const char *prefix) {
- if(!cmdline_conf) {
- return;
- }
-
size_t prefix_len = prefix ? strlen(prefix) : 0;
- for(const list_node_t *node = cmdline_conf->tail; node; node = node->prev) {
+ for(const list_node_t *node = cmdline_conf.tail; node; node = node->prev) {
const config_t *cfg = node->data;
config_t *new;
extern int pingtimeout;
extern int maxtimeout;
extern bool bypass_security;
-extern list_t *cmdline_conf;
+extern list_t cmdline_conf;
extern void init_configuration(splay_tree_t **config_tree);
extern void exit_configuration(splay_tree_t **config_tree);
#include "utils.h"
#include "xalloc.h"
-list_t *connection_list;
+list_t connection_list = {
+ .head = NULL,
+ .tail = NULL,
+ .count = 0,
+ .delete = (list_action_t) free_connection,
+};
+
connection_t *everyone;
void init_connections(void) {
- connection_list = list_alloc((list_action_t) free_connection);
everyone = new_connection();
everyone->name = xstrdup("everyone");
everyone->hostname = xstrdup("BROADCAST");
}
void exit_connections(void) {
- list_delete_list(connection_list);
- connection_list = NULL;
+ list_empty_list(&connection_list);
free_connection(everyone);
everyone = NULL;
}
void connection_add(connection_t *c) {
- list_insert_tail(connection_list, c);
+ list_insert_tail(&connection_list, c);
}
void connection_del(connection_t *c) {
- list_delete(connection_list, c);
+ list_delete(&connection_list, c);
}
bool dump_connections(connection_t *cdump) {
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
send_request(cdump, "%d %d %s %s %x %d %x",
CONTROL, REQ_DUMP_CONNECTIONS,
c->name, c->hostname, c->options, c->socket,
splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */
} connection_t;
-extern list_t *connection_list;
+extern list_t connection_list;
extern connection_t *everyone;
extern void init_connections(void);
return control_return(c, REQ_DISCONNECT, -1);
}
- for list_each(connection_t, other, connection_list) {
+ for list_each(connection_t, other, &connection_list) {
if(strcmp(other->name, name)) {
continue;
}
static void mst_kruskal(void) {
/* Clear MST status on connections */
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
c->status.mst = false;
}
/* Fast list deletion */
-void list_delete_list(list_t *list) {
+void list_empty_list(list_t *list) {
for(list_node_t *node = list->head, *next; next = node ? node->next : NULL, node; node = next) {
list_free_node(list, node);
}
+ list->head = NULL;
+ list->tail = NULL;
+ list->count = 0;
+}
+
+void list_delete_list(list_t *list) {
+ list_empty_list(list);
list_free(list);
}
extern list_node_t *list_insert_after(list_t *list, list_node_t *node, void *data);
extern list_node_t *list_insert_before(list_t *list, list_node_t *node, void *data);
+extern void list_empty_list(list_t *list);
extern void list_delete(list_t *list, const void *data);
extern void list_unlink_node(list_t *list, list_node_t *node);
}
}
- if(logcontrol && connection_list) {
+ if(logcontrol) {
suppress = true;
logcontrol = false;
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
if(!c->status.log) {
continue;
}
}
void broadcast_meta(connection_t *from, const char *buffer, size_t length) {
- for list_each(connection_t, c, connection_list)
+ for list_each(connection_t, c, &connection_list)
if(c != from && c->edge) {
send_meta(c, buffer, length);
}
last_periodic_run_time = now;
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
// control connections (eg. tinc ctl) do not have any timeout
if(c->status.control) {
continue;
/* Close connections to hosts that have a changed or deleted host config file */
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
if(c->status.control) {
continue;
}
void retry(void) {
/* Reset the reconnection timers for all outgoing connections */
- for list_each(outgoing_t, outgoing, outgoing_list) {
+ for list_each(outgoing_t, outgoing, &outgoing_list) {
outgoing->timeout = 0;
if(outgoing->ev.cb)
}
/* Check for outgoing connections that are in progress, and reset their ping timers */
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
if(c->outgoing && !c->node) {
c->last_ping_time = 0;
}
timeout_t ev;
} outgoing_t;
-extern list_t *outgoing_list;
+extern list_t outgoing_list;
extern int maxoutbufsize;
extern int seconds_till_retry;
// This guarantees all nodes receive the broadcast packet, and
// usually distributes the sending of broadcast packets over all nodes.
case BMODE_MST:
- for list_each(connection_t, c, connection_list)
+ for list_each(connection_t, c, &connection_list)
if(c->edge && c->status.mst && c != from->nexthop->connection) {
send_packet(c->node, packet);
}
close all open network connections
*/
void close_network_connections(void) {
- for(list_node_t *node = connection_list->head, *next; node; node = next) {
+ for(list_node_t *node = connection_list.head, *next; node; node = next) {
next = node->next;
connection_t *c = node->data;
terminate_connection(c, false);
}
- if(outgoing_list) {
- list_delete_list(outgoing_list);
- }
+ list_empty_list(&outgoing_list);
if(myself && myself->connection) {
subnet_update(myself, NULL, false);
#ifndef HAVE_MINGW
io_t unix_socket;
#endif
-list_t *outgoing_list = NULL;
+
+static void free_outgoing(outgoing_t *outgoing) {
+ timeout_del(&outgoing->ev);
+ free(outgoing);
+}
+
+list_t outgoing_list = {
+ .head = NULL,
+ .tail = NULL,
+ .count = 0,
+ .delete = (list_action_t)free_outgoing,
+};
/* Setup sockets */
return;
remove:
- list_delete(outgoing_list, outgoing);
+ list_delete(&outgoing_list, outgoing);
}
/*
}
#endif
-static void free_outgoing(outgoing_t *outgoing) {
- timeout_del(&outgoing->ev);
- free(outgoing);
-}
-
void try_outgoing_connections(void) {
/* If there is no outgoing list yet, create one. Otherwise, mark all outgoings as deleted. */
- if(!outgoing_list) {
- outgoing_list = list_alloc((list_action_t)free_outgoing);
- } else {
- for list_each(outgoing_t, outgoing, outgoing_list) {
- outgoing->timeout = -1;
- }
+ for list_each(outgoing_t, outgoing, &outgoing_list) {
+ outgoing->timeout = -1;
}
/* Make sure there is one outgoing_t in the list for each ConnectTo. */
bool found = false;
- for list_each(outgoing_t, outgoing, outgoing_list) {
+ for list_each(outgoing_t, outgoing, &outgoing_list) {
if(!strcmp(outgoing->node->name, name)) {
found = true;
outgoing->timeout = 0;
free(name);
outgoing->node = n;
- list_insert_tail(outgoing_list, outgoing);
+ list_insert_tail(&outgoing_list, outgoing);
setup_outgoing_connection(outgoing, true);
}
}
/* Terminate any connections whose outgoing_t is to be deleted. */
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
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_each(outgoing_t, outgoing, outgoing_list)
+ for list_each(outgoing_t, outgoing, &outgoing_list)
if(outgoing->timeout == -1) {
- list_delete_node(outgoing_list, node);
+ list_delete_node(&outgoing_list, node);
}
}
/* Immediately send new keys to directly connected nodes to keep UDP mappings alive */
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
if(c->edge && c->node && c->node->status.reachable && !c->node->status.sptps) {
send_ans_key(c->node);
}
}
}
- for list_each(connection_t, c, connection_list)
+ for list_each(connection_t, c, &connection_list)
if(c->edge) {
send_del_subnet(c, s);
}
/* And tell all other tinc daemons it's our MAC */
- for list_each(connection_t, c, connection_list)
+ for list_each(connection_t, c, &connection_list)
if(c->edge) {
send_add_subnet(c, subnet);
}
static void send_pcap(vpn_packet_t *packet) {
pcap = false;
- for list_each(connection_t, c, connection_list) {
+ for list_each(connection_t, c, &connection_list) {
if(!c->status.pcap) {
continue;
}
int option_index = 0;
int lineno = 0;
- cmdline_conf = list_alloc((list_action_t)free_config);
-
while((r = getopt_long(argc, argv, "c:DLd::n:so:RU:", long_options, &option_index)) != EOF) {
switch(r) {
case 0: /* long option */
goto exit_fail;
}
- list_insert_tail(cmdline_conf, cfg);
+ list_insert_tail(&cmdline_conf, cfg);
break;
#ifdef HAVE_MINGW
exit_fail:
free_names();
- list_delete_list(cmdline_conf);
- cmdline_conf = NULL;
+ list_empty_list(&cmdline_conf);
return false;
}
exit_configuration(&config_tree);
}
- list_delete_list(cmdline_conf);
+ list_empty_list(&cmdline_conf);
free_names();
}