More robust handling of whois referrals from RIRs.
An example problem case is 163.1.0.0 (University of Oxford) which is in an APNIC ERX address range. Previously we assumed that ARIN has the correct information for all ERX allocations, but in this case ARIN refers back to APNIC, rather than referring to RIPE. This caused whois to loop. Whois will no longer loop back and forth forever between two RIRs that don't have an answer, but instead try the other RIRs in turn.
This commit is contained in:
parent
22884d4715
commit
aec30d9b8d
@ -119,12 +119,38 @@ static struct {
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* We have a list of patterns for RIRs that assert ignorance rather than
|
||||
* providing referrals. If that happens, we guess that ARIN will be more
|
||||
* helpful. But, before following a referral to an RIR, we check if we have
|
||||
* asked that RIR already, and if so we make another guess.
|
||||
*/
|
||||
static const char *actually_arin[] = {
|
||||
"netname: ERX-NETBLOCK\n", /* APNIC */
|
||||
"netname: NON-RIPE-NCC-MANAGED-ADDRESS-BLOCK\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct {
|
||||
int loop;
|
||||
const char *host;
|
||||
} try_rir[] = {
|
||||
{ 0, ANICHOST },
|
||||
{ 0, RNICHOST },
|
||||
{ 0, PNICHOST },
|
||||
{ 0, FNICHOST },
|
||||
{ 0, LNICHOST },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
reset_rir(void) {
|
||||
int i;
|
||||
|
||||
for (i = 0; try_rir[i].host != NULL; i++)
|
||||
try_rir[i].loop = 0;
|
||||
}
|
||||
|
||||
static const char *port = DEFAULT_PORT;
|
||||
|
||||
static const char *choose_server(char *);
|
||||
@ -232,6 +258,7 @@ main(int argc, char *argv[])
|
||||
} else
|
||||
whois(*argv, host != NULL ? host :
|
||||
choose_server(*argv), flags);
|
||||
reset_rir();
|
||||
argv++;
|
||||
}
|
||||
exit(0);
|
||||
@ -420,7 +447,7 @@ whois(const char *query, const char *hostname, int flags)
|
||||
FILE *fp;
|
||||
struct addrinfo *hostres;
|
||||
char *buf, *host, *nhost, *p;
|
||||
int s, f;
|
||||
int comment, s, f;
|
||||
size_t len, i;
|
||||
|
||||
hostres = gethostinfo(hostname, 1);
|
||||
@ -467,12 +494,28 @@ whois(const char *query, const char *hostname, int flags)
|
||||
fprintf(fp, "%s\r\n", query);
|
||||
fflush(fp);
|
||||
|
||||
comment = 0;
|
||||
if (!(flags & WHOIS_SPAM_ME) &&
|
||||
(strcasecmp(hostname, ANICHOST) == 0 ||
|
||||
strcasecmp(hostname, RNICHOST) == 0)) {
|
||||
comment = 2;
|
||||
}
|
||||
|
||||
nhost = NULL;
|
||||
while ((buf = fgetln(fp, &len)) != NULL) {
|
||||
/* Nominet */
|
||||
if (!(flags & WHOIS_SPAM_ME) &&
|
||||
len == 5 && strncmp(buf, "-- \r\n", 5) == 0)
|
||||
break;
|
||||
/* RIRs */
|
||||
if (comment == 1 && buf[0] == '#')
|
||||
break;
|
||||
else if (comment == 2) {
|
||||
if (strchr("#%\r\n", buf[0]) != NULL)
|
||||
continue;
|
||||
else
|
||||
comment = 1;
|
||||
}
|
||||
|
||||
printf("%.*s", (int)len, buf);
|
||||
|
||||
@ -487,8 +530,7 @@ whois(const char *query, const char *hostname, int flags)
|
||||
SCAN(p, buf+len, *p == ' ');
|
||||
host = p;
|
||||
SCAN(p, buf+len, ishost(*p));
|
||||
/* avoid loops */
|
||||
if (strncmp(hostname, host, p - host) != 0)
|
||||
if (p > host)
|
||||
s_asprintf(&nhost, "%.*s",
|
||||
(int)(p - host), host);
|
||||
break;
|
||||
@ -511,8 +553,37 @@ whois(const char *query, const char *hostname, int flags)
|
||||
}
|
||||
fclose(fp);
|
||||
freeaddrinfo(hostres);
|
||||
|
||||
f = 0;
|
||||
for (i = 0; try_rir[i].host != NULL; i++) {
|
||||
/* Remember visits to RIRs */
|
||||
if (try_rir[i].loop == 0 &&
|
||||
strcasecmp(try_rir[i].host, hostname) == 0)
|
||||
try_rir[i].loop = 1;
|
||||
/* Do we need to find an alternative RIR? */
|
||||
if (try_rir[i].loop != 0 && nhost != NULL &&
|
||||
strcasecmp(try_rir[i].host, nhost) == 0) {
|
||||
free(nhost);
|
||||
nhost = NULL;
|
||||
f = 1;
|
||||
}
|
||||
}
|
||||
if (f) {
|
||||
/* Find a replacement RIR */
|
||||
for (i = 0; try_rir[i].host != NULL; i++) {
|
||||
if (try_rir[i].loop == 0) {
|
||||
s_asprintf(&nhost, "%s",
|
||||
try_rir[i].host);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nhost != NULL) {
|
||||
whois(query, nhost, flags);
|
||||
/* Ignore self-referrals */
|
||||
if (strcasecmp(hostname, nhost) != 0) {
|
||||
printf("# %s\n\n", nhost);
|
||||
whois(query, nhost, flags);
|
||||
}
|
||||
free(nhost);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user