From c9c35747c0d20cff54561c0b8fe15813c7a8e0ff Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 15 May 2015 10:25:14 +0200 Subject: ripe-atlas-fw: imported version 4570 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bjørn Mork --- eperd/evtdig.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 9 deletions(-) (limited to 'eperd/evtdig.c') 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); } -- cgit v1.2.3