#include #include #include #include #include #include #include #include #include #include "config.h" #define NS_TO_MS(X) ((long)(X) / (long)1000000) #define S_TO_MS(X) ((long)(X) * (long)1000) int get_socket() { int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { fprintf(stderr, "socket error: %s", strerror(errno)); exit(EXIT_FAILURE); } return sockfd; } size_t send_datagram(int sockfd, struct sockaddr_in server_address, char *buffer, size_t buffer_len) { return sendto(sockfd, buffer, buffer_len, 0, (struct sockaddr*) &server_address, sizeof(server_address)); } void send_data_request(int sockfd, struct sockaddr_in server_address, size_t pos, size_t bytes) { char buffer[40]; sprintf(buffer, "GET %ld %ld\n", pos, bytes); size_t buffer_len = strlen(buffer); if (send_datagram(sockfd, server_address, buffer, buffer_len) != buffer_len) { fprintf(stderr, "sendto error: %s\n", strerror(errno)); exit(EXIT_FAILURE); } } long get_time_interval(struct timespec start, struct timespec finish) { return S_TO_MS(finish.tv_sec - start.tv_sec) + NS_TO_MS(finish.tv_nsec - start.tv_nsec); } int poll_socket_modify_timeout(int sockfd, int *timeout) { if (*timeout < 0) { *timeout = 0; return 0; } struct pollfd fds; struct timespec start; struct timespec finish; fds.fd = sockfd; fds.events = POLLIN; fds.revents = 0; clock_gettime(CLOCK_REALTIME, &start); int result = poll(&fds, 1, *timeout); clock_gettime(CLOCK_REALTIME, &finish); if (result == -1) { fprintf(stderr, "poll error: %s\n", strerror(errno)); exit(EXIT_FAILURE); } if (result == 0) { *timeout = 0; return 0; } *timeout -= get_time_interval(start, finish); return result; } size_t recv_message(int sockfd, char *buffer, struct sockaddr_in *sender) { socklen_t sender_len = sizeof(*sender); bzero(buffer, HEADER_LEN + DATAGRAM_LEN); bzero(sender, sizeof(*sender)); size_t datagram_len = recvfrom(sockfd, buffer, IP_MAXPACKET, 0, (struct sockaddr*)sender, &sender_len); if (datagram_len < 0) { fprintf(stderr, "recvfrom error: %s\n", strerror(errno)); exit(EXIT_FAILURE); } return datagram_len; } inline size_t min(size_t x, size_t y) { return (x