Skip to content

Commit

Permalink
see if we can remove the need for res_rcode() by changing the error p…
Browse files Browse the repository at this point in the history
…ath (#200)

Co-authored-by: paul vixie <vixie@fsi.io>
  • Loading branch information
vixie and paul vixie committed Jan 16, 2022
1 parent 11fb87f commit 4e70ffd
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 44 deletions.
77 changes: 42 additions & 35 deletions asinfo.c
Expand Up @@ -45,22 +45,22 @@ static struct __res_state res;

/* forward. */

static const char *asinfo_from_ipv4(const char *, char **, char **);
static char *asinfo_from_ipv4(const char *, char **, char **);
#ifdef asinfo_ipv6
static const char *asinfo_from_ipv6(const char *, char **, char **);
#endif
static const char *asinfo_from_dns(const char *, char **, char **);
static char *asinfo_from_dns(const char *, char **, char **);
static const char *keep_best(char **, char **, char *, char *);

/* public. */

/* asinfo_from_rr(rrtype, rdata, asnum, cidr) -- find ASINFO for A/AAAA string
*
* return NULL on success, or else, reason (string) for failure.
* return NULL on success, or else, reason (malloc'd string) for failure.
*
* side effect: on success, *asnum and *cidr will be heap-allocated strings.
*/
const char *
char *
asinfo_from_rr(const char *rrtype, const char *rdata,
char **asnum, char **cidr)
{
Expand Down Expand Up @@ -99,53 +99,52 @@ asinfo_shutdown(void) {

/* asinfo_from_ipv4(addr, asnum, cidr) -- prepare and use ASINFO IPv4 name
*
* return NULL on success, or else, reason (string) for failure.
* return NULL on success, or else, reason (malloc'd string) for failure.
*
* side effect: on success, *asnum and *cidr will be heap-allocated strings.
*/
static const char *
static char *
asinfo_from_ipv4(const char *addr, char **asnum, char **cidr) {
u_char a4[32/8];
char *dname;

if (inet_pton(AF_INET, addr, a4) < 0)
return strerror(errno);
return strdup(strerror(errno));
int n = asprintf(&dname, "%d.%d.%d.%d.%s",
a4[3], a4[2], a4[1], a4[0], asinfo_domain);
if (n < 0)
return strerror(errno);
const char *result = asinfo_from_dns(dname, asnum, cidr);
return strdup(strerror(errno));
char *result = asinfo_from_dns(dname, asnum, cidr);
free(dname);
return result;
}

#ifdef asinfo_ipv6
/* asinfo_from_ipv6(addr, asnum, cidr) -- prepare and use ASINFO IPv6 name
*
* return NULL on success, or else, reason (string) for failure.
* return NULL on success, or else, reason (malloc'd string) for failure.
*
* side effect: on success, *asnum and *cidr will be heap-allocated strings.
*
* NOTE WELL: this is a placeholder, since no ASINFO source has working IPv6.
*/
static const char *
static char *
asinfo_from_ipv6(const char *addr, char **asnum, char **cidr) {
char *result, *dname, *p;
u_char a6[128/8];
const char *result;
char *dname, *p;
int i;

if (inet_pton(AF_INET6, addr, &a6) < 0)
return strerror(errno);
return strdup(strerror(errno));
dname = malloc(strlen(asinfo_domain) + (128/4)*2);
if (dname == NULL)
return strerror(errno);
return strdup(strerror(errno));
result = NULL;
p = dname;
for (i = (128/8) - 1; i >= 0; i--) {
int n = sprintf(p, "%x.%x.", a6[i] & 0xf, a6[i] >> 4);
if (n < 0) {
result = strerror(errno);
result = strdup(strerror(errno));
break;
}
p += n;
Expand All @@ -162,15 +161,15 @@ asinfo_from_ipv6(const char *addr, char **asnum, char **cidr) {

/* asinfo_from_dns(dname, asnum, cidr) -- retrieve and parse a ASINFO DNS TXT
*
* return NULL on success, or else, reason (string) for failure.
* return NULL on success, or else, reason (malloc'd string) for failure.
*
* side effect: on success, *asnum and *cidr will be heap-allocated strings.
*/
static const char *
static char *
asinfo_from_dns(const char *dname, char **asnum, char **cidr) {
u_char buf[NS_PACKETSZ];
int n, an, rrn, rcode;
const char *result;
char *result;
ns_msg msg;
ns_rr rr;

Expand All @@ -185,16 +184,19 @@ asinfo_from_dns(const char *dname, char **asnum, char **cidr) {
if (res.res_h_errno == HOST_NOT_FOUND)
return NULL;
else
return hstrerror(res.res_h_errno);
return strdup(hstrerror(res.res_h_errno));
}
if (ns_initparse(buf, n, &msg) < 0)
return strerror(errno);
return strdup(strerror(errno));
rcode = ns_msg_getflag(msg, ns_f_rcode);
if (rcode != ns_r_noerror)
return p_rcode(rcode);
if (rcode != ns_r_noerror) {
if (asprintf(&result, "DNS RCODE 0x%x", rcode) < 0)
return strdup(strerror(errno));
return result;
}
an = ns_msg_count(msg, ns_s_an);
if (an == 0)
return "ANCOUNT == 0";
return strdup("ANCOUNT == 0");
/* some ASINFO data sources return multiple TXT RR's, each having
* a prefix length measured in bits. we will select the best
* (longest match) prefix offered.
Expand All @@ -205,7 +207,7 @@ asinfo_from_dns(const char *dname, char **asnum, char **cidr) {
char *txt[3];

if (ns_parserr(&msg, ns_s_an, rrn, &rr) < 0) {
result = strerror(errno);
result = strdup(strerror(errno));
break;
}
rdata = ns_rr_rdata(rr);
Expand All @@ -216,18 +218,18 @@ asinfo_from_dns(const char *dname, char **asnum, char **cidr) {
* more than three TXT segments (<character-strings>).
*/
if (ntxt == 3) {
result = "len(TXT[]) > 3";
result = strdup("len(TXT[]) > 3");
break;
}
n = *rdata++;
rdlen--;
if (n > rdlen) {
result = "TXT overrun";
result = strdup("TXT overrun");
break;
}
txt[ntxt] = strndup((const char *)rdata, (size_t)n);
if (txt[ntxt] == NULL) {
result = "strndup FAIL";
result = strdup("strndup FAIL");
break;
}
DEBUG(2, true, "TXT[%d] \"%s\"\n", ntxt, txt[ntxt]);
Expand Down Expand Up @@ -258,8 +260,11 @@ asinfo_from_dns(const char *dname, char **asnum, char **cidr) {
new_cidr = strndup(t1 + seplen, (size_t)
(t2 - (t1 + seplen)));
t1 = t2 = NULL;
result = keep_best(asnum, cidr,
new_asnum, new_cidr);
const char *t = keep_best(asnum, cidr,
new_asnum,
new_cidr);
if (t != NULL)
result = strdup(t);
} else if (ntxt == 3) {
/* routeviews.org format:
*
Expand All @@ -274,14 +279,16 @@ asinfo_from_dns(const char *dname, char **asnum, char **cidr) {
txt[1], txt[2]) >= 0)
{
new_asnum = strdup(txt[0]);
result = keep_best(asnum, cidr,
new_asnum,
new_cidr);
const char *t = keep_best(asnum, cidr,
new_asnum,
new_cidr);
if (t != NULL)
result = strdup(t);
} else {
result = strerror(errno);
result = strdup(strerror(errno));
}
} else {
result = "unrecognized asinfo TXT format";
result = strdup("unrecognized TXT format");
}
}
for (n = 0; n < ntxt; n++) {
Expand Down
2 changes: 1 addition & 1 deletion asinfo.h
Expand Up @@ -20,7 +20,7 @@
#include <stdbool.h>

#ifndef CRIPPLED_LIBC
const char *
char *
asinfo_from_rr(const char *rrtype, const char *rdata, char **asn, char **cidr);
#endif

Expand Down
16 changes: 8 additions & 8 deletions pdns.c
Expand Up @@ -128,14 +128,14 @@ present_text_lookup(pdns_tuple_ct tup,
*/
static void
present_text_line(const char *rrname, const char *rrtype, const char *rdata) {
char *asnum = NULL, *cidr = NULL, *comment = NULL;
const char *result = NULL;
char *asnum = NULL, *cidr = NULL, *comment = NULL, *result = NULL;

#ifndef CRIPPLED_LIBC
result = asinfo_from_rr(rrtype, rdata, &asnum, &cidr);
#endif
if (result != NULL) {
comment = strdup(result);
comment = result;
result = NULL;
} else if (asnum != NULL && cidr != NULL) {
const char *src = asnum;
bool wordbreak = true;
Expand Down Expand Up @@ -369,14 +369,14 @@ annotate_one(json_t *anno, const char *rdata, const char *name, json_t *obj) {
#ifndef CRIPPLED_LIBC
static json_t *
annotate_asinfo(const char *rrtype, const char *rdata) {
char *asnum = NULL, *cidr = NULL;
char *asnum = NULL, *cidr = NULL, *result = NULL;
json_t *asinfo = NULL;
const char *result;

if ((result = asinfo_from_rr(rrtype, rdata, &asnum, &cidr)) != NULL) {
asinfo = json_object();
json_object_set_new_nocheck(asinfo, "comment",
json_string(result));
free(result);
} else if (asnum != NULL && cidr != NULL) {
json_t *array = json_array();
char *copy, *walker, *token;
Expand Down Expand Up @@ -467,15 +467,15 @@ present_csv_line(pdns_tuple_ct tup, const char *rdata) {
printf("\"%s\"", rdata);
if (asinfo_lookup && tup->obj.rrtype != NULL &&
tup->obj.rdata != NULL) {
char *asnum = NULL, *cidr = NULL;
const char *result = NULL;
char *asnum = NULL, *cidr = NULL, *result = NULL;

#ifndef CRIPPLED_LIBC
result = asinfo_from_rr(tup->rrtype, rdata, &asnum, &cidr);
#endif
if (result != NULL) {
asnum = strdup(result);
cidr = strdup(result);
cidr = result;
result = NULL;
}
putchar(',');
if (asnum != NULL) {
Expand Down

0 comments on commit 4e70ffd

Please sign in to comment.