diff options
author | Florian Weimer <fweimer@redhat.com> | 2017-06-30 21:10:23 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2017-07-03 20:52:59 +0200 |
commit | 352f4ff9a268b81ef5d4b2413f582565806e4790 (patch) | |
tree | fb27056dfdeafe43c021f6127c9544c016e78019 /resolv/res_mkquery.c | |
parent | 4e45d83c92dbb5b8dc20654f32395108d18cf739 (diff) | |
download | glibc-352f4ff9a268b81ef5d4b2413f582565806e4790.tar.gz |
resolv: Introduce struct resolv_context [BZ #21668]
struct resolv_context objects provide a temporary resolver context
which does not change during a name lookup operation. Only when the
outmost context is created, the stub resolver configuration is
verified to be current (at present, only against previous res_init
calls). Subsequent attempts to obtain the context will reuse the
result of the initial verification operation.
struct resolv_context can also be extended in the future to store
data which needs to be deallocated during thread cancellation.
Diffstat (limited to 'resolv/res_mkquery.c')
-rw-r--r-- | resolv/res_mkquery.c | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c index 9afb410980..59fc5ab28c 100644 --- a/resolv/res_mkquery.c +++ b/resolv/res_mkquery.c @@ -88,6 +88,7 @@ #include <arpa/nameser.h> #include <netdb.h> #include <resolv/resolv-internal.h> +#include <resolv/resolv_context.h> #include <string.h> #include <sys/time.h> #include <shlib-compat.h> @@ -98,22 +99,10 @@ # define RANDOM_BITS(Var) { uint64_t v64; HP_TIMING_NOW (v64); Var = v64; } #endif -/* Form all types of queries. Returns the size of the result or -1 on - error. - - STATP points to an initialized resolver state. OP is the opcode of - the query. DNAME is the domain. CLASS and TYPE are the DNS query - class and type. DATA can be NULL; otherwise, it is a pointer to a - domain name which is included in the generated packet (if op == - NS_NOTIFY_OP). BUF must point to the out buffer of BUFLEN bytes. - - DATALEN and NEWRR_IN are currently ignored. */ int -res_nmkquery (res_state statp, int op, const char *dname, - int class, int type, - const unsigned char *data, int datalen, - const unsigned char *newrr_in, - unsigned char *buf, int buflen) +__res_context_mkquery (struct resolv_context *ctx, int op, const char *dname, + int class, int type, const unsigned char *data, + unsigned char *buf, int buflen) { HEADER *hp; unsigned char *cp; @@ -132,22 +121,17 @@ res_nmkquery (res_state statp, int op, const char *dname, by one after the initial randomization which still predictable if the application does multiple requests. */ int randombits; - do - { #ifdef RANDOM_BITS - RANDOM_BITS (randombits); + RANDOM_BITS (randombits); #else - struct timeval tv; - __gettimeofday (&tv, NULL); - randombits = (tv.tv_sec << 8) ^ tv.tv_usec; + struct timeval tv; + __gettimeofday (&tv, NULL); + randombits = (tv.tv_sec << 8) ^ tv.tv_usec; #endif - } - while ((randombits & 0xffff) == 0); - statp->id = (statp->id + randombits) & 0xffff; - hp->id = statp->id; + hp->id = randombits; hp->opcode = op; - hp->rd = (statp->options & RES_RECURSE) != 0; + hp->rd = (ctx->resp->options & RES_RECURSE) != 0; hp->rcode = NOERROR; cp = buf + HFIXEDSZ; buflen -= HFIXEDSZ; @@ -201,7 +185,45 @@ res_nmkquery (res_state statp, int op, const char *dname, } return cp - buf; } -libresolv_hidden_def (res_nmkquery) + +/* Common part of res_nmkquery and res_mkquery. */ +static int +context_mkquery_common (struct resolv_context *ctx, + int op, const char *dname, int class, int type, + const unsigned char *data, + unsigned char *buf, int buflen) +{ + if (ctx == NULL) + return -1; + int result = __res_context_mkquery + (ctx, op, dname, class, type, data, buf, buflen); + if (result >= 2) + memcpy (&ctx->resp->id, buf, 2); + __resolv_context_put (ctx); + return result; +} + +/* Form all types of queries. Returns the size of the result or -1 on + error. + + STATP points to an initialized resolver state. OP is the opcode of + the query. DNAME is the domain. CLASS and TYPE are the DNS query + class and type. DATA can be NULL; otherwise, it is a pointer to a + domain name which is included in the generated packet (if op == + NS_NOTIFY_OP). BUF must point to the out buffer of BUFLEN bytes. + + DATALEN and NEWRR_IN are currently ignored. */ +int +res_nmkquery (res_state statp, int op, const char *dname, + int class, int type, + const unsigned char *data, int datalen, + const unsigned char *newrr_in, + unsigned char *buf, int buflen) +{ + return context_mkquery_common + (__resolv_context_get_override (statp), + op, dname, class, type, data, buf, buflen); +} int res_mkquery (int op, const char *dname, int class, int type, @@ -209,13 +231,9 @@ res_mkquery (int op, const char *dname, int class, int type, const unsigned char *newrr_in, unsigned char *buf, int buflen) { - if (__res_maybe_init (&_res, 1) == -1) - { - RES_SET_H_ERRNO (&_res, NETDB_INTERNAL); - return -1; - } - return res_nmkquery (&_res, op, dname, class, type, - data, datalen, newrr_in, buf, buflen); + return context_mkquery_common + (__resolv_context_get_preinit (), + op, dname, class, type, data, buf, buflen); } /* Create an OPT resource record. Return the length of the final @@ -227,8 +245,8 @@ res_mkquery (int op, const char *dname, int class, int type, pointers to must be BUFLEN bytes long. ANSLEN is the advertised EDNS buffer size (to be included in the OPT resource record). */ int -__res_nopt (res_state statp, int n0, unsigned char *buf, int buflen, - int anslen) +__res_nopt (struct resolv_context *ctx, + int n0, unsigned char *buf, int buflen, int anslen) { uint16_t flags = 0; HEADER *hp = (HEADER *) buf; @@ -269,7 +287,7 @@ __res_nopt (res_state statp, int n0, unsigned char *buf, int buflen, *cp++ = NOERROR; /* Extended RCODE. */ *cp++ = 0; /* EDNS version. */ - if (statp->options & RES_USE_DNSSEC) + if (ctx->resp->options & RES_USE_DNSSEC) flags |= NS_OPT_DNSSEC_OK; NS_PUT16 (flags, cp); |