Better retry on badcookie flooding prevention

This commit is contained in:
Willem Toorop 2020-04-08 19:16:51 +02:00
parent 8b62970e0c
commit de13a0c32d
3 changed files with 8 additions and 7 deletions

View File

@ -209,6 +209,7 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
net_req->transport_current = 0; net_req->transport_current = 0;
memset(&net_req->event, 0, sizeof(net_req->event)); memset(&net_req->event, 0, sizeof(net_req->event));
net_req->keepalive_sent = 0; net_req->keepalive_sent = 0;
net_req->badcookie_retry = 0;
net_req->write_queue_tail = NULL; net_req->write_queue_tail = NULL;
/* Some fields to record info for return_call_reporting */ /* Some fields to record info for return_call_reporting */
net_req->debug_tls_auth_status = GETDNS_AUTH_NONE; net_req->debug_tls_auth_status = GETDNS_AUTH_NONE;

View File

@ -1358,7 +1358,6 @@ stub_udp_read_cb(void *userarg)
getdns_network_req *netreq = (getdns_network_req *)userarg; getdns_network_req *netreq = (getdns_network_req *)userarg;
getdns_dns_req *dnsreq = netreq->owner; getdns_dns_req *dnsreq = netreq->owner;
getdns_upstream *upstream = netreq->upstream; getdns_upstream *upstream = netreq->upstream;
int prev_server_cookie = 0;
ssize_t read; ssize_t read;
DEBUG_STUB("%s %-35s: MSG: %p \n", STUB_DEBUG_READ, DEBUG_STUB("%s %-35s: MSG: %p \n", STUB_DEBUG_READ,
__FUNC__, (void*)netreq); __FUNC__, (void*)netreq);
@ -1399,7 +1398,6 @@ stub_udp_read_cb(void *userarg)
return; /* Cache poisoning attempt ;) */ return; /* Cache poisoning attempt ;) */
if (netreq->owner->edns_cookies) { if (netreq->owner->edns_cookies) {
prev_server_cookie = upstream->has_server_cookie;
netreq->response_len = read; netreq->response_len = read;
if (match_and_process_server_cookie(upstream, netreq)) { if (match_and_process_server_cookie(upstream, netreq)) {
netreq->response_len = 0; /* 0 means error */ netreq->response_len = 0; /* 0 means error */
@ -1434,14 +1432,14 @@ stub_udp_read_cb(void *userarg)
} }
netreq->response_len = read; netreq->response_len = read;
if (netreq->owner->edns_cookies if (netreq->owner->edns_cookies
&& !prev_server_cookie && !netreq->badcookie_retry
&& upstream->has_server_cookie /* newly learned server cookie */
&& netreq->response_opt /* actually: assert(netreq->response_opt) */ && netreq->response_opt /* actually: assert(netreq->response_opt) */
&& (netreq->response_opt[-4] << 4 | GLDNS_RCODE_WIRE(netreq->response)) && (netreq->response_opt[-4] << 4 | GLDNS_RCODE_WIRE(netreq->response))
== GETDNS_RCODE_BADCOOKIE == GETDNS_RCODE_BADCOOKIE
&& netreq->fd >= 0) { && netreq->fd >= 0) {
/* Retry over UDP with the newly learned Cookie */ /* Retry over UDP with the newly learned Cookie */
netreq->badcookie_retry = 1;
GETDNS_SCHEDULE_EVENT(dnsreq->loop, netreq->fd, GETDNS_SCHEDULE_EVENT(dnsreq->loop, netreq->fd,
_getdns_ms_until_expiry(dnsreq->expires), _getdns_ms_until_expiry(dnsreq->expires),
getdns_eventloop_event_init(&netreq->event, netreq, getdns_eventloop_event_init(&netreq->event, netreq,

View File

@ -233,8 +233,6 @@ typedef struct getdns_network_req
int edns_maximum_udp_payload_size; int edns_maximum_udp_payload_size;
uint16_t max_udp_payload_size; uint16_t max_udp_payload_size;
size_t keepalive_sent;
/* 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;
@ -244,7 +242,11 @@ typedef struct getdns_network_req
getdns_auth_state_t debug_tls_auth_status; getdns_auth_state_t debug_tls_auth_status;
getdns_bindata debug_tls_peer_cert; getdns_bindata debug_tls_peer_cert;
const char *debug_tls_version; const char *debug_tls_version;
size_t debug_udp;
/* Some booleans */
unsigned debug_udp : 1;
unsigned keepalive_sent : 1;
unsigned badcookie_retry: 1;
/* When more space is needed for the wire_data response than is /* When more space is needed for the wire_data response than is
* available in wire_data[], it will be allocated separately. * available in wire_data[], it will be allocated separately.