From: Fufu Fang Date: Tue, 10 Aug 2021 00:53:00 +0000 (+0100) Subject: Reduce pointer indirection for global list_t variables X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=commitdiff_plain;h=0871c3095151bce6a4031a2662aa51b7193b855c Reduce pointer indirection for global list_t variables Converted cmdline_conf, connection_list, outgoing_list from pointer-to-structs to structs. Created list_empty_list for these structs. This is necessary, because list_delete_list frees the supplied list_t pointer. Part of https://github.com/gsliepen/tinc/issues/294 --- diff --git a/src/autoconnect.c b/src/autoconnect.c index d819ee46..5651f54d 100644 --- a/src/autoconnect.c +++ b/src/autoconnect.c @@ -53,7 +53,7 @@ static void make_new_connection() { 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; @@ -64,7 +64,7 @@ static void make_new_connection() { 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); } @@ -93,7 +93,7 @@ static void connect_to_unreachable() { } /* 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; } @@ -102,7 +102,7 @@ static void connect_to_unreachable() { 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; @@ -113,7 +113,7 @@ static void drop_superfluous_outgoing_connection() { /* 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; } @@ -127,7 +127,7 @@ static void drop_superfluous_outgoing_connection() { 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; } @@ -137,7 +137,7 @@ static void drop_superfluous_outgoing_connection() { } 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; @@ -145,11 +145,11 @@ static void drop_superfluous_outgoing_connection() { } 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; @@ -161,7 +161,7 @@ static void drop_superfluous_pending_connections() { } 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); } } @@ -169,7 +169,7 @@ void do_autoconnect() { /* 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++; } diff --git a/src/conf.c b/src/conf.c index a0107d02..90bd3697 100644 --- a/src/conf.c +++ b/src/conf.c @@ -38,7 +38,14 @@ splay_tree_t *config_tree = NULL; 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; @@ -334,13 +341,9 @@ bool read_config_file(splay_tree_t *config_tree, const char *fname, bool verbose } 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; diff --git a/src/conf.h b/src/conf.h index d6479a2e..07db631c 100644 --- a/src/conf.h +++ b/src/conf.h @@ -39,7 +39,7 @@ extern int pinginterval; 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); diff --git a/src/connection.c b/src/connection.c index 5a7c43b8..0c5e7ef0 100644 --- a/src/connection.c +++ b/src/connection.c @@ -31,19 +31,23 @@ #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; @@ -96,15 +100,15 @@ void free_connection(connection_t *c) { } 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, diff --git a/src/connection.h b/src/connection.h index 4a9ef446..b23e02b7 100644 --- a/src/connection.h +++ b/src/connection.h @@ -107,7 +107,7 @@ typedef struct connection_t { 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); diff --git a/src/control.c b/src/control.c index 6e2a7f32..175f2bd0 100644 --- a/src/control.c +++ b/src/control.c @@ -108,7 +108,7 @@ bool control_h(connection_t *c, const char *request) { 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; } diff --git a/src/graph.c b/src/graph.c index 4de9181c..3a843063 100644 --- a/src/graph.c +++ b/src/graph.c @@ -64,7 +64,7 @@ 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; } diff --git a/src/list.c b/src/list.c index 27494c89..50f3fdbb 100644 --- a/src/list.c +++ b/src/list.c @@ -184,11 +184,18 @@ void *list_get_tail(list_t *list) { /* 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); } diff --git a/src/list.h b/src/list.h index 3806495c..511b64a4 100644 --- a/src/list.h +++ b/src/list.h @@ -57,6 +57,7 @@ extern list_node_t *list_insert_tail(list_t *list, void *data); 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); diff --git a/src/logger.c b/src/logger.c index 55616fba..1a2e95ff 100644 --- a/src/logger.c +++ b/src/logger.c @@ -96,11 +96,11 @@ static void real_logger(debug_t level, int priority, const char *message) { } } - 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; } diff --git a/src/meta.c b/src/meta.c index afc98ab2..7a8baac4 100644 --- a/src/meta.c +++ b/src/meta.c @@ -109,7 +109,7 @@ void send_meta_raw(connection_t *c, const void *buffer, size_t length) { } 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); } diff --git a/src/net.c b/src/net.c index 33870f1e..dffe0b47 100644 --- a/src/net.c +++ b/src/net.c @@ -209,7 +209,7 @@ static void timeout_handler(void *data) { 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; @@ -434,7 +434,7 @@ int reload_configuration(void) { /* 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; } @@ -455,7 +455,7 @@ int reload_configuration(void) { 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) @@ -465,7 +465,7 @@ void retry(void) { } /* 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; } diff --git a/src/net.h b/src/net.h index 28f8cb5e..f945a1f9 100644 --- a/src/net.h +++ b/src/net.h @@ -120,7 +120,7 @@ typedef struct outgoing_t { timeout_t ev; } outgoing_t; -extern list_t *outgoing_list; +extern list_t outgoing_list; extern int maxoutbufsize; extern int seconds_till_retry; diff --git a/src/net_packet.c b/src/net_packet.c index dab74e5d..3f2fb489 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -1623,7 +1623,7 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet) { // 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); } diff --git a/src/net_setup.c b/src/net_setup.c index c2e0825e..4e1f2b81 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -1149,7 +1149,7 @@ bool setup_network(void) { 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; @@ -1162,9 +1162,7 @@ void close_network_connections(void) { 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); diff --git a/src/net_socket.c b/src/net_socket.c index 40671db0..a29398d3 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -49,7 +49,18 @@ int listen_sockets; #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 */ @@ -675,7 +686,7 @@ void setup_outgoing_connection(outgoing_t *outgoing, bool verbose) { return; remove: - list_delete(outgoing_list, outgoing); + list_delete(&outgoing_list, outgoing); } /* @@ -809,20 +820,11 @@ void handle_new_unix_connection(void *data, int flags) { } #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. */ @@ -846,7 +848,7 @@ void try_outgoing_connections(void) { 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; @@ -867,14 +869,14 @@ void try_outgoing_connections(void) { 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); @@ -884,8 +886,8 @@ void try_outgoing_connections(void) { /* 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); } } diff --git a/src/protocol_key.c b/src/protocol_key.c index 29fe5090..b69d5adc 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -39,7 +39,7 @@ void send_key_changed(void) { /* 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); } diff --git a/src/route.c b/src/route.c index e11a7922..559cf2fc 100644 --- a/src/route.c +++ b/src/route.c @@ -504,7 +504,7 @@ static void age_subnets(void *data) { } } - for list_each(connection_t, c, connection_list) + for list_each(connection_t, c, &connection_list) if(c->edge) { send_del_subnet(c, s); } @@ -543,7 +543,7 @@ static void learn_mac(mac_t *address) { /* 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); } @@ -1111,7 +1111,7 @@ static void route_mac(node_t *source, vpn_packet_t *packet) { 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; } diff --git a/src/tincd.c b/src/tincd.c index 95872c34..dee38ef1 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -148,8 +148,6 @@ static bool parse_options(int argc, char **argv) { 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 */ @@ -203,7 +201,7 @@ static bool parse_options(int argc, char **argv) { goto exit_fail; } - list_insert_tail(cmdline_conf, cfg); + list_insert_tail(&cmdline_conf, cfg); break; #ifdef HAVE_MINGW @@ -294,8 +292,7 @@ static bool parse_options(int argc, char **argv) { exit_fail: free_names(); - list_delete_list(cmdline_conf); - cmdline_conf = NULL; + list_empty_list(&cmdline_conf); return false; } @@ -386,7 +383,7 @@ static void cleanup() { exit_configuration(&config_tree); } - list_delete_list(cmdline_conf); + list_empty_list(&cmdline_conf); free_names(); }