mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-09 00:27:08 +02:00
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.
This commit is contained in:
parent
747359eeca
commit
9d8dbbc56b
@ -11716,9 +11716,11 @@ accepted_payload_size <nb>
|
|||||||
<nb> is in bytes. If not set, HAProxy announces 512. (minimal value defined
|
<nb> is in bytes. If not set, HAProxy announces 512. (minimal value defined
|
||||||
by RFC 6891)
|
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.
|
dropped on the wire, one can choose a value between 1280 and 1410.
|
||||||
|
|
||||||
|
Note: the maximum allowed value is 8192.
|
||||||
|
|
||||||
nameserver <id> <ip>:<port>
|
nameserver <id> <ip>:<port>
|
||||||
DNS server description:
|
DNS server description:
|
||||||
<id> : label of the server, should be unique
|
<id> : label of the server, should be unique
|
||||||
|
@ -33,7 +33,7 @@ int dns_build_query(int query_id, int query_type, unsigned int accepted_payload_
|
|||||||
struct task *dns_process_resolve(struct task *t);
|
struct task *dns_process_resolve(struct task *t);
|
||||||
int dns_init_resolvers(int close_socket);
|
int dns_init_resolvers(int close_socket);
|
||||||
uint16_t dns_rnd16(void);
|
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,
|
int dns_get_ip_from_response(struct dns_response_packet *dns_p,
|
||||||
struct dns_options *dns_opts, void *currentip,
|
struct dns_options *dns_opts, void *currentip,
|
||||||
short currentip_sin_family,
|
short currentip_sin_family,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
#define DNS_MAX_LABEL_SIZE 63
|
#define DNS_MAX_LABEL_SIZE 63
|
||||||
#define DNS_MAX_NAME_SIZE 255
|
#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 */
|
/* DNS minimun record size: 1 char + 1 NULL + type + class */
|
||||||
#define DNS_MIN_RECORD_SIZE ( 1 + 1 + 2 + 2 )
|
#define DNS_MIN_RECORD_SIZE ( 1 + 1 + 2 + 2 )
|
||||||
|
@ -2294,13 +2294,24 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
|
|||||||
|
|
||||||
}
|
}
|
||||||
else if (strcmp(args[0], "accepted_payload_size") == 0) {
|
else if (strcmp(args[0], "accepted_payload_size") == 0) {
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
if (!*args[1]) {
|
if (!*args[1]) {
|
||||||
Alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
|
Alert("parsing [%s:%d] : '%s' expects <nb> as argument.\n",
|
||||||
file, linenum, args[0]);
|
file, linenum, args[0]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
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) {
|
else if (strcmp(args[0], "resolution_pool_size") == 0) {
|
||||||
if (!*args[1]) {
|
if (!*args[1]) {
|
||||||
|
15
src/dns.c
15
src/dns.c
@ -391,6 +391,7 @@ void dns_resolve_recv(struct dgram_conn *dgram)
|
|||||||
unsigned char buf[DNS_MAX_UDP_MESSAGE + 1];
|
unsigned char buf[DNS_MAX_UDP_MESSAGE + 1];
|
||||||
unsigned char *bufend;
|
unsigned char *bufend;
|
||||||
int fd, buflen, dns_resp, need_resend = 0;
|
int fd, buflen, dns_resp, need_resend = 0;
|
||||||
|
int max_answer_records = 0;
|
||||||
unsigned short query_id;
|
unsigned short query_id;
|
||||||
struct eb32_node *eb;
|
struct eb32_node *eb;
|
||||||
struct lru64 *lru = NULL;
|
struct lru64 *lru = NULL;
|
||||||
@ -413,15 +414,15 @@ void dns_resolve_recv(struct dgram_conn *dgram)
|
|||||||
while (1) {
|
while (1) {
|
||||||
int removed_reso = 0;
|
int removed_reso = 0;
|
||||||
/* read message received */
|
/* read message received */
|
||||||
memset(buf, '\0', DNS_MAX_UDP_MESSAGE + 1);
|
memset(buf, '\0', resolvers->accepted_payload_size + 1);
|
||||||
if ((buflen = recv(fd, (char*)buf , DNS_MAX_UDP_MESSAGE, 0)) < 0) {
|
if ((buflen = recv(fd, (char*)buf , resolvers->accepted_payload_size + 1, 0)) < 0) {
|
||||||
/* FIXME : for now we consider EAGAIN only */
|
/* FIXME : for now we consider EAGAIN only */
|
||||||
fd_cant_recv(fd);
|
fd_cant_recv(fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* message too big */
|
/* message too big */
|
||||||
if (buflen > DNS_MAX_UDP_MESSAGE) {
|
if (buflen > resolvers->accepted_payload_size) {
|
||||||
nameserver->counters.too_big += 1;
|
nameserver->counters.too_big += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -455,7 +456,9 @@ void dns_resolve_recv(struct dgram_conn *dgram)
|
|||||||
/* number of responses received */
|
/* number of responses received */
|
||||||
resolution->nb_responses += 1;
|
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) {
|
switch (dns_resp) {
|
||||||
case DNS_RESP_VALID:
|
case DNS_RESP_VALID:
|
||||||
@ -1086,7 +1089,7 @@ int dns_read_name(unsigned char *buffer, unsigned char *bufend, unsigned char *n
|
|||||||
* This function returns one of the DNS_RESP_* code to indicate the type of
|
* This function returns one of the DNS_RESP_* code to indicate the type of
|
||||||
* error found.
|
* 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;
|
unsigned char *reader;
|
||||||
char *previous_dname, tmpname[DNS_MAX_NAME_SIZE];
|
char *previous_dname, tmpname[DNS_MAX_NAME_SIZE];
|
||||||
@ -1157,7 +1160,7 @@ int dns_validate_dns_response(unsigned char *resp, unsigned char *bufend, struct
|
|||||||
if (dns_p->header.ancount == 0)
|
if (dns_p->header.ancount == 0)
|
||||||
return DNS_RESP_ANCOUNT_ZERO;
|
return DNS_RESP_ANCOUNT_ZERO;
|
||||||
/* check if too many records are announced */
|
/* 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;
|
return DNS_RESP_INVALID;
|
||||||
reader += 2;
|
reader += 2;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user