#include #include #include "protocol.h" /* ensures all bytes from the buffer are sent note: applies a timeout during the send of bytes note: modyfies the len variable to reflect the number of bytes send */ int send_all(int sock, char *buf, int *len) { struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = TCP_TIMEOUT; // if (setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, // sizeof timeout) < 0) // perror("setsockopt failed\n"); int total = 0; // how many bytes we've sent int bytesleft = *len; // how many we have left to send int n; // ensure we don't send more than MAX_PACKET_SIZE bytes size_t max_send = bytesleft >= MAX_PACKET_SIZE ? MAX_PACKET_SIZE : bytesleft; while(total < *len) { n = send(sock, buf+total, max_send, 0); if (n == -1) { break; } total += n; bytesleft -= n; } *len = total; // return number actually sent here return n==-1?-1:0; // return -1 on failure, 0 on success } /* ensures all bytes that can be sent are loaded into the buffer note: applies a timeout during the collection of bytes note: modyfies the len variable to reflect the number of bytes read */ int recv_all(int sock, char *buf, int *len) { // setup the timeout on the socket struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = TCP_TIMEOUT; if (setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout) < 0) perror("setsockopt failed\n"); // printf("start: %ld\n", start); int total = 0; // how many bytes we've sent int bytesleft = *len; // how many we have left to send int n; while(total < *len) { n = recv(sock, buf+total, bytesleft, 0); // start = time(NULL); if (n == -1) { break; } total += n; bytesleft -= n; } timeout.tv_sec = 0; timeout.tv_usec = 0; if (setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout) < 0) perror("setsockopt failed\n"); *len = total; // return number actually sent here return n==-1?-1:0; // return -1 on failure, 0 on success } /* applies a timeout to the socket itself note: should only be used with tcp connections, after connect() */ int apply_timeout(int fd) { // handle handshake struct timeval tv; tv.tv_sec = 0; tv.tv_usec = TCP_TIMEOUT; if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { perror("setsockopt (in apply_timeout)"); return -1; } return 1; } /* removes the timeout on a socket note: should only be used with tcp connections, after connect() */ int remove_timeout(int fd) { // handle handshake struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { perror("setsockopt (in remove_timeout)"); return -1; } return 1; } /* basic helper, not "really" used as we are only Ipv4 */ void *get_in_addr(struct sockaddr *sa){ if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); }