resolver: abuse _res a little less
In the past, _res was a global variable. Now, it's multiple function calls. Several functions in the resolver use _res multiple times and therefore call the function(s) far more than necessary. Fix those callers to store the result of _res in a local variable. Add __noinline to the definition of res_init() to avoid the code bloat that these changes would have otherwise incurred. Thanks to jilles for noticing this. Reviewed by: jilles MFC after: 1 week Sponsored by: Dell Inc. Differential Revision: https://reviews.freebsd.org/D3887
This commit is contained in:
parent
ee74891fc7
commit
4cf0f1f5b3
@ -77,9 +77,10 @@ const char *_res_sectioncodes[] = {
|
||||
|
||||
int res_ourserver_p(const res_state, const struct sockaddr_in *);
|
||||
|
||||
int
|
||||
__noinline int
|
||||
res_init(void) {
|
||||
extern int __res_vinit(res_state, int);
|
||||
res_state statp = &_res;
|
||||
|
||||
/*
|
||||
* These three fields used to be statically initialized. This made
|
||||
@ -100,14 +101,14 @@ res_init(void) {
|
||||
* set in RES_DEFAULT). Our solution is to declare such applications
|
||||
* "broken". They could fool us by setting RES_INIT but none do (yet).
|
||||
*/
|
||||
if (!_res.retrans)
|
||||
_res.retrans = RES_TIMEOUT;
|
||||
if (!_res.retry)
|
||||
_res.retry = RES_DFLRETRY;
|
||||
if (!(_res.options & RES_INIT))
|
||||
_res.options = RES_DEFAULT;
|
||||
if (!statp->retrans)
|
||||
statp->retrans = RES_TIMEOUT;
|
||||
if (!statp->retry)
|
||||
statp->retry = RES_DFLRETRY;
|
||||
if (!(statp->options & RES_INIT))
|
||||
statp->options = RES_DEFAULT;
|
||||
|
||||
return (__res_vinit(&_res, 1));
|
||||
return (__res_vinit(statp, 1));
|
||||
}
|
||||
|
||||
void
|
||||
@ -122,10 +123,11 @@ fp_query(const u_char *msg, FILE *file) {
|
||||
|
||||
void
|
||||
fp_nquery(const u_char *msg, int len, FILE *file) {
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1)
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1)
|
||||
return;
|
||||
|
||||
res_pquery(&_res, msg, len, file);
|
||||
res_pquery(statp, msg, len, file);
|
||||
}
|
||||
|
||||
int
|
||||
@ -138,23 +140,25 @@ res_mkquery(int op, /*!< opcode of query */
|
||||
u_char *buf, /*!< buffer to put query */
|
||||
int buflen) /*!< size of buffer */
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
return (res_nmkquery(&_res, op, dname, class, type,
|
||||
return (res_nmkquery(statp, op, dname, class, type,
|
||||
data, datalen,
|
||||
newrr_in, buf, buflen));
|
||||
}
|
||||
|
||||
int
|
||||
res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
|
||||
return (res_nmkupdate(statp, rrecp_in, buf, buflen));
|
||||
}
|
||||
|
||||
int
|
||||
@ -163,11 +167,12 @@ res_query(const char *name, /*!< domain name */
|
||||
u_char *answer, /*!< buffer to put answer */
|
||||
int anslen) /*!< size of answer buffer */
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
return (res_nquery(&_res, name, class, type, answer, anslen));
|
||||
return (res_nquery(statp, name, class, type, answer, anslen));
|
||||
}
|
||||
|
||||
#ifndef _LIBC
|
||||
@ -189,12 +194,13 @@ res_isourserver(const struct sockaddr_in *inp) {
|
||||
|
||||
int
|
||||
res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
|
||||
/* errno should have been set by res_init() in this case. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (res_nsend(&_res, buf, buflen, ans, anssiz));
|
||||
return (res_nsend(statp, buf, buflen, ans, anssiz));
|
||||
}
|
||||
|
||||
#ifndef _LIBC
|
||||
@ -202,12 +208,13 @@ int
|
||||
res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
|
||||
u_char *ans, int anssiz)
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
|
||||
/* errno should have been set by res_init() in this case. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
|
||||
return (res_nsendsigned(statp, buf, buflen, key, ans, anssiz));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -218,12 +225,13 @@ res_close(void) {
|
||||
|
||||
int
|
||||
res_update(ns_updrec *rrecp_in) {
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (res_nupdate(&_res, rrecp_in, NULL));
|
||||
return (res_nupdate(statp, rrecp_in, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
@ -232,12 +240,13 @@ res_search(const char *name, /*!< domain name */
|
||||
u_char *answer, /*!< buffer to put answer */
|
||||
int anslen) /*!< size of answer */
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (res_nsearch(&_res, name, class, type, answer, anslen));
|
||||
return (res_nsearch(statp, name, class, type, answer, anslen));
|
||||
}
|
||||
|
||||
int
|
||||
@ -247,24 +256,26 @@ res_querydomain(const char *name,
|
||||
u_char *answer, /*!< buffer to put answer */
|
||||
int anslen) /*!< size of answer */
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (res_nquerydomain(&_res, name, domain,
|
||||
return (res_nquerydomain(statp, name, domain,
|
||||
class, type,
|
||||
answer, anslen));
|
||||
}
|
||||
|
||||
u_int
|
||||
res_randomid(void) {
|
||||
if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
|
||||
res_state statp = &_res;
|
||||
if ((statp->options & RES_INIT) == 0U && res_init() == -1) {
|
||||
RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (res_nrandomid(&_res));
|
||||
return (res_nrandomid(statp));
|
||||
}
|
||||
|
||||
int
|
||||
@ -284,13 +295,15 @@ hostalias(const char *name) {
|
||||
int
|
||||
local_hostname_length(const char *hostname) {
|
||||
int len_host, len_domain;
|
||||
res_state statp;
|
||||
|
||||
if (!*_res.defdname)
|
||||
statp = &_res;
|
||||
if (!*statp->defdname)
|
||||
res_init();
|
||||
len_host = strlen(hostname);
|
||||
len_domain = strlen(_res.defdname);
|
||||
len_domain = strlen(statp->defdname);
|
||||
if (len_host > len_domain &&
|
||||
!strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
|
||||
!strcasecmp(hostname + len_host - len_domain, statp->defdname) &&
|
||||
hostname[len_host - len_domain - 1] == '.')
|
||||
return (len_host - len_domain - 1);
|
||||
return (0);
|
||||
|
Loading…
Reference in New Issue
Block a user