MINOR: dns: enabled edns0 extension and make accpeted payload size tunable

Edns extensions may be used to negotiate some settings between a DNS
client and a server.
For now we only use it to announce the maximum response payload size accpeted
by HAProxy.
This size can be set through a configuration parameter in the resolvers
section. If not set, it defaults to 512 bytes.
diff --git a/src/cfgparse.c b/src/cfgparse.c
index a8e54aa..eebd72c 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2162,6 +2162,8 @@
 		curr_resolvers->conf.line = linenum;
 		curr_resolvers->id = strdup(args[1]);
 		curr_resolvers->query_ids = EB_ROOT;
+		/* default maximum response size */
+		curr_resolvers->accepted_payload_size = 512;
 		/* default hold period for nx, other, refuse and timeout is 30s */
 		curr_resolvers->hold.nx = 30000;
 		curr_resolvers->hold.other = 30000;
@@ -2291,6 +2293,15 @@
 		}
 
 	}
+	else if (strcmp(args[0], "accepted_payload_size") == 0) {
+		if (!*args[1]) {
+			Alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
+				file, linenum, args[0]);
+			err_code |= ERR_ALERT | ERR_FATAL;
+			goto out;
+		}
+		curr_resolvers->accepted_payload_size = atoi(args[1]);
+	}
 	else if (strcmp(args[0], "resolution_pool_size") == 0) {
 		if (!*args[1]) {
 			Alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
diff --git a/src/dns.c b/src/dns.c
index 09ba8f6..d46160f 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -897,8 +897,8 @@
 	if (!resolvers)
 		return 0;
 
-	bufsize = dns_build_query(resolution->query_id, resolution->query_type, resolution->hostname_dn,
-			resolution->hostname_dn_len, trash.str, trash.size);
+	bufsize = dns_build_query(resolution->query_id, resolution->query_type, resolvers->accepted_payload_size,
+			resolution->hostname_dn, resolution->hostname_dn_len, trash.str, trash.size);
 
 	if (bufsize == -1)
 		return 0;
@@ -1820,10 +1820,11 @@
  * returns:
  *  -1 if <buf> is too short
  */
-int dns_build_query(int query_id, int query_type, char *hostname_dn, int hostname_dn_len, char *buf, int bufsize)
+int dns_build_query(int query_id, int query_type, unsigned int accepted_payload_size, char *hostname_dn, int hostname_dn_len, char *buf, int bufsize)
 {
 	struct dns_header *dns;
 	struct dns_question qinfo;
+	struct dns_additional_record edns;
 	char *ptr, *bufend;
 
 	memset(buf, '\0', bufsize);
@@ -1841,7 +1842,7 @@
 	dns->qdcount = htons(1);	/* 1 question */
 	dns->ancount = 0;
 	dns->nscount = 0;
-	dns->arcount = 0;
+	dns->arcount = htons(1);
 
 	/* move forward ptr */
 	ptr += sizeof(struct dns_header);
@@ -1868,6 +1869,19 @@
 
 	ptr += sizeof(struct dns_question);
 
+	/* check if there is enough room for additional records */
+	if (ptr + sizeof(edns) >= bufend)
+		return -1;
+
+	/* set the DNS extension */
+	edns.name = 0;
+	edns.type = htons(DNS_RTYPE_OPT);
+	edns.udp_payload_size = htons(accepted_payload_size);
+	edns.extension = 0;
+	edns.data_length = 0;
+	memcpy(ptr, &edns, sizeof(edns));
+	ptr += sizeof(edns);
+
 	return ptr - buf;
 }