#include "measure.h" void measure_parse(int size, struct measure_conf* mc) { struct timespec curr; uint64_t micro_sec; if (size != mc->payload_size) { fprintf(stderr, "read size: %d, expected: %ld\n", size, mc->payload_size); 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"); perror("read error, payload has wrong size"); //exit(EXIT_FAILURE); } struct measure_packet* head = (struct measure_packet*) mc->payload_rcv; if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1){ perror("clock_gettime error"); exit(EXIT_FAILURE); } micro_sec = elapsed_micros (&head->emit_time, &curr); uint8_t is_slow = head->flag >> 7; 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", current_human_datetime(), (unsigned long long)head->counter, micro_sec, is_slow, link_id, is_vanilla); if ((!mc->is_server || mc->is_rtt) && head->counter >= mc->max_measure) { 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); 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); 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; } } 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; head->flag = 0; if (clock_gettime(CLOCK_MONOTONIC, &head->emit_time) == -1) { perror("clock_gettime error"); exit(EXIT_FAILURE); } return head; } void measure_next_tick(struct measure_conf *mc, struct timespec *next) { struct measure_packet *head = (struct measure_packet*) mc->payload_rcv; struct timespec now, *sent_at = &head->emit_time; mc->counter = head->counter; if (clock_gettime(CLOCK_MONOTONIC, &now) == -1) { 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; };