#include #include #include #include #include #include #include #include #include #include #include "qarsh_packet.h" /* Some generic socket related functions to make things easier */ int getsockport(int sd) { struct sockaddr_in addr; socklen_t addrlen; addrlen = sizeof addr; if (getsockname(sd, (struct sockaddr *)&addr, &addrlen) == 0) { return ntohs(addr.sin_port); } else { return -1; } } int bind_any(int minport) { int sd; struct sockaddr_in addr; sd = socket(AF_INET, SOCK_STREAM, 0); if (sd == -1) return -1; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); do { addr.sin_port = htons(minport++); } while (bind(sd, (struct sockaddr *)&addr, sizeof addr) != 0); if (listen(sd, 0) == -1) { syslog(LOG_WARNING, "listen error %d, %s", errno, strerror(errno)); } return sd; } int connect_to_host(char *hostname, int port) { struct hostent *h; struct sockaddr_in haddr; int sd; if ((h = gethostbyname(hostname)) == NULL) { return -1; } haddr.sin_family = h->h_addrtype; haddr.sin_port = htons(port); memcpy(&haddr.sin_addr, h->h_addr, h->h_length); sd = socket(PF_INET, SOCK_STREAM, 0); if (sd == -1) return -1; if (connect(sd, (struct sockaddr *)&haddr, sizeof haddr) == -1) { return -1; } return sd; } int connect_to_peer(struct sockaddr_in *peer, int port) { struct sockaddr_in in_peer; int sd; int fdflags; in_peer.sin_family = AF_INET; in_peer.sin_port = htons(port); in_peer.sin_addr = peer->sin_addr; sd = socket(PF_INET, SOCK_STREAM, 0); if (sd == -1) return -1; /* Set close-on-exec for these sds */ if ((fdflags = fcntl(sd, F_GETFD, 0)) < 0) { return -1; } fdflags |= FD_CLOEXEC; if (fcntl(sd, F_SETFD, fdflags) < 0) { return -1; } if (connect(sd, (struct sockaddr *)&in_peer, sizeof in_peer) == -1) { return -1; } return sd; } struct qa_packet * recv_packet(int fd) { char *packetbuf; int packetsize; struct qa_packet *qp = NULL; packetbuf = malloc(QARSH_MAX_PACKET_SIZE); memset(packetbuf, 0, QARSH_MAX_PACKET_SIZE); packetsize = read(fd, packetbuf, QARSH_MAX_PACKET_SIZE); if (packetsize > 0) { qp = parse_packets(packetbuf, packetsize); } free(packetbuf); return qp; } int send_packet(int fd, struct qa_packet *qp) { char *packetbuf; int packetsize; ssize_t ret; packetbuf = malloc(1024); memset(packetbuf, 0, 1024); packetbuf = qptostr(qp, &packetbuf, &packetsize); ret = write(fd, packetbuf, packetsize); free(packetbuf); return ret; }