summaryrefslogtreecommitdiff
path: root/gweb
diff options
context:
space:
mode:
authorTomasz Bursztyka <tomasz.bursztyka@linux.intel.com>2013-02-15 12:30:19 +0200
committerPatrik Flykt <patrik.flykt@linux.intel.com>2013-02-18 10:49:49 +0200
commit5441662cf582d86736f94ed42f68bec9a031e42f (patch)
tree93d075c9c5028b06d8734f43c2c745693ff20d23 /gweb
parent6af0579c434058536fb40480f40f5e9895cfe863 (diff)
downloadconnman-5441662cf582d86736f94ed42f68bec9a031e42f.tar.gz
connman-5441662cf582d86736f94ed42f68bec9a031e42f.tar.bz2
connman-5441662cf582d86736f94ed42f68bec9a031e42f.zip
gresolv: Do not remove a query on failure if other results are pending
Fixes BMC#25973 In the case one of the resolving failed, the query is removed and destroyed from the queue. So the responses of the requests sent to the other namerservers - which might be successful - will thus be lost since they cannot be matched anymore to their initial request.
Diffstat (limited to 'gweb')
-rw-r--r--gweb/gresolv.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/gweb/gresolv.c b/gweb/gresolv.c
index 71b70dc7..9505f677 100644
--- a/gweb/gresolv.c
+++ b/gweb/gresolv.c
@@ -79,6 +79,7 @@ struct resolv_lookup {
struct resolv_query {
GResolv *resolv;
+ int nr_ns;
guint timeout;
uint16_t msgid;
@@ -579,12 +580,13 @@ static void flush_nameservers(GResolv *resolv)
static int send_query(GResolv *resolv, const unsigned char *buf, int len)
{
GList *list;
+ int nr_ns;
if (resolv->nameserver_list == NULL)
return -ENOENT;
- for (list = g_list_first(resolv->nameserver_list);
- list; list = g_list_next(list)) {
+ for (list = g_list_first(resolv->nameserver_list), nr_ns = 0;
+ list; list = g_list_next(list), nr_ns++) {
struct resolv_nameserver *nameserver = list->data;
int sk, sent;
@@ -598,7 +600,7 @@ static int send_query(GResolv *resolv, const unsigned char *buf, int len)
continue;
}
- return 0;
+ return nr_ns;
}
static gint compare_lookup_id(gconstpointer a, gconstpointer b)
@@ -701,15 +703,14 @@ static void parse_response(struct resolv_nameserver *nameserver,
return;
query = list->data;
+ query->nr_ns--;
+
lookup = query->lookup;
- if (query == lookup->ipv6_query) {
+ if (query == lookup->ipv6_query)
lookup->ipv6_status = status;
- lookup->ipv6_query = NULL;
- } else if (query == lookup->ipv4_query) {
+ else if (query == lookup->ipv4_query)
lookup->ipv4_status = status;
- lookup->ipv4_query = NULL;
- }
for (i = 0; i < count; i++) {
ns_parserr(&msg, ns_s_an, i, &rr);
@@ -729,6 +730,14 @@ static void parse_response(struct resolv_nameserver *nameserver,
}
}
+ if (status != G_RESOLV_RESULT_STATUS_SUCCESS && query->nr_ns > 0)
+ return;
+
+ if (query == lookup->ipv6_query)
+ lookup->ipv6_query = NULL;
+ else
+ lookup->ipv4_query = NULL;
+
g_queue_remove(resolv->query_queue, query);
destroy_query(query);
@@ -975,7 +984,8 @@ static gint add_query(struct resolv_lookup *lookup, const char *hostname, int ty
debug(lookup->resolv, "sending %d bytes", len);
- if (send_query(lookup->resolv, buf, len) < 0) {
+ query->nr_ns = send_query(lookup->resolv, buf, len);
+ if (query->nr_ns <= 0) {
g_free(query);
return -EIO;
}