MINOR: dns: Maximum DNS udp payload set to 8192

Following up DNS extension introduction, this patch aims at making the
computation of the maximum number of records in DNS response dynamic.
This computation is based on the announced payload size accepted by
HAProxy.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 66c9325..9f7f9ff 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -11716,9 +11716,11 @@
   <nb> is in bytes. If not set, HAProxy announces 512. (minimal value defined
        by RFC 6891)
 
-  Note: to get biggers response but still be sure that responses won't be
+  Note: to get bigger responses but still be sure that responses won't be
         dropped on the wire, one can choose a value between 1280 and 1410.
 
+  Note: the maximum allowed value is 8192.
+
 nameserver <id> <ip>:<port>
   DNS server description:
     <id>   : label of the server, should be unique
diff --git a/include/proto/dns.h b/include/proto/dns.h
index 5aed46e..aa063c7 100644
--- a/include/proto/dns.h
+++ b/include/proto/dns.h
@@ -33,7 +33,7 @@
 struct task *dns_process_resolve(struct task *t);
 int dns_init_resolvers(int close_socket);
 uint16_t dns_rnd16(void);
-int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, struct dns_resolution *resolution);
+int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, struct dns_resolution *resolution, int max_answer_records);
 int dns_get_ip_from_response(struct dns_response_packet *dns_p,
                              struct dns_options *dns_opts, void *currentip,
                              short currentip_sin_family,
diff --git a/include/types/dns.h b/include/types/dns.h
index 0f9c1b9..c7338c7 100644
--- a/include/types/dns.h
+++ b/include/types/dns.h
@@ -30,7 +30,7 @@
  */
 #define DNS_MAX_LABEL_SIZE	63
 #define DNS_MAX_NAME_SIZE	255
-#define DNS_MAX_UDP_MESSAGE	512
+#define DNS_MAX_UDP_MESSAGE	8192
 
 /* DNS minimun record size: 1 char + 1 NULL + type + class */
 #define DNS_MIN_RECORD_SIZE	( 1 + 1 + 2 + 2 )
diff --git a/src/cfgparse.c b/src/cfgparse.c
index ee24979..e69a4ab 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2294,13 +2294,24 @@
 
 	}
 	else if (strcmp(args[0], "accepted_payload_size") == 0) {
+		int i = 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]);
+
+		i = atoi(args[1]);
+		if (i > DNS_MAX_UDP_MESSAGE) {
+			Alert("parsing [%s:%d] : '%s' size %d exceeds maximum allowed size %d.\n",
+				file, linenum, args[0], i, DNS_MAX_UDP_MESSAGE);
+			err_code |= ERR_ALERT | ERR_FATAL;
+			goto out;
+		}
+
+		curr_resolvers->accepted_payload_size = i;
 	}
 	else if (strcmp(args[0], "resolution_pool_size") == 0) {
 		if (!*args[1]) {
diff --git a/src/dns.c b/src/dns.c
index c91d423..62291fe 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -391,6 +391,7 @@
 	unsigned char buf[DNS_MAX_UDP_MESSAGE + 1];
 	unsigned char *bufend;
 	int fd, buflen, dns_resp, need_resend = 0;
+	int max_answer_records = 0;
 	unsigned short query_id;
 	struct eb32_node *eb;
 	struct lru64 *lru = NULL;
@@ -413,15 +414,15 @@
 	while (1) {
 		int removed_reso = 0;
 		/* read message received */
-		memset(buf, '\0', DNS_MAX_UDP_MESSAGE + 1);
-		if ((buflen = recv(fd, (char*)buf , DNS_MAX_UDP_MESSAGE, 0)) < 0) {
+		memset(buf, '\0', resolvers->accepted_payload_size + 1);
+		if ((buflen = recv(fd, (char*)buf , resolvers->accepted_payload_size + 1, 0)) < 0) {
 			/* FIXME : for now we consider EAGAIN only */
 			fd_cant_recv(fd);
 			break;
 		}
 
 		/* message too big */
-		if (buflen > DNS_MAX_UDP_MESSAGE) {
+		if (buflen > resolvers->accepted_payload_size) {
 			nameserver->counters.too_big += 1;
 			continue;
 		}
@@ -455,7 +456,9 @@
 		/* number of responses received */
 		resolution->nb_responses += 1;
 
-		dns_resp = dns_validate_dns_response(buf, bufend, resolution);
+
+		max_answer_records = (resolvers->accepted_payload_size - DNS_HEADER_SIZE) / DNS_MIN_RECORD_SIZE;
+		dns_resp = dns_validate_dns_response(buf, bufend, resolution, max_answer_records);
 
 		switch (dns_resp) {
 			case DNS_RESP_VALID:
@@ -1086,7 +1089,7 @@
  * This function returns one of the DNS_RESP_* code to indicate the type of
  * error found.
  */
-int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, struct dns_resolution *resolution)
+int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, struct dns_resolution *resolution, int max_answer_records)
 {
 	unsigned char *reader;
 	char *previous_dname, tmpname[DNS_MAX_NAME_SIZE];
@@ -1157,7 +1160,7 @@
 	if (dns_p->header.ancount == 0)
 		return DNS_RESP_ANCOUNT_ZERO;
 	/* check if too many records are announced */
-	if (dns_p->header.ancount > DNS_MAX_ANSWER_RECORDS)
+	if (dns_p->header.ancount > max_answer_records)
 		return DNS_RESP_INVALID;
 	reader += 2;