#include "packet.h" enum FD_STATE read_packet_from_tcp(int fd, struct buffer_packet* bp) { ssize_t nread; size_t pkt_size_size = sizeof(bp->ip.ap.str.size); if (bp->mode == BP_WRITING) return FDS_ERR; while (bp->aread < pkt_size_size) { nread = read(fd, &(bp->ip.ap.raw) + bp->aread, pkt_size_size - bp->aread); if (nread == 0) return FDS_AGAIN; if (nread == -1 && errno == EAGAIN) return FDS_AGAIN; if (nread == -1) return FDS_ERR; bp->aread += nread; } while (bp->aread < bp->ip.ap.str.size) { nread = read(fd, &(bp->ip.ap.raw) + bp->aread, bp->ip.ap.str.size - bp->aread); if (nread == 0) return FDS_AGAIN; if (nread == -1 && errno == EAGAIN) return FDS_AGAIN; if (nread == -1) return FDS_ERR; bp->aread += nread; } bp->mode = BP_WRITING; bp->awrite = 0; return FDS_READY; } enum FD_STATE write_packet_to_tcp(int fd, struct buffer_packet* bp) { ssize_t nwrite; while (bp->awrite < bp->ip.ap.str.size) { nwrite = send(fd, &(bp->ip.ap.raw), bp->ip.ap.str.size, 0); if (nwrite == -1 && errno == EAGAIN) return FDS_AGAIN; if (nwrite == -1) return FDS_ERR; bp->awrite += nwrite; } bp->mode = BP_READING; bp->aread = 0; return FDS_READY; } enum FD_STATE write_packet_to_udp(int fd, struct buffer_packet* bp, struct udp_target* udp_t) { ssize_t nwrite; size_t bytes_to_send; size_t pkt_size_size = sizeof(bp->ip.ap.str.size); struct sockaddr* addr = (struct sockaddr*)&(udp_t->addr); socklen_t addrlen = udp_t->addrlen; if (!udp_t->set) { printf("UDP address is not yet set. Hope we are a connected client...\n"); addr = NULL; addrlen = 0; } if (bp->mode == BP_READING) return FDS_ERR; bytes_to_send = bp->ip.ap.str.size - pkt_size_size; nwrite = sendto(fd, &(bp->ip.ap.str.payload), bytes_to_send, 0, addr, addrlen); if (nwrite == -1 && errno == EAGAIN) return FDS_AGAIN; if (nwrite != bytes_to_send) return FDS_ERR; bp->mode = BP_READING; bp->aread = 0; return FDS_READY; } enum FD_STATE read_packet_from_udp (int fd, struct buffer_packet* bp, struct udp_target* udp_t) { ssize_t nread; if (bp->mode == BP_WRITING) return FDS_ERR; udp_t->addrlen = sizeof(struct sockaddr_in); size_t pkt_size_size = sizeof(bp->ip.ap.str.size); size_t udp_packet_size = sizeof(struct internet_packet) - pkt_size_size; nread = recvfrom(fd, &(bp->ip.ap.str.payload), udp_packet_size, MSG_TRUNC, (struct sockaddr*)&(udp_t->addr), &(udp_t->addrlen)); if ((int)nread > (int)udp_packet_size) return FDS_ERR; if (nread == -1 && errno == EAGAIN) return FDS_AGAIN; if (nread == -1) return FDS_ERR; udp_t->set = 1; bp->ip.ap.str.size = nread + pkt_size_size; bp->mode = BP_WRITING; bp->awrite = 0; return FDS_READY; }