aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2015-05-15 10:25:29 +0200
committerBjørn Mork <bjorn@mork.no>2015-05-15 10:25:29 +0200
commit13762fce1926efb6b553bf20df256ccf6586f518 (patch)
tree7ac288e17edd643380c1e18dda5b49d02839fa85
parent73e699faf130d0fc0f2f076d95db9dbd7f42a8b6 (diff)
ripe-atlas-fw: imported version 46704670
Signed-off-by: Bjørn Mork <bjorn@mork.no>
-rw-r--r--checksum4
-rw-r--r--eperd/eooqd.c147
-rw-r--r--eperd/eperd.c140
-rw-r--r--eperd/eperd.h2
-rw-r--r--eperd/evntp.c2
-rw-r--r--eperd/evtdig.c282
-rw-r--r--eperd/httpget.c22
-rw-r--r--eperd/ntp.c24
-rw-r--r--eperd/ping.c50
-rw-r--r--eperd/readresolv.c2
-rw-r--r--eperd/readresolv.h2
-rw-r--r--eperd/sslgetcert.c23
-rw-r--r--eperd/tcputil.c57
-rw-r--r--eperd/tcputil.h2
-rw-r--r--eperd/traceroute.c2
-rw-r--r--include/cmdtable.h17
-rw-r--r--libbb/atlas_timesync.c2
-rw-r--r--miscutils/ooqd.c363
-rw-r--r--miscutils/perd.c5
-rw-r--r--networking/httppost.c2
-rw-r--r--networking/rptaddrs.c27
-rw-r--r--networking/rptra6.c2
-rw-r--r--networking/sslgetcert.c4
-rw-r--r--networking/telnetd.c5
24 files changed, 842 insertions, 346 deletions
diff --git a/checksum b/checksum
index cd6d912..7dd5f3c 100644
--- a/checksum
+++ b/checksum
@@ -1,2 +1,2 @@
-6b015256e73151f92c700c31c4551c24fef023e57c74316fa35d024f013b1737 ripe-atlas-fw-4610.tar.gz
-8d22f3f0e332df7271c893ea599975939e29fda1e0a9f001dc7b50dd2ffc835c43c2859042ba835edce312222e830e38c6c6cc417b038e234d3f14942120dd39 ripe-atlas-fw-4610.tar.gz
+166960d42c8ba05656d36433787c989d007299de57bbed189dd2904912336f8a ripe-atlas-fw-4660.tar.gz
+b958d461a3abfde6a5ab5db396808b0df34e5fa3234fe922043331525c18886089a369a34b7ffb4567e1b9aebbc11d07e3a32ba2e5414f1eb5e71847ec0df582 ripe-atlas-fw-4660.tar.gz
diff --git a/eperd/eooqd.c b/eperd/eooqd.c
index 4f572b7..8ce460f 100644
--- a/eperd/eooqd.c
+++ b/eperd/eooqd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* eooqd.c Libevent-based One-off queue daemon
*/
@@ -16,7 +16,7 @@
#define SUFFIX ".curr"
#define OOQD_NEW_PREFIX "/home/atlas/data/new/ooq"
-#define OOQD_OUT "/home/atlas/data/ooq.out/ooq"
+#define OOQD_OUT_PREFIX "/home/atlas/data/out/ooq"
#define ATLAS_SESSION_FILE "/home/atlas/status/con_session_id.txt"
#define ATLAS_NARGS 64 /* Max arguments to a built-in command */
@@ -26,6 +26,9 @@
#define DBQ(str) "\"" #str "\""
+#define BARRIER_CMD "barrier"
+#define POST_CMD "post"
+
struct slot
{
void *cmdstate;
@@ -42,6 +45,9 @@ static struct
int curr_busy;
int curr_index;
struct slot *slots;
+
+ int barrier;
+ char *barrier_file;
} *state;
static struct builtin
@@ -60,16 +66,16 @@ static struct builtin
};
static const char *atlas_id;
-static const char *out_filename;
+static const char *queue_id;
static void report(const char *fmt, ...);
static void report_err(const char *fmt, ...);
static void checkQueue(evutil_socket_t fd, short what, void *arg);
-static void add_line(void);
+static int add_line(void);
static void cmddone(void *cmdstate);
static void re_post(evutil_socket_t fd, short what, void *arg);
-static void post_results(void);
+static void post_results(int force_post);
static void skip_space(char *cp, char **ncpp);
static void skip_nonspace(char *cp, char **ncpp);
static void find_eos(char *cp, char **ncpp);
@@ -89,9 +95,10 @@ int eooqd_main(int argc, char *argv[])
atlas_id= NULL;
pid_file_name= NULL;
+ queue_id= "";
- (void)getopt32(argv, "A:P:O:", &atlas_id, &pid_file_name,
- &out_filename);
+ (void)getopt32(argv, "A:P:q:", &atlas_id, &pid_file_name,
+ &queue_id);
if (argc != optind+1)
{
@@ -125,7 +132,6 @@ int eooqd_main(int argc, char *argv[])
strlcat(state->curr_qfile, SUFFIX, sizeof(state->curr_qfile));
signal(SIGQUIT, SIG_DFL);
- chdir("/home/atlas/data");
limit.rlim_cur= RLIM_INFINITY;
limit.rlim_max= RLIM_INFINITY;
setrlimit(RLIMIT_CORE, &limit);
@@ -168,9 +174,12 @@ int eooqd_main(int argc, char *argv[])
static void checkQueue(evutil_socket_t fd UNUSED_PARAM,
short what UNUSED_PARAM, void *arg UNUSED_PARAM)
{
+ int r;
+ char filename[80];
+
if (!state->curr_file)
{
- /* Try to move queue_file to curr_qfile. This provide at most
+ /* 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.
*/
@@ -194,16 +203,20 @@ static void checkQueue(evutil_socket_t fd UNUSED_PARAM,
while (state->curr_file && state->curr_busy < state->max_busy)
{
- add_line();
+ r= add_line();
+ if (r == -1)
+ break; /* Wait for barrier to complete */
}
- check_resolv_conf2(out_filename, atlas_id);
+ snprintf(filename, sizeof(filename),
+ OOQD_OUT_PREFIX "%s/ooq.out", queue_id);
+ check_resolv_conf2(filename, atlas_id);
}
-static void add_line(void)
+static int add_line(void)
{
char c;
- int i, argc, skip, slot;
+ int i, argc, fd, skip, slot;
size_t len;
char *cp, *ncp;
struct builtin *bp;
@@ -215,15 +228,33 @@ static void add_line(void)
char args[ATLAS_ARGSIZE];
char cmdline[256];
char filename[80];
+ char filename2[80];
struct stat sb;
+ if (state->barrier)
+ {
+ if (state->curr_busy > 0)
+ return -1;
+ fd= open(state->barrier_file, O_CREAT, 0);
+ if (fd != -1)
+ close(fd);
+ else
+ {
+ report_err("unable to create barrier file '%s'",
+ state->barrier_file);
+ }
+ free(state->barrier_file);
+ state->barrier_file= NULL;
+ state->barrier= 0;
+ }
+
if (fgets(cmdline, sizeof(cmdline), state->curr_file) == NULL)
{
if (ferror(state->curr_file))
report_err("error reading queue file");
fclose(state->curr_file);
state->curr_file= NULL;
- return;
+ return 0;
}
cp= strchr(cmdline, '\n');
@@ -232,6 +263,33 @@ static void add_line(void)
crondlog(LVL7 "atlas_run: looking for '%s'", cmdline);
+ /* Check for post command */
+ if (strcmp(cmdline, POST_CMD) == 0)
+ {
+ /* Trigger a post */
+ post_results(1 /* force_post */);
+ return 0; /* Done */
+ }
+
+ /* Check for barrier command */
+ len= strlen(BARRIER_CMD);
+ if (strlen(cmdline) >= len &&
+ strncmp(cmdline, BARRIER_CMD, len) == 0 &&
+ cmdline[len] == ' ')
+ {
+ p= &cmdline[len];
+ while (*p != '\0' && *p == ' ')
+ p++;
+ if (!validate_filename(p, SAFE_PREFIX))
+ {
+ crondlog(LVL8 "insecure file '%s'. allowed path '%s'",
+ p, SAFE_PREFIX);
+ }
+ state->barrier= 1;
+ state->barrier_file= strdup(p);
+ return 0;
+ }
+
cmdstate= NULL;
reason= NULL;
for (bp= builtin_cmds; bp->cmd != NULL; bp++)
@@ -337,7 +395,8 @@ static void add_line(void)
if (state->slots[slot].cmdstate != NULL)
crondlog(DIE9 "no empty slot?");
argv[argc++]= "-O";
- snprintf(filename, sizeof(filename), OOQD_NEW_PREFIX ".%d", slot);
+ snprintf(filename, sizeof(filename), OOQD_NEW_PREFIX "%s.%d",
+ queue_id, slot);
argv[argc++]= filename;
argv[argc]= NULL;
@@ -361,11 +420,12 @@ static void add_line(void)
error:
if (cmdstate == NULL)
{
- fn= fopen(OOQD_NEW_PREFIX, "a");
+ snprintf(filename, sizeof(filename), OOQD_NEW_PREFIX "%s",
+ queue_id);
+ fn= fopen(filename, "a");
if (!fn)
{
- crondlog(DIE9 "unable to append to '%s'",
- OOQD_NEW_PREFIX);
+ crondlog(DIE9 "unable to append to '%s'", filename);
}
fprintf(fn, "RESULT { ");
if (state->atlas_id)
@@ -389,17 +449,21 @@ error:
fprintf(fn, " }\n");
fclose(fn);
- if (stat(OOQD_OUT, &sb) == -1 &&
- stat(OOQD_NEW_PREFIX, &sb) == 0)
+ snprintf(filename2, sizeof(filename2),
+ OOQD_OUT_PREFIX "%s/ooq", queue_id);
+ if (stat(filename2, &sb) == -1 &&
+ stat(filename, &sb) == 0)
{
- if (rename(OOQD_NEW_PREFIX, OOQD_OUT) == -1)
+ if (rename(filename, filename2) == -1)
{
report_err("move '%s' to '%s' failed",
- OOQD_NEW_PREFIX, OOQD_OUT);
+ filename, filename2);
}
}
- post_results();
+ post_results(0 /* !force_post */);
}
+
+ return 0;
}
static void cmddone(void *cmdstate)
@@ -432,9 +496,9 @@ static void cmddone(void *cmdstate)
report("cmddone: strange, cmd %p is busy", cmdstate);
snprintf(from_filename, sizeof(from_filename),
- "/home/atlas/data/new/ooq.%d", i);
+ OOQD_NEW_PREFIX "%s.%d", queue_id, i);
snprintf(to_filename, sizeof(to_filename),
- "/home/atlas/data/ooq.out/%d", i);
+ OOQD_OUT_PREFIX "%s/%d", queue_id, i);
if (stat(to_filename, &sb) == 0)
{
report("output file '%s' is busy", to_filename);
@@ -449,7 +513,7 @@ static void cmddone(void *cmdstate)
if (state->curr_busy == 0)
{
- post_results();
+ post_results(0 /* !force_post */);
}
}
@@ -477,7 +541,7 @@ static void check_resolv_conf2(const char *out_file, const char *atlasid)
RESOLV_CONF);
evdns_base_resume(DnsBase);
- if ((r != 0 || last_time != -1) && out_filename != NULL)
+ if ((r != 0 || last_time != -1) && out_file != NULL)
{
fn= fopen(out_file, "a");
if (!fn)
@@ -503,10 +567,10 @@ static void re_post(evutil_socket_t fd UNUSED_PARAM, short what UNUSED_PARAM,
/* Just call post_results every once in awhile in case some results
* were left behind.
*/
- post_results();
+ post_results(0 /* !force_post */);
}
-static void post_results(void)
+static void post_results(int force_post)
{
int i, j, r, need_post, probe_id;
const char *session_id;
@@ -519,28 +583,33 @@ static void post_results(void)
for (j= 0; j<5; j++)
{
/* Grab results and see if something need to be done. */
- need_post= 0;
-
- if (stat(OOQD_OUT, &sb) == 0)
+ need_post= force_post;
+ force_post= 0; /* Only one time */
+
+ snprintf(from_filename, sizeof(from_filename),
+ OOQD_NEW_PREFIX "%s", queue_id);
+ snprintf(to_filename, sizeof(to_filename),
+ OOQD_OUT_PREFIX "%s/ooq", queue_id);
+ if (stat(to_filename, &sb) == 0)
{
/* There is more to post */
need_post= 1;
- } else if (stat(OOQD_NEW_PREFIX, &sb) == 0)
+ } else if (stat(from_filename, &sb) == 0)
{
- if (rename(OOQD_NEW_PREFIX, OOQD_OUT) == 0)
+ if (rename(from_filename, to_filename) == 0)
need_post= 1;
else
{
report_err("move '%s' to '%s' failed",
- OOQD_NEW_PREFIX, OOQD_OUT);
+ from_filename, to_filename);
}
}
for (i= 0; i<state->max_busy; i++)
{
snprintf(from_filename, sizeof(from_filename),
- "/home/atlas/data/new/ooq.%d", i);
+ OOQD_NEW_PREFIX "%s.%d", queue_id, i);
snprintf(to_filename, sizeof(to_filename),
- "/home/atlas/data/ooq.out/%d", i);
+ OOQD_OUT_PREFIX "%s/%d", queue_id, i);
if (stat(to_filename, &sb) == 0)
{
/* There is more to post */
@@ -573,6 +642,8 @@ static void post_results(void)
snprintf(url, sizeof(url),
"http://127.0.0.1:8080/?PROBE_ID=%d&SESSION_ID=%s&SRC=oneoff",
probe_id, session_id);
+ snprintf(from_filename, sizeof(from_filename),
+ OOQD_OUT_PREFIX "%s", queue_id);
i= 0;
argv[i++]= "httppost";
@@ -582,7 +653,7 @@ static void post_results(void)
argv[i++]= "--post-header";
argv[i++]= "/home/atlas/status/p_to_c_report_header";
argv[i++]= "--post-dir";
- argv[i++]= "/home/atlas/data/ooq.out";
+ argv[i++]= from_filename;
argv[i++]= "--post-footer";
argv[i++]= "/home/atlas/status/con_session_id.txt";
argv[i++]= "-O";
diff --git a/eperd/eperd.c b/eperd/eperd.c
index 20b68b5..2ccaa6a 100644
--- a/eperd/eperd.c
+++ b/eperd/eperd.c
@@ -72,7 +72,9 @@ struct CronLine {
time_t end_time;
enum distribution { DISTR_NONE, DISTR_UNIFORM } distribution;
int distr_param; /* Parameter for distribution, if any */
- int distr_offset; /* Current offset to randomize the interval */
+ struct timeval distr_offset; /* Current offset to randomize the
+ * interval
+ */
struct event event;
struct testops *testops;
void *teststate;
@@ -250,6 +252,7 @@ int eperd_main(int argc UNUSED_PARAM, char **argv)
unsigned seed;
struct event *updateEventMin, *updateEventHour;
struct timeval tv;
+ struct rlimit limit;
const char *PidFileName = NULL;
@@ -290,6 +293,11 @@ int eperd_main(int argc UNUSED_PARAM, char **argv)
xsetenv("SHELL", DEFAULT_SHELL); /* once, for all future children */
crondlog(LVL9 "crond (busybox "BB_VER") started, log level %d", LogLevel);
+ signal(SIGQUIT, SIG_DFL);
+ limit.rlim_cur= RLIM_INFINITY;
+ limit.rlim_max= RLIM_INFINITY;
+ setrlimit(RLIMIT_CORE, &limit);
+
/* Create libevent event base */
EventBase= event_base_new();
if (!EventBase)
@@ -421,7 +429,8 @@ static void do_distr(CronLine *line)
{
long n, r, modulus, max;
- line->distr_offset= 0; /* Safe default */
+ line->distr_offset.tv_sec= 0; /* Safe default */
+ line->distr_offset.tv_usec= 0;
if (line->distribution == DISTR_UNIFORM)
{
/* Generate a random number in the range [0..distr_param] */
@@ -433,9 +442,11 @@ static void do_distr(CronLine *line)
r= random();
} while (r >= max);
r %= modulus;
- line->distr_offset= r - line->distr_param/2;
+ line->distr_offset.tv_sec= r - line->distr_param/2;
+ line->distr_offset.tv_usec= random() % 1000000;
}
- crondlog(LVL7 "do_distr: using %d", line->distr_offset);
+ crondlog(LVL7 "do_distr: using %f", line->distr_offset.tv_sec +
+ line->distr_offset.tv_usec/1e6);
}
static void SynchronizeFile(const char *fileName)
@@ -662,14 +673,50 @@ static void SynchronizeDir(void)
DeleteFile();
}
+static void set_timeout(CronLine *line, int init_next_cycle)
+{
+ struct timeval now, tv;
+
+ gettimeofday(&now, NULL);
+ if (now.tv_sec > line->end_time)
+ return; /* This job has expired */
+
+ if (init_next_cycle)
+ {
+ if (now.tv_sec < line->start_time)
+ line->nextcycle= 0;
+ else
+ {
+ line->nextcycle= (now.tv_sec-line->start_time)/
+ line->interval + 1;
+ }
+ do_distr(line);
+ }
+
+ tv.tv_sec= line->nextcycle*line->interval + line->start_time +
+ line->distr_offset.tv_sec - now.tv_sec;
+ tv.tv_usec= line->distr_offset.tv_usec - now.tv_usec;
+ if (tv.tv_usec < 0)
+ {
+ tv.tv_usec += 1e6;
+ tv.tv_sec--;
+ }
+ if (tv.tv_sec < 0)
+ tv.tv_sec= tv.tv_usec= 0;
+ crondlog(LVL7 "set_timeout: nextcycle %d, interval %d, start_time %d, distr_offset %f, now %d, tv_sec %d",
+ line->nextcycle, line->interval,
+ line->start_time,
+ line->distr_offset.tv_sec + line->distr_offset.tv_usec/1e6,
+ now.tv_sec, tv.tv_sec);
+ event_add(&line->event, &tv);
+}
+
/*
* Insert - insert if not already there
*/
static int Insert(CronLine *line)
{
CronLine *last;
- struct timeval tv;
- time_t now;
if (oldLine)
{
@@ -709,18 +756,7 @@ static int Insert(CronLine *line)
oldLine->needs_delete= 0;
/* Reschedule event */
- now= time(NULL);
- tv.tv_sec= oldLine->nextcycle*oldLine->interval +
- oldLine->start_time +
- oldLine->distr_offset - now;
- if (tv.tv_sec < 0)
- tv.tv_sec= 0;
- tv.tv_usec= 0;
- crondlog(LVL7 "Insert: nextcycle %d, interval %d, start_time %d, distr_offset %d, now %d, tv_sec %d",
- oldLine->nextcycle, oldLine->interval,
- oldLine->start_time, oldLine->distr_offset, now,
- tv.tv_sec);
- event_add(&oldLine->event, &tv);
+ set_timeout(oldLine, 0 /*!init_netcycle*/);
return 0;
}
@@ -736,9 +772,6 @@ static int Insert(CronLine *line)
static void Start(CronLine *line)
{
- time_t now;
- struct timeval tv;
-
line->testops= NULL;
/* Parse command line and init test */
@@ -746,26 +779,7 @@ static void Start(CronLine *line)
if (!line->testops)
return; /* Test failed to initialize */
- now= time(NULL);
- if (now > line->end_time)
- return; /* This job has expired */
-
- if (now < line->start_time)
- line->nextcycle= 0;
- else
- line->nextcycle= (now-line->start_time)/line->interval + 1;
- do_distr(line);
-
- tv.tv_sec= line->nextcycle*line->interval + line->start_time +
- line->distr_offset - now;
- if (tv.tv_sec < 0)
- tv.tv_sec= 0;
- tv.tv_usec= 0;
- crondlog(LVL7 "Start: nextcycle %d, interval %d, start_time %d, distr_offset %d, now %d, tv_sec %d",
- line->nextcycle, line->interval,
- line->start_time, line->distr_offset, now,
- tv.tv_sec);
- event_add(&line->event, &tv);
+ set_timeout(line, 1 /*init_nextcycle*/);
}
/*
@@ -1164,22 +1178,12 @@ static void EndJob(const char *user, CronLine *line)
static void RunJob(evutil_socket_t __attribute__ ((unused)) fd,
short __attribute__ ((unused)) what, void *arg)
{
- time_t now;
CronLine *line;
- struct timeval tv;
+ struct timeval now;
line= arg;
- now= time(NULL);
-
crondlog(LVL7 "RunJob for %p, '%s'\n", arg, line->cl_Shell);
- crondlog(LVL7 "RubJob, now %d, end_time %d\n", now, line->end_time);
-
- if (now > line->end_time)
- {
- crondlog(LVL7 "RunJob: expired\n");
- return; /* This job has expired */
- }
if (line->needs_delete)
{
@@ -1187,6 +1191,17 @@ static void RunJob(evutil_socket_t __attribute__ ((unused)) fd,
return; /* Line is to be deleted */
}
+ gettimeofday(&now, NULL);
+
+ crondlog(LVL7 "RubJob, now %d, end_time %d\n", now.tv_sec,
+ line->end_time);
+
+ if (now.tv_sec > line->end_time)
+ {
+ crondlog(LVL7 "RunJob: expired\n");
+ return; /* This job has expired */
+ }
+
if (!line->teststate)
{
crondlog(LVL8 "not starting cmd '%s' (not init)\n",
@@ -1194,30 +1209,19 @@ static void RunJob(evutil_socket_t __attribute__ ((unused)) fd,
return;
}
- // crondlog(LVL8 "starting cmd '%s'\n", line->cl_Shell);
-
line->testops->start(line->teststate);
- // crondlog(LVL8 "after cmd '%s'\n", line->cl_Shell);
-
line->nextcycle++;
- if (line->start_time + line->nextcycle*line->interval < now)
+ if (line->start_time + line->nextcycle*line->interval < now.tv_sec)
{
crondlog(LVL7 "recomputing nextcycle");
- line->nextcycle= (now-line->start_time)/line->interval + 1;
+ line->nextcycle= (now.tv_sec-line->start_time)/line->interval
+ + 1;
}
do_distr(line);
- tv.tv_sec= line->nextcycle*line->interval + line->start_time +
- line->distr_offset - now;
- if (tv.tv_sec < 0)
- tv.tv_sec= 0;
- tv.tv_usec= 0;
- crondlog(LVL7 "RunJob: nextcycle %d, interval %d, start_time %d, distr_offset %d, now %d, tv_sec %d",
- line->nextcycle, line->interval,
- line->start_time, line->distr_offset, now,
- tv.tv_sec);
- event_add(&line->event, &tv);
+
+ set_timeout(line, 0 /*!init_nextcycle*/);
}
#endif /* ENABLE_FEATURE_CROND_CALL_SENDMAIL */
diff --git a/eperd/eperd.h b/eperd/eperd.h
index 25994fa..16cb1d7 100644
--- a/eperd/eperd.h
+++ b/eperd/eperd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* eperd.h
*/
diff --git a/eperd/evntp.c b/eperd/evntp.c
index 0047d1b..a959d9c 100644
--- a/eperd/evntp.c
+++ b/eperd/evntp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* Standalone version of the event-based ntp.
*/
diff --git a/eperd/evtdig.c b/eperd/evtdig.c
index a836745..c94e884 100644
--- a/eperd/evtdig.c
+++ b/eperd/evtdig.c
@@ -230,16 +230,11 @@ typedef uint32_t counter_t;
struct tdig_base {
struct event_base *event_base;
- evutil_socket_t rawfd_v4; /* Raw socket used to nsm hosts */
- evutil_socket_t rawfd_v6; /* Raw socket used to nsm hosts */
-
struct timeval tv_noreply; /* DNS query Reply timeout */
/* A circular list of user queries */
struct query_state *qry_head;
- struct event event4; /* Used to detect read events on raw socket */
- struct event event6; /* Used to detect read events on raw socket */
struct event statsReportEvent;
int resolv_max;
char nslist[MAXNS][INET6_ADDRSTRLEN * 2];
@@ -270,7 +265,10 @@ struct query_state {
char * name; /* Host identifier as given by the user */
char * fqname; /* Full qualified hostname */
char * ipname; /* Remote address in dot notation */
- u_int16_t qryid; /* query id 16 bit */
+ char * infname; /* Bind to this interface (or address) */
+ u_int16_t qryid; /* query id 16 bit */
+ struct event event; /* Used to detect read events on udp socket */
+ int udp_fd; /* udp_fd and tcp_fd should be merged */
int tcp_fd;
FILE *tcp_file;
int wire_size;
@@ -495,17 +493,18 @@ static void tdig_stats(int unused UNUSED_PARAM, const short event UNUSED_PARAM,
static int tdig_delete(void *state);
static void ChangetoDnsNameFormat(u_char *dns, char * qry) ;
struct tdig_base *tdig_base_new(struct event_base *event_base);
-void tdig_start (struct query_state *qry);
+void tdig_start (void *qry);
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, int af, void *remote);
+static void process_reply(void * arg, int nrecv, struct timeval 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, struct query_state *qry);
+static void udp_dns_cb(int err, struct evutil_addrinfo *ev_res, void *arg);
static void noreply_callback(int unused UNUSED_PARAM, const short event UNUSED_PARAM, void *h);
static void free_qry_inst(struct query_state *qry);
+static void ready_callback (int unused, const short event, void * arg);
/* move the next functions from tdig.c */
u_int32_t get32b (char *p);
@@ -654,39 +653,6 @@ int ip_addr_cmp (u_int16_t af_a, void *a, u_int16_t af_b, void *b)
return 1;
}
-/* Lookup for a query by its index */
-static struct query_state* tdig_lookup_query( struct tdig_base * base, int idx, int af, void * remote)
-{
- int i = 0;
- struct query_state *qry;
-
- qry = base->qry_head;
- if (!qry)
- return NULL;
- do {
- i++;
- if (qry->qryid == idx)
- {
- crondlog(LVL5 "found matching query id %d", idx);
- if( qry->ressent && ip_addr_cmp (af, remote, qry->ressent->ai_family, qry->ressent->ai_addr) == 0) {
- crondlog(LVL7 "matching id and address id %d", idx);
- return qry;
- }
- else {
- crondlog(LVL7 "matching id and address mismatch id %d", idx);
- }
- }
- qry = qry->next;
- if (i > (2*base->activeqry) ) {
- crondlog(LVL7 "i am looping %d AA", idx);
- return NULL;
- }
-
- } while (qry != base->qry_head);
-
- return NULL;
-}
-
static void mk_dns_buff(struct query_state *qry, u_char *packet)
{
struct DNS_HEADER *dns = NULL;
@@ -811,12 +777,13 @@ 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;
+ sa_family_t af;
struct query_state *qry = h;
struct tdig_base *base = qry->base;
uint32_t nsent = 0;
u_char *outbuff;
int err = 0;
- int sockfd;
/* Clean the no reply timer (if any was previously set) */
evtimer_del(&qry->noreply_timer);
@@ -828,33 +795,63 @@ static void tdig_send_query_callback(int unused UNUSED_PARAM, const short event
gettimeofday(&qry->xmit_time, NULL);
mk_dns_buff(qry, outbuff);
do {
- switch (qry->res->ai_family) {
- case AF_INET:
- nsent = sendto(base->rawfd_v4, outbuff,qry->pktsize, MSG_DONTWAIT, qry->res->ai_addr, qry->res->ai_addrlen);
- break;
- case AF_INET6:
- nsent = sendto(base->rawfd_v6, outbuff,qry->pktsize, MSG_DONTWAIT, qry->res->ai_addr, qry->res->ai_addrlen);
- break;
+ if (qry->udp_fd != -1)
+ {
+ event_del(&qry->event);
+ close(qry->udp_fd);
+ qry->udp_fd= -1;
}
+
+ af = ((struct sockaddr *)(qry->res->ai_addr))->sa_family;
+
+ if ((fd = socket(af, SOCK_DGRAM, 0) ) < 0 )
+ {
+ 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);
+ return;
+ }
+
+ qry->udp_fd= fd;
+
+ evutil_make_socket_nonblocking(fd);
+
+ event_assign(&qry->event, tdig_base->event_base, fd,
+ EV_READ | EV_PERSIST, ready_callback, qry);
+ event_add(&qry->event, NULL);
+
+ if (qry->infname)
+ {
+ if (bind_interface(fd, af, qry->infname) == -1)
+ {
+ snprintf(line, DEFAULT_LINE_LENGTH,
+ "%s \"socket\" : \"bind_interface failed\"",
+ 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)
+ {
+ snprintf(line, DEFAULT_LINE_LENGTH,
+ "%s \"socket\" : \"connect failed %s\"",
+ qry->err.size ? ", " : "",
+ strerror(errno));
+ buf_add(&qry->err, line, strlen(line));
+ printReply (qry, 0, NULL);
+ return;
+ }
+
+ nsent = send(qry->udp_fd, outbuff,qry->pktsize, MSG_DONTWAIT);
qry->ressent = qry->res;
if (nsent == qry->pktsize) {
- // the packet is send. Now lets try to the source address we would have used.
- // create another sock with same dest, connect and get the source address
- // delete that socket and hope the the source address is the right one.
- if ((sockfd = socket(qry->res->ai_family, SOCK_DGRAM, 0 ) ) < 0 ) {
- snprintf(line, DEFAULT_LINE_LENGTH, "%s \"socket\" : \"temp socket to get src address failed %s\"", qry->err.size ? ", " : "", strerror(errno));
- buf_add(&qry->err, line, strlen(line));
- return;
- }
- else {
- qry->loc_socklen = sizeof(qry->loc_sin6);
- connect(sockfd, qry->res->ai_addr, qry->res->ai_addrlen);
- if (getsockname(sockfd,(struct sockaddr *)&qry->loc_sin6, &qry->loc_socklen) == -1) {
- snprintf(line, DEFAULT_LINE_LENGTH, "%s \"getscokname\" : \"%s\"", qry->err.size ? ", " : "", strerror(errno));
- buf_add(&qry->err, line, strlen(line));
- }
- close(sockfd);
+ if (getsockname(qry->udp_fd, (struct sockaddr *)&qry->loc_sin6, &qry->loc_socklen) == -1) {
+ snprintf(line, DEFAULT_LINE_LENGTH, "%s \"getscokname\" : \"%s\"", qry->err.size ? ", " : "", strerror(errno));
+ buf_add(&qry->err, line, strlen(line));
}
/* One more DNS Query is sent */
@@ -947,6 +944,12 @@ static void tcp_reporterr(struct tu_env *env, enum tu_err cause,
buf_add(&qry->err, line, strlen(line));
break;
+ case TU_SOCKET_ERR:
+
+ snprintf(line, DEFAULT_LINE_LENGTH, "%s \"TUSOCKET\" : \"%s\"", qry->err.size ? ", " : "", str );
+ buf_add(&qry->err, line, strlen(line));
+ break;
+
case TU_READ_ERR:
// need more than this reporting for this case AA
snprintf(line, DEFAULT_LINE_LENGTH, "%s \"TU_READ_ERR\" : \"%s\"", qry->err.size ? ", " : "", str );
@@ -1078,7 +1081,7 @@ static void tcp_readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
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;
- printReply (qry, qry->packet.size, qry->packet.buf);
+ printReply (qry, qry->packet.size, (unsigned char *)qry->packet.buf);
}
else {
bzero(line, DEFAULT_LINE_LENGTH);
@@ -1091,7 +1094,7 @@ static void tcp_readcb(struct bufferevent *bev UNUSED_PARAM, void *ptr)
}
}
-static void tcp_writecb(struct bufferevent *bev, void *ptr)
+static void tcp_writecb(struct bufferevent *bev UNUSED_PARAM, void *ptr UNUSED_PARAM)
{
/*
struct query_state * qry;
@@ -1112,14 +1115,16 @@ static void tcp_writecb(struct bufferevent *bev, void *ptr)
* 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, int af, void *remote )
+static void process_reply(void * arg, int nrecv, struct timeval now)
{
- struct tdig_base *base = arg;
-
struct DNS_HEADER *dnsR = NULL;
+ struct tdig_base * base;
struct query_state * qry;
+ qry= arg;
+ base= qry->base;
+
if (nrecv < sizeof (struct DNS_HEADER)) {
base->shortpkt++;
return;
@@ -1130,13 +1135,10 @@ static void process_reply(void * arg, int nrecv, struct timeval now, int af, voi
crondlog(LVL7 "DBG: base address process reply %p, nrec %d", base, nrecv);
- /* Get the pointer to the qry descriptor in our internal table */
- qry = tdig_lookup_query(base, ntohs(dnsR->id), af, remote);
-
- if ( ! qry) {
+ if (ntohs(dnsR->id) != qry->qryid)
+ {
base->martian++;
- crondlog(LVL7 "DBG: no match found for qry id i %d",\
-ntohs(dnsR->id));
+ crondlog(LVL7 "DBG: wrong id %d for qry", ntohs(dnsR->id));
return;
}
@@ -1150,46 +1152,50 @@ ntohs(dnsR->id));
return;
}
-static void ready_callback4 (int unused UNUSED_PARAM, const short event UNUSED_PARAM, void * arg)
+static void ready_callback (int unused UNUSED_PARAM, const short event UNUSED_PARAM, void * arg)
{
- struct tdig_base *base = arg;
+ struct query_state * qry;
int nrecv;
- struct sockaddr_in remote4; /* responding internet address */
- socklen_t slen;
struct timeval rectime;
+
+ printf("in ready_callback\n");
+
+ qry = arg;
- slen = sizeof(struct sockaddr);
- bzero(base->packet, MAX_DNS_BUF_SIZE);
+ bzero(qry->base->packet, MAX_DNS_BUF_SIZE);
/* Time the packet has been received */
gettimeofday(&rectime, NULL);
/* Receive data from the network */
- nrecv = recvfrom(base->rawfd_v4, base->packet, sizeof(base->packet), MSG_DONTWAIT, &remote4, &slen);
+ nrecv = recv(qry->udp_fd, qry->base->packet,
+ sizeof(qry->base->packet), MSG_DONTWAIT);
if (nrecv < 0) {
/* One more failure */
- base->recvfail++;
+ qry->base->recvfail++;
return ;
}
- process_reply(arg, nrecv, rectime, remote4.sin_family, &remote4);
+ process_reply(arg, nrecv, rectime);
return;
}
+#if 0
static void ready_callback6 (int unused UNUSED_PARAM, const short event UNUSED_PARAM, void * arg)
{
- struct tdig_base *base = arg;
+ struct query_state * qry;
int nrecv;
struct timeval rectime;
struct msghdr msg;
struct iovec iov[1];
//char buf[INET6_ADDRSTRLEN];
- struct sockaddr_in6 remote6;
char cmsgbuf[256];
+ qry= arg;
+
/* Time the packet has been received */
gettimeofday(&rectime, NULL);
- iov[0].iov_base= base->packet;
- iov[0].iov_len= sizeof(base->packet);
+ iov[0].iov_base= qry->base->packet;
+ iov[0].iov_len= sizeof(qry->base->packet);
msg.msg_name= &remote6;
msg.msg_namelen= sizeof( struct sockaddr_in6);
@@ -1199,16 +1205,17 @@ static void ready_callback6 (int unused UNUSED_PARAM, const short event UNUSED_P
msg.msg_controllen= sizeof(cmsgbuf);
msg.msg_flags= 0; /* Not really needed */
- nrecv= recvmsg(base->rawfd_v6, &msg, MSG_DONTWAIT);
+ nrecv= recvmsg(qry->udp_fd, &msg, MSG_DONTWAIT);
if (nrecv == -1) {
/* Strange, read error */
printf("ready_callback6: read error '%s'\n", strerror(errno));
return;
}
- process_reply(arg, nrecv, rectime, remote6.sin6_family, &remote6);
+ process_reply(arg, nrecv, rectime);
return;
}
+#endif
static bool argProcess (int argc, char *argv[], struct query_state *qry )
{
@@ -1284,9 +1291,11 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
qry->out_filename = NULL;
qry->opt_proto = 17;
qry->tcp_file = NULL;
+ qry->udp_fd = -1;
qry->tcp_fd = -1;
qry->server_name = NULL;
qry->str_Atlas = NULL;
+ qry->infname = NULL;
tdig_base->activeqry++;
qry->qst = STATUS_FREE;
qry->retry = 0;
@@ -1329,7 +1338,7 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
evtimer_assign(&qry->done_qry_timer, tdig_base->event_base, done_qry_cb, qry);
optind = 0;
- while (c= getopt_long(argc, argv, "46adD:e:tbhinqO:Rrs:A:?", longopts, NULL), c != -1) {
+ while (c= getopt_long(argc, argv, "46adD:e:tbhinqO:Rrs:A:I:?", longopts, NULL), c != -1) {
switch(c) {
case '4':
qry->opt_v4_only = 1;
@@ -1355,6 +1364,10 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
}
qry->str_Atlas = strdup(optarg);
break;
+ case 'I':
+ free(qry->infname);
+ qry->infname= strdup(optarg);
+ break;
case 'b':
qry->lookupname = strdup ("version.bind.");
break;
@@ -1702,36 +1715,11 @@ static void *tdig_init(int argc, char *argv[], void (*done)(void *state))
/* called only once. Initialize tdig_base variables here */
struct tdig_base * tdig_base_new(struct event_base *event_base)
{
- evutil_socket_t fd6;
- evutil_socket_t fd4;
- struct addrinfo hints;
- int on = 1;
struct timeval tv;
- bzero(&hints,sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_flags = 0;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = 0;
-
- /* Create an endpoint for communication using raw socket for ICMP calls */
- if ((fd4 = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol) ) < 0 )
- {
- return NULL;
- }
-
- hints.ai_family = AF_INET6;
- if ((fd6 = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol) ) < 0 )
- {
- close(fd4);
- return NULL;
- }
-
tdig_base= xzalloc(sizeof( struct tdig_base));
if (tdig_base == NULL)
{
- close(fd4);
- close(fd6);
return (NULL);
}
@@ -1751,33 +1739,16 @@ struct tdig_base * tdig_base_new(struct event_base *event_base)
memset(tdig_base, 0, sizeof(struct tdig_base));
tdig_base->event_base = event_base;
- tdig_base->rawfd_v4 = fd4;
- tdig_base->rawfd_v6 = fd6;
-
- setsockopt(fd6, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on));
-
- on = 1;
- setsockopt(fd6, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on, sizeof(on));
-
//memset(&tdig_base-->loc_sin6, '\0', sizeof(tdig_base-->loc_sin6));
//tdig_base-->loc_socklen= 0;
- evutil_make_socket_nonblocking(tdig_base->rawfd_v4);
+ evtimer_assign(&tdig_base->statsReportEvent, tdig_base->event_base, tdig_stats, tdig_base);
msecstotv(DEFAULT_NOREPLY_TIMEOUT, &tdig_base->tv_noreply);
// Define the callback to handle UDP Reply
// add the raw file descriptor to those monitored for read events
- event_assign(&tdig_base->event4, tdig_base->event_base, tdig_base->rawfd_v4,
- EV_READ | EV_PERSIST, ready_callback4, tdig_base);
- event_add(&tdig_base->event4, NULL);
-
- event_assign(&tdig_base->event6, tdig_base->event_base, tdig_base->rawfd_v6,
- EV_READ | EV_PERSIST, ready_callback6, tdig_base);
- event_add(&tdig_base->event6, NULL);
-
- evtimer_assign(&tdig_base->statsReportEvent, tdig_base->event_base, tdig_stats, tdig_base);
tv.tv_sec = DEFAULT_STATS_REPORT_INTERVEL;
tv.tv_usec = 0;
event_add(&tdig_base->statsReportEvent, &tv);
@@ -1785,7 +1756,9 @@ struct tdig_base * tdig_base_new(struct event_base *event_base)
return tdig_base;
}
-static void udp_dns_cb(int err, struct evutil_addrinfo *ev_res, struct query_state *qry) {
+static void udp_dns_cb(int err, struct evutil_addrinfo *ev_res, void *arg) {
+ struct query_state *qry;
+ qry= arg;
if (err) {
snprintf(line, DEFAULT_LINE_LENGTH, "\"evdns_getaddrinfo\": "
"\"%s %s\"", qry->server_name,
@@ -1803,16 +1776,19 @@ static void udp_dns_cb(int err, struct evutil_addrinfo *ev_res, struct query_sta
}
}
-void tdig_start (struct query_state *qry)
+void tdig_start (void *arg)
{
struct timeval asap = { 0, 0 };
struct timeval interval;
int err_num;
+ struct query_state *qry;
struct addrinfo hints, *res;
char port[] = "domain";
char port_as_char[] = "53";
+ qry= arg;
+
switch(qry->qst)
{
case STATUS_FREE :
@@ -1897,7 +1873,7 @@ void tdig_start (struct query_state *qry)
interval.tv_sec = CONN_TO;
interval.tv_usec= 0;
tu_connect_to_name (&qry->tu_env, qry->server_name, port_as_char,
- &interval, &hints, NULL,
+ &interval, &hints, qry->infname,
tcp_timeout_callback, tcp_reporterr,
tcp_dnscount, tcp_beforeconnect,
tcp_connected, tcp_readcb, tcp_writecb);
@@ -2048,6 +2024,13 @@ static void free_qry_inst(struct query_state *qry)
if(qry->opt_proto == 6)
tu_cleanup(&qry->tu_env);
+ if (qry->udp_fd != -1)
+ {
+ event_del(&qry->event);
+ close(qry->udp_fd);
+ qry->udp_fd= -1;
+ }
+
if ( qry->opt_resolv_conf) {
// this loop goes over servers in /etc/resolv.conf
// select the next server and restart
@@ -2096,6 +2079,11 @@ static int tdig_delete(void *state)
free(qry->lookupname);
qry->lookupname = NULL;
}
+ if(qry->infname)
+ {
+ free(qry->infname);
+ qry->infname = NULL;
+ }
/* Delete timers */
evtimer_del(&qry->noreply_timer);
@@ -2131,6 +2119,12 @@ static int tdig_delete(void *state)
free(qry->server_name);
qry->server_name = NULL;
}
+ if (qry->udp_fd != -1)
+ {
+ event_del(&qry->event);
+ close(qry->udp_fd);
+ qry->udp_fd= -1;
+ }
if(qry->base)
qry->base->activeqry--;
free(qry);
@@ -2374,7 +2368,7 @@ void printReply(struct query_state *qry, int wire_size, unsigned char *result)
reader-result,&stop);
JSDOT( RNAME, answers[i].rdata);
reader = reader + stop;
- serial = get32b(reader);
+ serial = get32b((char *)reader);
JU_NC(SERIAL, serial);
reader = reader + 4;
reader = reader + 16; // skip REFRESH, RETRY, EXIPIRE, and MINIMUM
@@ -2470,7 +2464,7 @@ unsigned char* ReadName(unsigned char *base, size_t size, size_t offset,
if ((len & 0xc0) != 0xc0)
{
/* Bad format */
- strcpy(name, "format-error");
+ strcpy((char *)name, "format-error");
printf("format-error: len = %d\n",
len);
abort();
@@ -2480,7 +2474,7 @@ unsigned char* ReadName(unsigned char *base, size_t size, size_t offset,
offset= ((len & ~0xc0) << 8) | base[offset+1];
if (offset >= size)
{
- strcpy(name, "offset-error");
+ strcpy((char *)name, "offset-error");
printf("offset-error\n");
abort();
return name;
@@ -2497,7 +2491,7 @@ unsigned char* ReadName(unsigned char *base, size_t size, size_t offset,
}
if (offset+len+1 > size)
{
- strcpy(name, "buf-bounds-error");
+ strcpy((char *)name, "buf-bounds-error");
printf("buf-bounds-error\n");
abort();
return name;
@@ -2505,7 +2499,7 @@ unsigned char* ReadName(unsigned char *base, size_t size, size_t offset,
if (p+len+1 > 255)
{
- strcpy(name, "name-length-error");
+ strcpy((char *)name, "name-length-error");
printf("name-length-error\n");
abort();
return name;
diff --git a/eperd/httpget.c b/eperd/httpget.c
index 4b22bca..1a8fe09 100644
--- a/eperd/httpget.c
+++ b/eperd/httpget.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* httpget.c -- libevent-based version of httpget
*/
@@ -627,7 +627,7 @@ static void *httpget_init(int __attribute((unused)) argc, char *argv[],
state->max_body= max_body;
state->read_limit= read_limit;
state->timeout= timeout;
- state->infname= infname;
+ state->infname= infname ? strdup(infname) : NULL;
state->only_v4= 2;
@@ -744,12 +744,16 @@ static void report(struct hgstate *state)
if (state->read_truncated)
add_str(state, ", " DBQ(read-truncated) ": True");
- getnameinfo((struct sockaddr *)&state->sin6, state->socklen,
- namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
+ if (state->socklen != 0)
+ {
+ getnameinfo((struct sockaddr *)&state->sin6,
+ state->socklen, namebuf, sizeof(namebuf),
+ NULL, 0, NI_NUMERICHOST);
- snprintf(line, sizeof(line), ", " DBQ(dst_addr) ":" DBQ(%s),
- namebuf);
- add_str(state, line);
+ snprintf(line, sizeof(line),
+ ", " DBQ(dst_addr) ":" DBQ(%s), namebuf);
+ add_str(state, line);
+ }
/* End of readtiming */
if (state->etim >= 2)
@@ -1627,7 +1631,7 @@ static void writecb(struct bufferevent *bev, void *ptr)
state->do_head ? "HEAD" : "POST", state->path,
state->do_http10 ? '0' : '1');
evbuffer_add_printf(output, "Host: %s\r\n",
- state->host);
+ state->hostport);
evbuffer_add_printf(output, "Connection: close\r\n");
evbuffer_add_printf(output, "User-Agent: %s\r\n",
state->user_agent);
@@ -1940,6 +1944,8 @@ static int httpget_delete(void *state)
hgstate->atlas= NULL;
free(hgstate->output_file);
hgstate->output_file= NULL;
+ free(hgstate->infname);
+ hgstate->infname= NULL;
free(hgstate->host);
hgstate->host= NULL;
free(hgstate->hostport);
diff --git a/eperd/ntp.c b/eperd/ntp.c
index 251510d..457f34a 100644
--- a/eperd/ntp.c
+++ b/eperd/ntp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* traceroute.c
*/
@@ -342,12 +342,16 @@ static void report(struct ntpstate *state)
fprintf(fh, ", " DBQ(dst_addr) ":" DBQ(%s), namebuf);
- namebuf[0]= '\0';
- getnameinfo((struct sockaddr *)&state->loc_sin6,
- state->loc_socklen,
- namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
+ if (state->loc_socklen != 0)
+ {
+ namebuf[0]= '\0';
+ getnameinfo((struct sockaddr *)&state->loc_sin6,
+ state->loc_socklen,
+ namebuf, sizeof(namebuf), NULL, 0,
+ NI_NUMERICHOST);
- fprintf(fh, ", " DBQ(src_addr) ":" DBQ(%s), namebuf);
+ fprintf(fh, ", " DBQ(src_addr) ":" DBQ(%s), namebuf);
+ }
}
proto= "UDP";
@@ -1655,7 +1659,7 @@ static void *ntp_init(int __attribute((unused)) argc, char *argv[],
state= xzalloc(sizeof(*state));
state->count= count;
- state->interface= interface;
+ state->interface= interface ? strdup(interface) : NULL;
state->destportstr= strdup(destportstr);
state->timeout= timeout*1000;
state->atlas= str_Atlas ? strdup(str_Atlas) : NULL;
@@ -1764,7 +1768,7 @@ static int create_socket(struct ntpstate *state)
serrno= errno;
snprintf(line, sizeof(line),
- ", " DBQ(error) ":" DBQ(socket failed: %s) " }",
+ "{ " DBQ(error) ":" DBQ(socket failed: %s) " }",
strerror(serrno));
add_str(state, line);
report(state);
@@ -1777,7 +1781,7 @@ static int create_socket(struct ntpstate *state)
af, state->interface) == -1)
{
snprintf(line, sizeof(line),
- ", " DBQ(error) ":" DBQ(bind_interface failed) " }");
+ "{ " DBQ(error) ":" DBQ(bind_interface failed) " }");
add_str(state, line);
report(state);
return -1;
@@ -1945,6 +1949,8 @@ static int ntp_delete(void *state)
ntpstate->destportstr= NULL;
free(ntpstate->out_filename);
ntpstate->out_filename= NULL;
+ free(ntpstate->interface);
+ ntpstate->interface= NULL;
free(ntpstate);
diff --git a/eperd/ping.c b/eperd/ping.c
index 834b9dc..8d0866d 100644
--- a/eperd/ping.c
+++ b/eperd/ping.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Copyright (c) 2009 Rocco Carbone
* This includes code Copyright (c) 2009 Rocco Carbone
* taken from the libevent-based ping.
@@ -222,14 +222,12 @@ static void report(struct pingstate *state)
if (!state->no_dst)
{
+ namebuf[0]= '\0';
getnameinfo((struct sockaddr *)&state->sin6, state->socklen,
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
fprintf(fh, ", " DBQ(dst_addr) ":" DBQ(%s), namebuf);
- }
- if (state->got_reply)
- {
namebuf[0]= '\0';
getnameinfo((struct sockaddr *)&state->loc_sin6,
state->loc_socklen, namebuf, sizeof(namebuf),
@@ -322,7 +320,7 @@ static void ping_cb(int result, int bytes, int psize,
usecs/1000.);
add_str(pingstate, line);
- if (!pingstate->got_reply)
+ if (!pingstate->got_reply && result != PING_ERR_DUP)
{
memcpy(&pingstate->loc_sin6, loc_sa, loc_socklen);
pingstate->loc_socklen= loc_socklen;
@@ -355,7 +353,7 @@ static void ping_cb(int result, int bytes, int psize,
}
namebuf1[0]= '\0';
getnameinfo((struct sockaddr *)&pingstate->loc_sin6,
- loc_socklen, namebuf1,
+ pingstate->loc_socklen, namebuf1,
sizeof(namebuf1), NULL, 0, NI_NUMERICHOST);
namebuf2[0]= '\0';
getnameinfo(loc_sa, loc_socklen, namebuf2,
@@ -368,7 +366,7 @@ static void ping_cb(int result, int bytes, int psize,
printf("loc_sa: %s\n", namebuf2);
snprintf(line, sizeof(line),
- ", " DBQ(srcaddr) ":" DBQ(%s), namebuf2);
+ ", " DBQ(src_addr) ":" DBQ(%s), namebuf2);
add_str(pingstate, line);
}
@@ -392,18 +390,6 @@ static void ping_cb(int result, int bytes, int psize,
}
if (result == PING_ERR_TIMEOUT || result == PING_ERR_SENDTO)
{
- if (pingstate->first && pingstate->loc_socklen != 0)
- {
- namebuf1[0]= '\0';
- getnameinfo((struct sockaddr *)&pingstate->loc_sin6,
- pingstate->loc_socklen,
- namebuf1, sizeof(namebuf1),
- NULL, 0, NI_NUMERICHOST);
-
- snprintf(line, sizeof(line),
- ", " DBQ(srcaddr) ":" DBQ(%s), namebuf1);
- add_str(pingstate, line);
- }
add_str(pingstate, " }");
pingstate->first= 0;
}
@@ -556,9 +542,8 @@ static void fmticmp6(u_char *buffer, size_t *sizep,
static void ping_xmit(struct pingstate *host)
{
struct pingbase *base = host->base;
- struct timeval tv_interval;
-
int nsent;
+ struct timeval tv_interval;
if (host->sentpkts >= host->maxpkts)
{
@@ -691,7 +676,6 @@ static void ready_callback4 (int __attribute((unused)) unused,
/* Time the packet has been received */
gettimeofday(&now, NULL);
-// printf("ready_callback4: before recvfrom\n");
/* Receive data from the network */
nrecv = recvfrom(state->socket, base->packet, sizeof(base->packet), MSG_DONTWAIT, (struct sockaddr *) &remote, &slen);
if (nrecv < 0)
@@ -781,11 +765,13 @@ printf("ready_callback4: too short\n");
ntohs(icmp->un.echo.sequence), ip->ip_ttl, &elapsed,
state);
- /* Update the sequence number for the next run */
- state->seq = (state->seq + 1) % 256;
-
if (!isDup)
+ {
state->got_reply= 1;
+
+ /* Update the sequence number for the next run */
+ state->seq = (state->seq + 1) % 256;
+ }
}
else
{
@@ -884,8 +870,12 @@ static void ready_callback6 (int __attribute((unused)) unused,
}
/* Check for Destination Host Unreachable */
- if (icmp->icmp6_type == ICMP6_ECHO_REPLY)
- {
+ if (icmp->icmp6_type == ICMP6_ECHO_REQUEST)
+ {
+ /* Completely ignore echo requests */
+ }
+ 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 */
@@ -931,7 +921,7 @@ static void ready_callback6 (int __attribute((unused)) unused,
if (!isDup)
state->got_reply= 1;
- }
+ }
else
/* Handle this condition exactly as the request has expired */
noreply_callback (-1, -1, state);
@@ -1230,6 +1220,10 @@ static void ping_start2(void *state)
return;
}
+ pingstate->loc_socklen= sizeof(pingstate->loc_sin6);
+ getsockname(pingstate->socket, &pingstate->loc_sin6,
+ &pingstate->loc_socklen);
+
event_add(&pingstate->event, NULL);
ping_xmit(pingstate);
diff --git a/eperd/readresolv.c b/eperd/readresolv.c
index 0f68a37..9d04866 100644
--- a/eperd/readresolv.c
+++ b/eperd/readresolv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
diff --git a/eperd/readresolv.h b/eperd/readresolv.h
index b418d71..a71fd4a 100644
--- a/eperd/readresolv.h
+++ b/eperd/readresolv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
void get_local_resolvers(char nslist[MAXNS][INET6_ADDRSTRLEN * 2], int *resolv_max);
diff --git a/eperd/sslgetcert.c b/eperd/sslgetcert.c
index 0a0f885..d00bf7a 100644
--- a/eperd/sslgetcert.c
+++ b/eperd/sslgetcert.c
@@ -1,6 +1,6 @@
/*
sslgetcert.c -- libevent-based version of sslgetcert
-
+Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
Created: April 2013 by Philip Homburg for RIPE NCC
*/
@@ -73,6 +73,7 @@ struct state
/* Parameters */
char *output_file;
char *atlas;
+ char *infname;
char only_v4;
char only_v6;
@@ -602,7 +603,7 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[],
{
int c, i, only_v4, only_v6;
size_t newsiz;
- char *hostname, *str_port;
+ char *hostname, *str_port, *infname;
char *output_file, *A_arg;
struct state *state;
FILE *fh;
@@ -610,6 +611,7 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[],
/* Arguments */
output_file= NULL;
A_arg= NULL;
+ infname= NULL;
str_port= NULL;
only_v4= 0;
only_v6= 0;
@@ -624,7 +626,7 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[],
/* Allow us to be called directly by another program in busybox */
optind= 0;
- while (c= getopt_long(argc, argv, "A:O:p:46", longopts, NULL), c != -1)
+ while (c= getopt_long(argc, argv, "A:O:i:p:46", longopts, NULL), c != -1)
{
switch(c)
{
@@ -634,6 +636,9 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[],
case 'O':
output_file= optarg;
break;
+ case 'i':
+ infname= optarg;
+ break;
case 'p':
str_port= optarg;
break;
@@ -688,6 +693,7 @@ static void *sslgetcert_init(int __attribute((unused)) argc, char *argv[],
state->base= hg_base;
state->atlas= A_arg ? strdup(A_arg) : NULL;
state->output_file= output_file ? strdup(output_file) : NULL;
+ state->infname= infname ? strdup(infname) : NULL;
state->hostname= strdup(hostname);
if (str_port)
state->portname= strdup(str_port);
@@ -1192,6 +1198,13 @@ static void reporterr(struct tu_env *env, enum tu_err cause,
err_reading(state);
break;
+ case TU_SOCKET_ERR:
+ snprintf(line, sizeof(line),
+ DBQ(sockerr) ":" DBQ(%s), str);
+ add_str(state, line);
+ report(state);
+ break;
+
case TU_CONNECT_ERR:
snprintf(line, sizeof(line),
DBQ(err) ":" DBQ(connect: %s), str);
@@ -1263,7 +1276,7 @@ static void sslgetcert_start(void *vstate)
tu_connect_to_name(&state->tu_env, state->hostname,
state->portname,
- &interval, &hints, NULL, timeout_callback,
+ &interval, &hints, state->infname, timeout_callback,
reporterr, dnscount, beforeconnect,
connected, readcb, writecb);
}
@@ -1302,6 +1315,8 @@ static int sslgetcert_delete(void *vstate)
state->hostname= NULL;
free(state->portname);
state->portname= NULL;
+ free(state->infname);
+ state->infname= NULL;
free(state);
diff --git a/eperd/tcputil.c b/eperd/tcputil.c
index 355f42a..201f1eb 100644
--- a/eperd/tcputil.c
+++ b/eperd/tcputil.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* tcputil.c
*/
@@ -54,24 +54,8 @@ void tu_restart_connect(struct tu_env *env)
int r;
struct bufferevent *bev;
- /* Delete old bev */
- if (env->bev)
- {
- bufferevent_free(env->bev);
- env->bev= NULL;
- }
-
- /* And create a new one */
- r= create_bev(env);
- if (r == -1)
- {
- return;
- }
- bev= env->bev;
-
/* Connect failed, try next address */
- if (env->dns_curr)
- /* Just to be on the safe side */
+ if (env->dns_curr) /* Just to be on the safe side */
{
env->dns_curr= env->dns_curr->ai_next;
}
@@ -81,6 +65,22 @@ void tu_restart_connect(struct tu_env *env)
env->beforeconnect(env,
env->dns_curr->ai_addr, env->dns_curr->ai_addrlen);
+
+ /* Delete old bev */
+ if (env->bev)
+ {
+ bufferevent_free(env->bev);
+ env->bev= NULL;
+ }
+
+ /* And create a new one */
+ r= create_bev(env);
+ if (r == -1)
+ {
+ return;
+ }
+ bev= env->bev;
+
if (bufferevent_socket_connect(bev,
env->dns_curr->ai_addr,
env->dns_curr->ai_addrlen) == 0)
@@ -158,18 +158,27 @@ static void dns_cb(int result, struct evutil_addrinfo *res, void *ctx)
env->reportcount(env, count);
- r= create_bev(env);
- if (r == -1)
- {
- return;
- }
-
while (env->dns_curr)
{
evtimer_add(&env->timer, &env->interval);
env->beforeconnect(env,
env->dns_curr->ai_addr, env->dns_curr->ai_addrlen);
+
+ /* Delete old bev if any */
+ if (env->bev)
+ {
+ bufferevent_free(env->bev);
+ env->bev= NULL;
+ }
+
+ /* And create a new one */
+ r= create_bev(env);
+ if (r == -1)
+ {
+ return;
+ }
+
bev= env->bev;
if (bufferevent_socket_connect(bev,
env->dns_curr->ai_addr,
diff --git a/eperd/tcputil.h b/eperd/tcputil.h
index da26641..1264299 100644
--- a/eperd/tcputil.h
+++ b/eperd/tcputil.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* tcputil.h
*/
diff --git a/eperd/traceroute.c b/eperd/traceroute.c
index ee0489b..06f6ac1 100644
--- a/eperd/traceroute.c
+++ b/eperd/traceroute.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* traceroute.c
*/
diff --git a/include/cmdtable.h b/include/cmdtable.h
index b50d12e..ee84b3a 100644
--- a/include/cmdtable.h
+++ b/include/cmdtable.h
@@ -5,9 +5,17 @@ Commands for perd and ooqd
*/
int condmv_main(int argc, char *argv[]);
-int httpget_main(int argc, char *argv[]);
int httppost_main(int argc, char *argv[]);
+#if 0
+int httpget_main(int argc, char *argv[]);
+int nslookup_main(int argc, char *argv[]);
+int ping6_main(int argc, char *argv[]);
+int ping_main(int argc, char *argv[]);
int sslgetcert_main(int argc, char *argv[]);
+int tdig_main(int argc, char *argv[]);
+int traceroute_main(int argc, char *argv[]);
+int wifimsm_main(int argc, char *argv[]);
+#endif
static struct builtin
{
@@ -17,7 +25,12 @@ static struct builtin
{
{ "condmv", condmv_main },
{ "httppost", httppost_main },
+#if 0
+ { "ping6", ping6_main },
+ { "ping", ping_main },
{ "sslgetcert", sslgetcert_main },
+ { "traceroute", traceroute_main },
+ { "wifimsm", wifimsm_main },
+#endif
{ NULL, 0 }
};
-
diff --git a/libbb/atlas_timesync.c b/libbb/atlas_timesync.c
index 3434493..a47ab7f 100644
--- a/libbb/atlas_timesync.c
+++ b/libbb/atlas_timesync.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
diff --git a/miscutils/ooqd.c b/miscutils/ooqd.c
new file mode 100644
index 0000000..4317e05
--- /dev/null
+++ b/miscutils/ooqd.c
@@ -0,0 +1,363 @@
+/*
+ * ooqd.c One-off queue daemon
+ * Copyright (c) 2011-2014 RIPE NCC <atlas@ripe.net>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <libbb.h>
+#include <cmdtable.h>
+
+#define SUFFIX ".curr"
+#define WAIT_TIME 10 /* in seconds */
+#define NARGS 40 /* Max arguments to a built-in command */
+#define WIFIMSM_PATH "/home/atlas/bin/wifimsm"
+
+#define SAFE_PREFIX ATLAS_DATA_NEW
+
+#ifdef __uClinux__
+#define NO_FORK 1
+#endif
+
+static void process(FILE *file);
+static void report(const char *fmt, ...);
+static void report_err(const char *fmt, ...);
+
+int ooqd_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE;
+int ooqd_main(int argc, char *argv[])
+{
+ char *queue_file;
+ FILE *file;
+ char curr_qfile[256];
+
+ if (argc != 2)
+ {
+ bb_show_usage();
+ return 1;
+ }
+
+ queue_file= argv[1];
+
+ if (strlen(queue_file) + strlen(SUFFIX) + 1 > sizeof(curr_qfile))
+ {
+ report("filename too long ('%s')", queue_file);
+ return 1;
+ }
+
+ strlcpy(curr_qfile, queue_file, sizeof(curr_qfile));
+ strlcat(curr_qfile, SUFFIX, sizeof(curr_qfile));
+
+ for(;;)
+ {
+ /* Try to move queue_file to curr_qfile. This provide at most
+ * once behavior and allows producers to create a new
+ * queue_file while we process the old one.
+ */
+ if (rename(queue_file, curr_qfile) == -1)
+ {
+ if (errno == ENOENT)
+ {
+ sleep(WAIT_TIME);
+ continue;
+ }
+ report_err("rename failed");
+ return 1;
+ }
+
+ file= fopen(curr_qfile, "r");
+ if (file == NULL)
+ {
+ report_err("open '%s' failed", curr_qfile);
+ continue;
+ }
+
+ process(file);
+
+ fclose(file);
+
+ /* No need to delete curr_qfile */
+ }
+ return 0;
+}
+
+static void skip_space(char *cp, char **ncpp)
+{
+ while (cp[0] != '\0' && isspace(*(unsigned char *)cp))
+ cp++;
+ *ncpp= cp;
+}
+
+static void skip_nonspace(char *cp, char **ncpp)
+{
+ while (cp[0] != '\0' && !isspace(*(unsigned char *)cp))
+ cp++;
+ *ncpp= cp;
+}
+
+static void find_eos(char *cp, char **ncpp)
+{
+ while (cp[0] != '\0' && cp[0] != '"')
+ cp++;
+ *ncpp= cp;
+}
+
+static void process(FILE *file)
+{
+ int i, argc, do_append, saved_fd, out_fd, flags;
+ size_t len;
+ char *cp, *ncp, *outfile;
+ struct builtin *bp;
+ char line[2048];
+ char *argv[NARGS];
+
+printf("in process\n");
+ while (cp= fgets(line, sizeof(line), file), cp != NULL)
+ {
+printf("got cp %p, line %p, '%s'\n", cp, line, cp);
+ if (strchr(line, '\n') == NULL)
+ {
+ report("line '%s' too long", line);
+ return;
+ }
+
+ /* Skip leading white space */
+ cp= line;
+ while (cp[0] != '\0' && isspace((unsigned char)cp[0]))
+ cp++;
+
+ if (cp[0] == '\0' || cp[0] == '#')
+ continue; /* Empty or comment line */
+
+ for (bp= builtin_cmds; bp->cmd != NULL; bp++)
+ {
+ len= strlen(bp->cmd);
+ if (strncmp(cp, bp->cmd, len) != 0)
+ continue;
+ if (cp[len] != ' ')
+ continue;
+ break;
+ }
+ if (bp->cmd == NULL)
+ {
+ report("nothing found for '%s'", cp);
+ return; /* Nothing found */
+ }
+
+ /* Remove trailing white space */
+ len= strlen(cp);
+ while (len > 0 && isspace((unsigned char)cp[len-1]))
+ {
+ cp[len-1]= '\0';
+ len--;
+ }
+
+ outfile= NULL;
+ do_append= 0;
+
+ /* Split the command line */
+ argc= 0;
+ argv[argc]= cp;
+ skip_nonspace(cp, &ncp);
+ cp= ncp;
+
+ for(;;)
+ {
+ /* End of list */
+ if (cp[0] == '\0')
+ {
+ argc++;
+ break;
+ }
+
+ /* Find start of next argument */
+ skip_space(cp, &ncp);
+
+ /* Terminate current one */
+ cp[0]= '\0';
+
+ /* Special case for '>' */
+ if (argv[argc][0] == '>')
+ {
+ cp= argv[argc]+1;
+ if (cp[0] == '>')
+ {
+ /* Append */
+ do_append= 1;
+ cp++;
+ }
+ if (cp[0] != '\0')
+ {
+ /* Filename immediately follows '>' */
+ outfile= cp;
+
+ /* And move on with the next option */
+ }
+ else
+ {
+ /* Get the next argument */
+ outfile= ncp;
+ cp= ncp;
+ skip_nonspace(cp, &ncp);
+ cp= ncp;
+
+ if (cp[0] == '\0')
+ break;
+
+ /* Find start of next argument */
+ skip_space(cp, &ncp);
+ *cp= '\0';
+
+ if (ncp[0] == '\0')
+ break; /* No more arguments */
+ }
+ }
+ else
+ {
+ argc++;
+ }
+
+ if (argc >= NARGS-1)
+ {
+ report("command line '%s', too many arguments",
+ line);
+ continue; /* Just skip it */
+ }
+
+ cp= ncp;
+ argv[argc]= cp;
+ if (cp[0] == '"')
+ {
+ /* Special code for strings */
+ find_eos(cp+1, &ncp);
+ if (ncp[0] != '"')
+ {
+ report(
+ "command line '%s', end of string not found",
+ line);
+ continue; /* Just skip it */
+ }
+ argv[argc]= cp+1;
+ cp= ncp;
+ cp[0]= '\0';
+ cp++;
+ }
+ else
+ {
+ skip_nonspace(cp, &ncp);
+ cp= ncp;
+ }
+ }
+
+ if (argc >= NARGS)
+ {
+ report("command line '%s', too many arguments", line);
+ return;
+ }
+ argv[argc]= NULL;
+
+ for (i= 0; i<argc; i++)
+ report("argv[%d] = '%s'", i, argv[i]);
+
+ saved_fd= -1; /* lint */
+ if (outfile)
+ {
+ /* Redirect I/O */
+ report("sending output to '%s'", outfile);
+ if (!validate_filename(outfile, SAFE_PREFIX))
+ {
+ report("insecure output file '%s'", outfile);
+ return;
+ }
+ flags= O_CREAT | O_WRONLY;
+ if (do_append)
+ flags |= O_APPEND;
+ out_fd= open(outfile, flags, 0644);
+ if (out_fd == -1)
+ {
+ report_err("unable to create output file '%s'",
+ outfile);
+ return;
+ }
+ fflush(stdout);
+ saved_fd= dup(1);
+ if (saved_fd == -1)
+ {
+ report("unable to dub stdout");
+ close(out_fd);
+ return;
+ }
+ dup2(out_fd, 1);
+ close(out_fd);
+ }
+
+ bp->func(argc, argv);
+
+ if (outfile)
+ {
+ fflush(stdout);
+ dup2(saved_fd, 1);
+ close(saved_fd);
+ }
+ }
+}
+
+static void report(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "ooqd: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+
+ va_end(ap);
+}
+
+static void report_err(const char *fmt, ...)
+{
+ int terrno;
+ va_list ap;
+
+ terrno= errno;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "ooqd: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ": %s\n", strerror(terrno));
+
+ va_end(ap);
+}
+
+int wifimsm_main(int argc UNUSED_PARAM, char *argv[])
+{
+#if NO_FORK
+ return 1;
+#else
+ pid_t pid;
+ int r, status;
+
+ pid= fork();
+ if (pid == -1)
+ {
+ report_err("wifimsm_main: fork failed");
+ return 1;
+ }
+ if (pid)
+ {
+ r= waitpid(pid, &status, 0);
+ if (r == -1)
+ {
+ report_err("wifimsm_main: waitpid failed");
+ return 1;
+ }
+ if (WIFEXITED(status))
+ return WEXITSTATUS(status);
+ return 1;
+ }
+
+ execv(WIFIMSM_PATH, argv);
+ report_err("wifimsm_main: execv '%s' failed", WIFIMSM_PATH);
+ return 1;
+#endif
+}
diff --git a/miscutils/perd.c b/miscutils/perd.c
index 3a7b496..95707f9 100644
--- a/miscutils/perd.c
+++ b/miscutils/perd.c
@@ -7,6 +7,7 @@
* run as root, but NOT setuid root
*
* Copyright 1994 Matthew Dillon (dillon@apollo.west.oic.com)
+ * Copyright (c) 2014 RIPE NCC <atlas@ripe.net>
* (version 2.3.2)
* Vladimir Oleynik <dzo@simtreas.ru> (C) 2002
*
@@ -1174,8 +1175,8 @@ static void find_eos(char *cp, char **ncpp)
}
-#define ATLAS_NARGS 20 /* Max arguments to a built-in command */
-#define ATLAS_ARGSIZE 512 /* Max size of the command line */
+#define ATLAS_NARGS 40 /* Max arguments to a built-in command */
+#define ATLAS_ARGSIZE 4096 /* Max size of the command line */
static int atlas_run(char *cmdline)
{
diff --git a/networking/httppost.c b/networking/httppost.c
index 24f1430..03cd72c 100644
--- a/networking/httppost.c
+++ b/networking/httppost.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2011-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
* httppost.c -- Simple program that uses the HTTP POST command
*/
diff --git a/networking/rptaddrs.c b/networking/rptaddrs.c
index 1115559..3285d36 100644
--- a/networking/rptaddrs.c
+++ b/networking/rptaddrs.c
@@ -1,6 +1,6 @@
/*
* rptaddrs.c
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
@@ -25,7 +25,7 @@
#define IPV4_STATIC ATLAS_STATUS "/network_v4_static_info.json"
#define IPV6_STATIC ATLAS_STATUS "/network_v6_static_info.json"
#define DNS_STATIC ATLAS_STATUS "/network_dns_static_info.json"
-#define NETWORK_INFO ATLAS_STATUS "/network_info.txt"
+#define NETWORK_INFO ATLAS_STATUS "/network_v4_info.txt"
#define SAFE_PREFIX_N ATLAS_DATA_NEW
@@ -63,7 +63,9 @@ static int rpt_ipv6(char *cache_name, char *out_name, char *opt_atlas, int opt_a
static void report(const char *fmt, ...);
static void report_err(const char *fmt, ...);
-int rptaddrs_main(int argc, char *argv[])
+int rptaddrs_main(int argc, char *argv[]);
+
+int rptaddrs_main(int argc UNUSED_PARAM, char *argv[])
{
int r, need_report;
unsigned opt;
@@ -277,7 +279,7 @@ static int setup_dhcpv4(FILE *of)
{
int found;
FILE *in_file;
- char *value;
+ const char *value;
char line[128];
in_file= fopen(NETWORK_INFO, "r");
@@ -452,6 +454,9 @@ static int setup_ipv6_rpt(FILE *of)
continue;
}
+ if (prefix_len == 128)
+ continue; /* Skip host routes */
+
snprintf(dst6in, sizeof(dst6in), "%s:%s:%s:%s:%s:%s:%s:%s",
dst6p[0], dst6p[1], dst6p[2], dst6p[3],
dst6p[4], dst6p[5], dst6p[6], dst6p[7]);
@@ -575,7 +580,7 @@ static int report_line(FILE *of, const char *fn)
{
FILE *f;
char *nl;
- char line[256];
+ char line[512];
f= fopen(fn, "r");
if (f == NULL)
@@ -616,6 +621,7 @@ static int report_line(FILE *of, const char *fn)
static int check_cache(char *cache_name)
{
int r, need_report;
+ struct stat sb;
char filename[80];
char buf1[1024];
@@ -627,6 +633,17 @@ static int check_cache(char *cache_name)
need_report= 0;
+ if (stat(cache_name, &sb) == 0 &&
+ sb.st_mtime < time(NULL) - 30 * 24 * 3600)
+ {
+ /* This basically makes sure that this information gets
+ * reported again when the clock is set for the first time.
+ * A side effect is that it gets reported once a month if
+ * nothing changes.
+ */
+ need_report= 1;
+ }
+
/* Now check if the new file is different from the cache one */
cache_file= fopen(cache_name, "r");
if (cache_file == NULL)
diff --git a/networking/rptra6.c b/networking/rptra6.c
index b481252..9499125 100644
--- a/networking/rptra6.c
+++ b/networking/rptra6.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Copyright (c) 2013-2014 RIPE NCC <atlas@ripe.net>
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
#include "libbb.h"
diff --git a/networking/sslgetcert.c b/networking/sslgetcert.c
index a443b32..f6378c7 100644
--- a/networking/sslgetcert.c
+++ b/networking/sslgetcert.c
@@ -1,4 +1,6 @@
-/* Simple SSL client to get server certificates */
+/* Simple SSL client to get server certificates
+ * Copyright (c) 2014 RIPE NCC <atlas@ripe.net>
+ */
#include "libbb.h"
diff --git a/networking/telnetd.c b/networking/telnetd.c
index 778156c..f7fe1db 100644
--- a/networking/telnetd.c
+++ b/networking/telnetd.c
@@ -2,6 +2,7 @@
/*
* Simple telnet server
* Bjorn Wesen, Axis Communications AB (bjornw@axis.com)
+ * Copyright (c) 2014 RIPE NCC <atlas@ripe.net>
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*
@@ -102,8 +103,8 @@ struct tsession {
};
/* Two buffers are directly after tsession in malloced memory.
- * Make whole thing fit in 4k */
-enum { BUFSIZE = (4 * 1024 - sizeof(struct tsession)) / 2 };
+ * Make whole thing fit in 8k */
+enum { BUFSIZE = (8 * 1024 - sizeof(struct tsession)) / 2 };
#ifdef ATLAS
static int equal_sessionid(char *passwd);