*
* Connection Manager
*
- * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ * Copyright (C) 2007-2012 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
/* now the query, which is a name and 2 16 bit words */
l = dns_name_length(c) + 1;
c += l;
- len -= l;
w = (uint16_t *) c;
type = ntohs(*w);
sk = g_io_channel_unix_get_fd(server->channel);
err = send(sk, request, req->request_len, 0);
+ if (err < 0)
+ return -EIO;
req->numserv++;
cache_size = 0;
}
+static gboolean try_remove_cache(gpointer user_data)
+{
+ if (__sync_fetch_and_sub(&cache_refcount, 1) == 1) {
+ DBG("No cache users, removing it.");
+
+ g_hash_table_destroy(cache);
+ cache = NULL;
+ }
+
+ return FALSE;
+}
+
static void destroy_server(struct server_data *server)
{
GList *list;
}
g_free(server->interface);
- if (__sync_fetch_and_sub(&cache_refcount, 1) == 1) {
- g_hash_table_destroy(cache);
- cache = NULL;
- }
+ /*
+ * We do not remove cache right away but delay it few seconds.
+ * The idea is that when IPv6 DNS server is added via RDNSS, it has a
+ * lifetime. When the lifetime expires we decrease the refcount so it
+ * is possible that the cache is then removed. Because a new DNS server
+ * is usually created almost immediately we would then loose the cache
+ * without any good reason. The small delay allows the new RDNSS to
+ * create a new DNS server instance and the refcount does not go to 0.
+ */
+ g_timeout_add_seconds(3, try_remove_cache, NULL);
g_free(server);
}
return 0;
}
+static void destroy_request_data(struct request_data *req)
+{
+ if (req->timeout > 0)
+ g_source_remove(req->timeout);
+
+ g_free(req->resp);
+ g_free(req->request);
+ g_free(req->name);
+ g_free(req);
+}
+
static void destroy_listener(struct listener_data *ifdata)
{
GSList *list;
DBG("Dropping pending request (id 0x%04x -> 0x%04x)",
req->srcid, req->dstid);
- if (req->timeout > 0)
- g_source_remove(req->timeout);
-
- g_free(req->resp);
- g_free(req->request);
- g_free(req->name);
- g_free(req);
+ destroy_request_data(req);
list->data = NULL;
}
DBG("Dropping request (id 0x%04x -> 0x%04x)",
req->srcid, req->dstid);
- if (req->timeout > 0)
- g_source_remove(req->timeout);
-
- g_free(req->resp);
- g_free(req->request);
- g_free(req->name);
- g_free(req);
+ destroy_request_data(req);
list->data = NULL;
}