diff options
-rw-r--r-- | econpacket.c | 84 | ||||
-rw-r--r-- | econpacket.h | 9 | ||||
-rw-r--r-- | econproxy.c | 14 |
3 files changed, 68 insertions, 39 deletions
diff --git a/econpacket.c b/econpacket.c index 12bfe10..adddd8d 100644 --- a/econpacket.c +++ b/econpacket.c @@ -16,6 +16,7 @@ */ #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> @@ -33,6 +34,10 @@ init_iov(struct econ_packet *pkt) pkt->iov[1].iov_len = sizeof pkt->cmd; pkt->iov[2].iov_base = &pkt->rec; pkt->iov[2].iov_len = sizeof pkt->rec; + + /* To receive oversized commands */ + pkt->iov[3].iov_base = pkt->long_data; + pkt->iov[3].iov_len = sizeof pkt->long_data; } static void @@ -55,6 +60,9 @@ epkt_init(struct econ_packet *pkt, int cmd) memset(&pkt->rec, 0, sizeof pkt->rec); memset(&pkt->cmd, 0, sizeof pkt->cmd); init_header(&pkt->hdr, cmd); + + /* For irregular commands like 21 */ + pkt->long_data_size = 0; } int @@ -77,8 +85,9 @@ epkt_read(int fd, struct econ_packet *pkt) union { ssize_t s; size_t u; } len; init_iov(pkt); + pkt->long_data_size = 0; - len.s = readv(fd, pkt->iov, 3); + len.s = readv(fd, pkt->iov, 4); if (len.s < 0) return -1; @@ -87,38 +96,59 @@ epkt_read(int fd, struct econ_packet *pkt) return -1; } - if (len.u < sizeof(struct econ_header) + pkt->hdr.datasize) { + if (pkt->hdr.datasize == 0) { + if (len.u > sizeof(struct econ_header)) + return -1; + return 0; + } + + if (len.u != sizeof(struct econ_header) + pkt->hdr.datasize) { fprintf(stderr, "packet has invalid datasize\n"); return -1; } - if (pkt->hdr.datasize > 0) { - if (pkt->hdr.datasize < sizeof(struct econ_command)) { - fprintf(stderr, - "epkt_read: error: command to short\n"); - return -1; + if (pkt->hdr.datasize < sizeof(struct econ_command)) { + fprintf(stderr, + "epkt_read: error: command to short\n"); + return -1; + } + + /* Keepalive is an irregular command if datasize > 0: + * the regular field recordCount is 1, + * without actually having one. */ + if (pkt->hdr.commandID == E_CMD_KEEPALIVE) + return 0; + + /* Handle irregular long datasize */ + if (pkt->hdr.datasize > (sizeof(struct econ_command) + + sizeof(struct econ_record))) { + switch (pkt->hdr.commandID) { + case E_CMD_21: + break; + default: + fprintf(stderr, "epkt_read: received cmd: %d" + " with oversized datasize\n", + pkt->hdr.commandID); + exit(EXIT_FAILURE); } + pkt->long_data_size = (pkt->hdr.datasize - + (sizeof (struct econ_command) + + sizeof (struct econ_record))); + return 0; + } - /* Keepalive is an irregular if datasize > 0: - * the regular field recordCount is 1, - * without actually having one. */ - if (pkt->hdr.commandID == E_CMD_KEEPALIVE) - return 0; - - if (pkt->cmd.recordCount > 0) { - if (pkt->cmd.recordCount > 1) { - fprintf(stderr, "epkt_read:" - " did not expect a packet with more" - " that one record: %d, datasize: %d.\n", - pkt->cmd.recordCount, pkt->hdr.datasize); - return -1; - } - if (pkt->hdr.datasize != (sizeof (struct econ_command) + - sizeof (struct econ_record))) { - fprintf(stderr, "epkt_read: datasize incorrect, cmd: %d\n", - pkt->hdr.commandID); - return -1; - } + if (pkt->cmd.recordCount > 0) { + if (pkt->cmd.recordCount > 1) { + fprintf(stderr, "epkt_read: did not expect a packet " + "with more than one record: %d, datasize: %d.\n", + pkt->cmd.recordCount, pkt->hdr.datasize); + return -1; + } + if (pkt->hdr.datasize != (sizeof (struct econ_command) + + sizeof (struct econ_record))) { + fprintf(stderr, "epkt_read: datasize incorrect, cmd: %d\n", + pkt->hdr.commandID); + return -1; } } diff --git a/econpacket.h b/econpacket.h index 7eb9a2e..eccb453 100644 --- a/econpacket.h +++ b/econpacket.h @@ -18,6 +18,7 @@ #ifndef _ECONPACKET_H_ #define _ECONPACKET_H_ +#include <stddef.h> #include "econproto.h" struct econ_packet { @@ -26,7 +27,13 @@ struct econ_packet { struct econ_record rec; /* Holding the previous elements */ - struct iovec iov[3]; + struct iovec iov[4]; + + /* Storage for irregular long commands. + * This is just the remaining part, the first + * bytes are stored in cmd and rec. */ + char long_data[1024]; + size_t long_data_size; }; void diff --git a/econproxy.c b/econproxy.c index 508eae5..f6624e2 100644 --- a/econproxy.c +++ b/econproxy.c @@ -108,22 +108,14 @@ ep_get_clientinfo(struct ep *ep) /* cache projUniqInfo needed for reqconnect */ memcpy(ep->projUniqInfo, ep->epkt.rec.projUniqInfo, ECON_UNIQINFO_LENGTH); -#if 1 - char buf[BUFSIZ]; - ssize_t len = read(ep->ec_fd, buf, BUFSIZ); - struct econ_header *hdr = (void *) buf; - printf("cmd: %d, len: %zd\n", hdr->commandID, len); -#if 0 if (epkt_read(ep->ec_fd, &ep->epkt) < 0) - return -1; -#endif + return -1; - if (hdr->commandID != 21) { + if (ep->epkt.hdr.commandID != 21) { fprintf(stderr, "expected ex clientinfo (21), got: %d\n", - hdr->commandID); + ep->epkt.hdr.commandID); return -1; } -#endif return 0; } |