int probes = DEFAULT_PROBES;
int timeout_ms = DEFAULT_TIMEOUT_MS;
int interval_ms = DEFAULT_INTERVAL_MS;
+ int period_ms = DEFAULT_PERIOD_MS;
- while ((opt = getopt(argc, argv, "hv46m:c:t:i:")) != -1) {
+ while ((opt = getopt(argc, argv, "hv46m:c:t:i:p:")) != -1) {
switch (opt) {
case 'h':
usage(argv[0]);
case 'i':
interval_ms = atoi(optarg);
break;
+ case 'p':
+ period_ms = atoi(optarg);
+ break;
case '?':
- if(optopt == 'm' || optopt == 'c' || optopt == 'i') {
+ if(optopt == 'm' || optopt == 'c' || optopt == 'i' || optopt == 'p') {
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
} else {
fprintf(stderr, "Unknown option '-%c'\n", optopt);
printf("Probes: %d\n", probes);
printf("Timeout: %d ms\n", timeout_ms);
printf("Interval: %d ms\n", interval_ms);
+ printf("Period: %d ms\n", period_ms);
printf("--------------\n");
#endif /* DEBUG || _DEBUG */
// Initialization of all sessions
for (int i = 0; i < num_hosts; i++) {
- session_init(&sessions[i], argv[optind + i], max_hops, probes, timeout_ms, interval_ms, i);
+ session_init(&sessions[i], argv[optind + i], max_hops, probes, timeout_ms, interval_ms, period_ms, i);
}
// Main loop (event loop)
process_timeout_check(s);
}
- // B2) Interval wait between probes
+ // B2) Period wait between probes within the same hop
+ if (s->state == STATE_PERIOD_WAIT) {
+ process_period_check(s);
+ }
+
+ // B3) Interval wait between hops
if (s->state == STATE_INTERVAL_WAIT) {
process_interval_check(s);
}
* Functions
*/
-void session_init(trace_session_t *s, char *host, int mh, int pp, int tm, int im, int idx) {
+void session_init(trace_session_t *s, char *host, int mh, int pp, int tm, int im, int pm, int idx) {
s->host_arg = host;
s->max_hops = mh;
s->probes_per_hop = pp;
s->timeout_ms = tm;
s->interval_ms = im;
+ s->period_ms = pm;
s->current_ttl = 0;
s->reached_dest = false;
s->ident = (getpid() & 0xFFFF) + idx; // Unique ID per session
if (s->reached_dest) {
s->state = STATE_FINISHED;
session_close(s);
+ } else if (s->interval_ms > 0) {
+ gettimeofday(&s->t_interval, NULL);
+ s->state = STATE_INTERVAL_WAIT;
} else {
s->state = STATE_PREPARE_HOP;
}
if (elapsed > s->timeout_ms) {
s->line_off += snprintf(s->line_buf + s->line_off, sizeof(s->line_buf) - s->line_off, "* ");
s->current_probe++;
- if (s->interval_ms > 0) {
- gettimeofday(&s->t_interval, NULL);
- s->state = STATE_INTERVAL_WAIT;
+ if (s->period_ms > 0) {
+ gettimeofday(&s->t_period, NULL);
+ s->state = STATE_PERIOD_WAIT;
} else {
s->state = STATE_SEND_PROBE;
}
}
}
+void process_period_check(trace_session_t *s) {
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ double elapsed = ms_between(s->t_period, now);
+ if (elapsed >= s->period_ms) {
+ s->state = STATE_SEND_PROBE;
+ }
+}
+
void process_read(trace_session_t *s) {
unsigned char recvbuf[PACKET_SIZE];
struct sockaddr_storage reply_addr;
if (is_final) s->reached_dest = true;
- // Test successful -> Next test
+ // Test successful -> Next probe (with optional period between probes within hop)
s->current_probe++;
- if (s->interval_ms > 0) {
- gettimeofday(&s->t_interval, NULL);
- s->state = STATE_INTERVAL_WAIT;
+ if (s->period_ms > 0) {
+ gettimeofday(&s->t_period, NULL);
+ s->state = STATE_PERIOD_WAIT;
} else {
s->state = STATE_SEND_PROBE;
}
printf(" -m <value> Set max hops\n");
printf(" -c <value> Set probe count\n");
printf(" -t <value> Set timeout in ms\n");
- printf(" -i <value> Set interval between probes in ms\n");
+ printf(" -i <value> Set interval between hops in ms\n");
+ printf(" -p <value> Set interval between probes within a hop in ms\n");
}
\ No newline at end of file
#include <netinet/in.h>
#define DEFAULT_INTERVAL_MS 0
-
-
+#define DEFAULT_PERIOD_MS 0
/* State definition for a session */
typedef enum {
STATE_SEND_PROBE, // Ready to send a sample
STATE_AWAIT_REPLY, // Waiting for response (select)
STATE_FINISHED, // Goal achieved or Max Hops through
+ STATE_PERIOD_WAIT,
STATE_INTERVAL_WAIT,
STATE_ERROR // Error case (socket defective, etc.)
} session_state_t;
int timeout_ms;
int interval_ms;
struct timeval t_interval;
+ int period_ms;
+ struct timeval t_period;
// Current progress
int current_ttl;
bool printed_addr; // Has the address for this hop already been buffered?
} trace_session_t;
-void session_init(trace_session_t *s, char *host, int mh, int pp, int tm, int im, int idx);
+void session_init(trace_session_t *s, char *host, int mh, int pp, int tm, int im, int pm, int idx);
void session_close(trace_session_t *s);
void process_send(trace_session_t *s);
void process_timeout_check(trace_session_t *s);
void process_interval_check(trace_session_t *s);
+void process_period_check(trace_session_t *s);
void process_read(trace_session_t *s);
void flush_line(trace_session_t *s);
unsigned short checksum(void *b, int len);