#include #include "ping_pong.h" #include "timespec.h" #include "packet.h" int handle_ping_pong(int sockfd, void * buf, ssize_t length, struct link_state * link_state ) { struct event * evt = (struct event *)buf; switch (evt->type) { case EVENT_TYPE__PING: { if (length != (sizeof (struct packet_ping_pong))) { printf("handle_ping_pong: ping: invalid length\n"); return 0; // recoverable } //printf("recv ping; send pong\n"); struct packet_ping_pong * ping_pkt = (struct packet_ping_pong *)buf; int ret = packet_send_pong(sockfd, &link_state->dest_addr, &ping_pkt->time); if (ret == -1) { return -1; } } break; case EVENT_TYPE__PONG: { if (length != (sizeof (struct packet_ping_pong))) { printf("handle_ping_pong: pong: invalid length\n"); return 0; // recoverable } //printf("recv pong\n"); struct packet_ping_pong * ping_pkt = (struct packet_ping_pong *)buf; struct timespec now; int ret = clock_gettime(CLOCK_MONOTONIC_RAW, &now); assert(ret != -1); link_state->last_pong = now; struct timespec * rtt = &link_state->ping_pong_rtt[link_state->rtt_ix]; link_state->rtt_ix = (link_state->rtt_ix + 1) % RTT_AVERAGE_SAMPLES; *rtt = timespec_sub(&now, &ping_pkt->time); printf("pong rtt: %ld.%09ld\n", rtt->tv_sec, rtt->tv_nsec); struct timespec average_rtt = timespec_average(link_state->ping_pong_rtt, RTT_AVERAGE_SAMPLES); ret = packet_send_average_rtt(sockfd, &link_state->dest_addr, &average_rtt); if (ret == -1) { return -1; } } break; case EVENT_TYPE__AVERAGE_RTT: { if (length != (sizeof (struct packet_average_rtt))) { printf("handle_average_rtt: average_rtt: invalid length\n"); return 0; // recoverable } struct packet_average_rtt * ping_pkt = (struct packet_average_rtt *)buf; printf("recv average_rtt: %ld.%09ld\n", ping_pkt->offset.tv_sec, ping_pkt->offset.tv_nsec); link_state->remote_average_rtt = ping_pkt->offset; } break; default: break; } return 0; }