aboutsummaryrefslogtreecommitdiff
path: root/eperd/evtdig.c
diff options
context:
space:
mode:
Diffstat (limited to 'eperd/evtdig.c')
-rw-r--r--eperd/evtdig.c76
1 files changed, 67 insertions, 9 deletions
diff --git a/eperd/evtdig.c b/eperd/evtdig.c
index c0d606c..da67a2a 100644
--- a/eperd/evtdig.c
+++ b/eperd/evtdig.c
@@ -50,6 +50,7 @@
#define O_RESOLV_CONF 1003
#define O_PREPEND_PROBE_ID 1004
#define O_EVDNS 1005
+#define O_RETRY 1006
#define DNS_FLAG_RD 0x0100
@@ -63,10 +64,11 @@
#define MAX_DNS_OUT_BUF_SIZE 512
/* Intervals and timeouts (all are in milliseconds unless otherwise specified) */
-#define DEFAULT_NOREPLY_TIMEOUT 5000 /* 1000 msec - 0 is illegal */
+#define DEFAULT_NOREPLY_TIMEOUT 5000 /* 5000 msec - 0 is illegal */
#define DEFAULT_LINE_LENGTH 80
#define DEFAULT_STATS_REPORT_INTERVEL 180 /* in seconds */
#define CONN_TO 5 /* TCP connection time out in seconds */
+#define DEFAULT_RETRY_MAX 10
/* state of the dns query */
#define STATUS_DNS_RESOLV 1001
@@ -74,6 +76,7 @@
#define STATUS_TCP_CONNECTED 1003
#define STATUS_TCP_WRITE 1004
#define STATUS_NEXT_QUERY 1005
+#define STATUS_RETRANSMIT_QUERY 1006
#define STATUS_FREE 0
// seems T_DNSKEY is not defined header files of lenny and sdk
@@ -187,6 +190,8 @@ struct query_state {
int opt_rd;
int opt_prepend_probe_id;
int opt_evdns;
+ int opt_retry_max;
+ int retry;
char * str_Atlas;
u_int16_t qtype;
@@ -319,6 +324,8 @@ static struct option longopts[]=
{ "ds", required_argument, NULL, (100000 + T_DS) },
{ "rrsig", required_argument, NULL, (100000 + T_RRSIG) },
{ "soa", required_argument, NULL, 's' },
+ { "srv", required_argument, NULL, (100000 + T_SRV) },
+ { "naptr", required_argument, NULL, (100000 + T_NAPTR) },
// clas CHAOS
{ "hostname.bind", no_argument, NULL, 'h' },
@@ -331,6 +338,7 @@ static struct option longopts[]=
{ "nsid", no_argument, NULL, 'n' },
{ "d0", no_argument, NULL, 'd' },
+ { "retry", required_argument, NULL, O_RETRY },
{ "resolv", no_argument, NULL, O_RESOLV_CONF },
{ "qbuf", no_argument, NULL, 1001 },
{ "noabuf", no_argument, NULL, 1002 },
@@ -355,6 +363,8 @@ static void process_reply(void * arg, int nrecv, struct timeval now, int af, voi
static void mk_dns_buff(struct query_state *qry, u_char *packet);
int ip_addr_cmp (u_int16_t af_a, void *a, u_int16_t af_b, void *b);
static void udp_dns_cb(int err, struct evutil_addrinfo *ev_res, struct query_state *qry);
+static void noreply_callback(int unused UNUSED_PARAM, const short event UNUSED_PARAM, void *h);
+static void free_qry_inst(struct query_state *qry);
/* move the next functions from tdig.c */
u_int32_t get32b (char *p);
@@ -724,15 +734,26 @@ static void next_qry_cb(int unused UNUSED_PARAM, const short event UNUSED_PARAM
/* The callback to handle timeouts due to destination host unreachable condition */
static void noreply_callback(int unused UNUSED_PARAM, const short event UNUSED_PARAM, void *h)
{
+ struct timeval asap = { 0, 0 };
struct query_state *qry = h;
qry->base->timeout++;
snprintf(line, DEFAULT_LINE_LENGTH, "%s \"timeout\" : %d", qry->err.size ? ", " : "", DEFAULT_NOREPLY_TIMEOUT);
buf_add(&qry->err, line, strlen(line));
- BLURT(LVL5 "AAA timeout for %s ", qry->server_name);
- printReply (qry, 0, NULL);
+ BLURT(LVL5 "AAA timeout for %s retry %d/%d ", qry->server_name, qry->retry, qry->opt_retry_max);
+ if (qry->retry < qry->opt_retry_max) {
+ qry->retry++;
+ free_qry_inst(qry);
+ qry->qst = STATUS_RETRANSMIT_QUERY;
+ evtimer_add(&qry->next_qry_timer, &asap);
+ } else {
+ printReply (qry, 0, NULL);
+ }
+
return;
-}
+}
+
+
static void tcp_timeout_callback (int __attribute((unused)) unused,
const short __attribute((unused)) event, void *s)
@@ -746,6 +767,7 @@ static void tcp_reporterr(struct tu_env *env, enum tu_err cause,
const char *str)
{
struct query_state * qry;
+ struct timeval asap = { 0, 0 };
qry = ENV2QRY(env);
// if (env != &state->tu_env) abort(); // Why do i need this? AA
@@ -780,7 +802,14 @@ static void tcp_reporterr(struct tu_env *env, enum tu_err cause,
crondlog(DIE9 "reporterr: bad cause %d", cause);
break;
}
- printReply (qry, 0, NULL);
+ if (qry->retry < qry->opt_retry_max) {
+ qry->retry++;
+ free_qry_inst(qry);
+ qry->qst = STATUS_RETRANSMIT_QUERY;
+ evtimer_add(&qry->next_qry_timer, &asap);
+ } else {
+ printReply (qry, 0, NULL);
+ }
}
static void tcp_dnscount(struct tu_env *env, int count)
@@ -1044,6 +1073,8 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
qry->str_Atlas = NULL;
tdig_base->activeqry++;
qry->qst = 0;
+ qry->retry = 0;
+ qry->opt_retry_max = DEFAULT_RETRY_MAX;
qry->wire_size = 0;
qry->triptime = 0;
qry->opt_edns0 = 512;
@@ -1157,6 +1188,10 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
qry->opt_abuf = 0;
break;
+ case O_RETRY :
+ qry->opt_retry_max = strtoul(optarg, NULL, 10);
+ break;
+
case O_RESOLV_CONF :
qry->opt_resolv_conf = Q_RESOLV_CONF ;
qry->opt_v6_only = 1;
@@ -1253,7 +1288,19 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
qry->qtype = T_RRSIG;
qry->qclass = C_IN;
qry->lookupname = strdup(optarg);
- break;break;
+ break;
+
+ case (100000 + T_SRV):
+ qry->qtype = T_SRV;
+ qry->qclass = C_IN;
+ qry->lookupname = strdup(optarg);
+ break;
+
+ case (100000 + T_NAPTR):
+ qry->qtype = T_NAPTR;
+ qry->qclass = C_IN;
+ qry->lookupname = strdup(optarg);
+ break;
default:
fprintf(stderr, "ERROR unknown option %d ??\n", c);
@@ -1289,12 +1336,19 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
else
qry->server_name = strdup(argv[optind]);
- if(qry->lookupname == NULL) {
+ if (qry->lookupname == NULL) {
crondlog(LVL9 "ERROR no query in command line");
tdig_delete(qry);
return NULL;
}
+ if (qry->lookupname[strlen(qry->lookupname) - 1] != '.') {
+ crondlog(LVL9 "ERROR query %s does not end with a dot ", qry->lookupname);
+ tdig_delete(qry);
+ return NULL;
+ }
+
+
if (qry->out_filename &&
!validate_filename(qry->out_filename, SAFE_PREFIX))
{
@@ -1450,7 +1504,8 @@ void tdig_start (struct query_state *qry)
switch(qry->qst)
{
case STATUS_NEXT_QUERY :
- case STATUS_FREE :
+ case STATUS_FREE :
+ case STATUS_RETRANSMIT_QUERY:
break;
default:
printErrorQuick(qry);
@@ -1861,6 +1916,9 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result )
if(strlen(line))
JS(src_addr, line);
}
+ if(qry->retry) {
+ JS1(retry, %d, qry->retry);
+ }
JS_NC(proto, qry->opt_proto == 6 ? "TCP" : "UDP" );
if(qry->opt_qbuf && qry->qbuf.size) {
@@ -1870,7 +1928,6 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result )
JS_NC(qbuf, qry->qbuf.buf );
}
-
if(result)
{
dnsR = (struct DNS_HEADER*) result;
@@ -2013,6 +2070,7 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result )
fprintf(fh, "\n");
if (qry->out_filename)
fclose(fh);
+ qry->retry = 0;
free_qry_inst(qry);
}