nslookup: move array of queries to "globals"

function                                             old     new   delta
add_query                                             95      89      -6
nslookup_main                                       2692    2641     -51
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-57)             Total: -57 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko
2018-04-15 14:10:45 +02:00
parent 50aea2786b
commit 58e43a4c40

@ -314,8 +314,10 @@ struct globals {
unsigned default_port; unsigned default_port;
unsigned default_retry; unsigned default_retry;
unsigned default_timeout; unsigned default_timeout;
unsigned query_count;
unsigned serv_count; unsigned serv_count;
struct ns *server; struct ns *server;
struct query *query;
} FIX_ALIASING; } FIX_ALIASING;
#define G (*(struct globals*)bb_common_bufsiz1) #define G (*(struct globals*)bb_common_bufsiz1)
#define INIT_G() do { \ #define INIT_G() do { \
@ -518,9 +520,9 @@ static char *make_ptr(char resbuf[80], const char *addrstr)
/* /*
* Function logic borrowed & modified from musl libc, res_msend.c * Function logic borrowed & modified from musl libc, res_msend.c
* n_queries is always > 0. * G.query_count is always > 0.
*/ */
static int send_queries(struct ns *ns, struct query *query, int n_queries) static int send_queries(struct ns *ns)
{ {
unsigned char reply[512]; unsigned char reply[512];
uint8_t rcode; uint8_t rcode;
@ -557,10 +559,10 @@ static int send_queries(struct ns *ns, struct query *query, int n_queries)
if (tcur - tsent >= retry_interval) { if (tcur - tsent >= retry_interval) {
send: send:
for (qn = 0; qn < n_queries; qn++) { for (qn = 0; qn < G.query_count; qn++) {
if (query[qn].rlen) if (G.query[qn].rlen)
continue; continue;
if (write(pfd.fd, query[qn].query, query[qn].qlen) < 0) { if (write(pfd.fd, G.query[qn].query, G.query[qn].qlen) < 0) {
bb_perror_msg("write to '%s'", ns->name); bb_perror_msg("write to '%s'", ns->name);
n_replies = -1; /* "no go, try next server" */ n_replies = -1; /* "no go, try next server" */
goto ret; goto ret;
@ -568,7 +570,7 @@ static int send_queries(struct ns *ns, struct query *query, int n_queries)
dbg("query %u sent\n", qn); dbg("query %u sent\n", qn);
} }
tsent = tcur; tsent = tcur;
servfail_retry = 2 * n_queries; servfail_retry = 2 * G.query_count;
} }
/* Wait for a response, or until time to retry */ /* Wait for a response, or until time to retry */
@ -602,17 +604,17 @@ static int send_queries(struct ns *ns, struct query *query, int n_queries)
// qn = save_idx; // qn = save_idx;
qn = 0; qn = 0;
for (;;) { for (;;) {
if (memcmp(reply, query[qn].query, 2) == 0) { if (memcmp(reply, G.query[qn].query, 2) == 0) {
dbg("response matches query %u\n", qn); dbg("response matches query %u\n", qn);
break; break;
} }
if (++qn >= n_queries) { if (++qn >= G.query_count) {
dbg("response does not match any query\n"); dbg("response does not match any query\n");
goto next; goto next;
} }
} }
if (query[qn].rlen) { if (G.query[qn].rlen) {
dbg("dropped duplicate response to query %u\n", qn); dbg("dropped duplicate response to query %u\n", qn);
goto next; goto next;
} }
@ -625,14 +627,14 @@ static int send_queries(struct ns *ns, struct query *query, int n_queries)
ns->failures++; ns->failures++;
if (servfail_retry) { if (servfail_retry) {
servfail_retry--; servfail_retry--;
write(pfd.fd, query[qn].query, query[qn].qlen); write(pfd.fd, G.query[qn].query, G.query[qn].qlen);
dbg("query %u resent\n", qn); dbg("query %u resent\n", qn);
goto next; goto next;
} }
} }
/* Process reply */ /* Process reply */
query[qn].rlen = recvlen; G.query[qn].rlen = recvlen;
tcur = monotonic_ms(); tcur = monotonic_ms();
#if 1 #if 1
if (option_mask32 & OPT_debug) { if (option_mask32 & OPT_debug) {
@ -640,30 +642,30 @@ static int send_queries(struct ns *ns, struct query *query, int n_queries)
} }
if (rcode != 0) { if (rcode != 0) {
printf("** server can't find %s: %s\n", printf("** server can't find %s: %s\n",
query[qn].name, rcodes[rcode]); G.query[qn].name, rcodes[rcode]);
} else { } else {
if (parse_reply(reply, recvlen) < 0) if (parse_reply(reply, recvlen) < 0)
printf("*** Can't find %s: Parse error\n", query[qn].name); printf("*** Can't find %s: Parse error\n", G.query[qn].name);
} }
bb_putchar('\n'); bb_putchar('\n');
n_replies++; n_replies++;
if (n_replies >= n_queries) if (n_replies >= G.query_count)
goto ret; goto ret;
#else #else
//used to store replies and process them later //used to store replies and process them later
query[qn].latency = tcur - tstart; G.query[qn].latency = tcur - tstart;
n_replies++; n_replies++;
if (qn != save_idx) { if (qn != save_idx) {
/* "wrong" receive buffer, move to correct one */ /* "wrong" receive buffer, move to correct one */
memcpy(query[qn].reply, query[save_idx].reply, recvlen); memcpy(G.query[qn].reply, G.query[save_idx].reply, recvlen);
continue; continue;
} }
/* query[0..save_idx] have replies, move to next one, if exists */ /* G.query[0..save_idx] have replies, move to next one, if exists */
for (;;) { for (;;) {
save_idx++; save_idx++;
if (save_idx >= n_queries) if (save_idx >= G.query_count)
goto ret; /* all are full: we have all results */ goto ret; /* all are full: we have all results */
if (!query[save_idx].rlen) if (!G.query[save_idx].rlen)
break; /* this one is empty */ break; /* this one is empty */
} }
#endif #endif
@ -718,36 +720,27 @@ static void parse_resolvconf(void)
} }
} }
static struct query *add_query(struct query **queries, int *n_queries, static void add_query(int type, const char *dname)
int type, const char *dname)
{ {
struct query *new_q; struct query *new_q;
int pos; unsigned count;
ssize_t qlen; ssize_t qlen;
pos = *n_queries; count = G.query_count++;
*n_queries = pos + 1;
*queries = new_q = xrealloc(*queries, sizeof(**queries) * (pos + 1));
dbg("new query#%u type %u for '%s'\n", pos, type, dname); G.query = xrealloc_vector(G.query, /*2=2^1:*/ 1, count);
new_q += pos; new_q = &G.query[count];
memset(new_q, 0, sizeof(*new_q));
dbg("new query#%u type %u for '%s'\n", count, type, dname);
new_q->name = dname;
qlen = res_mkquery(QUERY, dname, C_IN, type, NULL, 0, NULL, qlen = res_mkquery(QUERY, dname, C_IN, type, NULL, 0, NULL,
new_q->query, sizeof(new_q->query)); new_q->query, sizeof(new_q->query));
new_q->qlen = qlen; new_q->qlen = qlen;
new_q->name = dname;
return new_q;
} }
int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int nslookup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int nslookup_main(int argc UNUSED_PARAM, char **argv) int nslookup_main(int argc UNUSED_PARAM, char **argv)
{ {
struct ns *ns;
struct query *queries;
int n_queries;
unsigned types; unsigned types;
int rc; int rc;
int err; int err;
@ -837,8 +830,6 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
} }
} }
n_queries = 0;
queries = NULL;
if (types == 0) { if (types == 0) {
/* No explicit type given, guess query type. /* No explicit type given, guess query type.
* If we can convert the domain argument into a ptr (means that * If we can convert the domain argument into a ptr (means that
@ -851,18 +842,18 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
ptr = make_ptr(buf80, argv[0]); ptr = make_ptr(buf80, argv[0]);
if (ptr) { if (ptr) {
add_query(&queries, &n_queries, T_PTR, xstrdup(ptr)); add_query(T_PTR, xstrdup(ptr));
} else { } else {
add_query(&queries, &n_queries, T_A, argv[0]); add_query(T_A, argv[0]);
#if ENABLE_FEATURE_IPV6 #if ENABLE_FEATURE_IPV6
add_query(&queries, &n_queries, T_AAAA, argv[0]); add_query(T_AAAA, argv[0]);
#endif #endif
} }
} else { } else {
int c; int c;
for (c = 0; c < ARRAY_SIZE(qtypes); c++) { for (c = 0; c < ARRAY_SIZE(qtypes); c++) {
if (types & (1 << c)) if (types & (1 << c))
add_query(&queries, &n_queries, qtypes[c].type, argv[0]); add_query(qtypes[c].type, argv[0]);
} }
} }
@ -881,7 +872,7 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
for (rc = 0; rc < G.serv_count;) { for (rc = 0; rc < G.serv_count;) {
int c; int c;
c = send_queries(&G.server[rc], queries, n_queries); c = send_queries(&G.server[rc]);
if (c > 0) { if (c > 0) {
/* more than zero replies received */ /* more than zero replies received */
#if 0 /* which version does this? */ #if 0 /* which version does this? */
@ -921,9 +912,9 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
} }
err = 0; err = 0;
for (rc = 0; rc < n_queries; rc++) { for (rc = 0; rc < G.query_count; rc++) {
if (queries[rc].rlen == 0) { if (G.query[rc].rlen == 0) {
printf("*** Can't find %s: No answer\n", queries[rc].name); printf("*** Can't find %s: No answer\n", G.query[rc].name);
err = 1; err = 1;
} }
} }
@ -931,9 +922,8 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
bb_putchar('\n'); /* should this affect exicode too? */ bb_putchar('\n'); /* should this affect exicode too? */
if (ENABLE_FEATURE_CLEAN_UP) { if (ENABLE_FEATURE_CLEAN_UP) {
free(ns); free(G.server);
if (n_queries) free(G.query);
free(queries);
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;