mirror of https://github.com/getdnsapi/getdns.git
Merge pull request #104 from saradickinson/features/transport_api
Commit addition of transport list to the API.
This commit is contained in:
commit
d819bc901b
|
@ -1,5 +1,9 @@
|
||||||
* 2015-06-??: Version 0.?.?
|
* 2015-06-??: Version 0.?.?
|
||||||
* Unit test for spurious execute bits. Thanks Paul Wouters.
|
* Unit test for spurious execute bits. Thanks Paul Wouters.
|
||||||
|
* Added new transport list options in API. The option is now an ordered list of
|
||||||
|
GETDNS_TRANSPORT_UDP, GETDNS_TRANSPORT_TCP, GETDNS_TRANSPORT_TLS,
|
||||||
|
GETDNS_TRANSPORT_STARTTLS.
|
||||||
|
* Added new context setting for idle_timeout
|
||||||
|
|
||||||
* 2015-05-21: Version 0.2.0
|
* 2015-05-21: Version 0.2.0
|
||||||
* Fix libversion numbering: Thanks Daniel Kahn Gillmor
|
* Fix libversion numbering: Thanks Daniel Kahn Gillmor
|
||||||
|
|
|
@ -2198,6 +2198,20 @@ The value is <span class=default>
|
||||||
<code>GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN></code>, or
|
<code>GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN></code>, or
|
||||||
<code>GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN></code>
|
<code>GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN></code>
|
||||||
|
|
||||||
|
<div class=forh>
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_dns_transport_list(
|
||||||
|
size_t transport_list,
|
||||||
|
getdns_transport_list_t *transports
|
||||||
|
);</div>
|
||||||
|
<p class=cont>The <code>transports</code> array contains an ordered list
|
||||||
|
of transports that will be used for DNS lookups. The
|
||||||
|
values are <span class=default>
|
||||||
|
<code>GETDNS_TRANSPORT_UDP</code></span>,
|
||||||
|
<code>GETDNS_TRANSPORT_TCP</code>,
|
||||||
|
<code>GETDNS_TRANSPORT_TLS></code>, or
|
||||||
|
<code>GETDNS_TRANSPORT_STARTTLS></code>
|
||||||
|
|
||||||
<div class=forh>
|
<div class=forh>
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_set_limit_outstanding_queries(
|
getdns_context_set_limit_outstanding_queries(
|
||||||
|
@ -2219,6 +2233,16 @@ getdns_context_set_timeout(
|
||||||
<p class=cont>Specifies number of milliseconds the API will wait for request to return.
|
<p class=cont>Specifies number of milliseconds the API will wait for request to return.
|
||||||
The default is <span class=default>not specified</span>.</p>
|
The default is <span class=default>not specified</span>.</p>
|
||||||
|
|
||||||
|
<div class=forh>
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_idle_timeout(
|
||||||
|
getdns_context *context,
|
||||||
|
uint64_t timeout
|
||||||
|
);</div>
|
||||||
|
<p class=cont>Specifies number of milliseconds the API will leave an idle TCP, TLS or STARTTLS
|
||||||
|
connection open for (idle means no outstanding responses and no pending queries).
|
||||||
|
The default is <span class=default>0</span>.</p>
|
||||||
|
|
||||||
<h2>8.4 Context for Recursive Resolvers</h2>
|
<h2>8.4 Context for Recursive Resolvers</h2>
|
||||||
|
|
||||||
<div class=forh>
|
<div class=forh>
|
||||||
|
@ -2430,7 +2454,8 @@ The response dicts inherit the custom memory management functions and the value
|
||||||
<p class=descrip>Change related to <code>getdns_context_set_memory_functions</code></p>
|
<p class=descrip>Change related to <code>getdns_context_set_memory_functions</code></p>
|
||||||
<p class=define>GETDNS_CONTEXT_CODE_TIMEOUT</p>
|
<p class=define>GETDNS_CONTEXT_CODE_TIMEOUT</p>
|
||||||
<p class=descrip>Change related to <code>getdns_context_set_timeout</code></p>
|
<p class=descrip>Change related to <code>getdns_context_set_timeout</code></p>
|
||||||
|
<p class=define>GETDNS_CONTEXT_CODE_IDLE_TIMEOUT</p>
|
||||||
|
<p class=descrip>Change related to <code>getdns_context_set_idle_timeout</code></p>
|
||||||
|
|
||||||
<h2>8.11 Getting API information and current Contexts</h2>
|
<h2>8.11 Getting API information and current Contexts</h2>
|
||||||
<p>An application might want to see information about the API itself and inspect the current context.
|
<p>An application might want to see information about the API itself and inspect the current context.
|
||||||
|
|
|
@ -63,6 +63,7 @@ static struct const_info consts_info[] = {
|
||||||
{ 614, "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW_TEXT },
|
{ 614, "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW_TEXT },
|
||||||
{ 615, "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS_TEXT },
|
{ 615, "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS_TEXT },
|
||||||
{ 616, "GETDNS_CONTEXT_CODE_TIMEOUT", GETDNS_CONTEXT_CODE_TIMEOUT_TEXT },
|
{ 616, "GETDNS_CONTEXT_CODE_TIMEOUT", GETDNS_CONTEXT_CODE_TIMEOUT_TEXT },
|
||||||
|
{ 617, "GETDNS_CONTEXT_CODE_IDLE_TIMEOUT", GETDNS_CONTEXT_CODE_TIMEOUT_IDLE_TEXT },
|
||||||
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
|
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
|
||||||
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
|
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
|
||||||
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
|
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
|
||||||
|
@ -79,6 +80,11 @@ static struct const_info consts_info[] = {
|
||||||
{ 1100, "GETDNS_BAD_DNS_CNAME_IN_TARGET", GETDNS_BAD_DNS_CNAME_IN_TARGET_TEXT },
|
{ 1100, "GETDNS_BAD_DNS_CNAME_IN_TARGET", GETDNS_BAD_DNS_CNAME_IN_TARGET_TEXT },
|
||||||
{ 1101, "GETDNS_BAD_DNS_ALL_NUMERIC_LABEL", GETDNS_BAD_DNS_ALL_NUMERIC_LABEL_TEXT },
|
{ 1101, "GETDNS_BAD_DNS_ALL_NUMERIC_LABEL", GETDNS_BAD_DNS_ALL_NUMERIC_LABEL_TEXT },
|
||||||
{ 1102, "GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE", GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE_TEXT },
|
{ 1102, "GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE", GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE_TEXT },
|
||||||
|
{ 1200, "GETDNS_TRANSPORT_UDP", GETDNS_TRANSPORT_UDP_TEXT },
|
||||||
|
{ 1201, "GETDNS_TRANSPORT_TCP", GETDNS_TRANSPORT_TCP_TEXT },
|
||||||
|
{ 1202, "GETDNS_TRANSPORT_TLS", GETDNS_TRANSPORT_TLS_TEXT },
|
||||||
|
{ 1203, "GETDNS_TRANSPORT_STARTTLS", GETDNS_TRANSPORT_STARTTLS_TEXT },
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int const_info_cmp(const void *a, const void *b)
|
static int const_info_cmp(const void *a, const void *b)
|
||||||
|
|
335
src/context.c
335
src/context.c
|
@ -102,7 +102,7 @@ static void cancel_outstanding_requests(struct getdns_context*, int);
|
||||||
static getdns_return_t rebuild_ub_ctx(struct getdns_context* context);
|
static getdns_return_t rebuild_ub_ctx(struct getdns_context* context);
|
||||||
static void set_ub_string_opt(struct getdns_context *, char *, char *);
|
static void set_ub_string_opt(struct getdns_context *, char *, char *);
|
||||||
static void set_ub_number_opt(struct getdns_context *, char *, uint16_t);
|
static void set_ub_number_opt(struct getdns_context *, char *, uint16_t);
|
||||||
static getdns_return_t set_ub_dns_transport(struct getdns_context*, getdns_transport_t);
|
static getdns_return_t set_ub_dns_transport(struct getdns_context*);
|
||||||
static void set_ub_limit_outstanding_queries(struct getdns_context*,
|
static void set_ub_limit_outstanding_queries(struct getdns_context*,
|
||||||
uint16_t);
|
uint16_t);
|
||||||
static void set_ub_dnssec_allowed_skew(struct getdns_context*, uint32_t);
|
static void set_ub_dnssec_allowed_skew(struct getdns_context*, uint32_t);
|
||||||
|
@ -139,6 +139,44 @@ create_default_namespaces(struct getdns_context *context)
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getdns_transport_list_t *
|
||||||
|
get_dns_transport_list(getdns_context *context, int *count)
|
||||||
|
{
|
||||||
|
if (context == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Count how many we have*/
|
||||||
|
for (*count = 0; *count < GETDNS_BASE_TRANSPORT_MAX; (*count)++) {
|
||||||
|
if (context->dns_base_transports[*count] == GETDNS_BASE_TRANSPORT_NONE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use normal malloc here so users can do normal free
|
||||||
|
getdns_transport_list_t * transports = malloc(*count * sizeof(getdns_transport_list_t));
|
||||||
|
|
||||||
|
if(transports == NULL)
|
||||||
|
return NULL;
|
||||||
|
for (int i = 0; i < (int)*count; i++) {
|
||||||
|
switch(context->dns_base_transports[i]) {
|
||||||
|
case GETDNS_BASE_TRANSPORT_UDP:
|
||||||
|
transports[i] = GETDNS_TRANSPORT_UDP;
|
||||||
|
break;
|
||||||
|
case GETDNS_BASE_TRANSPORT_TCP:
|
||||||
|
transports[i] = GETDNS_TRANSPORT_TCP;
|
||||||
|
break;
|
||||||
|
case GETDNS_BASE_TRANSPORT_TLS:
|
||||||
|
transports[i] = GETDNS_TRANSPORT_TLS;
|
||||||
|
break;
|
||||||
|
case GETDNS_BASE_TRANSPORT_STARTTLS:
|
||||||
|
transports[i] = GETDNS_TRANSPORT_STARTTLS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return transports;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void canonicalize_dname(uint8_t *dname)
|
static inline void canonicalize_dname(uint8_t *dname)
|
||||||
{
|
{
|
||||||
uint8_t *next_label;
|
uint8_t *next_label;
|
||||||
|
@ -809,6 +847,7 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
result->timeout = 5000;
|
result->timeout = 5000;
|
||||||
|
result->idle_timeout = 0;
|
||||||
result->follow_redirects = GETDNS_REDIRECTS_FOLLOW;
|
result->follow_redirects = GETDNS_REDIRECTS_FOLLOW;
|
||||||
result->dns_root_servers = create_default_root_servers();
|
result->dns_root_servers = create_default_root_servers();
|
||||||
result->append_name = GETDNS_APPEND_NAME_ALWAYS;
|
result->append_name = GETDNS_APPEND_NAME_ALWAYS;
|
||||||
|
@ -834,8 +873,8 @@ getdns_context_create_with_extended_memory_functions(
|
||||||
|
|
||||||
result->dnssec_allowed_skew = 0;
|
result->dnssec_allowed_skew = 0;
|
||||||
result->edns_maximum_udp_payload_size = -1;
|
result->edns_maximum_udp_payload_size = -1;
|
||||||
result->dns_transport = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP;
|
result->dns_base_transports[0] = GETDNS_BASE_TRANSPORT_UDP;
|
||||||
priv_set_base_dns_transports(result->dns_base_transports, result->dns_transport);
|
result->dns_base_transports[1] = GETDNS_BASE_TRANSPORT_TCP;
|
||||||
result->limit_outstanding_queries = 0;
|
result->limit_outstanding_queries = 0;
|
||||||
result->has_ta = priv_getdns_parse_ta_file(NULL, NULL);
|
result->has_ta = priv_getdns_parse_ta_file(NULL, NULL);
|
||||||
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
||||||
|
@ -1065,8 +1104,7 @@ rebuild_ub_ctx(struct getdns_context* context) {
|
||||||
context->dnssec_allowed_skew);
|
context->dnssec_allowed_skew);
|
||||||
set_ub_edns_maximum_udp_payload_size(context,
|
set_ub_edns_maximum_udp_payload_size(context,
|
||||||
context->edns_maximum_udp_payload_size);
|
context->edns_maximum_udp_payload_size);
|
||||||
set_ub_dns_transport(context,
|
set_ub_dns_transport(context);
|
||||||
context->dns_transport);
|
|
||||||
|
|
||||||
/* Set default trust anchor */
|
/* Set default trust anchor */
|
||||||
if (context->has_ta) {
|
if (context->has_ta) {
|
||||||
|
@ -1159,75 +1197,71 @@ getdns_context_set_namespaces(struct getdns_context *context,
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
} /* getdns_context_set_namespaces */
|
} /* getdns_context_set_namespaces */
|
||||||
|
|
||||||
/* TODO[TLS]: Modify further when API changed.*/
|
static getdns_return_t
|
||||||
getdns_return_t
|
getdns_set_base_dns_transports(struct getdns_context *context,
|
||||||
priv_set_base_dns_transports(getdns_base_transport_t *dns_base_transports,
|
size_t transport_count, getdns_transport_list_t *transports)
|
||||||
getdns_transport_t value)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < GETDNS_BASE_TRANSPORT_MAX; i++)
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
dns_base_transports[i] = GETDNS_BASE_TRANSPORT_NONE;
|
for (int i = 0; i < GETDNS_BASE_TRANSPORT_MAX; i++)
|
||||||
switch (value) {
|
context->dns_base_transports[i] = GETDNS_BASE_TRANSPORT_NONE;
|
||||||
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:
|
if ((int)transport_count == 0 || transports == NULL ||
|
||||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
(int)transport_count > GETDNS_BASE_TRANSPORT_MAX) {
|
||||||
}
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
return GETDNS_RETURN_GOOD;
|
}
|
||||||
|
|
||||||
|
for (size_t j = 0; j < transport_count; j++) {
|
||||||
|
switch(transports[j]) {
|
||||||
|
case GETDNS_TRANSPORT_UDP:
|
||||||
|
context->dns_base_transports[j] = GETDNS_BASE_TRANSPORT_UDP;
|
||||||
|
break;
|
||||||
|
case GETDNS_TRANSPORT_TCP:
|
||||||
|
context->dns_base_transports[j] = GETDNS_BASE_TRANSPORT_TCP;
|
||||||
|
break;
|
||||||
|
case GETDNS_TRANSPORT_TLS:
|
||||||
|
context->dns_base_transports[j] = GETDNS_BASE_TRANSPORT_TLS;
|
||||||
|
break;
|
||||||
|
case GETDNS_TRANSPORT_STARTTLS:
|
||||||
|
context->dns_base_transports[j] = GETDNS_BASE_TRANSPORT_STARTTLS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getdns_return_t
|
static getdns_return_t
|
||||||
set_ub_dns_transport(struct getdns_context* context,
|
set_ub_dns_transport(struct getdns_context* context) {
|
||||||
getdns_transport_t value) {
|
/* These mappings are not exact because Unbound is configured differently,
|
||||||
switch (value) {
|
so just map as close as possible from the first 1 or 2 transports. */
|
||||||
case GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP:
|
switch (context->dns_base_transports[0]) {
|
||||||
|
case GETDNS_BASE_TRANSPORT_UDP:
|
||||||
set_ub_string_opt(context, "do-udp:", "yes");
|
set_ub_string_opt(context, "do-udp:", "yes");
|
||||||
set_ub_string_opt(context, "do-tcp:", "yes");
|
if (context->dns_base_transports[1] == GETDNS_BASE_TRANSPORT_TCP)
|
||||||
|
set_ub_string_opt(context, "do-tcp:", "yes");
|
||||||
|
else
|
||||||
|
set_ub_string_opt(context, "do-tcp:", "no");
|
||||||
break;
|
break;
|
||||||
case GETDNS_TRANSPORT_UDP_ONLY:
|
case GETDNS_BASE_TRANSPORT_TLS:
|
||||||
set_ub_string_opt(context, "do-udp:", "yes");
|
/* Note: If TLS is used in recursive mode this will try TLS on port
|
||||||
set_ub_string_opt(context, "do-tcp:", "no");
|
* 53... So this is prohibited when preparing for resolution.*/
|
||||||
break;
|
if (context->dns_base_transports[1] == GETDNS_BASE_TRANSPORT_NONE) {
|
||||||
case GETDNS_TRANSPORT_TCP_ONLY:
|
set_ub_string_opt(context, "ssl-upstream:", "yes");
|
||||||
/* Note: no pipelining available directly in unbound.*/
|
set_ub_string_opt(context, "do-udp:", "no");
|
||||||
case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
|
set_ub_string_opt(context, "do-tcp:", "yes");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (context->dns_base_transports[1] != GETDNS_BASE_TRANSPORT_TCP)
|
||||||
|
break;
|
||||||
|
/* Fallthrough */
|
||||||
|
case GETDNS_BASE_TRANSPORT_STARTTLS:
|
||||||
|
case GETDNS_BASE_TRANSPORT_TCP:
|
||||||
|
/* Note: no STARTTLS or 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");
|
set_ub_string_opt(context, "do-udp:", "no");
|
||||||
set_ub_string_opt(context, "do-tcp:", "yes");
|
set_ub_string_opt(context, "do-tcp:", "yes");
|
||||||
break;
|
break;
|
||||||
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
|
|
||||||
/* 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 */
|
|
||||||
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");
|
|
||||||
set_ub_string_opt(context, "do-tcp:", "yes");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
}
|
}
|
||||||
|
@ -1242,25 +1276,71 @@ getdns_return_t
|
||||||
getdns_context_set_dns_transport(struct getdns_context *context,
|
getdns_context_set_dns_transport(struct getdns_context *context,
|
||||||
getdns_transport_t value)
|
getdns_transport_t value)
|
||||||
{
|
{
|
||||||
/* TODO[TLS]: Modify further when API changed.*/
|
|
||||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
for (int i = 0; i < GETDNS_BASE_TRANSPORT_MAX; i++)
|
||||||
|
context->dns_base_transports[i] = GETDNS_BASE_TRANSPORT_NONE;
|
||||||
|
|
||||||
|
switch (value) {
|
||||||
|
case GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP:
|
||||||
|
context->dns_base_transports[0] = GETDNS_BASE_TRANSPORT_UDP;
|
||||||
|
context->dns_base_transports[1] = GETDNS_BASE_TRANSPORT_TCP;
|
||||||
|
break;
|
||||||
|
case GETDNS_TRANSPORT_UDP_ONLY:
|
||||||
|
context->dns_base_transports[0] = GETDNS_BASE_TRANSPORT_UDP;
|
||||||
|
break;
|
||||||
|
case GETDNS_TRANSPORT_TCP_ONLY:
|
||||||
|
case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||||
|
context->dns_base_transports[0] = GETDNS_BASE_TRANSPORT_TCP;
|
||||||
|
break;
|
||||||
|
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||||
|
context->dns_base_transports[0] = GETDNS_BASE_TRANSPORT_TLS;
|
||||||
|
break;
|
||||||
|
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||||
|
context->dns_base_transports[0] = GETDNS_BASE_TRANSPORT_TLS;
|
||||||
|
context->dns_base_transports[1] = GETDNS_BASE_TRANSPORT_TCP;
|
||||||
|
break;
|
||||||
|
case GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||||
|
context->dns_base_transports[0] = GETDNS_BASE_TRANSPORT_STARTTLS;
|
||||||
|
context->dns_base_transports[1] = GETDNS_BASE_TRANSPORT_TCP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
|
}
|
||||||
/* Note that the call below does not have any effect in unbound after the
|
/* Note that the call below does not have any effect in unbound after the
|
||||||
* ctx is finalised so for recursive mode or stub + dnssec only the first
|
* ctx is finalised so for recursive mode or stub + dnssec only the first
|
||||||
* transport specified on the first query is used.
|
* transport specified on the first query is used.
|
||||||
* However the method returns success as otherwise the transport could not
|
* 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 */
|
* Also, not all transport options supported in libunbound yet */
|
||||||
if (set_ub_dns_transport(context, value) != GETDNS_RETURN_GOOD) {
|
if (set_ub_dns_transport(context) != GETDNS_RETURN_GOOD) {
|
||||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
}
|
}
|
||||||
if (value != context->dns_transport) {
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_TRANSPORT);
|
||||||
/*TODO[TLS]: remove this line when API updated*/
|
return GETDNS_RETURN_GOOD;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getdns_context_set_dns_transport
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_dns_transport_list(getdns_context *context,
|
||||||
|
size_t transport_count, getdns_transport_list_t *transports)
|
||||||
|
{
|
||||||
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
if (getdns_set_base_dns_transports(context, transport_count, transports) != GETDNS_RETURN_GOOD)
|
||||||
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
|
/* Note that the call below does not have any effect in unbound after the
|
||||||
|
* 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.
|
||||||
|
* Also, not all transport options supported in libunbound yet */
|
||||||
|
if (set_ub_dns_transport(context) != GETDNS_RETURN_GOOD) {
|
||||||
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
|
}
|
||||||
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_TRANSPORT);
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
} /* getdns_context_set_dns_transport */
|
} /* getdns_context_set_dns_transport */
|
||||||
|
|
||||||
|
@ -1308,6 +1388,27 @@ getdns_context_set_timeout(struct getdns_context *context, uint64_t timeout)
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
} /* getdns_context_set_timeout */
|
} /* getdns_context_set_timeout */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getdns_context_set_idle_timeout
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_idle_timeout(struct getdns_context *context, uint64_t timeout)
|
||||||
|
{
|
||||||
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
if (timeout == 0) {
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->idle_timeout = timeout;
|
||||||
|
|
||||||
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_IDLE_TIMEOUT);
|
||||||
|
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
} /* getdns_context_set_timeout */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getdns_context_set_follow_redirects
|
* getdns_context_set_follow_redirects
|
||||||
*
|
*
|
||||||
|
@ -1568,7 +1669,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
|
||||||
if (base_transport != GETDNS_BASE_TRANSPORT_TLS)
|
if (base_transport != GETDNS_BASE_TRANSPORT_TLS)
|
||||||
(void) getdns_dict_get_int(dict, "port", &port);
|
(void) getdns_dict_get_int(dict, "port", &port);
|
||||||
else
|
else
|
||||||
(void) getdns_dict_get_int(dict, "tls-port", &port);
|
(void) getdns_dict_get_int(dict, "tls_port", &port);
|
||||||
(void) snprintf(portstr, 1024, "%d", (int)port);
|
(void) snprintf(portstr, 1024, "%d", (int)port);
|
||||||
|
|
||||||
if (getaddrinfo(addrstr, portstr, &hints, &ai))
|
if (getaddrinfo(addrstr, portstr, &hints, &ai))
|
||||||
|
@ -1918,17 +2019,14 @@ getdns_context_prepare_for_resolution(struct getdns_context *context,
|
||||||
/* Create client context, use TLS v1.2 only for now */
|
/* Create client context, use TLS v1.2 only for now */
|
||||||
context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method());
|
context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method());
|
||||||
#endif
|
#endif
|
||||||
/* TODO[TLS]: Check if TLS is the only option in the list*/
|
if(context->tls_ctx == NULL)
|
||||||
// if(!context->tls_ctx && context->dns_transport ==
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
// 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 */
|
/* Block use of TLS ONLY in recursive mode as it won't work */
|
||||||
/* TODO[TLS]: Check if TLS is the only option in the list*/
|
|
||||||
if (context->resolution_type == GETDNS_RESOLUTION_RECURSING &&
|
if (context->resolution_type == GETDNS_RESOLUTION_RECURSING &&
|
||||||
context->dns_transport == GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN)
|
context->dns_base_transports[0] == GETDNS_BASE_TRANSPORT_TLS &&
|
||||||
|
context->dns_base_transports[1] == GETDNS_BASE_TRANSPORT_NONE)
|
||||||
return GETDNS_RETURN_BAD_CONTEXT;
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
|
|
||||||
if (context->resolution_type_set == context->resolution_type)
|
if (context->resolution_type_set == context->resolution_type)
|
||||||
|
@ -2192,8 +2290,7 @@ priv_get_context_settings(getdns_context* context) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* int fields */
|
/* int fields */
|
||||||
r = getdns_dict_set_int(result, "dns_transport", context->dns_transport);
|
r = getdns_dict_set_int(result, "timeout", context->timeout);
|
||||||
r |= getdns_dict_set_int(result, "timeout", context->timeout);
|
|
||||||
r |= getdns_dict_set_int(result, "limit_outstanding_queries", context->limit_outstanding_queries);
|
r |= getdns_dict_set_int(result, "limit_outstanding_queries", context->limit_outstanding_queries);
|
||||||
r |= getdns_dict_set_int(result, "dnssec_allowed_skew", context->dnssec_allowed_skew);
|
r |= getdns_dict_set_int(result, "dnssec_allowed_skew", context->dnssec_allowed_skew);
|
||||||
r |= getdns_dict_set_int(result, "follow_redirects", context->follow_redirects);
|
r |= getdns_dict_set_int(result, "follow_redirects", context->follow_redirects);
|
||||||
|
@ -2224,6 +2321,18 @@ priv_get_context_settings(getdns_context* context) {
|
||||||
upstreams);
|
upstreams);
|
||||||
getdns_list_destroy(upstreams);
|
getdns_list_destroy(upstreams);
|
||||||
}
|
}
|
||||||
|
/* create a transport list */
|
||||||
|
getdns_list* transports = getdns_list_create_with_context(context);
|
||||||
|
if (transports) {
|
||||||
|
int transport_count;
|
||||||
|
getdns_transport_list_t *transport_list =
|
||||||
|
get_dns_transport_list(context, &transport_count);
|
||||||
|
for (int i = 0; i < transport_count; i++) {
|
||||||
|
r |= getdns_list_set_int(transports, i, transport_list[i]);
|
||||||
|
}
|
||||||
|
r |= getdns_dict_set_list(result, "dns_transport_list", transports);
|
||||||
|
free(transport_list);
|
||||||
|
}
|
||||||
if (context->namespace_count > 0) {
|
if (context->namespace_count > 0) {
|
||||||
/* create a namespace list */
|
/* create a namespace list */
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -2416,10 +2525,60 @@ getdns_context_get_dns_transport(getdns_context *context,
|
||||||
getdns_transport_t* value) {
|
getdns_transport_t* value) {
|
||||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
*value = context->dns_transport;
|
int count;
|
||||||
|
getdns_transport_list_t *transport_list =
|
||||||
|
get_dns_transport_list(context, &count);
|
||||||
|
if (!count)
|
||||||
|
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
|
||||||
|
|
||||||
|
/* Best effort mapping for backwards compatibility*/
|
||||||
|
if (transport_list[0] == GETDNS_TRANSPORT_UDP) {
|
||||||
|
if (count == 1)
|
||||||
|
*value = GETDNS_TRANSPORT_UDP_ONLY;
|
||||||
|
else if (count == 2 && transport_list[1] == GETDNS_TRANSPORT_TCP)
|
||||||
|
*value = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP;
|
||||||
|
else
|
||||||
|
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
|
||||||
|
}
|
||||||
|
if (transport_list[0] == GETDNS_TRANSPORT_TCP) {
|
||||||
|
if (count == 1)
|
||||||
|
*value = GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN;
|
||||||
|
}
|
||||||
|
if (transport_list[0] == GETDNS_TRANSPORT_TLS) {
|
||||||
|
if (count == 1)
|
||||||
|
*value = GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN;
|
||||||
|
else if (count == 2 && transport_list[1] == GETDNS_TRANSPORT_TCP)
|
||||||
|
*value = GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN;
|
||||||
|
else
|
||||||
|
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
|
||||||
|
}
|
||||||
|
if (transport_list[0] == GETDNS_TRANSPORT_STARTTLS) {
|
||||||
|
if (count == 2 && transport_list[1] == GETDNS_TRANSPORT_TCP)
|
||||||
|
*value = GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN;
|
||||||
|
else
|
||||||
|
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
|
||||||
|
}
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_dns_transport_list(getdns_context *context,
|
||||||
|
size_t* transport_count, getdns_transport_list_t **transports) {
|
||||||
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
RETURN_IF_NULL(transport_count, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
RETURN_IF_NULL(transports, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
int count;
|
||||||
|
getdns_transport_list_t *transport_list =
|
||||||
|
get_dns_transport_list(context, &count);
|
||||||
|
*transport_count = count;
|
||||||
|
if (!transport_count) {
|
||||||
|
*transports = NULL;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
*transports = transport_list;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_get_limit_outstanding_queries(getdns_context *context,
|
getdns_context_get_limit_outstanding_queries(getdns_context *context,
|
||||||
|
@ -2438,6 +2597,14 @@ getdns_context_get_timeout(getdns_context *context, uint64_t* value) {
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_idle_timeout(getdns_context *context, uint64_t* value) {
|
||||||
|
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
|
||||||
|
*value = context->idle_timeout;
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_get_follow_redirects(getdns_context *context,
|
getdns_context_get_follow_redirects(getdns_context *context,
|
||||||
getdns_redirects_t* value) {
|
getdns_redirects_t* value) {
|
||||||
|
|
|
@ -131,13 +131,13 @@ struct getdns_context {
|
||||||
getdns_namespace_t *namespaces;
|
getdns_namespace_t *namespaces;
|
||||||
int namespace_count;
|
int namespace_count;
|
||||||
uint64_t timeout;
|
uint64_t timeout;
|
||||||
|
uint64_t idle_timeout;
|
||||||
getdns_redirects_t follow_redirects;
|
getdns_redirects_t follow_redirects;
|
||||||
struct getdns_list *dns_root_servers;
|
struct getdns_list *dns_root_servers;
|
||||||
getdns_append_name_t append_name;
|
getdns_append_name_t append_name;
|
||||||
struct getdns_list *suffix;
|
struct getdns_list *suffix;
|
||||||
struct getdns_list *dnssec_trust_anchors;
|
struct getdns_list *dnssec_trust_anchors;
|
||||||
getdns_upstreams *upstreams;
|
getdns_upstreams *upstreams;
|
||||||
getdns_transport_t dns_transport;
|
|
||||||
getdns_base_transport_t dns_base_transports[GETDNS_BASE_TRANSPORT_MAX];
|
getdns_base_transport_t dns_base_transports[GETDNS_BASE_TRANSPORT_MAX];
|
||||||
uint16_t limit_outstanding_queries;
|
uint16_t limit_outstanding_queries;
|
||||||
uint32_t dnssec_allowed_skew;
|
uint32_t dnssec_allowed_skew;
|
||||||
|
@ -234,9 +234,6 @@ int filechg_check(struct getdns_context *context, struct filechg *fchg);
|
||||||
|
|
||||||
void priv_getdns_context_ub_read_cb(void *userarg);
|
void priv_getdns_context_ub_read_cb(void *userarg);
|
||||||
|
|
||||||
getdns_return_t priv_set_base_dns_transports(getdns_base_transport_t *,
|
|
||||||
getdns_transport_t);
|
|
||||||
|
|
||||||
void priv_getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
void priv_getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
||||||
|
|
||||||
#endif /* _GETDNS_CONTEXT_H_ */
|
#endif /* _GETDNS_CONTEXT_H_ */
|
||||||
|
|
10
src/dict.c
10
src/dict.c
|
@ -608,14 +608,14 @@ static const char *unknown_str_l[] = {" <unknown>", " null", "null"};
|
||||||
* @param buf buffer to write to
|
* @param buf buffer to write to
|
||||||
* @param indent number of spaces to append after newline
|
* @param indent number of spaces to append after newline
|
||||||
* @param list the to list print
|
* @param list the to list print
|
||||||
* @param for_namespaces The list is a list of namespace literals.
|
* @param for_literals The list is a list of literals.
|
||||||
* Show the literal instead of the value.
|
* Show the literal instead of the value.
|
||||||
* @return on success the number of written characters
|
* @return on success the number of written characters
|
||||||
* if an output error is encountered, a negative value
|
* if an output error is encountered, a negative value
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
getdns_pp_list(gldns_buffer *buf, size_t indent, const getdns_list *list,
|
getdns_pp_list(gldns_buffer *buf, size_t indent, const getdns_list *list,
|
||||||
int for_namespaces, int json)
|
int for_literals, int json)
|
||||||
{
|
{
|
||||||
size_t i, length, p = gldns_buffer_position(buf);
|
size_t i, length, p = gldns_buffer_position(buf);
|
||||||
getdns_data_type dtype;
|
getdns_data_type dtype;
|
||||||
|
@ -651,7 +651,7 @@ getdns_pp_list(gldns_buffer *buf, size_t indent, const getdns_list *list,
|
||||||
|
|
||||||
if (getdns_list_get_int(list, i, &int_item))
|
if (getdns_list_get_int(list, i, &int_item))
|
||||||
return -1;
|
return -1;
|
||||||
if (!json && for_namespaces &&
|
if (!json && for_literals &&
|
||||||
(strval =
|
(strval =
|
||||||
priv_getdns_get_const_info(int_item)->name)) {
|
priv_getdns_get_const_info(int_item)->name)) {
|
||||||
if (gldns_buffer_printf(buf, "%s", strval) < 0)
|
if (gldns_buffer_printf(buf, "%s", strval) < 0)
|
||||||
|
@ -829,7 +829,6 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
|
||||||
strcmp(item->node.key, "dnssec_status") == 0 ||
|
strcmp(item->node.key, "dnssec_status") == 0 ||
|
||||||
strcmp(item->node.key, "status") == 0 ||
|
strcmp(item->node.key, "status") == 0 ||
|
||||||
strcmp(item->node.key, "append_name") == 0 ||
|
strcmp(item->node.key, "append_name") == 0 ||
|
||||||
strcmp(item->node.key, "dns_transport") == 0 ||
|
|
||||||
strcmp(item->node.key, "follow_redirects") == 0 ||
|
strcmp(item->node.key, "follow_redirects") == 0 ||
|
||||||
strcmp(item->node.key, "resolution_type") == 0) &&
|
strcmp(item->node.key, "resolution_type") == 0) &&
|
||||||
(strval =
|
(strval =
|
||||||
|
@ -893,7 +892,8 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
|
||||||
getdns_indent(indent)) < 0)
|
getdns_indent(indent)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (getdns_pp_list(buf, indent, item->data.list,
|
if (getdns_pp_list(buf, indent, item->data.list,
|
||||||
(strcmp(item->node.key, "namespaces") == 0),
|
(strcmp(item->node.key, "namespaces") == 0 ||
|
||||||
|
strcmp(item->node.key, "dns_transport_list") == 0),
|
||||||
json) < 0)
|
json) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -180,6 +180,26 @@ typedef enum getdns_transport_t {
|
||||||
#define GETDNS_TRANSPORT_TLS_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_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()"
|
#define GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
|
||||||
|
/** @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Base transports for use in transport list */
|
||||||
|
typedef enum getdns_transport_list_t {
|
||||||
|
GETDNS_TRANSPORT_UDP = 1200,
|
||||||
|
GETDNS_TRANSPORT_TCP = 1201,
|
||||||
|
GETDNS_TRANSPORT_TLS = 1202,
|
||||||
|
GETDNS_TRANSPORT_STARTTLS = 1203
|
||||||
|
} getdns_transport_list_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \defgroup Base transport texts
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define GETDNS_TRANSPORT_UDP_TEXT "See getdns_context_set_dns_transport()"
|
||||||
|
#define GETDNS_TRANSPORT_TCP_TEXT "See getdns_context_set_dns_transport()"
|
||||||
|
#define GETDNS_TRANSPORT_TLS_TEXT "See getdns_context_set_dns_transport()"
|
||||||
|
#define GETDNS_TRANSPORT_STARTTLS_TEXT "See getdns_context_set_dns_transport()"
|
||||||
/** @}
|
/** @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -222,7 +242,8 @@ typedef enum getdns_context_code_t {
|
||||||
GETDNS_CONTEXT_CODE_EDNS_DO_BIT = 613,
|
GETDNS_CONTEXT_CODE_EDNS_DO_BIT = 613,
|
||||||
GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW = 614,
|
GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW = 614,
|
||||||
GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS = 615,
|
GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS = 615,
|
||||||
GETDNS_CONTEXT_CODE_TIMEOUT = 616
|
GETDNS_CONTEXT_CODE_TIMEOUT = 616,
|
||||||
|
GETDNS_CONTEXT_CODE_IDLE_TIMEOUT = 617
|
||||||
} getdns_context_code_t;
|
} getdns_context_code_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -246,6 +267,7 @@ typedef enum getdns_context_code_t {
|
||||||
#define GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW_TEXT "Change related to getdns_context_set_dnssec_allowed_skew"
|
#define GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW_TEXT "Change related to getdns_context_set_dnssec_allowed_skew"
|
||||||
#define GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS_TEXT "Change related to getdns_context_set_memory_functions"
|
#define GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS_TEXT "Change related to getdns_context_set_memory_functions"
|
||||||
#define GETDNS_CONTEXT_CODE_TIMEOUT_TEXT "Change related to getdns_context_set_timeout"
|
#define GETDNS_CONTEXT_CODE_TIMEOUT_TEXT "Change related to getdns_context_set_timeout"
|
||||||
|
#define GETDNS_CONTEXT_CODE_TIMEOUT_IDLE_TEXT "Change related to getdns_context_set_idle_timeout"
|
||||||
/** @}
|
/** @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -942,6 +964,10 @@ getdns_return_t
|
||||||
getdns_context_set_dns_transport(getdns_context *context,
|
getdns_context_set_dns_transport(getdns_context *context,
|
||||||
getdns_transport_t value);
|
getdns_transport_t value);
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_dns_transport_list(getdns_context *context,
|
||||||
|
size_t transport_count, getdns_transport_list_t *transports);
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_set_limit_outstanding_queries(getdns_context *context,
|
getdns_context_set_limit_outstanding_queries(getdns_context *context,
|
||||||
uint16_t limit);
|
uint16_t limit);
|
||||||
|
@ -949,6 +975,9 @@ getdns_context_set_limit_outstanding_queries(getdns_context *context,
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_set_timeout(getdns_context *context, uint64_t timeout);
|
getdns_context_set_timeout(getdns_context *context, uint64_t timeout);
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_set_idle_timeout(getdns_context *context, uint64_t timeout);
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_set_follow_redirects(getdns_context *context,
|
getdns_context_set_follow_redirects(getdns_context *context,
|
||||||
getdns_redirects_t value);
|
getdns_redirects_t value);
|
||||||
|
|
|
@ -139,6 +139,10 @@ getdns_return_t
|
||||||
getdns_context_get_dns_transport(getdns_context *context,
|
getdns_context_get_dns_transport(getdns_context *context,
|
||||||
getdns_transport_t* value);
|
getdns_transport_t* value);
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_dns_transport_list(getdns_context *context,
|
||||||
|
size_t* transport_count, getdns_transport_list_t **transports);
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_get_limit_outstanding_queries(getdns_context *context,
|
getdns_context_get_limit_outstanding_queries(getdns_context *context,
|
||||||
uint16_t* limit);
|
uint16_t* limit);
|
||||||
|
@ -146,6 +150,9 @@ getdns_context_get_limit_outstanding_queries(getdns_context *context,
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_get_timeout(getdns_context *context, uint64_t* timeout);
|
getdns_context_get_timeout(getdns_context *context, uint64_t* timeout);
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_context_get_idle_timeout(getdns_context *context, uint64_t* timeout);
|
||||||
|
|
||||||
getdns_return_t
|
getdns_return_t
|
||||||
getdns_context_get_follow_redirects(getdns_context *context,
|
getdns_context_get_follow_redirects(getdns_context *context,
|
||||||
getdns_redirects_t* value);
|
getdns_redirects_t* value);
|
||||||
|
|
|
@ -12,6 +12,7 @@ getdns_context_get_dns_root_servers
|
||||||
getdns_context_get_dnssec_allowed_skew
|
getdns_context_get_dnssec_allowed_skew
|
||||||
getdns_context_get_dnssec_trust_anchors
|
getdns_context_get_dnssec_trust_anchors
|
||||||
getdns_context_get_dns_transport
|
getdns_context_get_dns_transport
|
||||||
|
getdns_context_get_dns_transport_list
|
||||||
getdns_context_get_edns_do_bit
|
getdns_context_get_edns_do_bit
|
||||||
getdns_context_get_edns_extended_rcode
|
getdns_context_get_edns_extended_rcode
|
||||||
getdns_context_get_edns_maximum_udp_payload_size
|
getdns_context_get_edns_maximum_udp_payload_size
|
||||||
|
@ -23,6 +24,7 @@ getdns_context_get_num_pending_requests
|
||||||
getdns_context_get_resolution_type
|
getdns_context_get_resolution_type
|
||||||
getdns_context_get_suffix
|
getdns_context_get_suffix
|
||||||
getdns_context_get_timeout
|
getdns_context_get_timeout
|
||||||
|
getdns_context_get_idle_timeout
|
||||||
getdns_context_get_update_callback
|
getdns_context_get_update_callback
|
||||||
getdns_context_get_upstream_recursive_servers
|
getdns_context_get_upstream_recursive_servers
|
||||||
getdns_context_process_async
|
getdns_context_process_async
|
||||||
|
@ -33,6 +35,7 @@ getdns_context_set_dns_root_servers
|
||||||
getdns_context_set_dnssec_allowed_skew
|
getdns_context_set_dnssec_allowed_skew
|
||||||
getdns_context_set_dnssec_trust_anchors
|
getdns_context_set_dnssec_trust_anchors
|
||||||
getdns_context_set_dns_transport
|
getdns_context_set_dns_transport
|
||||||
|
getdns_context_set_dns_transport_list
|
||||||
getdns_context_set_edns_do_bit
|
getdns_context_set_edns_do_bit
|
||||||
getdns_context_set_edns_extended_rcode
|
getdns_context_set_edns_extended_rcode
|
||||||
getdns_context_set_edns_maximum_udp_payload_size
|
getdns_context_set_edns_maximum_udp_payload_size
|
||||||
|
@ -47,6 +50,7 @@ getdns_context_set_resolution_type
|
||||||
getdns_context_set_return_dnssec_status
|
getdns_context_set_return_dnssec_status
|
||||||
getdns_context_set_suffix
|
getdns_context_set_suffix
|
||||||
getdns_context_set_timeout
|
getdns_context_set_timeout
|
||||||
|
getdns_context_set_idle_timeout
|
||||||
getdns_context_set_update_callback
|
getdns_context_set_update_callback
|
||||||
getdns_context_set_upstream_recursive_servers
|
getdns_context_set_upstream_recursive_servers
|
||||||
getdns_context_set_use_threads
|
getdns_context_set_use_threads
|
||||||
|
|
38
src/stub.c
38
src/stub.c
|
@ -530,6 +530,7 @@ stub_timeout_cb(void *userarg)
|
||||||
netreq->upstream->tls_hs_state = GETDNS_HS_FAILED;
|
netreq->upstream->tls_hs_state = GETDNS_HS_FAILED;
|
||||||
stub_next_upstream(netreq);
|
stub_next_upstream(netreq);
|
||||||
stub_cleanup(netreq);
|
stub_cleanup(netreq);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
stub_next_upstream(netreq);
|
stub_next_upstream(netreq);
|
||||||
|
@ -538,6 +539,26 @@ stub_timeout_cb(void *userarg)
|
||||||
(void) getdns_context_request_timed_out(netreq->owner);
|
(void) getdns_context_request_timed_out(netreq->owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
upstream_idle_timeout_cb(void *userarg)
|
||||||
|
{
|
||||||
|
DEBUG_STUB("%s\n", __FUNCTION__);
|
||||||
|
getdns_upstream *upstream = (getdns_upstream *)userarg;
|
||||||
|
/*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;
|
||||||
|
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||||
|
upstream->tls_hs_state = GETDNS_HS_NONE;
|
||||||
|
if (upstream->tls_obj != NULL) {
|
||||||
|
SSL_shutdown(upstream->tls_obj);
|
||||||
|
SSL_free(upstream->tls_obj);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
upstream_tls_timeout_cb(void *userarg)
|
upstream_tls_timeout_cb(void *userarg)
|
||||||
{
|
{
|
||||||
|
@ -1049,10 +1070,11 @@ stub_udp_read_cb(void *userarg)
|
||||||
return; /* Client cookie didn't match? */
|
return; /* Client cookie didn't match? */
|
||||||
|
|
||||||
close(netreq->fd);
|
close(netreq->fd);
|
||||||
/*TODO[TLS]: Switch this to use the transport fallback list*/
|
/* TODO: check not past end of transports*/
|
||||||
|
getdns_base_transport_t next_transport =
|
||||||
|
netreq->dns_base_transports[netreq->transport + 1];
|
||||||
if (GLDNS_TC_WIRE(netreq->response) &&
|
if (GLDNS_TC_WIRE(netreq->response) &&
|
||||||
dnsreq->context->dns_transport ==
|
next_transport == GETDNS_BASE_TRANSPORT_TCP) {
|
||||||
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP) {
|
|
||||||
|
|
||||||
if ((netreq->fd = socket(
|
if ((netreq->fd = socket(
|
||||||
upstream->addr.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
upstream->addr.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
||||||
|
@ -1203,6 +1225,7 @@ upstream_read_cb(void *userarg)
|
||||||
getdns_upstream *upstream = (getdns_upstream *)userarg;
|
getdns_upstream *upstream = (getdns_upstream *)userarg;
|
||||||
getdns_network_req *netreq;
|
getdns_network_req *netreq;
|
||||||
getdns_dns_req *dnsreq;
|
getdns_dns_req *dnsreq;
|
||||||
|
uint64_t idle_timeout;
|
||||||
int q;
|
int q;
|
||||||
uint16_t query_id;
|
uint16_t query_id;
|
||||||
intptr_t query_id_intptr;
|
intptr_t query_id_intptr;
|
||||||
|
@ -1242,6 +1265,8 @@ upstream_read_cb(void *userarg)
|
||||||
upstream->tcp.read_pos - upstream->tcp.read_buf;
|
upstream->tcp.read_pos - upstream->tcp.read_buf;
|
||||||
upstream->tcp.read_buf = NULL;
|
upstream->tcp.read_buf = NULL;
|
||||||
upstream->upstreams->current = 0;
|
upstream->upstreams->current = 0;
|
||||||
|
/* netreq may die before setting timeout*/
|
||||||
|
idle_timeout = netreq->owner->context->idle_timeout;
|
||||||
|
|
||||||
/* TODO: DNSSEC */
|
/* TODO: DNSSEC */
|
||||||
netreq->secure = 0;
|
netreq->secure = 0;
|
||||||
|
@ -1295,6 +1320,12 @@ upstream_read_cb(void *userarg)
|
||||||
GETDNS_SCHEDULE_EVENT(upstream->loop,
|
GETDNS_SCHEDULE_EVENT(upstream->loop,
|
||||||
upstream->fd, TIMEOUT_FOREVER,
|
upstream->fd, TIMEOUT_FOREVER,
|
||||||
&upstream->event);
|
&upstream->event);
|
||||||
|
else {
|
||||||
|
upstream->event.timeout_cb = upstream_idle_timeout_cb;
|
||||||
|
GETDNS_SCHEDULE_EVENT(upstream->loop,
|
||||||
|
upstream->fd, idle_timeout,
|
||||||
|
&upstream->event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1655,6 +1686,7 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq)
|
||||||
/* Append netreq to write_queue */
|
/* Append netreq to write_queue */
|
||||||
if (!upstream->write_queue) {
|
if (!upstream->write_queue) {
|
||||||
upstream->write_queue = upstream->write_queue_last = netreq;
|
upstream->write_queue = upstream->write_queue_last = netreq;
|
||||||
|
upstream->event.timeout_cb = NULL;
|
||||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||||
if (upstream->tls_hs_state == GETDNS_HS_WRITE ||
|
if (upstream->tls_hs_state == GETDNS_HS_WRITE ||
|
||||||
(upstream->starttls_req &&
|
(upstream->starttls_req &&
|
||||||
|
|
|
@ -77,6 +77,39 @@ START_TEST (getdns_context_set_timeout_2)
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (getdns_context_set_idle_timeout_1)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* context is NULL
|
||||||
|
* expect: GETDNS_RETURN_INVALID_PARAMETER
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct getdns_context *context = NULL;
|
||||||
|
|
||||||
|
ASSERT_RC(getdns_context_set_idle_timeout(context, 1000),
|
||||||
|
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_context_set_timeout()");
|
||||||
|
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (getdns_context_set_idle_timeout_2)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* timeout is 0
|
||||||
|
* expect: GETDNS_RETURN_INVALID_PARAMETER
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct getdns_context *context = NULL;
|
||||||
|
CONTEXT_CREATE(TRUE);
|
||||||
|
|
||||||
|
ASSERT_RC(getdns_context_set_idle_timeout(context, 0),
|
||||||
|
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_context_set_timeout()");
|
||||||
|
|
||||||
|
CONTEXT_DESTROY;
|
||||||
|
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
#define GETDNS_STR_IPV4 "IPv4"
|
#define GETDNS_STR_IPV4 "IPv4"
|
||||||
#define GETDNS_STR_IPV6 "IPv6"
|
#define GETDNS_STR_IPV6 "IPv6"
|
||||||
#define GETDNS_STR_ADDRESS_TYPE "address_type"
|
#define GETDNS_STR_ADDRESS_TYPE "address_type"
|
||||||
|
@ -270,6 +303,8 @@ getdns_context_set_timeout_suite (void)
|
||||||
TCase *tc_neg = tcase_create("Negative");
|
TCase *tc_neg = tcase_create("Negative");
|
||||||
tcase_add_test(tc_neg, getdns_context_set_timeout_1);
|
tcase_add_test(tc_neg, getdns_context_set_timeout_1);
|
||||||
tcase_add_test(tc_neg, getdns_context_set_timeout_2);
|
tcase_add_test(tc_neg, getdns_context_set_timeout_2);
|
||||||
|
tcase_add_test(tc_neg, getdns_context_set_idle_timeout_1);
|
||||||
|
tcase_add_test(tc_neg, getdns_context_set_idle_timeout_2);
|
||||||
suite_add_tcase(s, tc_neg);
|
suite_add_tcase(s, tc_neg);
|
||||||
|
|
||||||
/* Positive test cases */
|
/* Positive test cases */
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <getdns/getdns.h>
|
#include <getdns/getdns.h>
|
||||||
#include <getdns/getdns_extra.h>
|
#include <getdns/getdns_extra.h>
|
||||||
|
#include <types-internal.h>
|
||||||
|
|
||||||
static int quiet = 0;
|
static int quiet = 0;
|
||||||
static int batch_mode = 0;
|
static int batch_mode = 0;
|
||||||
|
@ -92,13 +93,40 @@ ipaddr_dict(getdns_context *context, char *ipstr)
|
||||||
if (*portstr)
|
if (*portstr)
|
||||||
getdns_dict_set_int(r, "port", (int32_t)atoi(portstr));
|
getdns_dict_set_int(r, "port", (int32_t)atoi(portstr));
|
||||||
if (*tls_portstr)
|
if (*tls_portstr)
|
||||||
getdns_dict_set_int(r, "tls-port", (int32_t)atoi(tls_portstr));
|
getdns_dict_set_int(r, "tls_port", (int32_t)atoi(tls_portstr));
|
||||||
if (*scope_id_str)
|
if (*scope_id_str)
|
||||||
getdns_dict_util_set_string(r, "scope_id", scope_id_str);
|
getdns_dict_util_set_string(r, "scope_id", scope_id_str);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getdns_return_t
|
||||||
|
fill_transport_list(getdns_context *context, char *transport_list_str,
|
||||||
|
getdns_transport_list_t *transports, size_t *transport_count)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < strlen(transport_list_str); i++, (*transport_count)++) {
|
||||||
|
switch(*(transport_list_str + i)) {
|
||||||
|
case 'U':
|
||||||
|
transports[i] = GETDNS_TRANSPORT_UDP;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
transports[i] = GETDNS_TRANSPORT_TCP;
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
transports[i] = GETDNS_TRANSPORT_TLS;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
transports[i] = GETDNS_TRANSPORT_STARTTLS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unrecognised transport '%c' in string %s\n",
|
||||||
|
*(transport_list_str + i), transport_list_str);
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
print_usage(FILE *out, const char *progname)
|
print_usage(FILE *out, const char *progname)
|
||||||
{
|
{
|
||||||
|
@ -124,6 +152,7 @@ print_usage(FILE *out, const char *progname)
|
||||||
fprintf(out, "\t-s\tSet stub resolution type (default = recursing)\n");
|
fprintf(out, "\t-s\tSet stub resolution type (default = recursing)\n");
|
||||||
fprintf(out, "\t-S\tservice lookup (<type> is ignored)\n");
|
fprintf(out, "\t-S\tservice lookup (<type> is ignored)\n");
|
||||||
fprintf(out, "\t-t <timeout>\tSet timeout in miliseconds\n");
|
fprintf(out, "\t-t <timeout>\tSet timeout in miliseconds\n");
|
||||||
|
fprintf(out, "\t-e <idle_timeout>\tSet idle timeout in miliseconds\n");
|
||||||
fprintf(out, "\t-T\tSet transport to TCP only\n");
|
fprintf(out, "\t-T\tSet transport to TCP only\n");
|
||||||
fprintf(out, "\t-O\tSet transport to TCP only keep connections open\n");
|
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-L\tSet transport to TLS only keep connections open\n");
|
||||||
|
@ -131,6 +160,8 @@ print_usage(FILE *out, const char *progname)
|
||||||
fprintf(out, "\t-R\tSet transport to STARTTLS 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 with TCP fallback\n");
|
||||||
fprintf(out, "\t-U\tSet transport to UDP only\n");
|
fprintf(out, "\t-U\tSet transport to UDP only\n");
|
||||||
|
fprintf(out, "\t-l <transports>\tSet transport list. List can contain 1 of each of the characters\n");
|
||||||
|
fprintf(out, "\t\t\t U T L S for UDP, TCP, TLS or STARTTLS e.g 'UT' or 'LST' \n");
|
||||||
fprintf(out, "\t-B\tBatch mode. Schedule all messages before processing responses.\n");
|
fprintf(out, "\t-B\tBatch mode. Schedule all messages before processing responses.\n");
|
||||||
fprintf(out, "\t-q\tQuiet mode - don't print response\n");
|
fprintf(out, "\t-q\tQuiet mode - don't print response\n");
|
||||||
}
|
}
|
||||||
|
@ -347,20 +378,36 @@ getdns_return_t parse_args(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
||||||
fprintf(stderr, "ttl expected "
|
fprintf(stderr, "timeout expected "
|
||||||
"after -t\n");
|
"after -t\n");
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
timeout = strtol(argv[i], &endptr, 10);
|
timeout = strtol(argv[i], &endptr, 10);
|
||||||
if (*endptr || timeout < 0) {
|
if (*endptr || timeout < 0) {
|
||||||
fprintf(stderr, "positive "
|
fprintf(stderr, "positive "
|
||||||
"numeric ttl expected "
|
"numeric timeout expected "
|
||||||
"after -t\n");
|
"after -t\n");
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
getdns_context_set_timeout(
|
getdns_context_set_timeout(
|
||||||
context, timeout);
|
context, timeout);
|
||||||
goto next;
|
goto next;
|
||||||
|
case 'e':
|
||||||
|
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
||||||
|
fprintf(stderr, "idle timeout expected "
|
||||||
|
"after -t\n");
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
timeout = strtol(argv[i], &endptr, 10);
|
||||||
|
if (*endptr || timeout < 0) {
|
||||||
|
fprintf(stderr, "positive "
|
||||||
|
"numeric idle timeout expected "
|
||||||
|
"after -t\n");
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
getdns_context_set_idle_timeout(
|
||||||
|
context, timeout);
|
||||||
|
goto next;
|
||||||
case 'T':
|
case 'T':
|
||||||
getdns_context_set_dns_transport(context,
|
getdns_context_set_dns_transport(context,
|
||||||
GETDNS_TRANSPORT_TCP_ONLY);
|
GETDNS_TRANSPORT_TCP_ONLY);
|
||||||
|
@ -389,6 +436,21 @@ getdns_return_t parse_args(int argc, char **argv)
|
||||||
getdns_context_set_dns_transport(context,
|
getdns_context_set_dns_transport(context,
|
||||||
GETDNS_TRANSPORT_UDP_ONLY);
|
GETDNS_TRANSPORT_UDP_ONLY);
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
||||||
|
fprintf(stderr, "transport list expected "
|
||||||
|
"after -l\n");
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
size_t transport_count = 0;
|
||||||
|
getdns_transport_list_t transports[GETDNS_BASE_TRANSPORT_MAX];
|
||||||
|
if ((r = fill_transport_list(context, argv[i], transports, &transport_count)) ||
|
||||||
|
(r = getdns_context_set_dns_transport_list(context,
|
||||||
|
transport_count, transports))){
|
||||||
|
fprintf(stderr, "Could not set transports\n");
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
batch_mode = 1;
|
batch_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -42,10 +42,12 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#define TRANSPORT_UDP "udp"
|
#define TRANSPORT_UDP "udp"
|
||||||
|
#define TRANSPORT_UDP_TCP "udp_tcp"
|
||||||
#define TRANSPORT_TCP "tcp"
|
#define TRANSPORT_TCP "tcp"
|
||||||
#define TRANSPORT_PIPELINE "pipeline"
|
#define TRANSPORT_PIPELINE "pipeline"
|
||||||
#define TRANSPORT_TLS_KEEPOPEN "tls"
|
#define TRANSPORT_TLS_KEEPOPEN "tls"
|
||||||
#define TRANSPORT_TLS_TCP_KEEPOPEN "dns-over-tls"
|
#define TRANSPORT_TLS_TCP_KEEPOPEN "dns-over-tls"
|
||||||
|
#define TRANSPORT_STARTTLS_TCP_KEEPOPEN "starttls"
|
||||||
#define RESOLUTION_STUB "stub"
|
#define RESOLUTION_STUB "stub"
|
||||||
#define RESOLUTION_REC "rec"
|
#define RESOLUTION_REC "rec"
|
||||||
|
|
||||||
|
@ -76,16 +78,16 @@ int
|
||||||
main(int argc, char** argv)
|
main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
const char *transport = argc > 2 ? argv[2] : "udp";
|
const char *transport = argc > 2 ? argv[2] : "udp_tcp";
|
||||||
const char *resolution = argc > 3 ? argv[3] : "stub";
|
const char *resolution = argc > 3 ? argv[3] : "stub";
|
||||||
|
|
||||||
/* Create the DNS context for this call */
|
/* Create the DNS context for this call */
|
||||||
struct getdns_context *this_context = NULL;
|
struct getdns_context *this_context = NULL;
|
||||||
getdns_return_t context_create_return =
|
getdns_return_t return_value =
|
||||||
getdns_context_create(&this_context, 1);
|
getdns_context_create(&this_context, 1);
|
||||||
if (context_create_return != GETDNS_RETURN_GOOD) {
|
if (return_value != GETDNS_RETURN_GOOD) {
|
||||||
fprintf(stderr, "Trying to create the context failed: %d",
|
fprintf(stderr, "Trying to create the context failed: %d",
|
||||||
context_create_return);
|
return_value);
|
||||||
return (GETDNS_RETURN_GENERIC_ERROR);
|
return (GETDNS_RETURN_GENERIC_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,16 +98,23 @@ main(int argc, char** argv)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Order matters*/
|
||||||
if (strncmp(transport, TRANSPORT_TCP, 3) == 0)
|
if (strncmp(transport, TRANSPORT_TCP, 3) == 0)
|
||||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY);
|
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY);
|
||||||
|
else if (strncmp(transport, TRANSPORT_UDP_TCP, 7) == 0)
|
||||||
|
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP);
|
||||||
|
else if (strncmp(transport, TRANSPORT_UDP, 3) == 0)
|
||||||
|
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_UDP_ONLY);
|
||||||
else if (strncmp(transport, TRANSPORT_PIPELINE, 8) == 0)
|
else if (strncmp(transport, TRANSPORT_PIPELINE, 8) == 0)
|
||||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN);
|
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN);
|
||||||
else if (strncmp(transport, TRANSPORT_TLS_KEEPOPEN, 3) == 0)
|
else if (strncmp(transport, TRANSPORT_TLS_KEEPOPEN, 3) == 0)
|
||||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN);
|
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN);
|
||||||
else if (strncmp(transport, TRANSPORT_TLS_TCP_KEEPOPEN, 12) == 0)
|
else if (strncmp(transport, TRANSPORT_TLS_TCP_KEEPOPEN, 12) == 0)
|
||||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
|
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
|
||||||
else if (strncmp(transport, TRANSPORT_UDP, 3) != 0) {
|
else if (strncmp(transport, TRANSPORT_STARTTLS_TCP_KEEPOPEN, 8) == 0)
|
||||||
fprintf(stderr, "Invalid transport %s, must be one of udp, tcp or pipeline\n", transport);
|
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
|
||||||
|
else if (strncmp(transport, TRANSPORT_UDP_TCP, 3) != 0) {
|
||||||
|
fprintf(stderr, "Invalid transport %s, must be one of udp, udp_tcp, tcp or pipeline\n", transport);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +138,29 @@ main(int argc, char** argv)
|
||||||
else {
|
else {
|
||||||
getdns_context_run(this_context);
|
getdns_context_run(this_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getdns_transport_t get_transport;
|
||||||
|
return_value = getdns_context_get_dns_transport(this_context, &get_transport);
|
||||||
|
if (return_value != GETDNS_RETURN_GOOD) {
|
||||||
|
fprintf(stderr, "Trying to get transport type failed: %d\n",
|
||||||
|
return_value);
|
||||||
|
return (GETDNS_RETURN_GENERIC_ERROR);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Transport type is %d\n", get_transport);
|
||||||
|
|
||||||
|
size_t transport_count = 0;
|
||||||
|
getdns_transport_list_t *get_transport_list;
|
||||||
|
return_value = getdns_context_get_dns_transport_list(this_context, &transport_count, &get_transport_list);
|
||||||
|
if (return_value != GETDNS_RETURN_GOOD) {
|
||||||
|
fprintf(stderr, "Trying to get transport type failed: %d\n",
|
||||||
|
return_value);
|
||||||
|
return (GETDNS_RETURN_GENERIC_ERROR);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < transport_count; i++) {
|
||||||
|
fprintf(stderr, "Transport %d is %d\n", (int)i, get_transport_list[i]);
|
||||||
|
}
|
||||||
|
free(get_transport_list);
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
getdns_context_destroy(this_context);
|
getdns_context_destroy(this_context);
|
||||||
/* Assuming we get here, leave gracefully */
|
/* Assuming we get here, leave gracefully */
|
||||||
|
|
Loading…
Reference in New Issue