tor_multipath_voip/src/measure.c

121 lines
3.9 KiB
C
Raw Normal View History

2019-09-23 14:32:59 +00:00
#include "measure.h"
void measure_parse(int size, struct measure_conf* mc) {
struct timespec curr;
uint64_t micro_sec;
if (size != mc->payload_size) {
2020-01-31 23:00:45 +00:00
fprintf(stderr, "read size: %d, expected: %ld\n", size, mc->payload_size);
2020-01-31 23:19:04 +00:00
int i;
fprintf(stderr, "received buffer:\n");
for (i = 0; i < mc->payload_size; i++) {
if (i > 0) fprintf(stderr, ":");
fprintf(stderr, "%02x", (unsigned char) mc->payload_rcv[i]);
}
fprintf(stderr, "\n");
fprintf(stderr, "local buffer (reference):\n");
for (i = 0; i < mc->payload_size; i++) {
if (i > 0) fprintf(stderr, ":");
fprintf(stderr, "%02X", (unsigned char) mc->payload[i]);
}
fprintf(stderr, "\n");
2019-10-17 09:00:18 +00:00
perror("read error, payload has wrong size");
2020-01-31 23:31:13 +00:00
//exit(EXIT_FAILURE);
2019-09-23 14:32:59 +00:00
}
2020-01-31 23:00:45 +00:00
struct measure_packet* head = (struct measure_packet*) mc->payload_rcv;
2020-01-31 21:49:54 +00:00
if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1){
2019-09-23 14:32:59 +00:00
perror("clock_gettime error");
exit(EXIT_FAILURE);
}
micro_sec = elapsed_micros (&head->emit_time, &curr);
2019-10-18 13:05:02 +00:00
uint8_t is_slow = head->flag >> 7;
2019-10-18 15:29:49 +00:00
uint8_t is_vanilla = (head->flag & 0x40) >> 6;
uint8_t link_id = head->flag & 0x3f;
printf(
"[%s] Packet %llu latency %luµs with flag %d sent on link %d with vanilla %d\n",
2020-01-23 09:48:36 +00:00
current_human_datetime(),
2019-10-18 15:29:49 +00:00
(unsigned long long)head->counter,
micro_sec,
is_slow,
link_id,
is_vanilla);
2019-09-23 14:32:59 +00:00
2020-02-05 09:29:41 +00:00
if ((!mc->is_server || mc->is_rtt) && head->counter >= mc->max_measure) {
2019-09-23 14:32:59 +00:00
printf("Measurement done\n");
exit(EXIT_SUCCESS);
}
}
void measure_prepare(struct measure_conf* mc) {
if (mc->interval <= 0) mc->interval = 1000;
if (mc->max_measure <= 0) mc->max_measure = 1;
if (mc->payload_size < sizeof(struct measure_packet)) mc->payload_size = sizeof(struct measure_packet);
if ((mc->payload = malloc(sizeof(char) * mc->payload_size)) == NULL) {
perror("payload malloc failed");
exit(EXIT_FAILURE);
}
memset(mc->payload, 0, mc->payload_size);
2020-01-31 23:00:45 +00:00
if ((mc->payload_rcv = malloc(sizeof(char) * mc->payload_size)) == NULL) {
perror("payload malloc failed");
exit(EXIT_FAILURE);
}
memset(mc->payload_rcv, 0, mc->payload_size);
2019-09-23 14:32:59 +00:00
char *my_msg = "Tu n'es pas tout a fait la misere,\nCar les levres les plus pauvres te denoncent\nPar un sourire.";
size_t msg_len = strlen(my_msg);
size_t cursor_msg = 0;
for (size_t i = sizeof(struct measure_packet); i < mc->payload_size; i++) {
mc->payload[i] = my_msg[cursor_msg];
cursor_msg = (cursor_msg + 1) % msg_len;
}
}
2019-09-24 13:37:12 +00:00
struct measure_packet* measure_generate(struct measure_conf* mc) {
struct measure_packet* head = (struct measure_packet*)mc->payload;
mc->counter++;
head->counter = mc->counter;
head->is_echo = mc->is_rtt && !mc->is_server;
2019-10-09 15:07:51 +00:00
head->flag = 0;
2020-01-31 21:49:54 +00:00
if (clock_gettime(CLOCK_MONOTONIC, &head->emit_time) == -1) {
2019-09-24 13:37:12 +00:00
perror("clock_gettime error");
exit(EXIT_FAILURE);
}
return head;
}
void measure_next_tick(struct measure_conf *mc, struct timespec *next) {
2020-01-31 23:00:45 +00:00
struct measure_packet *head = (struct measure_packet*) mc->payload_rcv;
2019-09-24 13:37:12 +00:00
struct timespec now, *sent_at = &head->emit_time;
mc->counter = head->counter;
2020-01-31 21:49:54 +00:00
if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) {
2019-09-24 13:37:12 +00:00
perror("clock_gettime error");
exit(EXIT_FAILURE);
}
memcpy(next, sent_at, sizeof(struct timespec));
while(!timespec_gt (next, &now)) {
next->tv_nsec += mc->interval * 1000000L;
if (next->tv_nsec > ONE_SEC) {
next->tv_sec += next->tv_nsec / ONE_SEC;
next->tv_nsec = next->tv_nsec % ONE_SEC;
}
mc->counter++;
}
mc->counter--;
printf("interval: %ld\n", mc->interval);
printf("sent_at: sec=%ld nsec=%ld \n", (uint64_t) sent_at->tv_sec, (uint64_t) sent_at->tv_nsec);
printf("now: sec=%ld nsec=%ld \n", (uint64_t) now.tv_sec, (uint64_t) now.tv_nsec);
printf("next: sec=%ld nsec=%ld \n", (uint64_t) next->tv_sec, (uint64_t) next->tv_nsec);
}
uint8_t measure_need_reply(struct measure_conf* mc) {
return mc->is_server && ((struct measure_packet*)mc->payload)->is_echo;
};