mirror of https://github.com/getdnsapi/getdns.git
Merge pull request #97 from saradickinson/features/async_tls
Features/async tls Thank you Sara!
This commit is contained in:
commit
802c693ee5
|
@ -41,6 +41,7 @@ static struct const_info consts_info[] = {
|
|||
{ 543, "GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN_TEXT },
|
||||
{ 544, "GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN_TEXT },
|
||||
{ 545, "GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT },
|
||||
{ 546, "GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT },
|
||||
{ 550, "GETDNS_APPEND_NAME_ALWAYS", GETDNS_APPEND_NAME_ALWAYS_TEXT },
|
||||
{ 551, "GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE", GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE_TEXT },
|
||||
{ 552, "GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE", GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE_TEXT },
|
||||
|
|
249
src/context.c
249
src/context.c
|
@ -53,6 +53,13 @@
|
|||
#include "stub.h"
|
||||
#include "list.h"
|
||||
|
||||
#define GETDNS_PORT_ZERO 0
|
||||
#define GETDNS_PORT_DNS 53
|
||||
#define GETDNS_PORT_DNS_OVER_TLS 1021
|
||||
#define GETDNS_STR_PORT_ZERO "0"
|
||||
#define GETDNS_STR_PORT_DNS "53"
|
||||
#define GETDNS_STR_PORT_DNS_OVER_TLS "1021"
|
||||
|
||||
void *plain_mem_funcs_user_arg = MF_PLAIN;
|
||||
|
||||
typedef struct host_name_addrs {
|
||||
|
@ -62,6 +69,26 @@ typedef struct host_name_addrs {
|
|||
uint8_t host_name[];
|
||||
} host_name_addrs;
|
||||
|
||||
static in_port_t
|
||||
getdns_port_array[GETDNS_BASE_TRANSPORT_MAX] = {
|
||||
GETDNS_PORT_ZERO,
|
||||
GETDNS_PORT_ZERO,
|
||||
GETDNS_PORT_ZERO,
|
||||
GETDNS_PORT_DNS,
|
||||
GETDNS_PORT_DNS,
|
||||
GETDNS_PORT_DNS_OVER_TLS
|
||||
};
|
||||
|
||||
char*
|
||||
getdns_port_str_array[] = {
|
||||
GETDNS_STR_PORT_ZERO,
|
||||
GETDNS_STR_PORT_ZERO,
|
||||
GETDNS_STR_PORT_ZERO,
|
||||
GETDNS_STR_PORT_DNS,
|
||||
GETDNS_STR_PORT_DNS,
|
||||
GETDNS_STR_PORT_DNS_OVER_TLS
|
||||
};
|
||||
|
||||
/* Private functions */
|
||||
getdns_return_t create_default_namespaces(struct getdns_context *context);
|
||||
static struct getdns_list *create_default_root_servers(void);
|
||||
|
@ -240,7 +267,7 @@ sockaddr_dict(getdns_context *context, struct sockaddr *sa)
|
|||
break;
|
||||
|
||||
port = ntohs(((struct sockaddr_in *)sa)->sin_port);
|
||||
if (port != 0 && port != 53 &&
|
||||
if (port != GETDNS_PORT_ZERO && port != GETDNS_PORT_DNS &&
|
||||
getdns_dict_set_int(address, "port", (uint32_t)port))
|
||||
break;
|
||||
|
||||
|
@ -256,7 +283,7 @@ sockaddr_dict(getdns_context *context, struct sockaddr *sa)
|
|||
break;
|
||||
|
||||
port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
|
||||
if (port != 0 && port != 53 &&
|
||||
if (port != GETDNS_PORT_DNS && port != GETDNS_PORT_DNS &&
|
||||
getdns_dict_set_int(address, "port", (uint32_t)port))
|
||||
break;
|
||||
|
||||
|
@ -514,8 +541,7 @@ upstream_scope_id(getdns_upstream *upstream)
|
|||
}
|
||||
|
||||
static void
|
||||
upstream_ntop_buf(getdns_upstream *upstream, getdns_transport_t transport,
|
||||
char *buf, size_t len)
|
||||
upstream_ntop_buf(getdns_upstream *upstream, char *buf, size_t len)
|
||||
{
|
||||
/* Also possible but prints scope_id by name (nor parsed by unbound)
|
||||
*
|
||||
|
@ -527,10 +553,7 @@ upstream_ntop_buf(getdns_upstream *upstream, getdns_transport_t transport,
|
|||
if (upstream_scope_id(upstream))
|
||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||
"%%%d", (int)*upstream_scope_id(upstream));
|
||||
if (transport == GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN)
|
||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||
"@%d", GETDNS_TLS_PORT);
|
||||
else if (upstream_port(upstream) != 53 && upstream_port(upstream) != 0)
|
||||
else if (upstream_port(upstream) != GETDNS_PORT_DNS && upstream_port(upstream) != GETDNS_PORT_ZERO)
|
||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||
"@%d", (int)upstream_port(upstream));
|
||||
}
|
||||
|
@ -557,6 +580,9 @@ upstream_init(getdns_upstream *upstream,
|
|||
/* For sharing a socket to this upstream with TCP */
|
||||
upstream->fd = -1;
|
||||
upstream->tls_obj = NULL;
|
||||
upstream->starttls_req = NULL;
|
||||
upstream->dns_base_transport = GETDNS_BASE_TRANSPORT_TCP;
|
||||
upstream->tls_hs_state = GETDNS_HS_NONE;
|
||||
upstream->loop = NULL;
|
||||
(void) getdns_eventloop_event_init(
|
||||
&upstream->event, upstream, NULL, NULL, NULL);
|
||||
|
@ -659,20 +685,27 @@ set_os_defaults(struct getdns_context *context)
|
|||
token = parse + strcspn(parse, " \t\r\n");
|
||||
*token = 0;
|
||||
|
||||
if ((s = getaddrinfo(parse, "53", &hints, &result)))
|
||||
continue;
|
||||
getdns_base_transport_t base_transport = GETDNS_BASE_TRANSPORT_MIN;
|
||||
for (; base_transport < GETDNS_BASE_TRANSPORT_MAX; base_transport++) {
|
||||
char *port_str = getdns_port_str_array[base_transport];
|
||||
if (strncmp(port_str, GETDNS_STR_PORT_ZERO, 1) == 0)
|
||||
continue;
|
||||
if ((s = getaddrinfo(parse, port_str, &hints, &result)))
|
||||
continue;
|
||||
|
||||
/* No lookups, so maximal 1 result */
|
||||
if (! result) continue;
|
||||
/* No lookups, so maximal 1 result */
|
||||
if (! result) continue;
|
||||
|
||||
/* Grow array when needed */
|
||||
if (context->upstreams->count == upstreams_limit)
|
||||
context->upstreams = upstreams_resize(
|
||||
context->upstreams, (upstreams_limit *= 2));
|
||||
/* Grow array when needed */
|
||||
if (context->upstreams->count == upstreams_limit)
|
||||
context->upstreams = upstreams_resize(
|
||||
context->upstreams, (upstreams_limit *= 2));
|
||||
|
||||
upstream = &context->upstreams->
|
||||
upstreams[context->upstreams->count++];
|
||||
upstream_init(upstream, context->upstreams, result);
|
||||
upstream = &context->upstreams->
|
||||
upstreams[context->upstreams->count++];
|
||||
upstream_init(upstream, context->upstreams, result);
|
||||
upstream->dns_base_transport = base_transport;
|
||||
}
|
||||
freeaddrinfo(result);
|
||||
}
|
||||
fclose(in);
|
||||
|
@ -801,6 +834,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->dnssec_allowed_skew = 0;
|
||||
result->edns_maximum_udp_payload_size = -1;
|
||||
result->dns_transport = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP;
|
||||
priv_set_base_dns_transports(result->dns_base_transports, result->dns_transport);
|
||||
result->limit_outstanding_queries = 0;
|
||||
result->has_ta = priv_getdns_parse_ta_file(NULL, NULL);
|
||||
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
||||
|
@ -1124,31 +1158,43 @@ getdns_context_set_namespaces(struct getdns_context *context,
|
|||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_namespaces */
|
||||
|
||||
getdns_base_transport_t
|
||||
priv_get_base_transport(getdns_transport_t transport, int level) {
|
||||
if (!(level == 0 || level == 1)) return GETDNS_TRANSPORT_NONE;
|
||||
switch (transport) {
|
||||
case GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP:
|
||||
if (level == 0) return GETDNS_TRANSPORT_UDP;
|
||||
if (level == 1) return GETDNS_TRANSPORT_TCP;
|
||||
case GETDNS_TRANSPORT_UDP_ONLY:
|
||||
if (level == 0) return GETDNS_TRANSPORT_UDP;
|
||||
if (level == 1) return GETDNS_TRANSPORT_NONE;
|
||||
case GETDNS_TRANSPORT_TCP_ONLY:
|
||||
if (level == 0) return GETDNS_TRANSPORT_TCP_SINGLE;
|
||||
if (level == 1) return GETDNS_TRANSPORT_NONE;
|
||||
case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
if (level == 0) return GETDNS_TRANSPORT_TCP;
|
||||
if (level == 1) return GETDNS_TRANSPORT_NONE;
|
||||
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
if (level == 0) return GETDNS_TRANSPORT_TLS;
|
||||
if (level == 1) return GETDNS_TRANSPORT_NONE;
|
||||
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||
if (level == 0) return GETDNS_TRANSPORT_TLS;
|
||||
if (level == 1) return GETDNS_TRANSPORT_TCP;
|
||||
default:
|
||||
return GETDNS_TRANSPORT_NONE;
|
||||
}
|
||||
/* TODO[TLS]: Modify further when API changed.*/
|
||||
getdns_return_t
|
||||
priv_set_base_dns_transports(getdns_base_transport_t *dns_base_transports,
|
||||
getdns_transport_t value)
|
||||
{
|
||||
for (int i = 0; i < GETDNS_BASE_TRANSPORT_MAX; i++)
|
||||
dns_base_transports[i] = GETDNS_BASE_TRANSPORT_NONE;
|
||||
switch (value) {
|
||||
case GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP:
|
||||
dns_base_transports[0] = GETDNS_BASE_TRANSPORT_UDP;
|
||||
dns_base_transports[1] = GETDNS_BASE_TRANSPORT_TCP_SINGLE;
|
||||
break;
|
||||
case GETDNS_TRANSPORT_UDP_ONLY:
|
||||
dns_base_transports[0] = GETDNS_BASE_TRANSPORT_UDP;
|
||||
break;
|
||||
case GETDNS_TRANSPORT_TCP_ONLY:
|
||||
dns_base_transports[0] = GETDNS_BASE_TRANSPORT_TCP_SINGLE;
|
||||
break;
|
||||
case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
dns_base_transports[0] = GETDNS_BASE_TRANSPORT_TCP;
|
||||
break;
|
||||
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
dns_base_transports[0] = GETDNS_BASE_TRANSPORT_TLS;
|
||||
break;
|
||||
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||
dns_base_transports[0] = GETDNS_BASE_TRANSPORT_TLS;
|
||||
dns_base_transports[1] = GETDNS_BASE_TRANSPORT_TCP;
|
||||
break;
|
||||
case GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||
dns_base_transports[0] = GETDNS_BASE_TRANSPORT_STARTTLS;
|
||||
dns_base_transports[1] = GETDNS_BASE_TRANSPORT_TCP;
|
||||
break;
|
||||
|
||||
default:
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
|
@ -1170,12 +1216,12 @@ set_ub_dns_transport(struct getdns_context* context,
|
|||
set_ub_string_opt(context, "do-tcp:", "yes");
|
||||
break;
|
||||
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
/* Hum. If used in recursive mode this will try TLS on port 53...
|
||||
* So we need to fix or document that or delay setting it until
|
||||
* resolution.*/
|
||||
/* Note: If TLS is used in recursive mode this will try TLS on port
|
||||
* 53... So this is prohibited when preparing for resolution.*/
|
||||
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_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||
/* Note: no fallback to TCP available directly in unbound, so we just
|
||||
* use TCP for now to make sure the messages are sent. */
|
||||
set_ub_string_opt(context, "do-udp:", "no");
|
||||
|
@ -1195,17 +1241,22 @@ getdns_return_t
|
|||
getdns_context_set_dns_transport(struct getdns_context *context,
|
||||
getdns_transport_t value)
|
||||
{
|
||||
/* TODO[TLS]: Modify further when API changed.*/
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* Note that the call below does not have any effect in unbound after the
|
||||
* ctx is finalised. So will not apply for recursive mode or stub + dnssec.
|
||||
* ctx is finalised so for recursive mode or stub + dnssec only the first
|
||||
* transport specified on the first query is used.
|
||||
* However the method returns success as otherwise the transport could not
|
||||
* be reset for stub mode.....
|
||||
* be reset for stub mode.
|
||||
* Also, not all transport options supported in libunbound yet */
|
||||
if (set_ub_dns_transport(context, value) != GETDNS_RETURN_GOOD) {
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
}
|
||||
if (value != context->dns_transport) {
|
||||
/*TODO[TLS]: remove this line when API updated*/
|
||||
context->dns_transport = value;
|
||||
if (priv_set_base_dns_transports(context->dns_base_transports, value) != GETDNS_RETURN_GOOD)
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_TRANSPORT);
|
||||
}
|
||||
|
||||
|
@ -1436,6 +1487,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
|
|||
getdns_return_t r;
|
||||
size_t count = 0;
|
||||
size_t i;
|
||||
//size_t upstreams_limit;
|
||||
getdns_upstreams *upstreams;
|
||||
char addrstr[1024], portstr[1024], *eos;
|
||||
struct addrinfo hints;
|
||||
|
@ -1456,17 +1508,17 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
|
|||
hints.ai_addr = NULL;
|
||||
hints.ai_next = NULL;
|
||||
|
||||
upstreams = upstreams_create(context, count);
|
||||
upstreams = upstreams_create(context, count*3);
|
||||
//upstreams_limit = count;
|
||||
for (i = 0; i < count; i++) {
|
||||
getdns_dict *dict;
|
||||
getdns_bindata *address_type;
|
||||
getdns_bindata *address_data;
|
||||
uint32_t port;
|
||||
struct sockaddr_storage addr;
|
||||
|
||||
getdns_bindata *scope_id;
|
||||
struct addrinfo *ai;
|
||||
getdns_upstream *upstream;
|
||||
|
||||
upstream = &upstreams->upstreams[upstreams->count];
|
||||
if ((r = getdns_list_get_dict(upstream_list, i, &dict)))
|
||||
goto error;
|
||||
|
||||
|
@ -1476,27 +1528,23 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
|
|||
if (address_type->size < 4)
|
||||
goto invalid_parameter;
|
||||
if (strncmp((char *)address_type->data, "IPv4", 4) == 0)
|
||||
upstream->addr.ss_family = AF_INET;
|
||||
addr.ss_family = AF_INET;
|
||||
else if (strncmp((char *)address_type->data, "IPv6", 4) == 0)
|
||||
upstream->addr.ss_family = AF_INET6;
|
||||
addr.ss_family = AF_INET6;
|
||||
else goto invalid_parameter;
|
||||
|
||||
if ((r = getdns_dict_get_bindata(
|
||||
dict, "address_data", &address_data)))
|
||||
goto error;
|
||||
if ((upstream->addr.ss_family == AF_INET &&
|
||||
if ((addr.ss_family == AF_INET &&
|
||||
address_data->size != 4) ||
|
||||
(upstream->addr.ss_family == AF_INET6 &&
|
||||
(addr.ss_family == AF_INET6 &&
|
||||
address_data->size != 16))
|
||||
goto invalid_parameter;
|
||||
if (inet_ntop(upstream->addr.ss_family, address_data->data,
|
||||
if (inet_ntop(addr.ss_family, address_data->data,
|
||||
addrstr, 1024) == NULL)
|
||||
goto invalid_parameter;
|
||||
|
||||
port = 53;
|
||||
(void) getdns_dict_get_int(dict, "port", &port);
|
||||
(void) snprintf(portstr, 1024, "%d", (int)port);
|
||||
|
||||
if (getdns_dict_get_bindata(dict, "scope_id", &scope_id) ==
|
||||
GETDNS_RETURN_GOOD) {
|
||||
if (strlen(addrstr) + scope_id->size > 1022)
|
||||
|
@ -1507,12 +1555,40 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
|
|||
eos[scope_id->size] = 0;
|
||||
}
|
||||
|
||||
if (getaddrinfo(addrstr, portstr, &hints, &ai))
|
||||
goto invalid_parameter;
|
||||
/* Loop to create upstreams as needed*/
|
||||
getdns_base_transport_t base_transport = GETDNS_BASE_TRANSPORT_MIN;
|
||||
for (; base_transport < GETDNS_BASE_TRANSPORT_MAX; base_transport++) {
|
||||
uint32_t port;
|
||||
struct addrinfo *ai;
|
||||
port = getdns_port_array[base_transport];
|
||||
if (port == GETDNS_PORT_ZERO)
|
||||
continue;
|
||||
|
||||
upstream_init(upstream, upstreams, ai);
|
||||
upstreams->count++;
|
||||
freeaddrinfo(ai);
|
||||
if (base_transport != GETDNS_BASE_TRANSPORT_TLS)
|
||||
(void) getdns_dict_get_int(dict, "port", &port);
|
||||
else
|
||||
(void) getdns_dict_get_int(dict, "tls-port", &port);
|
||||
(void) snprintf(portstr, 1024, "%d", (int)port);
|
||||
|
||||
if (getaddrinfo(addrstr, portstr, &hints, &ai))
|
||||
goto invalid_parameter;
|
||||
|
||||
/* TODO[TLS]: Should probably check that the upstream doesn't
|
||||
* already exist (in case user has specified TLS port explicitly and
|
||||
* to prevent duplicates) */
|
||||
|
||||
/* TODO[TLS]: Grow array when needed. This causes a crash later....
|
||||
if (upstreams->count == upstreams_limit)
|
||||
upstreams = upstreams_resize(
|
||||
upstreams, (upstreams_limit *= 2)); */
|
||||
|
||||
upstream = &upstreams->upstreams[upstreams->count];
|
||||
upstream->addr.ss_family = addr.ss_family;
|
||||
upstream_init(upstream, upstreams, ai);
|
||||
upstream->dns_base_transport = base_transport;
|
||||
upstreams->count++;
|
||||
freeaddrinfo(ai);
|
||||
}
|
||||
}
|
||||
priv_getdns_upstreams_dereference(context->upstreams);
|
||||
context->upstreams = upstreams;
|
||||
|
@ -1731,7 +1807,13 @@ ub_setup_stub(struct ub_ctx *ctx, getdns_context *context)
|
|||
(void) ub_ctx_set_fwd(ctx, NULL);
|
||||
for (i = 0; i < upstreams->count; i++) {
|
||||
upstream = &upstreams->upstreams[i];
|
||||
upstream_ntop_buf(upstream, context->dns_transport, addr, 1024);
|
||||
/*[TLS]: Use only the TLS subset of upstreams when TLS is the only thing
|
||||
* used. All other cases must currently fallback to TCP for libunbound.*/
|
||||
if (context->dns_base_transports[0] == GETDNS_BASE_TRANSPORT_TLS &&
|
||||
context->dns_base_transports[1] == GETDNS_BASE_TRANSPORT_NONE &&
|
||||
upstream->dns_base_transport != GETDNS_BASE_TRANSPORT_TLS)
|
||||
continue;
|
||||
upstream_ntop_buf(upstream, addr, 1024);
|
||||
ub_ctx_set_fwd(ctx, addr);
|
||||
}
|
||||
|
||||
|
@ -1826,29 +1908,24 @@ getdns_context_prepare_for_resolution(struct getdns_context *context,
|
|||
}
|
||||
|
||||
/* Transport can in theory be set per query in stub mode */
|
||||
/* TODO: move this transport logic to a separate functions*/
|
||||
if (context->resolution_type == GETDNS_RESOLUTION_STUB) {
|
||||
switch (context->dns_transport) {
|
||||
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||
if (context->tls_ctx == NULL) {
|
||||
/*TODO[TLS]: Check if TLS is in the list of transports.*/
|
||||
if (context->tls_ctx == NULL) {
|
||||
#ifdef HAVE_LIBTLS1_2
|
||||
/* Create client context, use TLS v1.2 only for now */
|
||||
context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method());
|
||||
/* Create client context, use TLS v1.2 only for now */
|
||||
context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method());
|
||||
#endif
|
||||
if(!context->tls_ctx && context->dns_transport ==
|
||||
GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN) {
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
/* TODO[TLS]: Check if TLS is the only option in the list*/
|
||||
// if(!context->tls_ctx && context->dns_transport ==
|
||||
// GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN) {
|
||||
// return GETDNS_RETURN_BAD_CONTEXT;
|
||||
// }
|
||||
}
|
||||
}
|
||||
/* Block use of TLS ONLY in recursive mode as it won't work */
|
||||
if (context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||
&& context->dns_transport == GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN)
|
||||
/* TODO[TLS]: Check if TLS is the only option in the list*/
|
||||
if (context->resolution_type == GETDNS_RESOLUTION_RECURSING &&
|
||||
context->dns_transport == GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN)
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
|
||||
if (context->resolution_type_set == context->resolution_type)
|
||||
|
|
|
@ -49,7 +49,6 @@ struct ub_ctx;
|
|||
|
||||
#define GETDNS_FN_RESOLVCONF "/etc/resolv.conf"
|
||||
#define GETDNS_FN_HOSTS "/etc/hosts"
|
||||
#define GETDNS_TLS_PORT 1021
|
||||
|
||||
enum filechgs { GETDNS_FCHG_ERRORS = -1
|
||||
, GETDNS_FCHG_NOERROR = 0
|
||||
|
@ -72,13 +71,13 @@ struct filechg {
|
|||
struct stat *prevstat;
|
||||
};
|
||||
|
||||
typedef enum getdns_base_transport {
|
||||
GETDNS_TRANSPORT_NONE,
|
||||
GETDNS_TRANSPORT_UDP,
|
||||
GETDNS_TRANSPORT_TCP_SINGLE,
|
||||
GETDNS_TRANSPORT_TCP,
|
||||
GETDNS_TRANSPORT_TLS
|
||||
} getdns_base_transport_t;
|
||||
typedef enum getdns_tls_hs_state {
|
||||
GETDNS_HS_NONE,
|
||||
GETDNS_HS_WRITE,
|
||||
GETDNS_HS_READ,
|
||||
GETDNS_HS_DONE,
|
||||
GETDNS_HS_FAILED
|
||||
} getdns_tls_hs_state_t;
|
||||
|
||||
typedef struct getdns_upstream {
|
||||
struct getdns_upstreams *upstreams;
|
||||
|
@ -92,7 +91,10 @@ typedef struct getdns_upstream {
|
|||
|
||||
/* For sharing a TCP socket to this upstream */
|
||||
int fd;
|
||||
getdns_base_transport_t dns_base_transport;
|
||||
SSL* tls_obj;
|
||||
getdns_tls_hs_state_t tls_hs_state;
|
||||
getdns_dns_req * starttls_req;
|
||||
getdns_eventloop_event event;
|
||||
getdns_eventloop *loop;
|
||||
getdns_tcp_state tcp;
|
||||
|
@ -136,6 +138,7 @@ struct getdns_context {
|
|||
struct getdns_list *dnssec_trust_anchors;
|
||||
getdns_upstreams *upstreams;
|
||||
getdns_transport_t dns_transport;
|
||||
getdns_base_transport_t dns_base_transports[GETDNS_BASE_TRANSPORT_MAX];
|
||||
uint16_t limit_outstanding_queries;
|
||||
uint32_t dnssec_allowed_skew;
|
||||
|
||||
|
@ -231,7 +234,8 @@ int filechg_check(struct getdns_context *context, struct filechg *fchg);
|
|||
|
||||
void priv_getdns_context_ub_read_cb(void *userarg);
|
||||
|
||||
getdns_base_transport_t priv_get_base_transport(getdns_transport_t transport, int level);
|
||||
getdns_return_t priv_set_base_dns_transports(getdns_base_transport_t *,
|
||||
getdns_transport_t);
|
||||
|
||||
void priv_getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
||||
|
||||
|
|
|
@ -165,7 +165,8 @@ typedef enum getdns_transport_t {
|
|||
GETDNS_TRANSPORT_TCP_ONLY = 542,
|
||||
GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN = 543,
|
||||
GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN = 544,
|
||||
GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN = 545
|
||||
GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN = 545,
|
||||
GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN = 546
|
||||
} getdns_transport_t;
|
||||
|
||||
/**
|
||||
|
@ -178,6 +179,7 @@ typedef enum getdns_transport_t {
|
|||
#define GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
|
||||
#define GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
|
||||
#define GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
|
||||
#define GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
|
|
@ -89,6 +89,9 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
|||
|
||||
net_req->upstream = NULL;
|
||||
net_req->fd = -1;
|
||||
for (i = 0; i < GETDNS_BASE_TRANSPORT_MAX; i++)
|
||||
net_req->dns_base_transports[i] = owner->context->dns_base_transports[i];
|
||||
net_req->transport = 0;
|
||||
memset(&net_req->event, 0, sizeof(net_req->event));
|
||||
memset(&net_req->tcp, 0, sizeof(net_req->tcp));
|
||||
net_req->query_id = 0;
|
||||
|
|
1673
src/stub.c
1673
src/stub.c
File diff suppressed because it is too large
Load Diff
|
@ -54,6 +54,7 @@ ipaddr_dict(getdns_context *context, char *ipstr)
|
|||
getdns_dict *r = getdns_dict_create_with_context(context);
|
||||
char *s = strchr(ipstr, '%'), *scope_id_str = "";
|
||||
char *p = strchr(ipstr, '@'), *portstr = "";
|
||||
char *t = strchr(ipstr, '#'), *tls_portstr = "";
|
||||
uint8_t buf[sizeof(struct in6_addr)];
|
||||
getdns_bindata addr;
|
||||
|
||||
|
@ -68,6 +69,10 @@ ipaddr_dict(getdns_context *context, char *ipstr)
|
|||
*p = 0;
|
||||
portstr = p + 1;
|
||||
}
|
||||
if (t) {
|
||||
*t = 0;
|
||||
tls_portstr = t + 1;
|
||||
}
|
||||
if (strchr(ipstr, ':')) {
|
||||
getdns_dict_util_set_string(r, "address_type", "IPv6");
|
||||
addr.size = 16;
|
||||
|
@ -86,6 +91,8 @@ ipaddr_dict(getdns_context *context, char *ipstr)
|
|||
getdns_dict_set_bindata(r, "address_data", &addr);
|
||||
if (*portstr)
|
||||
getdns_dict_set_int(r, "port", (int32_t)atoi(portstr));
|
||||
if (*tls_portstr)
|
||||
getdns_dict_set_int(r, "tls-port", (int32_t)atoi(tls_portstr));
|
||||
if (*scope_id_str)
|
||||
getdns_dict_util_set_string(r, "scope_id", scope_id_str);
|
||||
|
||||
|
@ -121,6 +128,7 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t-O\tSet transport to TCP only keep connections open\n");
|
||||
fprintf(out, "\t-L\tSet transport to TLS only keep connections open\n");
|
||||
fprintf(out, "\t-E\tSet transport to TLS with TCP fallback only keep connections open\n");
|
||||
fprintf(out, "\t-R\tSet transport to STARTTLS with TCP fallback only keep connections open\n");
|
||||
fprintf(out, "\t-u\tSet transport to UDP with TCP fallback\n");
|
||||
fprintf(out, "\t-U\tSet transport to UDP only\n");
|
||||
fprintf(out, "\t-B\tBatch mode. Schedule all messages before processing responses.\n");
|
||||
|
@ -369,6 +377,10 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
getdns_context_set_dns_transport(context,
|
||||
GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
|
||||
break;
|
||||
case 'R':
|
||||
getdns_context_set_dns_transport(context,
|
||||
GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
|
||||
break;
|
||||
case 'u':
|
||||
getdns_context_set_dns_transport(context,
|
||||
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP);
|
||||
|
|
|
@ -164,6 +164,18 @@ typedef struct getdns_tcp_state {
|
|||
|
||||
} getdns_tcp_state;
|
||||
|
||||
/* TODO[TLS]: change this name to getdns_transport when API updated*/
|
||||
typedef enum getdns_base_transport {
|
||||
GETDNS_BASE_TRANSPORT_MIN = 0,
|
||||
GETDNS_BASE_TRANSPORT_NONE = 0,
|
||||
GETDNS_BASE_TRANSPORT_UDP,
|
||||
GETDNS_BASE_TRANSPORT_TCP_SINGLE, /* To be removed? */
|
||||
GETDNS_BASE_TRANSPORT_STARTTLS, /* Define before TCP to allow fallback */
|
||||
GETDNS_BASE_TRANSPORT_TCP,
|
||||
GETDNS_BASE_TRANSPORT_TLS,
|
||||
GETDNS_BASE_TRANSPORT_MAX
|
||||
} getdns_base_transport_t;
|
||||
|
||||
/**
|
||||
* Request data
|
||||
**/
|
||||
|
@ -191,6 +203,8 @@ typedef struct getdns_network_req
|
|||
/* For stub resolving */
|
||||
struct getdns_upstream *upstream;
|
||||
int fd;
|
||||
getdns_base_transport_t dns_base_transports[GETDNS_BASE_TRANSPORT_MAX];
|
||||
int transport;
|
||||
getdns_eventloop_event event;
|
||||
getdns_tcp_state tcp;
|
||||
uint16_t query_id;
|
||||
|
|
Loading…
Reference in New Issue