Quick fix for TLS timeouts not re-using a connection. Better solution is needed.

Also minor fixes in getdns_query:
 - spurious semicolon (caused build warning)
 - build warning for initialised variable
 - have getdns_query honour the CLASS in the incoming query
This commit is contained in:
Sara Dickinson 2016-06-15 17:05:58 +01:00
parent c74bfb5339
commit c0187a19ea
2 changed files with 25 additions and 13 deletions

View File

@ -495,14 +495,17 @@ stub_cleanup(getdns_network_req *netreq)
} }
static int static int
tls_cleanup(getdns_upstream *upstream) tls_cleanup(getdns_upstream *upstream, int handshake_fail)
{ {
DEBUG_STUB("%s %-35s: FD: %d\n", DEBUG_STUB("%s %-35s: FD: %d\n",
STUB_DEBUG_CLEANUP, __FUNCTION__, upstream->fd); STUB_DEBUG_CLEANUP, __FUNCTION__, upstream->fd);
if (upstream->tls_obj != NULL) if (upstream->tls_obj != NULL)
SSL_free(upstream->tls_obj); SSL_free(upstream->tls_obj);
upstream->tls_obj = NULL; upstream->tls_obj = NULL;
upstream->tls_hs_state = GETDNS_HS_FAILED; /* This will prevent the connection from being tried again for the cases
where we know it didn't work. Otherwise leave it to try again.*/
if (handshake_fail)
upstream->tls_hs_state = GETDNS_HS_FAILED;
/* Reset timeout on failure*/ /* Reset timeout on failure*/
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event); GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd, TIMEOUT_FOREVER, GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd, TIMEOUT_FOREVER,
@ -514,6 +517,8 @@ tls_cleanup(getdns_upstream *upstream)
static void static void
upstream_erred(getdns_upstream *upstream) upstream_erred(getdns_upstream *upstream)
{ {
DEBUG_STUB("%s %-35s: FD: %d\n",
STUB_DEBUG_CLEANUP, __FUNCTION__, upstream->fd);
getdns_network_req *netreq; getdns_network_req *netreq;
while ((netreq = upstream->write_queue)) { while ((netreq = upstream->write_queue)) {
@ -588,7 +593,7 @@ upstream_tls_timeout_cb(void *userarg)
DEBUG_STUB("%s %-35s: FD: %d\n", DEBUG_STUB("%s %-35s: FD: %d\n",
STUB_DEBUG_CLEANUP, __FUNCTION__, upstream->fd); STUB_DEBUG_CLEANUP, __FUNCTION__, upstream->fd);
/* Clean up and trigger a write to let the fallback code to its job */ /* Clean up and trigger a write to let the fallback code to its job */
tls_cleanup(upstream); tls_cleanup(upstream, 1);
/* Need to handle the case where the far end doesn't respond to a /* Need to handle the case where the far end doesn't respond to a
* TCP SYN and doesn't do a reset (as is the case with e.g. 8.8.8.8@853). * TCP SYN and doesn't do a reset (as is the case with e.g. 8.8.8.8@853).
@ -616,7 +621,7 @@ stub_tls_timeout_cb(void *userarg)
DEBUG_STUB("%s %-35s: MSG: %p\n", DEBUG_STUB("%s %-35s: MSG: %p\n",
STUB_DEBUG_CLEANUP, __FUNCTION__, netreq); STUB_DEBUG_CLEANUP, __FUNCTION__, netreq);
/* Clean up and trigger a write to let the fallback code to its job */ /* Clean up and trigger a write to let the fallback code to its job */
tls_cleanup(upstream); tls_cleanup(upstream, 0);
/* Need to handle the case where the far end doesn't respond to a /* Need to handle the case where the far end doesn't respond to a
* TCP SYN and doesn't do a reset (as is the case with e.g. 8.8.8.8@853). * TCP SYN and doesn't do a reset (as is the case with e.g. 8.8.8.8@853).
@ -1021,7 +1026,7 @@ tls_do_handshake(getdns_upstream *upstream)
DEBUG_STUB("%s %-35s: FD: %d Handshake failed %d\n", DEBUG_STUB("%s %-35s: FD: %d Handshake failed %d\n",
STUB_DEBUG_SETUP_TLS, __FUNCTION__, upstream->fd, STUB_DEBUG_SETUP_TLS, __FUNCTION__, upstream->fd,
want); want);
return tls_cleanup(upstream); return tls_cleanup(upstream, 1);
} }
} }
upstream->tls_hs_state = GETDNS_HS_DONE; upstream->tls_hs_state = GETDNS_HS_DONE;
@ -1069,7 +1074,7 @@ tls_connected(getdns_upstream* upstream)
int q = tcp_connected(upstream); int q = tcp_connected(upstream);
if (q != 0) { if (q != 0) {
if (q == STUB_TCP_ERROR) if (q == STUB_TCP_ERROR)
tls_cleanup(upstream); tls_cleanup(upstream, 0);
return q; return q;
} }
@ -1798,8 +1803,8 @@ upstream_reschedule_events(getdns_upstream *upstream, size_t idle_timeout) {
GETDNS_SCHEDULE_EVENT(upstream->loop, GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_FOREVER, &upstream->event); upstream->fd, TIMEOUT_FOREVER, &upstream->event);
else { else {
DEBUG_STUB("%s %-35s: FD: %d Connection idle \n", DEBUG_STUB("%s %-35s: FD: %d Connection idle - timeout is %d\n",
STUB_DEBUG_SCHEDULE, __FUNCTION__, upstream->fd); STUB_DEBUG_SCHEDULE, __FUNCTION__, upstream->fd, (int)idle_timeout);
upstream->event.timeout_cb = upstream_idle_timeout_cb; upstream->event.timeout_cb = upstream_idle_timeout_cb;
if (upstream->tcp.write_error != 0) if (upstream->tcp.write_error != 0)
idle_timeout = 0; idle_timeout = 0;
@ -1890,7 +1895,6 @@ _getdns_submit_stub_request(getdns_network_req *netreq)
case GETDNS_TRANSPORT_TLS: case GETDNS_TRANSPORT_TLS:
case GETDNS_TRANSPORT_TCP: case GETDNS_TRANSPORT_TCP:
upstream_schedule_netreq(netreq->upstream, netreq); upstream_schedule_netreq(netreq->upstream, netreq);
/* TODO[TLS]: Change scheduling for sync calls. */
/* For TLS, set a short timeout to catch setup problems. This is reset /* For TLS, set a short timeout to catch setup problems. This is reset
when the connection is successful.*/ when the connection is successful.*/
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event); GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
@ -1958,8 +1962,7 @@ _getdns_submit_stub_request(getdns_network_req *netreq)
GETDNS_SCHEDULE_EVENT( GETDNS_SCHEDULE_EVENT(
dnsreq->loop, -1, dnsreq->loop, -1,
( transport == GETDNS_TRANSPORT_TLS dnsreq->context->timeout,
? dnsreq->context->timeout /2 : dnsreq->context->timeout),
getdns_eventloop_event_init( getdns_eventloop_event_init(
&netreq->event, netreq, NULL, NULL, &netreq->event, netreq, NULL, NULL,

View File

@ -2207,7 +2207,7 @@ void servfail(dns_msg *msg, getdns_dict **resp_p)
return; return;
if (!getdns_dict_get_dict(msg->query, "header", &dict)) if (!getdns_dict_get_dict(msg->query, "header", &dict))
getdns_dict_set_dict(*resp_p, "header", dict); getdns_dict_set_dict(*resp_p, "header", dict);
if (!getdns_dict_get_dict(msg->query, "question", &dict)); if (!getdns_dict_get_dict(msg->query, "question", &dict))
getdns_dict_set_dict(*resp_p, "question", dict); getdns_dict_set_dict(*resp_p, "question", dict);
(void) getdns_dict_set_int( (void) getdns_dict_set_int(
*resp_p, "/header/rcode", GETDNS_RCODE_SERVFAIL); *resp_p, "/header/rcode", GETDNS_RCODE_SERVFAIL);
@ -2332,12 +2332,13 @@ getdns_return_t schedule_request(dns_msg *msg)
getdns_bindata *qname; getdns_bindata *qname;
char *qname_str = NULL; char *qname_str = NULL;
uint32_t qtype; uint32_t qtype;
uint32_t qclass;
getdns_return_t r; getdns_return_t r;
getdns_dict *header; getdns_dict *header;
uint32_t n; uint32_t n;
getdns_list *list; getdns_list *list;
getdns_transaction_t transaction_id; getdns_transaction_t transaction_id;
getdns_dict *qext; getdns_dict *qext = NULL;
if (!query_extensions_spc && if (!query_extensions_spc &&
!(query_extensions_spc = getdns_dict_create())) !(query_extensions_spc = getdns_dict_create()))
@ -2418,6 +2419,14 @@ getdns_return_t schedule_request(dns_msg *msg)
fprintf(stderr, "Could get qtype from query: %s\n", fprintf(stderr, "Could get qtype from query: %s\n",
getdns_get_errorstr_by_id(r)); getdns_get_errorstr_by_id(r));
else if ((r=getdns_dict_get_int(msg->query,"/question/qclass",&qclass)))
fprintf(stderr, "Could get qclass from query: %s\n",
getdns_get_errorstr_by_id(r));
else if ((r = getdns_dict_set_int(qext, "specify_class", qclass)))
fprintf(stderr, "Could set class from query: %s\n",
getdns_get_errorstr_by_id(r));
else if ((r = getdns_general(context, qname_str, qtype, else if ((r = getdns_general(context, qname_str, qtype,
qext, msg, &transaction_id, request_cb))) qext, msg, &transaction_id, request_cb)))
fprintf(stderr, "Could not schedule query: %s\n", fprintf(stderr, "Could not schedule query: %s\n",