mirror of https://github.com/getdnsapi/getdns.git
Embed netreqs in dns_reqs and wire_data in netreqs
TODO: make sure the wire_data buffer is filled with the response
This commit is contained in:
parent
f9a0974e5a
commit
3f046cf573
|
@ -1389,9 +1389,9 @@ getdns_context_set_memory_functions(struct getdns_context *context,
|
|||
static void
|
||||
cancel_dns_req(getdns_dns_req *req)
|
||||
{
|
||||
getdns_network_req *netreq;
|
||||
getdns_network_req *netreq, **netreq_p;
|
||||
|
||||
for (netreq = req->first_req; netreq; netreq = netreq->next)
|
||||
for (netreq_p = req->netreqs; (netreq = *netreq_p); netreq_p++)
|
||||
if (netreq->unbound_id != -1) {
|
||||
ub_cancel(req->context->unbound_ctx,
|
||||
netreq->unbound_id);
|
||||
|
@ -1921,12 +1921,12 @@ getdns_context_local_namespace_resolve(
|
|||
ldns_rr_list *result_list = NULL;
|
||||
host_name_addrs *hnas;
|
||||
ldns_rdf *query_name;
|
||||
int ipv4 = dnsreq->first_req->request_type == GETDNS_RRTYPE_A ||
|
||||
(dnsreq->first_req->next &&
|
||||
dnsreq->first_req->next->request_type == GETDNS_RRTYPE_A);
|
||||
int ipv6 = dnsreq->first_req->request_type == GETDNS_RRTYPE_AAAA ||
|
||||
(dnsreq->first_req->next &&
|
||||
dnsreq->first_req->next->request_type == GETDNS_RRTYPE_AAAA);
|
||||
int ipv4 = dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_A ||
|
||||
(dnsreq->netreqs[1] &&
|
||||
dnsreq->netreqs[1]->request_type == GETDNS_RRTYPE_A);
|
||||
int ipv6 = dnsreq->netreqs[0]->request_type == GETDNS_RRTYPE_AAAA ||
|
||||
(dnsreq->netreqs[1] &&
|
||||
dnsreq->netreqs[1]->request_type == GETDNS_RRTYPE_AAAA);
|
||||
|
||||
if (!ipv4 && !ipv6)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
|
|
@ -272,7 +272,7 @@ static void destroy_chain(struct validation_chain *chain)
|
|||
static void
|
||||
getdns_get_validation_chain(getdns_dns_req *dns_req, uint64_t *timeout)
|
||||
{
|
||||
getdns_network_req *netreq = dns_req->first_req;
|
||||
getdns_network_req **netreq_p, *netreq;
|
||||
struct validation_chain *chain = create_chain(dns_req, timeout);
|
||||
|
||||
if (! chain) {
|
||||
|
@ -280,7 +280,7 @@ getdns_get_validation_chain(getdns_dns_req *dns_req, uint64_t *timeout)
|
|||
dns_req, create_getdns_response(dns_req));
|
||||
return;
|
||||
}
|
||||
while (netreq) {
|
||||
for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++) {
|
||||
size_t i;
|
||||
ldns_rr_list *answer = ldns_pkt_answer(netreq->result);
|
||||
ldns_rr_list *authority = ldns_pkt_authority(netreq->result);
|
||||
|
@ -296,7 +296,6 @@ getdns_get_validation_chain(getdns_dns_req *dns_req, uint64_t *timeout)
|
|||
launch_chain_link_lookup(chain,
|
||||
ldns_rdf2str(ldns_rr_rdf(rr, 7)));
|
||||
}
|
||||
netreq = netreq->next;
|
||||
}
|
||||
callback_on_complete_chain(chain);
|
||||
}
|
||||
|
|
|
@ -81,10 +81,10 @@ handle_network_request_error(getdns_network_req * netreq, int err)
|
|||
void
|
||||
priv_getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
||||
{
|
||||
getdns_network_req *netreq;
|
||||
getdns_network_req **netreq_p, *netreq;
|
||||
int results_found = 0;
|
||||
|
||||
for (netreq = dns_req->first_req; netreq; netreq = netreq->next)
|
||||
for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++)
|
||||
if (netreq->state != NET_REQ_FINISHED &&
|
||||
netreq->state != NET_REQ_CANCELED)
|
||||
return;
|
||||
|
@ -168,7 +168,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
getdns_callback_t callbackfn, int usenamespaces)
|
||||
{
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
getdns_network_req *netreq;
|
||||
getdns_network_req *netreq, **netreq_p;
|
||||
getdns_dns_req *req;
|
||||
getdns_dict *localnames_response;
|
||||
size_t i;
|
||||
|
@ -201,7 +201,9 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
if (!usenamespaces)
|
||||
/* issue all network requests */
|
||||
for (netreq = req->first_req; !r && netreq; netreq = netreq->next)
|
||||
for ( netreq_p = req->netreqs
|
||||
; !r && (netreq = *netreq_p)
|
||||
; netreq_p++)
|
||||
r = submit_network_request(netreq);
|
||||
|
||||
else for (i = 0; i < context->namespace_count; i++) {
|
||||
|
@ -221,11 +223,10 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
if this means we go onto the next namespace instead
|
||||
of returning */
|
||||
r = GETDNS_RETURN_GOOD;
|
||||
netreq = req->first_req;
|
||||
while (!r && netreq) {
|
||||
for ( netreq_p = req->netreqs
|
||||
; !r && (netreq = *netreq_p)
|
||||
; netreq_p++)
|
||||
r = submit_network_request(netreq);
|
||||
netreq = netreq->next;
|
||||
}
|
||||
break;
|
||||
} else
|
||||
r = GETDNS_RETURN_BAD_CONTEXT;
|
||||
|
|
|
@ -38,31 +38,24 @@
|
|||
#include "util-internal.h"
|
||||
#include "gldns/rrdef.h"
|
||||
|
||||
void
|
||||
network_req_free(getdns_network_req * net_req)
|
||||
static void
|
||||
network_req_cleanup(getdns_network_req *net_req)
|
||||
{
|
||||
if (!net_req) {
|
||||
return;
|
||||
}
|
||||
if (net_req->result) {
|
||||
assert(net_req);
|
||||
|
||||
if (net_req->result)
|
||||
ldns_pkt_free(net_req->result);
|
||||
}
|
||||
GETDNS_FREE(net_req->owner->my_mf, net_req);
|
||||
|
||||
if (net_req->response && net_req->response != net_req->wire_data)
|
||||
GETDNS_FREE(net_req->owner->my_mf, net_req->response);
|
||||
}
|
||||
|
||||
getdns_network_req *
|
||||
network_req_new(getdns_dns_req * owner,
|
||||
uint16_t request_type,
|
||||
uint16_t request_class, struct getdns_dict *extensions)
|
||||
static void
|
||||
network_req_init(getdns_network_req *net_req,
|
||||
getdns_dns_req *owner, uint16_t request_type,
|
||||
uint16_t request_class, size_t wire_data_sz)
|
||||
{
|
||||
|
||||
getdns_network_req *net_req = GETDNS_MALLOC( owner->my_mf
|
||||
, getdns_network_req);
|
||||
if (!net_req) {
|
||||
return NULL;
|
||||
}
|
||||
net_req->result = NULL;
|
||||
net_req->next = NULL;
|
||||
|
||||
net_req->request_type = request_type;
|
||||
net_req->request_class = request_class;
|
||||
|
@ -70,8 +63,6 @@ network_req_new(getdns_dns_req * owner,
|
|||
net_req->state = NET_REQ_NOT_SENT;
|
||||
net_req->owner = owner;
|
||||
|
||||
/* TODO: records and other extensions */
|
||||
|
||||
net_req->upstream = NULL;
|
||||
net_req->fd = -1;
|
||||
memset(&net_req->event, 0, sizeof(net_req->event));
|
||||
|
@ -79,16 +70,18 @@ network_req_new(getdns_dns_req * owner,
|
|||
net_req->query_id = 0;
|
||||
net_req->max_udp_payload_size = 0;
|
||||
net_req->write_queue_tail = NULL;
|
||||
return net_req;
|
||||
|
||||
net_req->wire_data_sz = wire_data_sz;
|
||||
net_req->response = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dns_req_free(getdns_dns_req * req)
|
||||
{
|
||||
getdns_network_req **net_req;
|
||||
if (!req) {
|
||||
return;
|
||||
}
|
||||
getdns_network_req *net_req = NULL;
|
||||
|
||||
/* free extensions */
|
||||
getdns_dict_destroy(req->extensions);
|
||||
|
@ -96,14 +89,11 @@ dns_req_free(getdns_dns_req * req)
|
|||
if (req->upstreams && --req->upstreams->referenced == 0)
|
||||
GETDNS_FREE(req->upstreams->mf, req->upstreams);
|
||||
|
||||
/* free network requests */
|
||||
net_req = req->first_req;
|
||||
while (net_req) {
|
||||
getdns_network_req *next = net_req->next;
|
||||
network_req_free(net_req);
|
||||
net_req = next;
|
||||
}
|
||||
/* cleanup network requests */
|
||||
for (net_req = req->netreqs; *net_req; net_req++)
|
||||
network_req_cleanup(*net_req);
|
||||
|
||||
/* clear timeout event */
|
||||
if (req->timeout.timeout_cb) {
|
||||
req->loop->vmt->clear(req->loop, &req->timeout);
|
||||
req->timeout.timeout_cb = NULL;
|
||||
|
@ -116,25 +106,47 @@ dns_req_free(getdns_dns_req * req)
|
|||
|
||||
/* create a new dns req to be submitted */
|
||||
getdns_dns_req *
|
||||
dns_req_new(struct getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, struct getdns_dict *extensions)
|
||||
dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions)
|
||||
{
|
||||
|
||||
getdns_dns_req *result = NULL;
|
||||
getdns_network_req *req = NULL;
|
||||
uint32_t klass = GLDNS_RR_CLASS_IN;
|
||||
size_t edns_maximum_udp_payload_size =
|
||||
getdns_get_maximum_udp_payload_size(context, extensions, NULL);
|
||||
int a_aaaa_query =
|
||||
is_extension_set(extensions, "return_both_v4_and_v6") &&
|
||||
( request_type == GETDNS_RRTYPE_A ||
|
||||
request_type == GETDNS_RRTYPE_AAAA );
|
||||
/* Reserve for the buffer at least one more byte
|
||||
* (to test for udp overflow) (hence the + 1),
|
||||
* And align on the 8 byte boundry (hence the (x + 7) / 8 * 8)
|
||||
*/
|
||||
size_t netreq_sz = ( sizeof(getdns_network_req)
|
||||
+ edns_maximum_udp_payload_size + 1 + 7) / 8 * 8;
|
||||
size_t dnsreq_base_sz = ( sizeof(getdns_dns_req)
|
||||
+ (a_aaaa_query ? 3 : 2)
|
||||
* sizeof(getdns_network_req *));
|
||||
uint8_t *region;
|
||||
|
||||
result = GETDNS_MALLOC(context->mf, getdns_dns_req);
|
||||
if (result == NULL) {
|
||||
if (! (region = GETDNS_XMALLOC(context->mf, uint8_t,
|
||||
dnsreq_base_sz + (a_aaaa_query ? 2 : 1) * netreq_sz)))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = (getdns_dns_req *)region;
|
||||
result->netreqs[0] = (getdns_network_req *)(region + dnsreq_base_sz);
|
||||
if (a_aaaa_query) {
|
||||
result->netreqs[1] = (getdns_network_req *)
|
||||
(region + dnsreq_base_sz + netreq_sz);
|
||||
result->netreqs[2] = NULL;
|
||||
} else
|
||||
result->netreqs[1] = NULL;
|
||||
|
||||
result->my_mf = context->mf;
|
||||
result->name = getdns_strdup(&(result->my_mf), name);
|
||||
result->context = context;
|
||||
result->loop = loop;
|
||||
result->canceled = 0;
|
||||
result->current_req = NULL;
|
||||
result->first_req = NULL;
|
||||
result->trans_id = (uint64_t)(((intptr_t) result) ^ ldns_get_random());
|
||||
|
||||
getdns_dict_copy(extensions, &result->extensions);
|
||||
|
@ -152,32 +164,14 @@ dns_req_new(struct getdns_context *context, getdns_eventloop *loop,
|
|||
if (result->upstreams)
|
||||
result->upstreams->referenced++;
|
||||
|
||||
/* create the requests */
|
||||
req = network_req_new(result, request_type, klass, extensions);
|
||||
if (!req) {
|
||||
dns_req_free(result);
|
||||
return NULL;
|
||||
}
|
||||
network_req_init(result->netreqs[0], result, request_type,
|
||||
klass, netreq_sz - sizeof(getdns_network_req));
|
||||
|
||||
result->current_req = req;
|
||||
result->first_req = req;
|
||||
|
||||
/* tack on A or AAAA if needed */
|
||||
if (is_extension_set(extensions, "return_both_v4_and_v6") &&
|
||||
(request_type == GETDNS_RRTYPE_A ||
|
||||
request_type == GETDNS_RRTYPE_AAAA)) {
|
||||
|
||||
uint16_t next_req_type = (request_type == GETDNS_RRTYPE_A) ?
|
||||
GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A;
|
||||
getdns_network_req *next_req = network_req_new(result,
|
||||
next_req_type, LDNS_RR_CLASS_IN, extensions);
|
||||
|
||||
if (!next_req) {
|
||||
dns_req_free(result);
|
||||
return NULL;
|
||||
}
|
||||
req->next = next_req;
|
||||
}
|
||||
if (a_aaaa_query)
|
||||
network_req_init(result->netreqs[1], result,
|
||||
( request_type == GETDNS_RRTYPE_A
|
||||
? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A ),
|
||||
klass, netreq_sz - sizeof(getdns_network_req));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -170,7 +170,6 @@ getdns_make_query_pkt_buf(const getdns_network_req *netreq, uint8_t *buf,
|
|||
if (len < 11)
|
||||
return GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
|
||||
|
||||
*omax_udp_payload_size = edns_maximum_udp_payload_size;
|
||||
buf[0] = 0; /* dname for . */
|
||||
gldns_write_uint16(buf + 1, GLDNS_RR_TYPE_OPT);
|
||||
gldns_write_uint16(buf + 3,
|
||||
|
|
|
@ -191,9 +191,6 @@ typedef struct getdns_network_req
|
|||
int secure;
|
||||
int bogus;
|
||||
|
||||
/* next request to issue after this one */
|
||||
struct getdns_network_req *next;
|
||||
|
||||
/* For stub resolving */
|
||||
struct getdns_upstream *upstream;
|
||||
int fd;
|
||||
|
@ -206,6 +203,14 @@ typedef struct getdns_network_req
|
|||
/* Network requests scheduled to write after me */
|
||||
struct getdns_network_req *write_queue_tail;
|
||||
|
||||
/* When more space is needed for the wire_data response than is
|
||||
* available in wire_data[], it will be allocated seperately.
|
||||
* response will then not point to wire_data anymore.
|
||||
*/
|
||||
uint8_t *response;
|
||||
size_t wire_data_sz;
|
||||
uint8_t wire_data[];
|
||||
|
||||
} getdns_network_req;
|
||||
|
||||
/**
|
||||
|
@ -222,12 +227,6 @@ typedef struct getdns_dns_req {
|
|||
/* canceled flag */
|
||||
int canceled;
|
||||
|
||||
/* current network request */
|
||||
struct getdns_network_req *current_req;
|
||||
|
||||
/* first request in list */
|
||||
struct getdns_network_req *first_req;
|
||||
|
||||
/* context that owns the request */
|
||||
struct getdns_context *context;
|
||||
|
||||
|
@ -256,6 +255,16 @@ typedef struct getdns_dns_req {
|
|||
/* Stuff for stub resolving */
|
||||
struct getdns_upstreams *upstreams;
|
||||
|
||||
/* network requests for this dns request.
|
||||
* The array is terminated with NULL.
|
||||
*
|
||||
* Memory for these netreqs has been allocated by the same malloc
|
||||
* operation that reserved space for this getdns_dns_req.
|
||||
* They will thus be freed as part of the desctruction of this struct,
|
||||
* and do not need to be freed seperately.
|
||||
*/
|
||||
getdns_network_req *netreqs[];
|
||||
|
||||
} getdns_dns_req;
|
||||
|
||||
#define GETDNS_XMALLOC(obj, type, count) \
|
||||
|
@ -294,13 +303,6 @@ typedef struct getdns_dns_req {
|
|||
|
||||
/* utility methods */
|
||||
|
||||
/* network request utilities */
|
||||
void network_req_free(getdns_network_req * net_req);
|
||||
|
||||
getdns_network_req *network_req_new(getdns_dns_req * owner,
|
||||
uint16_t request_type,
|
||||
uint16_t request_class, struct getdns_dict *extensions);
|
||||
|
||||
/* dns request utils */
|
||||
getdns_dns_req *dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions);
|
||||
|
|
|
@ -544,7 +544,7 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
|||
struct getdns_list *just_addrs = NULL;
|
||||
struct getdns_list *replies_tree = getdns_list_create_with_context(
|
||||
completed_request->context);
|
||||
getdns_network_req *netreq;
|
||||
getdns_network_req *netreq, **netreq_p;
|
||||
char *canonical_name = NULL;
|
||||
getdns_return_t r = 0;
|
||||
int nreplies = 0, nanswers = 0, nsecure = 0, ninsecure = 0, nbogus = 0;
|
||||
|
@ -562,13 +562,11 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
|||
completed_request->extensions, "dnssec_return_status") ||
|
||||
completed_request->return_dnssec_status == GETDNS_EXTENSION_TRUE;
|
||||
|
||||
if (completed_request->first_req &&
|
||||
(completed_request->first_req->request_class == GETDNS_RRTYPE_A ||
|
||||
completed_request->first_req->request_class ==
|
||||
GETDNS_RRTYPE_AAAA)) {
|
||||
if (completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_A ||
|
||||
completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_AAAA)
|
||||
just_addrs = getdns_list_create_with_context(
|
||||
completed_request->context);
|
||||
}
|
||||
|
||||
do {
|
||||
canonical_name = get_canonical_name(completed_request->name);
|
||||
r = getdns_dict_util_set_string(result, GETDNS_STR_KEY_CANONICAL_NM,
|
||||
|
@ -584,9 +582,9 @@ create_getdns_response(struct getdns_dns_req * completed_request)
|
|||
break;
|
||||
}
|
||||
|
||||
for ( netreq = completed_request->first_req
|
||||
; netreq && r == GETDNS_RETURN_GOOD
|
||||
; netreq = netreq->next ) {
|
||||
for ( netreq_p = completed_request->netreqs
|
||||
; ! r && (netreq = *netreq_p)
|
||||
; netreq_p++) {
|
||||
|
||||
if (! netreq->result)
|
||||
continue;
|
||||
|
@ -959,7 +957,7 @@ validate_dname(const char* dname) {
|
|||
} /* validate_dname */
|
||||
|
||||
int
|
||||
is_extension_set(struct getdns_dict *extensions, const char *extension)
|
||||
is_extension_set(getdns_dict *extensions, const char *extension)
|
||||
{
|
||||
getdns_return_t r;
|
||||
uint32_t value;
|
||||
|
@ -971,4 +969,76 @@ is_extension_set(struct getdns_dict *extensions, const char *extension)
|
|||
return r == GETDNS_RETURN_GOOD && value == GETDNS_EXTENSION_TRUE;
|
||||
}
|
||||
|
||||
size_t
|
||||
getdns_get_maximum_udp_payload_size(getdns_context *context,
|
||||
getdns_dict *extensions, getdns_upstream *upstream)
|
||||
{
|
||||
int dnssec_return_status
|
||||
= is_extension_set(extensions, "dnssec_return_status");
|
||||
int dnssec_return_only_secure
|
||||
= is_extension_set(extensions, "dnssec_return_only_secure");
|
||||
int dnssec_return_validation_chain
|
||||
= is_extension_set(extensions, "dnssec_return_validation_chain");
|
||||
int dnssec_extension_set = dnssec_return_status
|
||||
|| dnssec_return_only_secure || dnssec_return_validation_chain;
|
||||
|
||||
uint32_t edns_do_bit;
|
||||
int edns_maximum_udp_payload_size;
|
||||
uint32_t get_edns_maximum_udp_payload_size;
|
||||
uint32_t edns_extended_rcode;
|
||||
uint32_t edns_version;
|
||||
|
||||
getdns_dict *add_opt_parameters;
|
||||
int have_add_opt_parameters;
|
||||
|
||||
getdns_list *options;
|
||||
size_t noptions = 0;
|
||||
|
||||
int with_opt;
|
||||
|
||||
have_add_opt_parameters = getdns_dict_get_dict(extensions,
|
||||
"add_opt_parameters", &add_opt_parameters) == GETDNS_RETURN_GOOD;
|
||||
|
||||
if (dnssec_extension_set) {
|
||||
edns_maximum_udp_payload_size =
|
||||
( upstream && upstream->addr.ss_family == AF_INET6 )
|
||||
? 1232 : 1432;
|
||||
edns_extended_rcode = 0;
|
||||
edns_version = 0;
|
||||
edns_do_bit = 1;
|
||||
} else {
|
||||
edns_maximum_udp_payload_size =
|
||||
context->edns_maximum_udp_payload_size;
|
||||
edns_extended_rcode = context->edns_extended_rcode;
|
||||
edns_version = context->edns_version;
|
||||
edns_do_bit = context->edns_do_bit;
|
||||
|
||||
if (have_add_opt_parameters) {
|
||||
if (!getdns_dict_get_int(add_opt_parameters,
|
||||
"maximum_udp_payload_size",
|
||||
&get_edns_maximum_udp_payload_size))
|
||||
edns_maximum_udp_payload_size =
|
||||
get_edns_maximum_udp_payload_size;
|
||||
(void) getdns_dict_get_int(add_opt_parameters,
|
||||
"extended_rcode", &edns_extended_rcode);
|
||||
(void) getdns_dict_get_int(add_opt_parameters,
|
||||
"version", &edns_version);
|
||||
(void) getdns_dict_get_int(add_opt_parameters,
|
||||
"do_bit", &edns_do_bit);
|
||||
}
|
||||
}
|
||||
if (have_add_opt_parameters && getdns_dict_get_list(
|
||||
add_opt_parameters, "options", &options) == GETDNS_RETURN_GOOD)
|
||||
(void) getdns_list_get_length(options, &noptions);
|
||||
|
||||
with_opt = edns_do_bit != 0 || edns_maximum_udp_payload_size != -1 ||
|
||||
edns_extended_rcode != 0 || edns_version != 0 || noptions;
|
||||
|
||||
return ! with_opt ? 512
|
||||
: edns_maximum_udp_payload_size == -1 ?
|
||||
(upstream && upstream->addr.ss_family==AF_INET6 ) ? 1232 : 1432
|
||||
: edns_maximum_udp_payload_size > 512 ?
|
||||
edns_maximum_udp_payload_size : 512;
|
||||
}
|
||||
|
||||
/* util-internal.c */
|
||||
|
|
|
@ -147,7 +147,10 @@ create_list_from_rr_list(struct getdns_context *context, ldns_rr_list * rr_list)
|
|||
* @param extension name of extension to check
|
||||
* @return int with value 1 if set to GETDNS_EXTENSION_TRUE and 0 otherwise
|
||||
*/
|
||||
int is_extension_set(struct getdns_dict *extensions, const char *extension);
|
||||
int is_extension_set(getdns_dict *extensions, const char *extension);
|
||||
|
||||
size_t getdns_get_maximum_udp_payload_size(getdns_context *context,
|
||||
getdns_dict *extensions, getdns_upstream *upstream);
|
||||
|
||||
#define DEBUG_ON(...) do { \
|
||||
struct timeval tv; \
|
||||
|
|
Loading…
Reference in New Issue