X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Faddress_cache.c;h=f28dbf902d003d9fee443c0494bbeef95af13478;hb=c6a15e27d934e90a1f3a26438dddb395bdc9de19;hp=42b671b8990208c5d402f9f6005c1450cbc7b19e;hpb=e0f6d90e7fac4c567900e98c354af979c97f8d59;p=tinc diff --git a/src/address_cache.c b/src/address_cache.c index 42b671b8..f28dbf90 100644 --- a/src/address_cache.c +++ b/src/address_cache.c @@ -25,14 +25,14 @@ #include "netutl.h" #include "xalloc.h" -static const unsigned int NOT_CACHED = -1; +static const unsigned int NOT_CACHED = UINT_MAX; // Find edges pointing to this node, and use them to build a list of unique, known addresses. static struct addrinfo *get_known_addresses(node_t *n) { struct addrinfo *ai = NULL; struct addrinfo *oai = NULL; - for splay_each(edge_t, e, n->edge_tree) { + for splay_each(edge_t, e, &n->edge_tree) { if(!e->reverse) { continue; } @@ -67,6 +67,7 @@ static struct addrinfo *get_known_addresses(node_t *n) { static void free_known_addresses(struct addrinfo *ai) { for(struct addrinfo *aip = ai, *next; aip; aip = next) { next = aip->ai_next; + free(aip->ai_addr); free(aip); } } @@ -85,14 +86,18 @@ void add_recent_address(address_cache_t *cache, const sockaddr_t *sa) { unsigned int pos = find_cached(cache, sa); // It's in the first spot, so nothing to do - if (pos == 0) { + if(pos == 0) { return; } + logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Caching recent address for %s", cache->node->name); + // Shift everything, move/add the address to the first slot if(pos == NOT_CACHED) { - if(cache->data.used < MAX_CACHED_ADDRESSES) + if(cache->data.used < MAX_CACHED_ADDRESSES) { cache->data.used++; + } + pos = cache->data.used - 1; } @@ -106,7 +111,6 @@ void add_recent_address(address_cache_t *cache, const sockaddr_t *sa) { FILE *fp = fopen(fname, "wb"); if(fp) { - fprintf(stderr, "Writing cache to %s\n", fname); fwrite(&cache->data, sizeof(cache->data), 1, fp); fclose(fp); } @@ -126,13 +130,13 @@ const sockaddr_t *get_recent_address(address_cache_t *cache) { if(cache->ai) { if(cache->aip) { - sockaddr_t *sa = (sockaddr_t *)cache->aip; + sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr; + cache->aip = cache->aip->ai_next; if(find_cached(cache, sa) != NOT_CACHED) { continue; } - cache->aip = cache->aip->ai_next; return sa; } else { free_known_addresses(cache->ai); @@ -145,12 +149,12 @@ const sockaddr_t *get_recent_address(address_cache_t *cache) { // Otherwise, check if there are any known Address statements if(!cache->config_tree) { - init_configuration(&cache->config_tree); + cache->config_tree = create_configuration(); read_host_config(cache->config_tree, cache->node->name, false); cache->cfg = lookup_config(cache->config_tree, "Address"); } - while(cache->cfg && !cache->ai) { + while(cache->cfg && !cache->aip) { char *address, *port; get_config_string(cache->cfg, &address); @@ -166,28 +170,55 @@ const sockaddr_t *get_recent_address(address_cache_t *cache) { } } + if(cache->ai) { + free_known_addresses(cache->ai); + } + cache->aip = cache->ai = str2addrinfo(address, port, SOCK_STREAM); + + if(cache->ai) { + struct addrinfo *ai = NULL; + + for(; cache->aip; cache->aip = cache->aip->ai_next) { + struct addrinfo *oai = ai; + + ai = xzalloc(sizeof(*ai)); + ai->ai_family = cache->aip->ai_family; + ai->ai_socktype = cache->aip->ai_socktype; + ai->ai_protocol = cache->aip->ai_protocol; + ai->ai_addrlen = cache->aip->ai_addrlen; + ai->ai_addr = xmalloc(ai->ai_addrlen); + memcpy(ai->ai_addr, cache->aip->ai_addr, ai->ai_addrlen); + ai->ai_next = oai; + } + + freeaddrinfo(cache->ai); + cache->aip = cache->ai = ai; + } + free(address); free(port); cache->cfg = lookup_config_next(cache->config_tree, cache->cfg); } - if(cache->aip) { - sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr; - cache->aip = cache->aip->ai_next; + if(cache->ai) { + if(cache->aip) { + sockaddr_t *sa = (sockaddr_t *)cache->aip->ai_addr; - if(!cache->aip) { - freeaddrinfo(cache->ai); - cache->ai = cache->aip = NULL; + cache->aip = cache->aip->ai_next; + return sa; + } else { + free_known_addresses(cache->ai); + cache->ai = NULL; } - - return sa; } // We're all out of addresses. - exit_configuration(&cache->config_tree); - return false; + exit_configuration(cache->config_tree); + cache->config_tree = NULL; + + return NULL; } address_cache_t *open_address_cache(node_t *node) { @@ -222,21 +253,14 @@ address_cache_t *open_address_cache(node_t *node) { return cache; } -void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) { - if(sa) { - add_recent_address(cache, sa); - } - +void reset_address_cache(address_cache_t *cache) { if(cache->config_tree) { - exit_configuration(&cache->config_tree); + exit_configuration(cache->config_tree); + cache->config_tree = NULL; } if(cache->ai) { - if(cache->tried == cache->data.used) { - free_known_addresses(cache->ai); - } else { - freeaddrinfo(cache->ai); - } + free_known_addresses(cache->ai); } cache->config_tree = NULL; @@ -248,15 +272,12 @@ void reset_address_cache(address_cache_t *cache, const sockaddr_t *sa) { void close_address_cache(address_cache_t *cache) { if(cache->config_tree) { - exit_configuration(&cache->config_tree); + exit_configuration(cache->config_tree); + cache->config_tree = NULL; } if(cache->ai) { - if(cache->tried == cache->data.used) { - free_known_addresses(cache->ai); - } else { - freeaddrinfo(cache->ai); - } + free_known_addresses(cache->ai); } free(cache);