We know what struct addrinfo looks like, but the standard says nothing
about how it is allocated. So we cannot trust freeaddrinfo() to work
correctly on the struct addrinfo list we allocated ourselves in
get_known_addresses(). To make a distinction by allocations from the
latter and from str2addrinfo(), we keep two pointers (*ai and *kai) in
struct outgoing, and use the freeing function that is appropriate for
each.
int timeout;
splay_tree_t *config_tree;
struct config_t *cfg;
int timeout;
splay_tree_t *config_tree;
struct config_t *cfg;
+ struct addrinfo *ai; // addresses from config files
+ struct addrinfo *kai; // addresses known via other online nodes (use free_known_addresses())
timeout_t ev;
} outgoing_t;
timeout_t ev;
} outgoing_t;
handle_meta_connection_data(c);
}
handle_meta_connection_data(c);
}
+static void free_known_addresses(struct addrinfo *ai) {
+ for(struct addrinfo *aip = ai, *next; aip; aip = next) {
+ next = aip->ai_next;
+ free(aip);
+ }
+}
+
bool do_outgoing_connection(outgoing_t *outgoing) {
char *address, *port, *space;
struct addrinfo *proxyai = NULL;
int result;
begin:
bool do_outgoing_connection(outgoing_t *outgoing) {
char *address, *port, *space;
struct addrinfo *proxyai = NULL;
int result;
begin:
+ if(!outgoing->ai && !outgoing->kai) {
if(!outgoing->cfg) {
logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name);
retry_outgoing(outgoing);
if(!outgoing->cfg) {
logger(DEBUG_CONNECTIONS, LOG_ERR, "Could not set up a meta connection to %s", outgoing->name);
retry_outgoing(outgoing);
if(outgoing->ai)
freeaddrinfo(outgoing->ai);
outgoing->ai = NULL;
if(outgoing->ai)
freeaddrinfo(outgoing->ai);
outgoing->ai = NULL;
+
+ if(outgoing->kai)
+ free_known_addresses(outgoing->kai);
+ outgoing->kai = NULL;
+
if(!outgoing->cfg) {
if(n)
if(!outgoing->cfg) {
if(n)
- outgoing->aip = outgoing->ai = get_known_addresses(n);
- if(!outgoing->ai) {
+ outgoing->aip = outgoing->kai = get_known_addresses(n);
+ if(!outgoing->kai) {
logger(DEBUG_ALWAYS, LOG_DEBUG, "No address known for %s", outgoing->name);
goto remove;
}
logger(DEBUG_ALWAYS, LOG_DEBUG, "No address known for %s", outgoing->name);
goto remove;
}
if(outgoing->ai)
freeaddrinfo(outgoing->ai);
if(outgoing->ai)
freeaddrinfo(outgoing->ai);
+ if(outgoing->kai)
+ free_known_addresses(outgoing->kai);
+
if(outgoing->config_tree)
exit_configuration(&outgoing->config_tree);
if(outgoing->config_tree)
exit_configuration(&outgoing->config_tree);