timer/packet.c
Zack Buhman 8c1c1e97f6 duplicate send, resend, ack
The 'software' renderer is now explicitly requested.
2024-06-26 02:44:07 -05:00

181 lines
4.3 KiB
C

#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#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;
}