mirror of https://github.com/getdnsapi/getdns.git
fix: stub udp max_udp_size > 4096 support
This commit is contained in:
parent
6f6b8e65a2
commit
d03a22ba62
|
@ -76,6 +76,8 @@ network_req_new(getdns_dns_req * owner,
|
||||||
net_req->fd = -1;
|
net_req->fd = -1;
|
||||||
memset(&net_req->event, 0, sizeof(net_req->event));
|
memset(&net_req->event, 0, sizeof(net_req->event));
|
||||||
memset(&net_req->tcp, 0, sizeof(net_req->tcp));
|
memset(&net_req->tcp, 0, sizeof(net_req->tcp));
|
||||||
|
net_req->query_id = 0;
|
||||||
|
net_req->max_udp_payload_size = 0;
|
||||||
net_req->write_queue_tail = NULL;
|
net_req->write_queue_tail = NULL;
|
||||||
return net_req;
|
return net_req;
|
||||||
}
|
}
|
||||||
|
|
43
src/stub.c
43
src/stub.c
|
@ -44,8 +44,8 @@
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
getdns_make_query_pkt_buf(
|
getdns_make_query_pkt_buf(const getdns_network_req *netreq, uint8_t *buf,
|
||||||
getdns_network_req *netreq, uint8_t *buf, size_t *olen)
|
size_t *olen, uint16_t *omax_udp_payload_size)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
@ -163,6 +163,7 @@ getdns_make_query_pkt_buf(
|
||||||
if (len < 11)
|
if (len < 11)
|
||||||
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
*omax_udp_payload_size = edns_maximum_udp_payload_size;
|
||||||
buf[0] = 0; /* dname for . */
|
buf[0] = 0; /* dname for . */
|
||||||
gldns_write_uint16(buf + 1, GLDNS_RR_TYPE_OPT);
|
gldns_write_uint16(buf + 1, GLDNS_RR_TYPE_OPT);
|
||||||
gldns_write_uint16(buf + 3,
|
gldns_write_uint16(buf + 3,
|
||||||
|
@ -402,15 +403,21 @@ stub_udp_read_cb(void *userarg)
|
||||||
|
|
||||||
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
||||||
|
|
||||||
|
if (netreq->max_udp_payload_size > pkt_buf_len) {
|
||||||
|
pkt_len = netreq->max_udp_payload_size;
|
||||||
|
if (!(pkt = GETDNS_XMALLOC(
|
||||||
|
dnsreq->context->mf, uint8_t, pkt_len)))
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
read = recvfrom(netreq->fd, pkt, pkt_len, 0, NULL, NULL);
|
read = recvfrom(netreq->fd, pkt, pkt_len, 0, NULL, NULL);
|
||||||
if (read == -1 && (errno = EAGAIN || errno == EWOULDBLOCK))
|
if (read == -1 && (errno = EAGAIN || errno == EWOULDBLOCK))
|
||||||
return;
|
goto exit;
|
||||||
|
|
||||||
if (read < GLDNS_HEADER_SIZE)
|
if (read < GLDNS_HEADER_SIZE)
|
||||||
return; /* Not DNS */
|
goto exit; /* Not DNS */
|
||||||
|
|
||||||
if (GLDNS_ID_WIRE(pkt) != netreq->query_id)
|
if (GLDNS_ID_WIRE(pkt) != netreq->query_id)
|
||||||
return; /* Cache poisoning attempt ;) */
|
goto exit; /* Cache poisoning attempt ;) */
|
||||||
|
|
||||||
close(netreq->fd);
|
close(netreq->fd);
|
||||||
if (GLDNS_TC_WIRE(pkt) &&
|
if (GLDNS_TC_WIRE(pkt) &&
|
||||||
|
@ -433,7 +440,7 @@ stub_udp_read_cb(void *userarg)
|
||||||
getdns_eventloop_event_init(&netreq->event, netreq,
|
getdns_eventloop_event_init(&netreq->event, netreq,
|
||||||
NULL, stub_tcp_write_cb, stub_timeout_cb));
|
NULL, stub_tcp_write_cb, stub_timeout_cb));
|
||||||
|
|
||||||
return;
|
goto exit;
|
||||||
}
|
}
|
||||||
ldns_wire2pkt(&(netreq->result), pkt, read);
|
ldns_wire2pkt(&(netreq->result), pkt, read);
|
||||||
dnsreq->upstreams->current = 0;
|
dnsreq->upstreams->current = 0;
|
||||||
|
@ -441,10 +448,13 @@ stub_udp_read_cb(void *userarg)
|
||||||
/* TODO: DNSSEC */
|
/* TODO: DNSSEC */
|
||||||
netreq->secure = 0;
|
netreq->secure = 0;
|
||||||
netreq->bogus = 0;
|
netreq->bogus = 0;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
netreq->state = NET_REQ_FINISHED;
|
netreq->state = NET_REQ_FINISHED;
|
||||||
priv_getdns_check_dns_req_complete(dnsreq);
|
exit:
|
||||||
|
if (pkt && pkt != pkt_buf)
|
||||||
|
GETDNS_FREE(dnsreq->context->mf, pkt);
|
||||||
|
if (netreq->state == NET_REQ_FINISHED)
|
||||||
|
priv_getdns_check_dns_req_complete(dnsreq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -471,8 +481,9 @@ stub_udp_write_cb(void *userarg)
|
||||||
} else
|
} else
|
||||||
pkt_len = pkt_buf_len;
|
pkt_len = pkt_buf_len;
|
||||||
|
|
||||||
if (getdns_make_query_pkt_buf(netreq, pkt_buf, &pkt_len))
|
if (getdns_make_query_pkt_buf(netreq, pkt_buf, &pkt_len,
|
||||||
goto done;
|
&netreq->max_udp_payload_size))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
netreq->query_id = ldns_get_random();
|
netreq->query_id = ldns_get_random();
|
||||||
GLDNS_ID_SET(pkt, netreq->query_id);
|
GLDNS_ID_SET(pkt, netreq->query_id);
|
||||||
|
@ -481,18 +492,15 @@ stub_udp_write_cb(void *userarg)
|
||||||
(struct sockaddr *)&netreq->upstream->addr,
|
(struct sockaddr *)&netreq->upstream->addr,
|
||||||
netreq->upstream->addr_len)) {
|
netreq->upstream->addr_len)) {
|
||||||
close(netreq->fd);
|
close(netreq->fd);
|
||||||
goto done;
|
goto exit;
|
||||||
}
|
}
|
||||||
GETDNS_SCHEDULE_EVENT(
|
GETDNS_SCHEDULE_EVENT(
|
||||||
dnsreq->loop, netreq->fd, dnsreq->context->timeout,
|
dnsreq->loop, netreq->fd, dnsreq->context->timeout,
|
||||||
getdns_eventloop_event_init(&netreq->event, netreq,
|
getdns_eventloop_event_init(&netreq->event, netreq,
|
||||||
stub_udp_read_cb, NULL, stub_timeout_cb));
|
stub_udp_read_cb, NULL, stub_timeout_cb));
|
||||||
|
exit:
|
||||||
done:
|
if (pkt && pkt != pkt_buf)
|
||||||
if (pkt_size_needed > pkt_buf_len)
|
|
||||||
GETDNS_FREE(dnsreq->context->mf, pkt);
|
GETDNS_FREE(dnsreq->context->mf, pkt);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static getdns_upstream *
|
static getdns_upstream *
|
||||||
|
@ -754,7 +762,8 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
|
||||||
pkt_len = pkt_buf_len - 2;
|
pkt_len = pkt_buf_len - 2;
|
||||||
|
|
||||||
/* Construct query packet */
|
/* Construct query packet */
|
||||||
if (getdns_make_query_pkt_buf(netreq, pkt + 2, &pkt_len))
|
if (getdns_make_query_pkt_buf(netreq, pkt + 2, &pkt_len,
|
||||||
|
&netreq->max_udp_payload_size))
|
||||||
return STUB_TCP_ERROR;
|
return STUB_TCP_ERROR;
|
||||||
|
|
||||||
/* Prepend length short */
|
/* Prepend length short */
|
||||||
|
|
|
@ -202,6 +202,8 @@ typedef struct getdns_network_req
|
||||||
getdns_tcp_state tcp;
|
getdns_tcp_state tcp;
|
||||||
uint16_t query_id;
|
uint16_t query_id;
|
||||||
|
|
||||||
|
uint16_t max_udp_payload_size;
|
||||||
|
|
||||||
/* Network requests scheduled to write after me */
|
/* Network requests scheduled to write after me */
|
||||||
struct getdns_network_req *write_queue_tail;
|
struct getdns_network_req *write_queue_tail;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue