diff --git a/src/dns.c b/src/dns.c index c131f08f1..bc68a81c0 100644 --- a/src/dns.c +++ b/src/dns.c @@ -272,22 +272,49 @@ static int dns_send_query(struct dns_resolution *resolution) { struct dns_resolvers *resolvers = resolution->resolvers; struct dns_nameserver *ns; + int len; + + /* Update resolution */ + resolution->nb_queries = 0; + resolution->nb_responses = 0; + resolution->last_query = now_ms; + + len = dns_build_query(resolution->query_id, resolution->query_type, + resolvers->accepted_payload_size, + resolution->hostname_dn, resolution->hostname_dn_len, + trash.area, trash.size); list_for_each_entry(ns, &resolvers->nameservers, list) { int fd = ns->dgram->t.sock.fd; + int ret; + if (fd == -1) { if (dns_connect_namesaver(ns) == -1) continue; fd = ns->dgram->t.sock.fd; resolvers->nb_nameservers++; } - fd_want_send(fd); - } - /* Update resolution */ - resolution->nb_queries = 0; - resolution->nb_responses = 0; - resolution->last_query = now_ms; + if (len < 0) + goto snd_error; + + ret = send(fd, trash.area, len, 0); + if (ret == len) { + ns->counters.sent++; + resolution->nb_queries++; + continue; + } + + if (ret == -1 && errno == EAGAIN) { + /* retry once the socket is ready */ + fd_cant_send(fd); + continue; + } + + snd_error: + ns->counters.snd_error++; + resolution->nb_queries++; + } /* Push the resolution at the end of the active list */ LIST_DEL(&resolution->list); @@ -1751,8 +1778,14 @@ static void dns_resolve_send(struct dgram_conn *dgram) goto snd_error; ret = send(fd, trash.area, len, 0); - if (ret != len) + if (ret != len) { + if (ret == -1 && errno == EAGAIN) { + /* retry once the socket is ready */ + fd_cant_send(fd); + continue; + } goto snd_error; + } ns->counters.sent++; res->nb_queries++;