#include #include #include #include "link.h" #include "timer.h" #include "packet.h" #include "timespec.h" #define DUPLICATE_SEND 3 int packet_send_ping(int sockfd, struct sockaddr_in6 * dest_addr) { struct packet_ping_pong pkt; pkt.event.type = EVENT_TYPE__PING; pkt.event.sequence = 0; { int ret = clock_gettime(CLOCK_MONOTONIC_RAW, &pkt.time); assert(ret != -1); } int ret = sendto(sockfd, &pkt, (sizeof (pkt)), 0, (struct sockaddr *)dest_addr, (sizeof (struct sockaddr_in6))); if (ret == -1) { perror("packet_send_ping sendto"); return -1; } return 0; } int packet_send_pong(int sockfd, struct sockaddr_in6 * dest_addr, struct timespec * time) { struct packet_ping_pong pkt; pkt.event.type = EVENT_TYPE__PONG; pkt.event.sequence = 0; memcpy(&pkt.time, time, (sizeof (struct timespec))); int ret = sendto(sockfd, &pkt, (sizeof (pkt)), 0, (struct sockaddr *)dest_addr, (sizeof (struct sockaddr_in6))); if (ret == -1) { perror("packet_send_pong sendto"); return -1; } return 0; } int packet_send_average_rtt(int sockfd, struct sockaddr_in6 * dest_addr, struct timespec * offset) { struct packet_average_rtt pkt; pkt.event.type = EVENT_TYPE__AVERAGE_RTT; pkt.event.sequence = 0; memcpy(&pkt.offset, offset, (sizeof (struct timespec))); int ret = sendto(sockfd, &pkt, (sizeof (pkt)), 0, (struct sockaddr *)dest_addr, (sizeof (struct sockaddr_in6))); if (ret == -1) { perror("packet_send_average_rtt sendto"); return -1; } return 0; } int packet_send_start_event(int sockfd, struct sockaddr_in6 * dest_addr, struct link_state * link_state) { struct packet_start pkt; pkt.event.type = EVENT_TYPE__TIME_START; pkt.event.sequence = ++link_state->send_sequence; for (int i = 0; i < DUPLICATE_SEND; i++) { int ret = sendto(sockfd, &pkt, (sizeof (pkt)), 0, (struct sockaddr *)dest_addr, (sizeof (struct sockaddr_in6))); if (ret == -1) { perror("packet_send_start_event sendto"); return -1; } } return 0; } int packet_send_resume_event(int sockfd, struct sockaddr_in6 * dest_addr, struct timer_state * timer_state, struct link_state * link_state) { struct packet_resume pkt; pkt.event.type = EVENT_TYPE__TIME_RESUME; pkt.event.sequence = ++link_state->send_sequence; struct timespec now; int ret = clock_gettime(CLOCK_MONOTONIC_RAW, &now); assert(ret != -1); pkt.offset = timespec_sub(&now, &timer_state->counter.start); printf("resume offset %ld.%09ld\n", pkt.offset.tv_sec, pkt.offset.tv_nsec); for (int i = 0; i < DUPLICATE_SEND; i++) { int ret = sendto(sockfd, &pkt, (sizeof (pkt)), 0, (struct sockaddr *)dest_addr, (sizeof (struct sockaddr_in6))); if (ret == -1) { perror("packet_send_resume_event sendto"); return -1; } } return 0; } int packet_send_stopwatch_event(int sockfd, struct sockaddr_in6 * dest_addr, struct timer_state * timer_state, struct link_state * link_state) { struct packet_stopwatch pkt; pkt.event.type = EVENT_TYPE__TIME_STOP; pkt.event.sequence = ++link_state->send_sequence; memcpy(&pkt.stopwatch_time, &timer_state->time, (sizeof (struct stopwatch_time))); for (int i = 0; i < DUPLICATE_SEND; i++) { int ret = sendto(sockfd, &pkt, (sizeof (pkt)), 0, (struct sockaddr *)dest_addr, (sizeof (struct sockaddr_in6))); if (ret == -1) { perror("packet_send_stopwatch_event sendto"); return -1; } } return 0; } int packet_send_ack(int sockfd, struct sockaddr_in6 * dest_addr, uint32_t sequence) { struct packet_ack pkt; pkt.event.type = EVENT_TYPE__ACK; pkt.event.sequence = sequence; int ret = sendto(sockfd, &pkt, (sizeof (pkt)), 0, (struct sockaddr *)dest_addr, (sizeof (struct sockaddr_in6))); if (ret == -1) { perror("packet_send_pong sendto"); return -1; } return 0; }