mirror of https://github.com/getdnsapi/getdns.git
Improve TCP close handling and sync connection closing
This commit is contained in:
parent
8c61ecd024
commit
e20d679bc8
|
@ -537,6 +537,31 @@ priv_getdns_upstreams_dereference(getdns_upstreams *upstreams)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
priv_getdns_upstream_shutdown(getdns_upstream *upstream) {
|
||||
/*There is a race condition with a new request being scheduled
|
||||
while this happens so take ownership of the fd asap*/
|
||||
int fd = upstream->fd;
|
||||
upstream->fd = -1;
|
||||
/* If the connection had a problem, but had worked this time,
|
||||
* then allow re-use in the future*/
|
||||
if (upstream->tcp.write_error == 1 &&
|
||||
upstream->responses_received > 0)
|
||||
upstream->tcp.write_error = 0;
|
||||
upstream->writes_done = 0;
|
||||
upstream->responses_received = 0;
|
||||
if (upstream->tls_hs_state != GETDNS_HS_FAILED)
|
||||
upstream->tls_hs_state = GETDNS_HS_NONE;
|
||||
/* Now TLS stuff*/
|
||||
if (upstream->tls_obj != NULL) {
|
||||
SSL_shutdown(upstream->tls_obj);
|
||||
SSL_free(upstream->tls_obj);
|
||||
upstream->tls_obj = NULL;
|
||||
}
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static uint8_t*
|
||||
upstream_addr(getdns_upstream *upstream)
|
||||
{
|
||||
|
@ -597,7 +622,7 @@ upstream_init(getdns_upstream *upstream,
|
|||
|
||||
/* How is this upstream doing? */
|
||||
upstream->writes_done = 0;
|
||||
upstream->responses_recieved = 0;
|
||||
upstream->responses_received = 0;
|
||||
upstream->to_retry = 2;
|
||||
upstream->back_off = 1;
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ typedef struct getdns_upstream {
|
|||
|
||||
/* How is this upstream doing? */
|
||||
size_t writes_done;
|
||||
size_t responses_recieved;
|
||||
size_t responses_received;
|
||||
int to_retry;
|
||||
int back_off;
|
||||
|
||||
|
@ -241,4 +241,6 @@ void priv_getdns_context_ub_read_cb(void *userarg);
|
|||
|
||||
void priv_getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
||||
|
||||
void priv_getdns_upstream_shutdown(getdns_upstream *upstreams);
|
||||
|
||||
#endif /* _GETDNS_CONTEXT_H_ */
|
||||
|
|
36
src/stub.c
36
src/stub.c
|
@ -505,13 +505,7 @@ upstream_erred(getdns_upstream *upstream)
|
|||
netreq->state = NET_REQ_FINISHED;
|
||||
priv_getdns_check_dns_req_complete(netreq->owner);
|
||||
}
|
||||
if (upstream->tls_obj) {
|
||||
SSL_shutdown(upstream->tls_obj);
|
||||
SSL_free(upstream->tls_obj);
|
||||
upstream->tls_obj = NULL;
|
||||
}
|
||||
close(upstream->fd);
|
||||
upstream->fd = -1;
|
||||
priv_getdns_upstream_shutdown(upstream);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -555,30 +549,20 @@ stub_timeout_cb(void *userarg)
|
|||
(void) getdns_context_request_timed_out(netreq->owner);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
upstream_idle_timeout_cb(void *userarg)
|
||||
{
|
||||
getdns_upstream *upstream = (getdns_upstream *)userarg;
|
||||
DEBUG_STUB("*** %s: **Closing connection %d**\n",
|
||||
__FUNCTION__, upstream->fd);
|
||||
/*There is a race condition with a new request being scheduled while this happens
|
||||
so take ownership of the fd asap*/
|
||||
int fd = upstream->fd;
|
||||
upstream->fd = -1;
|
||||
|
||||
upstream->event.timeout_cb = NULL;
|
||||
upstream->event.read_cb = NULL;
|
||||
upstream->event.write_cb = NULL;
|
||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||
if (upstream->tls_hs_state != GETDNS_HS_FAILED)
|
||||
upstream->tls_hs_state = GETDNS_HS_NONE;
|
||||
if (upstream->tls_obj != NULL) {
|
||||
SSL_shutdown(upstream->tls_obj);
|
||||
SSL_free(upstream->tls_obj);
|
||||
upstream->tls_obj = NULL;
|
||||
priv_getdns_upstream_shutdown(upstream);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
upstream_tls_timeout_cb(void *userarg)
|
||||
|
@ -1329,7 +1313,7 @@ upstream_read_cb(void *userarg)
|
|||
netreq->response_len =
|
||||
upstream->tcp.read_pos - upstream->tcp.read_buf;
|
||||
upstream->tcp.read_buf = NULL;
|
||||
upstream->responses_recieved++;
|
||||
upstream->responses_received++;
|
||||
/* TODO[TLS]: I don't think we should do this for TCP. We should stay
|
||||
* on a working connection until we hit a problem.*/
|
||||
upstream->upstreams->current = 0;
|
||||
|
@ -1674,7 +1658,7 @@ fallback_on_write(getdns_network_req *netreq)
|
|||
|
||||
/* For sync messages we must re-schedule the events on the old upstream
|
||||
* here too. Must schedule this last to make sure it is called back first! */
|
||||
if (netreq->owner->loop != upstream->loop && upstream->write_queue)
|
||||
if (netreq->owner->loop != upstream->loop)
|
||||
upstream_reschedule_netreq_events(upstream, upstream->write_queue);
|
||||
|
||||
if (result != GETDNS_RETURN_GOOD)
|
||||
|
@ -1751,13 +1735,7 @@ upstream_reschedule_netreq_events(getdns_upstream *upstream,
|
|||
* So we will have to be aggressive and shut the connection....*/
|
||||
DEBUG_STUB("# %s: **Closing connection %d**\n",
|
||||
__FUNCTION__, upstream->fd);
|
||||
if (upstream->tls_obj) {
|
||||
SSL_shutdown(upstream->tls_obj);
|
||||
SSL_free(upstream->tls_obj);
|
||||
upstream->tls_obj = NULL;
|
||||
}
|
||||
close(upstream->fd);
|
||||
upstream->fd = -1;
|
||||
priv_getdns_upstream_shutdown(upstream);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue