<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
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,
}
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]) {
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;
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;
}
/* 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:
* 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];
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;