mirror of https://github.com/getdnsapi/getdns.git
Some clean up of connection handling. Still a problem with STARTTLS fallback that needs fixing.
This commit is contained in:
parent
79b3412fbf
commit
7905eda8b7
|
@ -267,7 +267,7 @@ sockaddr_dict(getdns_context *context, struct sockaddr *sa)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
port = ntohs(((struct sockaddr_in *)sa)->sin_port);
|
port = ntohs(((struct sockaddr_in *)sa)->sin_port);
|
||||||
if (port != 0 && port != GETDNS_PORT_TCP &&
|
if (port != GETDNS_PORT_ZERO && port != GETDNS_PORT_TCP &&
|
||||||
getdns_dict_set_int(address, "port", (uint32_t)port))
|
getdns_dict_set_int(address, "port", (uint32_t)port))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ sockaddr_dict(getdns_context *context, struct sockaddr *sa)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
|
port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
|
||||||
if (port != 0 && port != GETDNS_PORT_TCP &&
|
if (port != GETDNS_PORT_TCP && port != GETDNS_PORT_TCP &&
|
||||||
getdns_dict_set_int(address, "port", (uint32_t)port))
|
getdns_dict_set_int(address, "port", (uint32_t)port))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -553,7 +553,7 @@ upstream_ntop_buf(getdns_upstream *upstream, char *buf, size_t len)
|
||||||
if (upstream_scope_id(upstream))
|
if (upstream_scope_id(upstream))
|
||||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||||
"%%%d", (int)*upstream_scope_id(upstream));
|
"%%%d", (int)*upstream_scope_id(upstream));
|
||||||
else if (upstream_port(upstream) != GETDNS_PORT_TCP && upstream_port(upstream) != 0)
|
else if (upstream_port(upstream) != GETDNS_PORT_TCP && upstream_port(upstream) != GETDNS_PORT_ZERO)
|
||||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||||
"@%d", (int)upstream_port(upstream));
|
"@%d", (int)upstream_port(upstream));
|
||||||
}
|
}
|
||||||
|
@ -687,7 +687,7 @@ set_os_defaults(struct getdns_context *context)
|
||||||
|
|
||||||
getdns_base_transport_t base_transport = GETDNS_BASE_TRANSPORT_MIN;
|
getdns_base_transport_t base_transport = GETDNS_BASE_TRANSPORT_MIN;
|
||||||
for (; base_transport < GETDNS_BASE_TRANSPORT_MAX; base_transport++) {
|
for (; base_transport < GETDNS_BASE_TRANSPORT_MAX; base_transport++) {
|
||||||
char * port_str = getdns_port_str_array[base_transport];
|
char *port_str = getdns_port_str_array[base_transport];
|
||||||
if (strncmp(port_str, GETDNS_STR_PORT_ZERO, 1) == 0)
|
if (strncmp(port_str, GETDNS_STR_PORT_ZERO, 1) == 0)
|
||||||
continue;
|
continue;
|
||||||
if ((s = getaddrinfo(parse, port_str, &hints, &result)))
|
if ((s = getaddrinfo(parse, port_str, &hints, &result)))
|
||||||
|
@ -1219,7 +1219,7 @@ set_ub_dns_transport(struct getdns_context* context,
|
||||||
/* Note: If TLS is used in recursive mode this will try TLS on port
|
/* Note: If TLS is used in recursive mode this will try TLS on port
|
||||||
* 53... So this is prohibited when preparing for resolution.*/
|
* 53... So this is prohibited when preparing for resolution.*/
|
||||||
set_ub_string_opt(context, "ssl-upstream:", "yes");
|
set_ub_string_opt(context, "ssl-upstream:", "yes");
|
||||||
/* Fall through*/
|
/* Fall through */
|
||||||
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||||
case GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
case GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||||
/* Note: no fallback to TCP available directly in unbound, so we just
|
/* Note: no fallback to TCP available directly in unbound, so we just
|
||||||
|
@ -1792,11 +1792,13 @@ ub_setup_stub(struct ub_ctx *ctx, getdns_context *context)
|
||||||
(void) ub_ctx_set_fwd(ctx, NULL);
|
(void) ub_ctx_set_fwd(ctx, NULL);
|
||||||
for (i = 0; i < upstreams->count; i++) {
|
for (i = 0; i < upstreams->count; i++) {
|
||||||
upstream = &upstreams->upstreams[i];
|
upstream = &upstreams->upstreams[i];
|
||||||
/*[TLS]: Use only the subset of upstreams that match the first transport */
|
/*[TLS]: Use only the TLS subset of upstreams when only TLS is used.
|
||||||
if (context->dns_transport == GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN) {
|
* All other cases must currently fallback to TCP for libunbound. */
|
||||||
if (upstream_port(upstream) != GETDNS_PORT_TLS)
|
if (context->dns_base_transports[0] == GETDNS_BASE_TRANSPORT_TLS &&
|
||||||
|
context->dns_base_transports[0] == GETDNS_BASE_TRANSPORT_NONE &&
|
||||||
|
upstream_port(upstream) != GETDNS_PORT_TLS)
|
||||||
continue;
|
continue;
|
||||||
} else if (upstream_port(upstream) != GETDNS_PORT_TCP)
|
else if (upstream_port(upstream) != GETDNS_PORT_TCP)
|
||||||
continue;
|
continue;
|
||||||
upstream_ntop_buf(upstream, addr, 1024);
|
upstream_ntop_buf(upstream, addr, 1024);
|
||||||
ub_ctx_set_fwd(ctx, addr);
|
ub_ctx_set_fwd(ctx, addr);
|
||||||
|
|
|
@ -237,8 +237,6 @@ void priv_getdns_context_ub_read_cb(void *userarg);
|
||||||
getdns_return_t priv_set_base_dns_transports(getdns_base_transport_t *,
|
getdns_return_t priv_set_base_dns_transports(getdns_base_transport_t *,
|
||||||
getdns_transport_t);
|
getdns_transport_t);
|
||||||
|
|
||||||
getdns_base_transport_t priv_get_base_transport(getdns_transport_t transport, int level);
|
|
||||||
|
|
||||||
void priv_getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
void priv_getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
||||||
|
|
||||||
#endif /* _GETDNS_CONTEXT_H_ */
|
#endif /* _GETDNS_CONTEXT_H_ */
|
||||||
|
|
65
src/stub.c
65
src/stub.c
|
@ -757,9 +757,8 @@ create_tls_object(getdns_context *context, int fd)
|
||||||
if (context->tls_ctx == NULL)
|
if (context->tls_ctx == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
SSL* ssl = SSL_new(context->tls_ctx);
|
SSL* ssl = SSL_new(context->tls_ctx);
|
||||||
if(!ssl) {
|
if(!ssl)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
/* Connect the SSL object with a file descriptor */
|
/* Connect the SSL object with a file descriptor */
|
||||||
if(!SSL_set_fd(ssl,fd)) {
|
if(!SSL_set_fd(ssl,fd)) {
|
||||||
SSL_free(ssl);
|
SSL_free(ssl);
|
||||||
|
@ -1084,7 +1083,7 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
|
||||||
* by query_id in the process.
|
* by query_id in the process.
|
||||||
*/
|
*/
|
||||||
if ((*netreq->dns_base_transport == GETDNS_BASE_TRANSPORT_TCP_SINGLE) ||
|
if ((*netreq->dns_base_transport == GETDNS_BASE_TRANSPORT_TCP_SINGLE) ||
|
||||||
(*netreq->dns_base_transport == GETDNS_BASE_TRANSPORT_UDP))
|
(*netreq->dns_base_transport == GETDNS_BASE_TRANSPORT_UDP))
|
||||||
query_id = arc4random();
|
query_id = arc4random();
|
||||||
else do {
|
else do {
|
||||||
query_id = arc4random();
|
query_id = arc4random();
|
||||||
|
@ -1379,7 +1378,8 @@ tcp_connect(getdns_upstream *upstream, getdns_base_transport_t transport)
|
||||||
#ifdef USE_TCP_FASTOPEN
|
#ifdef USE_TCP_FASTOPEN
|
||||||
/* Leave the connect to the later call to sendto() if using TCP*/
|
/* Leave the connect to the later call to sendto() if using TCP*/
|
||||||
if (transport == GETDNS_BASE_TRANSPORT_TCP ||
|
if (transport == GETDNS_BASE_TRANSPORT_TCP ||
|
||||||
transport == GETDNS_BASE_TRANSPORT_TCP_SINGLE)
|
transport == GETDNS_BASE_TRANSPORT_TCP_SINGLE ||
|
||||||
|
transport == GETDNS_BASE_TRANSPORT_STARTTLS)
|
||||||
return fd;
|
return fd;
|
||||||
#endif
|
#endif
|
||||||
if (connect(fd, (struct sockaddr *)&upstream->addr,
|
if (connect(fd, (struct sockaddr *)&upstream->addr,
|
||||||
|
@ -1396,38 +1396,6 @@ int
|
||||||
connect_to_upstream(getdns_upstream *upstream, getdns_base_transport_t transport,
|
connect_to_upstream(getdns_upstream *upstream, getdns_base_transport_t transport,
|
||||||
getdns_dns_req *dnsreq)
|
getdns_dns_req *dnsreq)
|
||||||
{
|
{
|
||||||
/* First check if existing connection can be used, which may still be being
|
|
||||||
* set up. */
|
|
||||||
switch(transport) {
|
|
||||||
case GETDNS_BASE_TRANSPORT_TCP:
|
|
||||||
if (upstream->fd != -1) {
|
|
||||||
fprintf(stderr,"[TLS]: CONNECT(connect_to_upstream):"
|
|
||||||
"tcp_connect using existing TCP fd %d\n", upstream->fd);
|
|
||||||
return upstream->fd;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GETDNS_BASE_TRANSPORT_TLS:
|
|
||||||
if (tls_handshake_active(upstream->tls_hs_state)) {
|
|
||||||
fprintf(stderr,"[TLS]: CONNECT(connect_to_upstream):"
|
|
||||||
"tcp_connect using existing TLS fd %d\n", upstream->fd);
|
|
||||||
return upstream->fd;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GETDNS_BASE_TRANSPORT_STARTTLS:
|
|
||||||
/* Either negotiating, or doing handshake*/
|
|
||||||
if ((upstream->starttls_req != NULL) ||
|
|
||||||
(upstream->starttls_req == NULL &&
|
|
||||||
tls_handshake_active(upstream->tls_hs_state))) {
|
|
||||||
fprintf(stderr,"[TLS]: CONNECT(connect_to_upstream):"
|
|
||||||
"tcp_connect using existing STARTTLS fd %d\n", upstream->fd);
|
|
||||||
return upstream->fd;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If not, create a new one */
|
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
switch(transport) {
|
switch(transport) {
|
||||||
case GETDNS_BASE_TRANSPORT_UDP:
|
case GETDNS_BASE_TRANSPORT_UDP:
|
||||||
|
@ -1437,14 +1405,21 @@ connect_to_upstream(getdns_upstream *upstream, getdns_base_transport_t transport
|
||||||
getdns_sock_nonblock(fd);
|
getdns_sock_nonblock(fd);
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
case GETDNS_BASE_TRANSPORT_TCP_SINGLE:
|
|
||||||
case GETDNS_BASE_TRANSPORT_TCP:
|
case GETDNS_BASE_TRANSPORT_TCP:
|
||||||
|
/* Use existing if available*/
|
||||||
|
if (upstream->fd != -1)
|
||||||
|
return upstream->fd;
|
||||||
|
/* Otherwise, fall through */
|
||||||
|
case GETDNS_BASE_TRANSPORT_TCP_SINGLE:
|
||||||
fd = tcp_connect(upstream, transport);
|
fd = tcp_connect(upstream, transport);
|
||||||
upstream->loop = dnsreq->context->extension;
|
upstream->loop = dnsreq->context->extension;
|
||||||
upstream->fd = fd;
|
upstream->fd = fd;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETDNS_BASE_TRANSPORT_TLS:
|
case GETDNS_BASE_TRANSPORT_TLS:
|
||||||
|
/* Use existing if available*/
|
||||||
|
if (upstream->fd != 1 && tls_handshake_active(upstream->tls_hs_state))
|
||||||
|
return upstream->fd;
|
||||||
fd = tcp_connect(upstream, transport);
|
fd = tcp_connect(upstream, transport);
|
||||||
if (fd == -1) return -1;
|
if (fd == -1) return -1;
|
||||||
upstream->tls_obj = create_tls_object(dnsreq->context, fd);
|
upstream->tls_obj = create_tls_object(dnsreq->context, fd);
|
||||||
|
@ -1458,6 +1433,12 @@ connect_to_upstream(getdns_upstream *upstream, getdns_base_transport_t transport
|
||||||
upstream->fd = fd;
|
upstream->fd = fd;
|
||||||
break;
|
break;
|
||||||
case GETDNS_BASE_TRANSPORT_STARTTLS:
|
case GETDNS_BASE_TRANSPORT_STARTTLS:
|
||||||
|
/* Use existing if available. May be either negotiating or doing TLS */
|
||||||
|
if (upstream->fd != 1 &&
|
||||||
|
(upstream->starttls_req != NULL) ||
|
||||||
|
(upstream->starttls_req == NULL &&
|
||||||
|
tls_handshake_active(upstream->tls_hs_state)))
|
||||||
|
return upstream->fd;
|
||||||
fd = tcp_connect(upstream, transport);
|
fd = tcp_connect(upstream, transport);
|
||||||
if (fd == -1) return -1;
|
if (fd == -1) return -1;
|
||||||
if (!create_starttls_request(dnsreq, upstream, dnsreq->loop))
|
if (!create_starttls_request(dnsreq, upstream, dnsreq->loop))
|
||||||
|
@ -1479,12 +1460,13 @@ connect_to_upstream(getdns_upstream *upstream, getdns_base_transport_t transport
|
||||||
return -1;
|
return -1;
|
||||||
/* Nothing to do*/
|
/* Nothing to do*/
|
||||||
}
|
}
|
||||||
fprintf(stderr,"[TLS]: CONNECT(connect_to_upstream): created new connection %d\n", fd);
|
fprintf(stderr,"[TLS]: CONNECT(connect_to_upstream):"
|
||||||
|
" created new connection %d\n", fd);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getdns_upstream*
|
static getdns_upstream*
|
||||||
pick_and_connect_to_upstream(getdns_network_req *netreq,
|
find_upstream_for_specific_transport(getdns_network_req *netreq,
|
||||||
getdns_base_transport_t transport,
|
getdns_base_transport_t transport,
|
||||||
int *fd)
|
int *fd)
|
||||||
{
|
{
|
||||||
|
@ -1502,7 +1484,7 @@ find_upstream_for_netreq(getdns_network_req *netreq)
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
for (int i = 0; i < GETDNS_BASE_TRANSPORT_MAX &&
|
for (int i = 0; i < GETDNS_BASE_TRANSPORT_MAX &&
|
||||||
netreq->dns_base_transports[i] != GETDNS_BASE_TRANSPORT_NONE; i++) {
|
netreq->dns_base_transports[i] != GETDNS_BASE_TRANSPORT_NONE; i++) {
|
||||||
netreq->upstream = pick_and_connect_to_upstream(netreq,
|
netreq->upstream = find_upstream_for_specific_transport(netreq,
|
||||||
netreq->dns_base_transports[i],
|
netreq->dns_base_transports[i],
|
||||||
&fd);
|
&fd);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
|
@ -1524,6 +1506,7 @@ move_netreq(getdns_network_req *netreq, getdns_upstream *upstream,
|
||||||
upstream->write_queue_last = NULL;
|
upstream->write_queue_last = NULL;
|
||||||
upstream->event.write_cb = NULL;
|
upstream->event.write_cb = NULL;
|
||||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||||
|
|
||||||
close(upstream->fd);
|
close(upstream->fd);
|
||||||
upstream->fd = -1;
|
upstream->fd = -1;
|
||||||
}
|
}
|
||||||
|
@ -1591,7 +1574,7 @@ fallback_on_write(getdns_network_req *netreq)
|
||||||
getdns_upstream *upstream = netreq->upstream;
|
getdns_upstream *upstream = netreq->upstream;
|
||||||
int fd;
|
int fd;
|
||||||
getdns_upstream *new_upstream =
|
getdns_upstream *new_upstream =
|
||||||
pick_and_connect_to_upstream(netreq, *next_transport, &fd);
|
find_upstream_for_specific_transport(netreq, *next_transport, &fd);
|
||||||
if (!new_upstream)
|
if (!new_upstream)
|
||||||
return STUB_TCP_ERROR;
|
return STUB_TCP_ERROR;
|
||||||
return move_netreq(netreq, upstream, new_upstream);
|
return move_netreq(netreq, upstream, new_upstream);
|
||||||
|
|
Loading…
Reference in New Issue