aboutsummaryrefslogtreecommitdiff
path: root/eperd
diff options
context:
space:
mode:
Diffstat (limited to 'eperd')
-rw-r--r--eperd/eooqd.c32
-rw-r--r--eperd/eperd.c56
-rw-r--r--eperd/eperd.h4
-rw-r--r--eperd/evtdig.c142
-rw-r--r--eperd/httpget.c55
-rw-r--r--eperd/ntp.c62
-rw-r--r--eperd/ping.c90
-rw-r--r--eperd/sslgetcert.c334
-rw-r--r--eperd/tcputil.c16
-rw-r--r--eperd/tcputil.h2
-rw-r--r--eperd/traceroute.c153
11 files changed, 709 insertions, 237 deletions
diff --git a/eperd/eooqd.c b/eperd/eooqd.c
index 04bfcd6..ed8ea64 100644
--- a/eperd/eooqd.c
+++ b/eperd/eooqd.c
@@ -189,20 +189,44 @@ static void checkQueue(evutil_socket_t fd UNUSED_PARAM,
short what UNUSED_PARAM, void *arg UNUSED_PARAM)
{
int r;
+ struct stat sb;
char filename[80];
if (!state->curr_file)
{
+ if (stat(state->queue_file, &sb) == -1)
+ {
+ if (errno == ENOENT)
+ {
+ return;
+ }
+ report_err("stat failed");
+ return;
+ }
+
+ /* Remove curr_qfile. Renaming queue_file to curr_qfile
+ * will silently fail to delete queue_file if queue_file and
+ * curr_qfile are hard links.
+ */
+ if (unlink(state->curr_qfile) == -1)
+ {
+ /* Expect ENOENT */
+ if (errno != ENOENT)
+ {
+ report_err("unlink failed");
+ return;
+ }
+ }
+
/* Try to move queue_file to curr_qfile. This provides at most
* once behavior and allows producers to create a new
* queue_file while we process the old one.
*/
if (rename(state->queue_file, state->curr_qfile) == -1)
{
- if (errno == ENOENT)
- {
- return;
- }
+ /* We verified queue_file is there so any failure is
+ * fatal.
+ */
report_err("rename failed");
return;
}
diff --git a/eperd/eperd.c b/eperd/eperd.c
index 30a485d..464cd6c 100644
--- a/eperd/eperd.c
+++ b/eperd/eperd.c
@@ -84,6 +84,10 @@ struct CronLine {
/* For debugging */
time_t lasttime;
+ time_t nexttime;
+ time_t waittime;
+ time_t debug_cycle;
+ time_t debug_generated;
};
@@ -712,6 +716,11 @@ static void set_timeout(CronLine *line, int init_next_cycle)
line->start_time,
line->distr_offset.tv_sec + line->distr_offset.tv_usec/1e6,
now.tv_sec, tv.tv_sec);
+ line->debug_cycle= line->nextcycle;
+ line->debug_generated= now.tv_sec;
+ line->nexttime= line->nextcycle*line->interval + line->start_time +
+ line->distr_offset.tv_sec;
+ line->waittime= tv.tv_sec;
event_add(&line->event, &tv);
}
@@ -1182,8 +1191,11 @@ static void EndJob(const char *user, CronLine *line)
static void RunJob(evutil_socket_t __attribute__ ((unused)) fd,
short __attribute__ ((unused)) what, void *arg)
{
+ char c;
+ char *p;
CronLine *line;
struct timeval now;
+ FILE *fn;
line= arg;
@@ -1199,6 +1211,50 @@ static void RunJob(evutil_socket_t __attribute__ ((unused)) fd,
crondlog(LVL7 "RubJob, now %d, end_time %d\n", now.tv_sec,
line->end_time);
+ if (now.tv_sec < line->nexttime-10 || now.tv_sec > line->nexttime+10)
+ {
+ if (out_filename)
+ {
+ fn= fopen(out_filename, "a");
+ if (!fn)
+ {
+ crondlog(DIE9 "unable to append to '%s'",
+ out_filename);
+ }
+ fprintf(fn, "RESULT { ");
+ if (atlas_id)
+ fprintf(fn, DBQ(id) ":" DBQ(%s) ", ", atlas_id);
+ fprintf(fn, DBQ(fw) ":" DBQ(%d) ", " DBQ(time) ":%ld, ",
+ get_atlas_fw_version(), (long)time(NULL));
+ fprintf(fn, DBQ(reason) ": "
+ DBQ(inconsistent time; now %d; nexttime %d; waittime %d; cycle %d; generated %d) ", ",
+ (int)now.tv_sec, (int)line->nexttime,
+ (int)line->waittime, (int)line->debug_cycle,
+ (int)line->debug_generated);
+
+ fprintf(fn, DBQ(cmd) ": \"");
+ for (p= line->cl_Shell; *p; p++)
+ {
+ c= *p;
+ if (c == '"' || c == '\\')
+ fprintf(fn, "\\%c", c);
+ else if (isprint((unsigned char)c))
+ fputc(c, fn);
+ else
+ fprintf(fn, "\\u%04x", (unsigned char)c);
+ }
+ fprintf(fn, "\"");
+ fprintf(fn, " }\n");
+ fclose(fn);
+ }
+ crondlog(
+ LVL7 "RunJob: weird, now %d, nexttime %d, waittime %d\n",
+ now.tv_sec, line->nexttime, line->waittime);
+
+ /* Recompute nextcycle */
+ set_timeout(line, 1 /*init_next_cycle*/);
+ return;
+ }
if (now.tv_sec > line->end_time)
{
diff --git a/eperd/eperd.h b/eperd/eperd.h
index e19c1a0..73b5cc6 100644
--- a/eperd/eperd.h
+++ b/eperd/eperd.h
@@ -56,3 +56,7 @@ extern struct testops traceroute_ops;
void crondlog(const char *ctl, ...);
int get_atlas_fw_version(void);
+
+#ifndef CLOCK_MONOTONIC_RAW
+#define CLOCK_MONOTONIC_RAW 4
+#endif
diff --git a/eperd/evtdig.c b/eperd/evtdig.c
index 0de3541..299a79e 100644
--- a/eperd/evtdig.c
+++ b/eperd/evtdig.c
@@ -316,7 +316,8 @@ struct query_state {
struct event next_qry_timer; /* Timer event to start next query */
struct event done_qry_timer; /* Timer event to call done */
- struct timeval xmit_time;
+ time_t xmit_time;
+ struct timespec xmit_time_ts;
double triptime;
//tdig_callback_type user_callback;
@@ -462,8 +463,8 @@ static struct option longopts[]=
{ "tsig", required_argument, NULL, (100000 + T_TSIG) },
{ "txt", required_argument, NULL, (100000 + T_TXT) },
- { "type", required_argument, NULL, 'O_TYPE' },
- { "class", required_argument, NULL, 'O_CLASS' },
+ { "type", required_argument, NULL, O_TYPE },
+ { "class", required_argument, NULL, O_CLASS },
{ "query", required_argument, NULL, O_QUERY},
// clas CHAOS
@@ -476,7 +477,7 @@ static struct option longopts[]=
{ "edns0", required_argument, NULL, 'e' },
{ "nsid", no_argument, NULL, 'n' },
{ "do", no_argument, NULL, 'd' },
- { "cd", no_argument, NULL, 'O_CD'},
+ { "cd", no_argument, NULL, O_CD},
{ "retry", required_argument, NULL, O_RETRY },
{ "resolv", no_argument, NULL, O_RESOLV_CONF },
@@ -501,7 +502,7 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result);
void printErrorQuick (struct query_state *qry);
static void local_exit(void *state);
static void *tdig_init(int argc, char *argv[], void (*done)(void *state));
-static void process_reply(void * arg, int nrecv, struct timeval now);
+static void process_reply(void * arg, int nrecv, struct timespec now);
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, void *arg);
@@ -556,26 +557,39 @@ int evtdig_main(int argc, char **argv)
void print_txt_json(unsigned char *rdata, int txt_len,struct query_state *qry)
{
- int i;
+ int i, len;
- AS("\"RDATA\" : \"");
+ AS("\"RDATA\" : [ \"");
+ len= -1;
for(i = 0; i < txt_len; i++) {
+ if (len == 0)
+ {
+ AS("\", \"");
+ len= -1;
+ }
+ if (len == -1)
+ {
+ len= *rdata;
+ rdata++;
+ continue;
+ }
if( (*rdata == 34 ) || (*rdata == 92 )) {
- snprintf(line, DEFAULT_LINE_LENGTH, "\\%c", *(char *)rdata );
+ snprintf(line, DEFAULT_LINE_LENGTH, "\\\\%03d", *(char *)rdata );
buf_add(&qry->result, line, strlen (line));
}
- // Space - DEL
- else if ((*rdata > 31 ) && (*rdata < 128)) {
+ // Space - ~
+ else if ((*rdata >= ' ' ) && (*rdata <= '~')) {
snprintf(line, DEFAULT_LINE_LENGTH, "%c", *(char *)rdata );
buf_add(&qry->result, line, strlen (line));
}
else {
- snprintf(line, DEFAULT_LINE_LENGTH, "\\u00%02X", *rdata );
+ snprintf(line, DEFAULT_LINE_LENGTH, "\\\\%03d", *rdata );
buf_add(&qry->result, line, strlen (line));
}
+ len--;
rdata++;
}
- AS("\"");
+ AS("\" ] ");
}
static void local_exit(void *state UNUSED_PARAM)
@@ -709,7 +723,10 @@ static void mk_dns_buff(struct query_state *qry, u_char *packet)
lookup_prepend = xzalloc(DEFAULT_LINE_LENGTH + sizeof(qry->lookupname));
- snprintf(lookup_prepend, (sizeof(qry->lookupname) + DEFAULT_LINE_LENGTH - 1), "%d.%lu.%s", probe_id, qry->xmit_time.tv_sec, qry->lookupname);
+ snprintf(lookup_prepend, (sizeof(qry->lookupname) +
+ DEFAULT_LINE_LENGTH - 1),
+ "%d.%lu.%s", probe_id, qry->xmit_time,
+ qry->lookupname);
ChangetoDnsNameFormat(qname, lookup_prepend); // fill the query portion.
@@ -783,12 +800,12 @@ static void mk_dns_buff(struct query_state *qry, u_char *packet)
/* Attempt to transmit a UDP DNS Request to a serveri. TCP is else where */
static void tdig_send_query_callback(int unused UNUSED_PARAM, const short event UNUSED_PARAM, void *h)
{
- int fd;
+ int r, fd;
sa_family_t af;
struct query_state *qry = h;
struct tdig_base *base = qry->base;
uint32_t nsent = 0;
- u_char *outbuff;
+ u_char *outbuff= NULL;
int err = 0;
/* Clean the no reply timer (if any was previously set) */
@@ -798,7 +815,8 @@ static void tdig_send_query_callback(int unused UNUSED_PARAM, const short event
outbuff = xzalloc(MAX_DNS_OUT_BUF_SIZE);
bzero(outbuff, MAX_DNS_OUT_BUF_SIZE);
//AA delete qry->outbuff = outbuff;
- gettimeofday(&qry->xmit_time, NULL);
+ qry->xmit_time= time(NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &qry->xmit_time_ts);
mk_dns_buff(qry, outbuff);
do {
if (qry->udp_fd != -1)
@@ -815,6 +833,8 @@ static void tdig_send_query_callback(int unused UNUSED_PARAM, const short event
snprintf(line, DEFAULT_LINE_LENGTH, "%s \"socket\" : \"socket failed %s\"", qry->err.size ? ", " : "", strerror(errno));
buf_add(&qry->err, line, strlen(line));
printReply (qry, 0, NULL);
+ free (outbuff);
+ outbuff = NULL;
return;
}
@@ -835,10 +855,28 @@ static void tdig_send_query_callback(int unused UNUSED_PARAM, const short event
qry->err.size ? ", " : "");
buf_add(&qry->err, line, strlen(line));
printReply (qry, 0, NULL);
+ free (outbuff);
+ outbuff = NULL;
return;
}
}
+ if (!qry->opt_resolv_conf)
+ {
+ r= atlas_check_addr(qry->res->ai_addr,
+ qry->res->ai_addrlen);
+ if (r == -1)
+ {
+ free (outbuff);
+ outbuff = NULL;
+ snprintf(line, DEFAULT_LINE_LENGTH,
+ "%s \"reason\" : \"address not allowed\"",
+ qry->err.size ? ", " : "");
+ buf_add(&qry->err, line, strlen(line));
+ printReply (qry, 0, NULL);
+ return;
+ }
+ }
qry->loc_socklen = sizeof(qry->loc_sin6);
if (connect(qry->udp_fd, qry->res->ai_addr, qry->res->ai_addrlen) == -1)
{
@@ -848,6 +886,8 @@ static void tdig_send_query_callback(int unused UNUSED_PARAM, const short event
strerror(errno));
buf_add(&qry->err, line, strlen(line));
printReply (qry, 0, NULL);
+ free (outbuff);
+ outbuff = NULL;
return;
}
@@ -973,6 +1013,11 @@ static void tcp_reporterr(struct tu_env *env, enum tu_err cause,
buf_add(&qry->err, line, strlen(line));
break;
+ case TU_BAD_ADDR:
+ snprintf(line, DEFAULT_LINE_LENGTH, "%s \"TU_BAD_ADDR\" : true", qry->err.size ? ", " : "");
+ buf_add(&qry->err, line, strlen(line));
+ break;
+
default:
snprintf(line, DEFAULT_LINE_LENGTH, "%s \"TU_UNKNOWN\" : \"%d %s\"", qry->err.size ? ", " : "", cause, str );
crondlog(DIE9 "reporterr: bad cause %d", cause);
@@ -1001,9 +1046,10 @@ static void tcp_beforeconnect(struct tu_env *env,
{
struct query_state * qry;
qry = ENV2QRY(env);
- gettimeofday(&qry->xmit_time, NULL);
+ qry->xmit_time= time(NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &qry->xmit_time_ts);
qry->dst_ai_family = addr->sa_family;
- BLURT(LVL5 "time : %d", qry->xmit_time.tv_sec);
+ BLURT(LVL5 "time : %d", qry->xmit_time);
getnameinfo(addr, addrlen, qry->dst_addr_str, INET6_ADDRSTRLEN , NULL, 0, NI_NUMERICHOST);
}
@@ -1045,7 +1091,7 @@ static void tcp_readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
struct query_state *qry = ptr;
int n;
u_char b2[2];
- struct timeval rectime;
+ struct timespec rectime;
struct evbuffer *input ;
struct DNS_HEADER *dnsR = NULL;
@@ -1062,7 +1108,7 @@ static void tcp_readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
return;
}
- gettimeofday(&rectime, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &rectime);
bzero(qry->base->packet, MAX_DNS_BUF_SIZE);
input = bufferevent_get_input(bev);
@@ -1086,7 +1132,10 @@ static void tcp_readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
crondlog(LVL5 "DBG: base pointer address readcb %p", qry->base );
dnsR = (struct DNS_HEADER*) qry->packet.buf;
if ( ntohs(dnsR->id) == qry->qryid ) {
- qry->triptime = (rectime.tv_sec - qry->xmit_time.tv_sec)*1000 + (rectime.tv_usec-qry->xmit_time.tv_usec)/1e3;
+ qry->triptime = (rectime.tv_sec -
+ qry->xmit_time_ts.tv_sec)*1000 +
+ (rectime.tv_nsec -
+ qry->xmit_time_ts.tv_nsec)/1e6;
printReply (qry, qry->packet.size, (unsigned char *)qry->packet.buf);
}
else {
@@ -1121,7 +1170,7 @@ static void tcp_writecb(struct bufferevent *bev UNUSED_PARAM, void *ptr UNUSED_P
* o the one we are looking for (matching the same identifier of all the packets the program is able to send)
*/
-static void process_reply(void * arg, int nrecv, struct timeval now)
+static void process_reply(void * arg, int nrecv, struct timespec now)
{
struct DNS_HEADER *dnsR = NULL;
struct tdig_base * base;
@@ -1149,8 +1198,9 @@ static void process_reply(void * arg, int nrecv, struct timeval now)
}
qry->base->recvbytes += nrecv;
- gettimeofday(&now, NULL); // lave this till fix now from ready_callback6 corruption; ghoost
- qry->triptime = (now.tv_sec-qry->xmit_time.tv_sec)*1000 + (now.tv_usec-qry->xmit_time.tv_usec)/1e3;
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now); // lave this till fix now from ready_callback6 corruption; ghoost
+ qry->triptime = (now.tv_sec-qry->xmit_time_ts.tv_sec)*1000 +
+ (now.tv_nsec-qry->xmit_time_ts.tv_nsec)/1e6;
/* Clean the noreply timer */
evtimer_del(&qry->noreply_timer);
@@ -1162,7 +1212,7 @@ static void ready_callback (int unused UNUSED_PARAM, const short event UNUSED_PA
{
struct query_state * qry;
int nrecv;
- struct timeval rectime;
+ struct timespec rectime;
// printf("in ready_callback\n");
@@ -1171,7 +1221,7 @@ static void ready_callback (int unused UNUSED_PARAM, const short event UNUSED_PA
bzero(qry->base->packet, MAX_DNS_BUF_SIZE);
/* Time the packet has been received */
- gettimeofday(&rectime, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &rectime);
/* Receive data from the network */
nrecv = recv(qry->udp_fd, qry->base->packet,
sizeof(qry->base->packet), MSG_DONTWAIT);
@@ -1189,7 +1239,7 @@ static void ready_callback6 (int unused UNUSED_PARAM, const short event UNUSED_P
{
struct query_state * qry;
int nrecv;
- struct timeval rectime;
+ struct timespec rectime;
struct msghdr msg;
struct iovec iov[1];
//char buf[INET6_ADDRSTRLEN];
@@ -1429,7 +1479,7 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
qry->opt_abuf = 0;
break;
- case 'O_TYPE':
+ case O_TYPE:
qry->qtype = strtoul(optarg, &check, 10);
if ((qry->qtype >= 0 ) &&
(qry->qclass < 65536)) {
@@ -1448,11 +1498,11 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
}
break;
- case 'O_CD':
+ case O_CD:
qry->opt_cd = 1;
break;
- case 'O_CLASS':
+ case O_CLASS:
qry->qclass = strtoul(optarg, &check, 10);
if ((qry->qclass >= 0 ) &&
(qry->qclass < 65536)) {
@@ -1803,6 +1853,8 @@ void tdig_start (void *arg)
switch(qry->qst)
{
case STATUS_FREE :
+ /* Get time in case we don't send any packet */
+ qry->xmit_time= time(NULL);
qry->resolv_i = 0;
crondlog(LVL5 "RESOLV QUERY FREE %s resolv_max %d", qry->server_name, tdig_base->resolv_max);
if( qry->opt_resolv_conf) {
@@ -1820,6 +1872,7 @@ void tdig_start (void *arg)
snprintf(line, DEFAULT_LINE_LENGTH, "\"nameserver\": \"no local resolvers found\"");
buf_add(&qry->err, line, strlen(line));
printReply (qry, 0, NULL);
+ return;
}
}
break;
@@ -1838,7 +1891,8 @@ void tdig_start (void *arg)
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = 0;
- gettimeofday(&qry->xmit_time, NULL);
+ qry->xmit_time= time(NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &qry->xmit_time_ts);
qry->qst = STATUS_DNS_RESOLV;
if(qry->opt_v6_only == 1)
@@ -1915,6 +1969,7 @@ int tdig_base_count_queries(struct tdig_base *base)
static void tdig_stats(int unusg_statsed UNUSED_PARAM, const short event UNUSED_PARAM, void *h)
{
struct timeval now;
+ struct timeval interval;
FILE *fh;
struct tdig_base *base;
struct query_state *qry_h;
@@ -1932,9 +1987,9 @@ static void tdig_stats(int unusg_statsed UNUSED_PARAM, const short event UNUSED_
if(qry_h->base->done) {
- now.tv_sec = DEFAULT_STATS_REPORT_INTERVEL;
- now.tv_usec = 0;
- event_add(&tdig_base->statsReportEvent, &now);
+ interval.tv_sec = DEFAULT_STATS_REPORT_INTERVEL;
+ interval.tv_usec = 0;
+ event_add(&tdig_base->statsReportEvent, &interval);
return;
}
@@ -1954,7 +2009,7 @@ static void tdig_stats(int unusg_statsed UNUSED_PARAM, const short event UNUSED_
JS(id, "9201" );
fw = get_atlas_fw_version();
JU(fw, fw);
- gettimeofday(&now, NULL);
+ gettimeofday(&now, NULL);
JS1(time, %ld, now.tv_sec);
JU(sok , base->sentok);
JU(rok , base->recvok);
@@ -1975,10 +2030,9 @@ static void tdig_stats(int unusg_statsed UNUSED_PARAM, const short event UNUSED_
buf_cleanup(&qry->result);
free(qry);
- // reuse timeval now
- now.tv_sec = DEFAULT_STATS_REPORT_INTERVEL;
- now.tv_usec = 0;
- event_add(&tdig_base->statsReportEvent, &now);
+ interval.tv_sec = DEFAULT_STATS_REPORT_INTERVEL;
+ interval.tv_usec = 0;
+ event_add(&tdig_base->statsReportEvent, &interval);
}
@@ -2171,7 +2225,7 @@ void printErrorQuick (struct query_state *qry)
{
fprintf(fh, ",{");
fprintf(fh, "\"id\" : \"%s\"", qry->str_Atlas);
- fprintf(fh, ",\"start time\" : %ld", qry->xmit_time.tv_sec);
+ fprintf(fh, ",\"start time\" : %ld", qry->xmit_time);
if(qry->retry) {
fprintf(fh, ",\"retry\": %d", qry->retry);
@@ -2218,7 +2272,7 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result)
JD(fw, fw);
if (qry->opt_rset){
- JS1(time, %ld, qry->xmit_time.tv_sec);
+ JS1(time, %ld, qry->xmit_time);
JD(lts,lts);
AS("\"resultset\" : [ {");
}
@@ -2228,7 +2282,7 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result)
AS (",{");
}
- JS1(time, %ld, qry->xmit_time.tv_sec);
+ JS1(time, %ld, qry->xmit_time);
JD(lts,lts);
if ( qry->opt_resolv_conf ) {
@@ -2339,7 +2393,7 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result)
if(ntohs(answers[i].resource->type)==T_TXT) //txt
{
- data_len = ntohs(answers[i].resource->data_len) - 1;
+ data_len = ntohs(answers[i].resource->data_len);
if(flagAnswer == 0) {
AS(",\"answers\" : [ {");
flagAnswer++;
@@ -2350,7 +2404,7 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result)
flagAnswer++;
JS (TYPE, "TXT");
JS (NAME, answers[i].name);
- print_txt_json(&result[reader-result+1], data_len, qry);
+ print_txt_json(&result[reader-result], data_len, qry);
reader = reader + ntohs(answers[i].resource->data_len);
AS("}");
diff --git a/eperd/httpget.c b/eperd/httpget.c
index f68ec81..92ce453 100644
--- a/eperd/httpget.c
+++ b/eperd/httpget.c
@@ -117,7 +117,7 @@ struct hgstate
int subid;
int submax;
time_t gstart;
- struct timeval start;
+ struct timespec start;
double resptime;
double ttr; /* Time to resolve */
double ttc; /* Time to connect */
@@ -353,9 +353,11 @@ static void timeout_callback(int __attribute((unused)) unused,
#if 1
snprintf(errline, sizeof(errline),
DBQ(err) ":"
- DBQ(timeout reading chunk: state %d linelen %d lineoffset %d)
+ DBQ(timeout reading chunk: state %ld linelen %ld lineoffset %ld)
", ",
- state->readstate, state->linelen, state->lineoffset);
+ (long)state->readstate,
+ (long)state->linelen,
+ (long)state->lineoffset);
add_str(state, errline);
#else
add_str(state, DBQ(err) ":" DBQ(timeout reading chunk) ", ");
@@ -866,7 +868,7 @@ static int get_input(struct hgstate *state)
{
int n;
double t;
- struct timeval endtime;
+ struct timespec endtime;
char line[80];
/* Assume that we always end up with a full buffer anyway */
@@ -900,9 +902,9 @@ static int get_input(struct hgstate *state)
if (state->etim >= 2 && state->report_roffset)
{
- gettimeofday(&endtime, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &endtime);
t= (endtime.tv_sec-state->start.tv_sec)*1e3 +
- (endtime.tv_usec-state->start.tv_usec)/1e3;
+ (endtime.tv_nsec-state->start.tv_nsec)/1e6;
if (state->roffset != 0)
add_str2(state, ",");
snprintf(line, sizeof(line),
@@ -1025,7 +1027,7 @@ static void readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
char *cp, *ncp, *check, *line;
const char *prefix, *kw;
struct hgstate *state;
- struct timeval endtime;
+ struct timespec endtime;
state= ENV2STATE(ptr);
@@ -1053,10 +1055,10 @@ static void readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
switch(state->readstate)
{
case READ_FIRST:
- gettimeofday(&endtime, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &endtime);
state->ttfb= (endtime.tv_sec-
state->start.tv_sec)*1e3 +
- (endtime.tv_usec-state->start.tv_usec)/1e3;
+ (endtime.tv_nsec-state->start.tv_nsec)/1e6;
state->readstate= READ_STATUS;
state->roffset= 0;
if (state->etim >= 2)
@@ -1557,12 +1559,12 @@ static void readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
if (state->bev)
{
state->bev= NULL;
- gettimeofday(&endtime, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &endtime);
state->resptime=
(endtime.tv_sec-
state->start.tv_sec)*1e3 +
- (endtime.tv_usec-
- state->start.tv_usec)/1e3;
+ (endtime.tv_nsec-
+ state->start.tv_nsec)/1e6;
report(state);
}
return;
@@ -1619,7 +1621,7 @@ static void writecb(struct bufferevent *bev, void *ptr)
struct evbuffer *output;
off_t cLength;
struct stat sb;
- struct timeval endtime;
+ struct timespec endtime;
state= ENV2STATE(ptr);
@@ -1628,10 +1630,10 @@ static void writecb(struct bufferevent *bev, void *ptr)
switch(state->writestate)
{
case WRITE_FIRST:
- gettimeofday(&endtime, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &endtime);
state->ttc= (endtime.tv_sec-
state->start.tv_sec)*1e3 +
- (endtime.tv_usec-state->start.tv_usec)/1e3;
+ (endtime.tv_nsec-state->start.tv_nsec)/1e6;
state->writestate= WRITE_HEADER;
continue;
case WRITE_HEADER:
@@ -1733,7 +1735,7 @@ static void writecb(struct bufferevent *bev, void *ptr)
static void err_reading(struct hgstate *state)
{
- struct timeval endtime;
+ struct timespec endtime;
switch(state->readstate)
{
@@ -1762,9 +1764,9 @@ static void err_reading(struct hgstate *state)
add_str(state, DBQ(err) ":" DBQ(error reading body)
", ");
}
- gettimeofday(&endtime, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &endtime);
state->resptime= (endtime.tv_sec-state->start.tv_sec)*1e3 +
- (endtime.tv_usec-state->start.tv_usec)/1e3;
+ (endtime.tv_nsec-state->start.tv_nsec)/1e6;
report(state);
break;
default:
@@ -1785,7 +1787,7 @@ static void beforeconnect(struct tu_env *env,
struct sockaddr *addr, socklen_t addrlen)
{
struct hgstate *state;
- struct timeval endtime;
+ struct timespec endtime;
state= ENV2STATE(env);
@@ -1811,12 +1813,12 @@ static void beforeconnect(struct tu_env *env,
if (state->first_connect)
{
- gettimeofday(&endtime, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &endtime);
state->ttr= (endtime.tv_sec-state->start.tv_sec)*1e3 +
- (endtime.tv_usec-state->start.tv_usec)/1e3;
+ (endtime.tv_nsec-state->start.tv_nsec)/1e6;
state->first_connect= 0;
}
- gettimeofday(&state->start, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &state->start);
}
@@ -1866,6 +1868,13 @@ static void reporterr(struct tu_env *env, enum tu_err cause,
report(state);
break;
+ case TU_BAD_ADDR:
+ add_str(state, "{ " DBQ(error) ": "
+ DBQ(address not allowed) " }");
+ state->dnserr= 1;
+ report(state);
+ break;
+
default:
crondlog(DIE9 "reporterr: bad cause %d", cause);
}
@@ -1907,7 +1916,7 @@ static void httpget_start(void *state)
hgstate->readstate= READ_STATUS;
hgstate->writestate= WRITE_HEADER;
hgstate->gstart= time(NULL);
- gettimeofday(&hgstate->start, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &hgstate->start);
hgstate->first_connect= 1;
memset(&hints, '\0', sizeof(hints));
diff --git a/eperd/ntp.c b/eperd/ntp.c
index 457f34a..7dc1109 100644
--- a/eperd/ntp.c
+++ b/eperd/ntp.c
@@ -5,6 +5,7 @@
*/
#include "libbb.h"
+#include <math.h>
#include <event2/dns.h>
#include <event2/event.h>
#include <event2/event_struct.h>
@@ -260,14 +261,13 @@ static void format_stratum(char *line, size_t size, uint8_t stratum)
static void format_8bit(char *line, size_t size, const char *label,
int8_t value)
{
- if (value >= 0)
+ if (value >= 0 && value < 32)
{
- snprintf(line, size, DBQ(%s) ": %d", label, 1 << value);
+ snprintf(line, size, DBQ(%s) ": %u", label, 1U << value);
}
else
{
- snprintf(line, size, DBQ(%s) ": %g", label,
- 1.0 / (1 << -value));
+ snprintf(line, size, DBQ(%s) ": %g", label, pow(2, value));
}
}
@@ -280,10 +280,33 @@ static void format_short_ts(char *line, size_t size, const char *label,
static void format_ref_id(char *line, size_t size, uint32_t value,
uint8_t stratum)
{
+ int i;
+ size_t offset;
+ unsigned char *p;
+ char line2[40];
+
if (stratum == 0 || stratum == 1)
{
- snprintf(line, size, DBQ(ref-id) ": " DBQ(%.4s),
- (char *)&value);
+ line2[0]= '\0';
+ for (i= 0, p= (unsigned char *)&value;
+ i<sizeof(value) && *p != '\0'; i++, p++)
+ {
+ offset= strlen(line2);
+ if (*p < 32 || *p == '"' || *p == '\\' ||
+ *p >= 127)
+ {
+ snprintf(line2+offset, sizeof(line2)-offset,
+ "\\\\x%02x", *p);
+ }
+ else
+ {
+ snprintf(line2+offset, sizeof(line2)-offset,
+ "%c", *p);
+ }
+
+ }
+ snprintf(line, size, DBQ(ref-id) ": " DBQ(%s),
+ line2);
}
else
{
@@ -360,7 +383,7 @@ static void report(struct ntpstate *state)
state->dnsip ? (state->do_v6 ? 6 : 4) :
(state->sin6.sin6_family == AF_INET6 ? 6 : 4));
- if (!state->first)
+ if (!state->first && !state->dnsip)
{
format_li(line, sizeof(line), state->ntp_flags);
fprintf(fh, ", %s", line);
@@ -1763,6 +1786,9 @@ static int create_socket(struct ntpstate *state)
protocol= 0;
state->socket= xsocket(af, type, protocol);
+#if 0
+ { errno= ENOSYS; state->socket= -1; }
+#endif
if (state->socket == -1)
{
serrno= errno;
@@ -1799,7 +1825,7 @@ static int create_socket(struct ntpstate *state)
serrno= errno;
snprintf(line, sizeof(line),
- ", " DBQ(error) ":" DBQ(connect failed: %s) " }",
+ "{ " DBQ(error) ":" DBQ(connect failed: %s) " }",
strerror(serrno));
add_str(state, line);
report(state);
@@ -1832,7 +1858,7 @@ static int create_socket(struct ntpstate *state)
static void dns_cb(int result, struct evutil_addrinfo *res, void *ctx)
{
- int count;
+ int r, count;
struct ntpstate *env;
struct evutil_addrinfo *cur;
char line[160];
@@ -1884,6 +1910,24 @@ static void dns_cb(int result, struct evutil_addrinfo *res, void *ctx)
memcpy(&env->sin6, env->dns_curr->ai_addr,
env->socklen);
+ r= atlas_check_addr((struct sockaddr *)&env->sin6,
+ env->socklen);
+ if (r == -1)
+ {
+ if (env->result) free(env->result);
+ env->resmax= 80;
+ env->result= xmalloc(env->resmax);
+ env->reslen= 0;
+
+ env->starttime= time(NULL);
+ snprintf(line, sizeof(line),
+ "{ " DBQ(error) ":" DBQ(address not allowed) " }");
+ add_str(env, line);
+ env->dnsip= 1;
+ report(env);
+ return;
+ }
+
traceroute_start2(env);
evutil_freeaddrinfo(env->dns_res);
diff --git a/eperd/ping.c b/eperd/ping.c
index 53cbbe5..0b8d1b2 100644
--- a/eperd/ping.c
+++ b/eperd/ping.c
@@ -58,6 +58,7 @@ enum
#define PING_ERR_SENDTO 4 /* Sendto system call failed */
#define PING_ERR_DNS 5 /* DNS error */
#define PING_ERR_DNS_NO_ADDR 6 /* DNS no suitable addresses */
+#define PING_ERR_BAD_ADDR 7 /* Addresses is not allowed */
#define PING_ERR_SHUTDOWN 10 /* The request was canceled because the PING subsystem was shut down */
#define PING_ERR_CANCEL 12 /* The request was canceled via a call to evping_cancel_request */
#define PING_ERR_UNKNOWN 16 /* An unknown error occurred */
@@ -158,7 +159,7 @@ struct pingstate
* and it is used to relate each response with the corresponding request
*/
struct evdata {
- struct timeval ts;
+ struct timespec ts;
uint32_t index;
struct cookie cookie;
};
@@ -271,10 +272,10 @@ static void ping_cb(int result, int bytes, int psize,
struct sockaddr *sa, socklen_t socklen,
struct sockaddr *loc_sa, socklen_t loc_socklen,
int seq, int ttl,
- struct timeval * elapsed, void * arg)
+ struct timespec * elapsed, void * arg)
{
struct pingstate *pingstate;
- unsigned long usecs;
+ double nsecs;
char namebuf1[NI_MAXHOST], namebuf2[NI_MAXHOST];
char line[256];
@@ -304,7 +305,7 @@ static void ping_cb(int result, int bytes, int psize,
if (result == PING_ERR_NONE || result == PING_ERR_DUP)
{
/* Got a ping reply */
- usecs= (elapsed->tv_sec * 1000000 + elapsed->tv_usec);
+ nsecs= (elapsed->tv_sec * 1e9 + elapsed->tv_nsec);
snprintf(line, sizeof(line),
"%s{ ", pingstate->first ? "" : ", ");
@@ -317,7 +318,7 @@ static void ping_cb(int result, int bytes, int psize,
snprintf(line, sizeof(line),
DBQ(rtt) ":%f",
- usecs/1000.);
+ nsecs/1e6);
add_str(pingstate, line);
if (!pingstate->got_reply && result != PING_ERR_DUP)
@@ -403,6 +404,16 @@ static void ping_cb(int result, int bytes, int psize,
add_str(pingstate, line);
report(pingstate);
}
+ if (result == PING_ERR_BAD_ADDR)
+ {
+ pingstate->size= bytes;
+ pingstate->psize= psize;
+ snprintf(line, sizeof(line),
+ "%s{ " DBQ(error) ":" DBQ(address not allowed) " }",
+ pingstate->first ? "" : ", ");
+ add_str(pingstate, line);
+ report(pingstate);
+ }
if (result == PING_ERR_DONE)
{
report(pingstate);
@@ -462,7 +473,7 @@ static void fmticmp4(u_char *buffer, size_t *sizep, u_int8_t seq,
struct icmp *icmp = (struct icmp *) buffer;
struct evdata *data = (struct evdata *) (buffer + ICMP_MINLEN);
- struct timeval now;
+ struct timespec now;
minlen= sizeof(*data);
if (*sizep < minlen)
@@ -481,8 +492,8 @@ static void fmticmp4(u_char *buffer, size_t *sizep, u_int8_t seq,
icmp->icmp_seq = htons(seq); /* message identifier */
/* User data */
- gettimeofday(&now, NULL);
- data->ts = now; /* current time */
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
+ data->ts = now; /* current uptime time */
data->index = idx; /* index into an array */
data->cookie= *cookiep;
@@ -514,7 +525,7 @@ static void fmticmp6(u_char *buffer, size_t *sizep,
struct icmp6_hdr *icmp = (struct icmp6_hdr *) buffer;
struct evdata *data = (struct evdata *) (buffer + ICMP6_HDRSIZE);
- struct timeval now;
+ struct timespec now;
minlen= sizeof(*data);
if (*sizep < minlen)
@@ -531,8 +542,8 @@ static void fmticmp6(u_char *buffer, size_t *sizep,
icmp->icmp6_seq = htons(seq); /* message identifier */
/* User data */
- gettimeofday(&now, NULL);
- data->ts = now; /* current time */
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
+ data->ts = now; /* current uptime time */
data->index = idx; /* index into an array */
data->cookie= *cookiep;
@@ -666,7 +677,7 @@ static void ready_callback4 (int __attribute((unused)) unused,
struct icmphdr * icmp;
struct evdata * data;
int hlen = 0;
- struct timeval now;
+ struct timespec now;
state= arg;
base = state->base;
@@ -676,7 +687,7 @@ static void ready_callback4 (int __attribute((unused)) unused,
data = (struct evdata *) (base->packet + IPHDR + ICMP_MINLEN);
/* Time the packet has been received */
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
/* Receive data from the network */
nrecv = recvfrom(state->socket, base->packet, sizeof(base->packet), MSG_DONTWAIT, (struct sockaddr *) &remote, &slen);
@@ -743,10 +754,16 @@ printf("ready_callback4: too short\n");
else if (icmp->type == ICMP_ECHOREPLY)
{
/* Use the User Data to relate Echo Request/Reply and evaluate the Round Trip Time */
- struct timeval elapsed; /* response time */
+ struct timespec elapsed; /* response time */
/* Compute time difference to calculate the round trip */
- evutil_timersub (&now, &data->ts, &elapsed);
+ elapsed.tv_sec= now.tv_sec - data->ts.tv_sec;
+ if (now.tv_nsec < data->ts.tv_sec)
+ {
+ elapsed.tv_sec--;
+ now.tv_nsec += 1000000000;
+ }
+ elapsed.tv_nsec= now.tv_nsec - data->ts.tv_nsec;
/* Set destination address of packet as local address */
sin4p= &loc_sin4;
@@ -809,7 +826,7 @@ static void ready_callback6 (int __attribute((unused)) unused,
struct icmp6_hdr *icmp;
struct evdata * data;
- struct timeval now;
+ struct timespec now;
struct cmsghdr *cmsgptr;
struct sockaddr_in6 *sin6p;
struct msghdr msg;
@@ -827,7 +844,7 @@ static void ready_callback6 (int __attribute((unused)) unused,
offsetof(struct icmp6_hdr, icmp6_data16[2]));
/* Time the packet has been received */
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
iov[0].iov_base= base->packet;
iov[0].iov_len= sizeof(base->packet);
@@ -879,10 +896,16 @@ static void ready_callback6 (int __attribute((unused)) unused,
else if (icmp->icmp6_type == ICMP6_ECHO_REPLY)
{
/* Use the User Data to relate Echo Request/Reply and evaluate the Round Trip Time */
- struct timeval elapsed; /* response time */
+ struct timespec elapsed; /* response time */
/* Compute time difference to calculate the round trip */
- evutil_timersub (&now, &data->ts, &elapsed);
+ elapsed.tv_sec= now.tv_sec - data->ts.tv_sec;
+ if (now.tv_nsec < data->ts.tv_sec)
+ {
+ elapsed.tv_sec--;
+ now.tv_nsec += 1000000000;
+ }
+ elapsed.tv_nsec= now.tv_nsec - data->ts.tv_nsec;
/* Set destination address of packet as local address */
memset(&loc_sin6, '\0', sizeof(loc_sin6));
@@ -1055,6 +1078,12 @@ static void *ping_init(int __attribute((unused)) argc, char *argv[],
free(lsa);
return NULL;
}
+
+ if (atlas_check_addr(&lsa->u.sa, lsa->len) == -1)
+ {
+ free(lsa);
+ return NULL;
+ }
}
state= xzalloc(sizeof(*state));
@@ -1233,7 +1262,7 @@ static void ping_start2(void *state)
static void dns_cb(int result, struct evutil_addrinfo *res, void *ctx)
{
- int count;
+ int r, count;
struct pingstate *env;
struct evutil_addrinfo *cur;
@@ -1274,8 +1303,6 @@ static void dns_cb(int result, struct evutil_addrinfo *res, void *ctx)
for (cur= res; cur; cur= cur->ai_next)
count++;
- // env->reportcount(env, count);
-
while (env->dns_curr)
{
env->socklen= env->dns_curr->ai_addrlen;
@@ -1284,6 +1311,25 @@ static void dns_cb(int result, struct evutil_addrinfo *res, void *ctx)
memcpy(&env->sin6, env->dns_curr->ai_addr,
env->socklen);
+ r= atlas_check_addr((struct sockaddr *)&env->sin6,
+ env->socklen);
+ if (r == -1)
+ {
+ ping_cb(PING_ERR_BAD_ADDR, env->maxsize, -1,
+ NULL, 0,
+ (struct sockaddr *)NULL, 0,
+ 0, 0, NULL,
+ env);
+ ping_cb(PING_ERR_DONE, env->maxsize, -1,
+ (struct sockaddr *)NULL, 0,
+ (struct sockaddr *)NULL, 0,
+ 0, 0, NULL,
+ env);
+ if (env->base->done)
+ env->base->done(env);
+ return;
+ }
+
ping_start2(env);
return;
diff --git a/eperd/sslgetcert.c b/eperd/sslgetcert.c
index fa3c254..91dea01 100644
--- a/eperd/sslgetcert.c
+++ b/eperd/sslgetcert.c
@@ -101,8 +101,8 @@ struct state
int subid;
int submax;
time_t gstart;
- struct timeval start;
- struct timeval t_connect;
+ struct timespec start;
+ struct timespec t_connect;
double resptime;
FILE *post_fh;
char *post_buf;
@@ -133,6 +133,7 @@ struct state
#define BUF_CHUNK 4096
+#define MSG_ALERT 21
#define MSG_HANDSHAKE 22
#define HS_CLIENT_HELLO 1
#define HS_SERVER_HELLO 2
@@ -355,7 +356,7 @@ static void msgbuf_add(struct msgbuf *msgbuf, void *buf, size_t size)
buf_add(&msgbuf->buffer, buf, size);
}
-static int msgbuf_read(struct msgbuf *msgbuf, int type,
+static int msgbuf_read(struct msgbuf *msgbuf, int *typep,
char *majorp, char *minorp)
{
int r;
@@ -377,12 +378,7 @@ static int msgbuf_read(struct msgbuf *msgbuf, int type,
continue;
}
p= (uint8_t *)msgbuf->inbuf->buf+msgbuf->inbuf->offset;
- type= p[0];
- if (p[0] != type)
- {
- fprintf(stderr, "msgbuf_read: got type %d\n", p[0]);
- return -1;
- }
+ *typep= p[0];
*majorp= p[1];
*minorp= p[2];
len= (p[3] << 8) + p[4];
@@ -522,10 +518,17 @@ static void add_ciphers(struct hsbuf *hsbuf)
{
uint8_t c;
size_t len;
- uint8_t ciphers[]= { 0x0,0xff, 0x0,0x88, 0x0,0x87, 0x0,0x39, 0x0,0x38,
- 0x0,0x84, 0x0,0x35, 0x0,0x45, 0x0,0x44, 0x0,0x33, 0x0,0x32,
- 0x0,0x96, 0x0,0x41, 0x0,0x4, 0x0,0x5, 0x0,0x2f, 0x0,0x16,
- 0x0,0x13, 0xfe,0xff, 0x0,0xa };
+ uint8_t ciphers[]= {
+ 0xc0,0x0a, /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
+ 0xc0,0x09, /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
+ 0xc0,0x13, /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
+ 0xc0,0x14, /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
+ 0x00,0x33, /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
+ 0x00,0x39, /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
+ 0x00,0x2f, /* TLS_RSA_WITH_AES_128_CBC_SHA */
+ 0x00,0x35, /* TLS_RSA_WITH_AES_256_CBC_SHA */
+ 0x00,0x0a, /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
+ };
len= sizeof(ciphers);
@@ -872,6 +875,11 @@ static void readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
r= eat_server_hello(state);
if (r == -1)
return;
+ if (r == 1)
+ {
+ state->readstate= READ_DONE;
+ continue;
+ }
state->readstate= READ_CERTS;
continue;
@@ -898,9 +906,164 @@ static void readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
}
}
+static FILE *report_head(struct state *state)
+{
+ int major, minor;
+ const char *method;
+ FILE *fh;
+ double resptime;
+ struct timespec endtime;
+ char hostbuf[NI_MAXHOST];
+
+ clock_gettime(CLOCK_MONOTONIC_RAW, &endtime);
+
+ fh= NULL;
+ if (state->output_file)
+ {
+ fh= fopen(state->output_file, "a");
+ if (!fh)
+ {
+ crondlog(DIE9 "unable to append to '%s'",
+ state->output_file);
+ return NULL;
+ }
+ }
+ else
+ fh= stdout;
+
+ fprintf(fh, "RESULT { ");
+ if (state->atlas)
+ {
+ fprintf(fh, DBQ(id) ":" DBQ(%s)
+ ", " DBQ(fw) ":%d"
+ ", " DBQ(lts) ":%d",
+ state->atlas, get_atlas_fw_version(),
+ get_timesync());
+ }
+
+ fprintf(fh, "%s" DBQ(time) ":%ld",
+ state->atlas ? ", " : "", time(NULL));
+ fprintf(fh, ", " DBQ(dst_name) ":" DBQ(%s) ", "
+ DBQ(dst_port) ":" DBQ(%s),
+ state->hostname, state->portname);
+
+ if (state->recv_major == 3 && state->recv_minor == 3)
+ {
+ method= "TLS";
+ major= 1;
+ minor= 2;
+ }
+ else if (state->recv_major == 3 && state->recv_minor == 2)
+ {
+ method= "TLS";
+ major= 1;
+ minor= 1;
+ }
+ else if (state->recv_major == 3 && state->recv_minor == 1)
+ {
+ method= "TLS";
+ major= 1;
+ minor= 0;
+ }
+ else if (state->recv_major == 3 && state->recv_minor == 0)
+ {
+ method= "SSL";
+ major= 3;
+ minor= 0;
+ }
+ else
+ {
+ method= "(unknown)";
+ major= state->recv_major;
+ minor= state->recv_minor;
+ }
+
+ fprintf(fh, ", " DBQ(method) ":" DBQ(%s) ", "
+ DBQ(ver) ":" DBQ(%d.%d), method, major, minor);
+ getnameinfo((struct sockaddr *)&state->sin6, state->socklen,
+ hostbuf, sizeof(hostbuf), NULL, 0,
+ NI_NUMERICHOST);
+ fprintf(fh, ", " DBQ(dst_addr) ":" DBQ(%s), hostbuf);
+ fprintf(fh, ", " DBQ(af) ": %d",
+ state->sin6.sin6_family == AF_INET6 ? 6 : 4);
+
+ getnameinfo((struct sockaddr *)&state->loc_sin6,
+ state->loc_socklen, hostbuf, sizeof(hostbuf), NULL, 0,
+ NI_NUMERICHOST);
+ fprintf(fh, ", " DBQ(src_addr) ":" DBQ(%s), hostbuf);
+
+ resptime= (state->t_connect.tv_sec- state->start.tv_sec)*1e3 +
+ (state->t_connect.tv_nsec-state->start.tv_nsec)/1e6;
+ fprintf(fh, ", " DBQ(ttc) ": %f", resptime);
+
+ resptime= (endtime.tv_sec- state->start.tv_sec)*1e3 +
+ (endtime.tv_nsec-state->start.tv_nsec)/1e6;
+ fprintf(fh, ", " DBQ(rt) ": %f", resptime);
+
+ return fh;
+}
+
+static int eat_alert(struct state *state)
+{
+ int r, type, level, descr;
+ uint8_t *p;
+ struct msgbuf *msgbuf;
+ FILE *fh;
+
+ msgbuf= &state->msginbuf;
+
+ for (;;)
+ {
+ if (msgbuf->buffer.size - msgbuf->buffer.offset < 2)
+ {
+ r= msgbuf_read(msgbuf, &type,
+ &state->recv_major, &state->recv_minor);
+ if (r < 0)
+ {
+ if (errno != EAGAIN)
+ {
+ fprintf(stderr,
+ "eat_alert: msgbuf_read failed: %s\n",
+ strerror(errno));
+ }
+ return -1;
+ }
+ if (type != MSG_ALERT)
+ {
+ fprintf(stderr,
+ "eat_alert: got bad type %d from msgbuf_read\n",
+ type);
+ return -1;
+ }
+ continue;
+ }
+ p= (uint8_t *)msgbuf->buffer.buf+msgbuf->buffer.offset;
+ level= p[0];
+ descr= p[1];
+
+ fh= report_head(state);
+ if (!fh)
+ return -1;
+
+ fprintf(fh, ", " DBQ(alert) ": { " DBQ(level) ": %d, "
+ DBQ(decription) ": %d }",
+ level, descr);
+
+ msgbuf->buffer.offset += 2;
+ break;
+ }
+
+ fprintf(fh, " }\n");
+
+ if (state->output_file)
+ fclose(fh);
+
+ return 1;
+}
+
static int eat_server_hello(struct state *state)
{
- int r;
+ int r, type;
size_t len;
uint8_t *p;
struct msgbuf *msgbuf;
@@ -911,7 +1074,7 @@ static int eat_server_hello(struct state *state)
{
if (msgbuf->buffer.size - msgbuf->buffer.offset < 4)
{
- r= msgbuf_read(msgbuf, MSG_HANDSHAKE,
+ r= msgbuf_read(msgbuf, &type,
&state->recv_major, &state->recv_minor);
if (r < 0)
{
@@ -920,6 +1083,20 @@ static int eat_server_hello(struct state *state)
return -1;
}
+ if (type == MSG_ALERT)
+ {
+ r= eat_alert(state);
+ if (r == 0)
+ continue;
+ return r; /* No need to continue */
+ }
+ if (type != MSG_HANDSHAKE)
+ {
+ fprintf(stderr,
+ "eat_server_hello: got bad type %d from msgbuf_read\n",
+ type);
+ return -1;
+ }
continue;
}
p= (uint8_t *)msgbuf->buffer.buf+msgbuf->buffer.offset;
@@ -932,7 +1109,7 @@ static int eat_server_hello(struct state *state)
len= (p[1] << 16) + (p[2] << 8) + p[3];
if (msgbuf->buffer.size - msgbuf->buffer.offset < 4+len)
{
- r= msgbuf_read(msgbuf, MSG_HANDSHAKE,
+ r= msgbuf_read(msgbuf, &type,
&state->recv_major, &state->recv_minor);
if (r < 0)
{
@@ -940,6 +1117,13 @@ static int eat_server_hello(struct state *state)
"eat_server_hello: msgbuf_read failed\n");
return -1;
}
+ if (type != MSG_HANDSHAKE)
+ {
+ fprintf(stderr,
+ "eat_server_hello: got bad type %d from msgbuf_read\n",
+ type);
+ return -1;
+ }
continue;
}
msgbuf->buffer.offset += 4+len;
@@ -950,16 +1134,12 @@ static int eat_server_hello(struct state *state)
static int eat_certificate(struct state *state)
{
- int i, n, r, first, slen, need_nl, major, minor;
+ int i, n, r, first, slen, need_nl, type;
size_t o, len;
- const char *method;
uint8_t *p;
struct msgbuf *msgbuf;
FILE *fh;
- double resptime;
- struct timeval endtime;
struct buf tmpbuf;
- char hostbuf[NI_MAXHOST];
msgbuf= &state->msginbuf;
@@ -967,7 +1147,7 @@ static int eat_certificate(struct state *state)
{
if (msgbuf->buffer.size - msgbuf->buffer.offset < 4)
{
- r= msgbuf_read(msgbuf, MSG_HANDSHAKE,
+ r= msgbuf_read(msgbuf, &type,
&state->recv_major, &state->recv_minor);
if (r < 0)
{
@@ -979,6 +1159,13 @@ static int eat_certificate(struct state *state)
}
return -1;
}
+ if (type != MSG_HANDSHAKE)
+ {
+ fprintf(stderr,
+ "eat_certificate: got bad type %d from msgbuf_read\n",
+ type);
+ return -1;
+ }
continue;
}
p= (uint8_t *)msgbuf->buffer.buf+msgbuf->buffer.offset;
@@ -990,7 +1177,7 @@ static int eat_certificate(struct state *state)
len= (p[1] << 16) + (p[2] << 8) + p[3];
if (msgbuf->buffer.size - msgbuf->buffer.offset < 4+len)
{
- r= msgbuf_read(msgbuf, MSG_HANDSHAKE,
+ r= msgbuf_read(msgbuf, &type,
&state->recv_major, &state->recv_minor);
if (r < 0)
{
@@ -998,93 +1185,22 @@ static int eat_certificate(struct state *state)
"eat_certificate: msgbuf_read failed\n");
return -1;
}
+ if (type != MSG_HANDSHAKE)
+ {
+ fprintf(stderr,
+ "eat_certificate: got bad type %d from msgbuf_read\n",
+ type);
+ return -1;
+ }
continue;
}
p += 4;
n= (p[0] << 16) + (p[1] << 8) + p[2];
o= 3;
- gettimeofday(&endtime, NULL);
-
- fh= NULL;
- if (state->output_file)
- {
- fh= fopen(state->output_file, "a");
- if (!fh)
- crondlog(DIE9 "unable to append to '%s'",
- state->output_file);
- }
- else
- fh= stdout;
-
- fprintf(fh, "RESULT { ");
- if (state->atlas)
- {
- fprintf(fh, DBQ(id) ":" DBQ(%s)
- ", " DBQ(fw) ":%d"
- ", " DBQ(lts) ":%d",
- state->atlas, get_atlas_fw_version(),
- get_timesync());
- }
-
- fprintf(fh, "%s" DBQ(time) ":%ld",
- state->atlas ? ", " : "", time(NULL));
- fprintf(fh, ", " DBQ(dst_name) ":" DBQ(%s) ", "
- DBQ(dst_port) ":" DBQ(%s),
- state->hostname, state->portname);
-
- if (state->recv_major == 3 && state->recv_minor == 3)
- {
- method= "TLS";
- major= 1;
- minor= 2;
- }
- else if (state->recv_major == 3 && state->recv_minor == 2)
- {
- method= "TLS";
- major= 1;
- minor= 1;
- }
- else if (state->recv_major == 3 && state->recv_minor == 1)
- {
- method= "TLS";
- major= 1;
- minor= 0;
- }
- else if (state->recv_major == 3 && state->recv_minor == 0)
- {
- method= "SSL";
- major= 3;
- minor= 0;
- }
- else
- {
- method= "(unknown)";
- major= state->recv_major;
- minor= state->recv_minor;
- }
-
- fprintf(fh, ", " DBQ(method) ":" DBQ(%s) ", "
- DBQ(ver) ":" DBQ(%d.%d), method, major, minor);
- getnameinfo((struct sockaddr *)&state->sin6, state->socklen,
- hostbuf, sizeof(hostbuf), NULL, 0,
- NI_NUMERICHOST);
- fprintf(fh, ", " DBQ(dst_addr) ":" DBQ(%s), hostbuf);
- fprintf(fh, ", " DBQ(af) ": %d",
- state->sin6.sin6_family == AF_INET6 ? 6 : 4);
-
- getnameinfo((struct sockaddr *)&state->loc_sin6,
- state->loc_socklen, hostbuf, sizeof(hostbuf), NULL, 0,
- NI_NUMERICHOST);
- fprintf(fh, ", " DBQ(src_addr) ":" DBQ(%s), hostbuf);
-
- resptime= (state->t_connect.tv_sec- state->start.tv_sec)*1e3 +
- (state->t_connect.tv_usec-state->start.tv_usec)/1e3;
- fprintf(fh, ", " DBQ(ttc) ": %f", resptime);
-
- resptime= (endtime.tv_sec- state->start.tv_sec)*1e3 +
- (endtime.tv_usec-state->start.tv_usec)/1e3;
- fprintf(fh, ", " DBQ(rt) ": %f", resptime);
+ fh= report_head(state);
+ if (fh == NULL)
+ return -1;
first= 1;
fprintf(fh, ", " DBQ(cert) ":[ ");
@@ -1158,7 +1274,7 @@ static void writecb(struct bufferevent *bev, void *ptr)
switch(state->writestate)
{
case WRITE_HELLO:
- gettimeofday(&state->t_connect, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &state->t_connect);
buf_init(&outbuf, bev);
msgbuf_init(&msgoutbuf, NULL, &outbuf);
@@ -1242,7 +1358,7 @@ static void beforeconnect(struct tu_env *env,
//if (!state->do_all || !state->do_combine)
state->reslen= 0;
- gettimeofday(&state->start, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &state->start);
}
@@ -1292,6 +1408,12 @@ static void reporterr(struct tu_env *env, enum tu_err cause,
report(state);
break;
+ case TU_BAD_ADDR:
+ add_str(state, DBQ(error) ": " DBQ(address not allowed));
+ state->dnserr= 1;
+ report(state);
+ break;
+
default:
crondlog(DIE9 "reporterr: bad cause %d", cause);
}
diff --git a/eperd/tcputil.c b/eperd/tcputil.c
index e1d4505..22885b0 100644
--- a/eperd/tcputil.c
+++ b/eperd/tcputil.c
@@ -63,6 +63,14 @@ void tu_restart_connect(struct tu_env *env)
{
evtimer_add(&env->timer, &env->interval);
+ r= atlas_check_addr(env->dns_curr->ai_addr,
+ env->dns_curr->ai_addrlen);
+ if (r == -1)
+ {
+ env->reporterr(env, TU_BAD_ADDR, "");
+ return;
+ }
+
env->beforeconnect(env,
env->dns_curr->ai_addr, env->dns_curr->ai_addrlen);
@@ -166,6 +174,14 @@ static void dns_cb(int result, struct evutil_addrinfo *res, void *ctx)
{
evtimer_add(&env->timer, &env->interval);
+ r= atlas_check_addr(env->dns_curr->ai_addr,
+ env->dns_curr->ai_addrlen);
+ if (r == -1)
+ {
+ env->reporterr(env, TU_BAD_ADDR, "");
+ return;
+ }
+
env->beforeconnect(env,
env->dns_curr->ai_addr, env->dns_curr->ai_addrlen);
diff --git a/eperd/tcputil.h b/eperd/tcputil.h
index 1264299..89cfbcd 100644
--- a/eperd/tcputil.h
+++ b/eperd/tcputil.h
@@ -7,7 +7,7 @@
#include <event2/event_struct.h>
enum tu_err { TU_DNS_ERR, TU_READ_ERR, TU_SOCKET_ERR, TU_CONNECT_ERR,
- TU_OUT_OF_ADDRS };
+ TU_OUT_OF_ADDRS, TU_BAD_ADDR };
struct tu_env
{
char dnsip;
diff --git a/eperd/traceroute.c b/eperd/traceroute.c
index 26194c0..4875721 100644
--- a/eperd/traceroute.c
+++ b/eperd/traceroute.c
@@ -142,7 +142,7 @@ struct trtstate
struct evutil_addrinfo *dns_curr;
time_t starttime;
- struct timeval xmit_time;
+ struct timespec xmit_time;
struct event timer;
@@ -185,7 +185,7 @@ struct v6info
uint32_t pid;
uint32_t id;
uint32_t seq;
- struct timeval tv;
+ struct timespec tv;
};
static int create_socket(struct trtstate *state, int do_tcp);
@@ -520,7 +520,7 @@ static void send_pkt(struct trtstate *state)
}
state->seq++;
- gettimeofday(&state->xmit_time, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &state->xmit_time);
if (state->sin6.sin6_family == AF_INET6)
{
@@ -1362,11 +1362,12 @@ static void ready_callback4(int __attribute((unused)) unused,
struct tcphdr *etcp;
struct udphdr *eudp;
double ms;
- struct timeval now, interval;
+ struct timespec now;
+ struct timeval interval;
struct sockaddr_in remote;
char line[80];
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
state= s;
base= state->base;
@@ -1510,7 +1511,7 @@ static void ready_callback4(int __attribute((unused)) unused,
state->last_response_hop= state->hop;
ms= (now.tv_sec-state->xmit_time.tv_sec)*1000 +
- (now.tv_usec-state->xmit_time.tv_usec)/1e3;
+ (now.tv_nsec-state->xmit_time.tv_nsec)/1e6;
snprintf(line, sizeof(line), "%s\"from\":\"%s\"",
(late || isDup) ? ", " : "",
@@ -1724,7 +1725,7 @@ printf("curpacksize: %d\n", state->curpacksize);
state->last_response_hop= state->hop;
ms= (now.tv_sec-state->xmit_time.tv_sec)*1000 +
- (now.tv_usec-state->xmit_time.tv_usec)/1e3;
+ (now.tv_nsec-state->xmit_time.tv_nsec)/1e6;
snprintf(line, sizeof(line), "%s\"from\":\"%s\"",
(late || isDup) ? ", " : "",
@@ -1952,7 +1953,7 @@ printf("%s, %d: sin6_family = %d\n", __FILE__, __LINE__, state->sin6.sin6_family
state->last_response_hop= state->hop;
ms= (now.tv_sec-state->xmit_time.tv_sec)*1000 +
- (now.tv_usec-state->xmit_time.tv_usec)/1e3;
+ (now.tv_nsec-state->xmit_time.tv_nsec)/1e6;
snprintf(line, sizeof(line), "%s\"from\":\"%s\"",
(late || isDup) ? ", " : "",
@@ -2223,7 +2224,7 @@ printf("%s, %d: sin6_family = %d\n", __FILE__, __LINE__, state->sin6.sin6_family
}
ms= (now.tv_sec-state->xmit_time.tv_sec)*1000 +
- (now.tv_usec-state->xmit_time.tv_usec)/1e3;
+ (now.tv_nsec-state->xmit_time.tv_nsec)/1e6;
snprintf(line, sizeof(line), "%s\"from\":\"%s\"",
(late || isDup) ? ", " : "",
@@ -2278,12 +2279,52 @@ printf("%s, %d: sin6_family = %d\n", __FILE__, __LINE__, state->sin6.sin6_family
}
}
+static void report_hdropts(struct trtstate *state, unsigned char *s,
+ unsigned char *e)
+{
+ int o, len, mss;
+ unsigned char *orig_s;
+ char line[80];
+
+ add_str(state, ", " DBQ(hdropts) ": [ ");
+ orig_s= s;
+ while (s<e)
+ {
+ o= *s;
+ switch(o)
+ {
+ case 2:
+ len= s[1];
+ if (len < 4 || s+len > e)
+ {
+ printf("report_hdropts: bad option\n");
+ break;
+ }
+ mss= (s[2] << 8) | s[3];
+ snprintf(line, sizeof(line),
+ "%s{ " DBQ(mss) ":%d }",
+ s != orig_s ? ", " : "", mss);
+ add_str(state, line);
+ s += len;
+ continue;
+ default:
+ snprintf(line, sizeof(line),
+ "%s{ " DBQ(unknown-opt) ":%d }",
+ s != orig_s ? ", " : "", o);
+ add_str(state, line);
+ break;
+ }
+ break;
+ }
+ add_str(state, " ]");
+}
+
static void ready_tcp4(int __attribute((unused)) unused,
const short __attribute((unused)) event, void *s)
{
uint16_t myport;
socklen_t slen;
- int hlen, late, isDup;
+ int hlen, late, isDup, tcp_hlen;
unsigned ind, seq;
ssize_t nrecv;
struct trtbase *base;
@@ -2291,12 +2332,13 @@ static void ready_tcp4(int __attribute((unused)) unused,
struct ip *ip;
double ms;
struct tcphdr *tcphdr;
+ unsigned char *e, *p;
struct sockaddr_in remote;
- struct timeval now;
+ struct timespec now;
struct timeval interval;
char line[80];
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
state= s;
base= state->base;
@@ -2323,6 +2365,14 @@ static void ready_tcp4(int __attribute((unused)) unused,
tcphdr= (struct tcphdr *)(base->packet+hlen);
+ tcp_hlen= tcphdr->doff * 4;
+ if (nrecv < hlen + tcp_hlen || tcphdr->doff < 5)
+ {
+ /* Short packet */
+ printf("ready_tcp4: too short %d\n", (int)nrecv);
+ return;
+ }
+
/* Quick check if the port is in range */
myport= ntohs(tcphdr->dest);
if (myport < SRC_BASE_PORT || myport > SRC_BASE_PORT+256)
@@ -2389,7 +2439,7 @@ printf("got seq %d, expected %d\n", seq, state->seq);
}
ms= (now.tv_sec-state->xmit_time.tv_sec)*1000 +
- (now.tv_usec-state->xmit_time.tv_usec)/1e3;
+ (now.tv_nsec-state->xmit_time.tv_nsec)/1e6;
snprintf(line, sizeof(line), "%s\"from\":\"%s\"",
(late || isDup) ? ", " : "",
@@ -2407,6 +2457,13 @@ printf("got seq %d, expected %d\n", seq, state->seq);
(tcphdr->urg ? "U" : ""));
add_str(state, line);
+ if (tcp_hlen > sizeof(*tcphdr))
+ {
+ p= (unsigned char *)&tcphdr[1];
+ e= ((unsigned char *)tcphdr) + tcp_hlen;
+ report_hdropts(state, p, e);
+ }
+
if (!late)
{
snprintf(line, sizeof(line), ", \"rtt\":%.3f", ms);
@@ -2446,25 +2503,26 @@ static void ready_tcp6(int __attribute((unused)) unused,
const short __attribute((unused)) event, void *s)
{
uint16_t myport;
- int late, isDup, rcvdttl;
+ int late, isDup, rcvdttl, tcp_hlen;
unsigned ind, seq;
ssize_t nrecv;
struct trtbase *base;
struct trtstate *state;
double ms;
+ unsigned char *e, *p;
struct tcphdr *tcphdr;
struct cmsghdr *cmsgptr;
struct msghdr msg;
struct iovec iov[1];
struct sockaddr_in6 remote;
struct in6_addr dstaddr;
- struct timeval now;
+ struct timespec now;
struct timeval interval;
char buf[INET6_ADDRSTRLEN];
char line[80];
char cmsgbuf[256];
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
state= s;
base= state->base;
@@ -2509,6 +2567,14 @@ static void ready_tcp6(int __attribute((unused)) unused,
tcphdr= (struct tcphdr *)(base->packet);
+ tcp_hlen= tcphdr->doff * 4;
+ if (nrecv < tcp_hlen || tcphdr->doff < 5)
+ {
+ /* Short packet */
+ printf("ready_tcp6: too short %d\n", (int)nrecv);
+ return;
+ }
+
/* Quick check if the port is in range */
myport= ntohs(tcphdr->dest);
if (myport < SRC_BASE_PORT || myport > SRC_BASE_PORT+256)
@@ -2573,7 +2639,7 @@ printf("got seq %d, expected %d\n", seq, state->seq);
}
ms= (now.tv_sec-state->xmit_time.tv_sec)*1000 +
- (now.tv_usec-state->xmit_time.tv_usec)/1e3;
+ (now.tv_nsec-state->xmit_time.tv_nsec)/1e6;
snprintf(line, sizeof(line), "%s\"from\":\"%s\"",
(late || isDup) ? ", " : "",
@@ -2590,6 +2656,14 @@ printf("got seq %d, expected %d\n", seq, state->seq);
(tcphdr->ack ? "A" : ""),
(tcphdr->urg ? "U" : ""));
add_str(state, line);
+
+ if (tcp_hlen > sizeof(*tcphdr))
+ {
+ p= (unsigned char *)&tcphdr[1];
+ e= ((unsigned char *)tcphdr) + tcp_hlen;
+ report_hdropts(state, p, e);
+ }
+
if (!late)
{
snprintf(line, sizeof(line), ", \"rtt\":%.3f", ms);
@@ -2644,7 +2718,7 @@ static void ready_callback6(int __attribute((unused)) unused,
struct cmsghdr *cmsgptr;
void *ptr;
double ms;
- struct timeval now;
+ struct timespec now;
struct sockaddr_in6 remote;
struct in6_addr dstaddr;
struct msghdr msg;
@@ -2654,7 +2728,7 @@ static void ready_callback6(int __attribute((unused)) unused,
char line[80];
char cmsgbuf[256];
- gettimeofday(&now, NULL);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
state= s;
base= state->base;
@@ -3015,14 +3089,13 @@ printf("%s, %d: sin6_family = %d\n", __FILE__, __LINE__, state->sin6.sin6_family
if (!late)
{
ms= (now.tv_sec-state->xmit_time.tv_sec)*1000 +
- (now.tv_usec-state->xmit_time.tv_usec)/
- 1e3;
+ (now.tv_nsec-state->xmit_time.tv_nsec)/
+ 1e6;
}
else if (v6info)
{
ms= (now.tv_sec-v6info->tv.tv_sec)*1000 +
- (now.tv_usec-v6info->tv.tv_usec)/
- 1e3;
+ (now.tv_nsec-v6info->tv.tv_nsec)/1e6;
}
snprintf(line, sizeof(line), "%s\"from\":\"%s\"",
@@ -3295,14 +3368,12 @@ printf("%s, %d: sin6_family = %d\n", __FILE__, __LINE__, state->sin6.sin6_family
if (!late)
{
ms= (now.tv_sec-state->xmit_time.tv_sec)*1000 +
- (now.tv_usec-state->xmit_time.tv_usec)/
- 1e3;
+ (now.tv_nsec-state->xmit_time.tv_nsec)/1e6;
}
else
{
ms= (now.tv_sec-v6info->tv.tv_sec)*1000 +
- (now.tv_usec-v6info->tv.tv_usec)/
- 1e3;
+ (now.tv_nsec-v6info->tv.tv_nsec)/1e6;
}
snprintf(line, sizeof(line), "%s\"from\":\"%s\"",
@@ -3510,6 +3581,12 @@ for (i= 0; argv[i] != NULL; i++)
free(lsa);
return NULL;
}
+
+ if (atlas_check_addr(&lsa->u.sa, lsa->len) == -1)
+ {
+ free(lsa);
+ return NULL;
+ }
}
else
{
@@ -3547,6 +3624,8 @@ for (i= 0; argv[i] != NULL; i++)
state->result= NULL;
state->reslen= 0;
state->resmax= 0;
+ state->socket_icmp= -1;
+ state->socket_tcp= -1;
for (i= 0; i<trt_base->tabsiz; i++)
{
@@ -3863,7 +3942,7 @@ static int create_socket(struct trtstate *state, int do_tcp)
static void dns_cb(int result, struct evutil_addrinfo *res, void *ctx)
{
- int count;
+ int r, count;
struct trtstate *env;
struct evutil_addrinfo *cur;
char line[160];
@@ -3915,6 +3994,24 @@ static void dns_cb(int result, struct evutil_addrinfo *res, void *ctx)
memcpy(&env->sin6, env->dns_curr->ai_addr,
env->socklen);
+ r= atlas_check_addr((struct sockaddr *)&env->sin6,
+ env->socklen);
+ if (r == -1)
+ {
+ if (env->result) free(env->result);
+ env->resmax= 80;
+ env->result= xmalloc(env->resmax);
+ env->reslen= 0;
+
+ env->starttime= time(NULL);
+ snprintf(line, sizeof(line),
+ "{ " DBQ(error) ":" DBQ(address not allowed) " }");
+ add_str(env, line);
+ env->dnsip= 1;
+ report(env);
+ return;
+ }
+
traceroute_start2(env);
evutil_freeaddrinfo(env->dns_res);