From e22d028c15ddbd057f75da71cd59de8a50ee21d8 Mon Sep 17 00:00:00 2001 From: "tg(x)" <*@tg-x.net> Date: Fri, 6 May 2011 00:15:37 +0200 Subject: [PATCH] testServer: new cmdline options, memory handling fixes, fixes for routing-only mode --- test/Makefile | 38 ++++++++++++----- test/testServer.c | 102 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 117 insertions(+), 23 deletions(-) diff --git a/test/Makefile b/test/Makefile index bb10097..67c8524 100644 --- a/test/Makefile +++ b/test/Makefile @@ -17,6 +17,11 @@ debug: CFLAGS += -DDEBUG=${DEBUG} -g debug: CFLAGS := $(subst ${OPT},-O0,${CFLAGS}) debug: all +clean: + rm -f ${TARGETS} + +it: all + test: ${TARGETS} ./testRender ./testMatch @@ -26,7 +31,16 @@ test: ${TARGETS} for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f; done for f in packets/[0-9]*; do echo ">> $$f"; ./testParser $$f -r; done -testServer: CFLAGS := $(subst -std=c99,,${CFLAGS}) +nettest: nettestfull nettestsplit + +nettestfull: + for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done + +nettestsplit: + for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done + +nettesterr: + for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done netstart: ./testServer ${PORT} @@ -40,18 +54,20 @@ netstartv: netstartrv: ./testServer ${PORT} -rv -nettest: nettestfull nettestsplit +netstartm: + ./testServer ${PORT} -m -nettestfull: - for f in packets/[0-9]*; do echo ">> $$f"; cat $$f | nc localhost ${PORT} | diff -u $$f -; done +netstartmr: + ./testServer ${PORT} -mr -nettestsplit: - for f in packets/[0-9]*; do echo ">> $$f"; ./splittest.pl $$f ${PORT} | diff -u $$f -; done +netstartms: + ./testServer ${PORT} -ms -nettesterr: - for f in packets/err-*; do echo ">> $$f"; cat $$f | nc localhost ${PORT}; done +netstartmsp: + ./testServer ${PORT} -msp -clean: - rm -f ${TARGETS} +netstartmv: + ./testServer ${PORT} -mv -it: all +netstartmrv: + ./testServer ${PORT} -mrv diff --git a/test/testServer.c b/test/testServer.c index a93bc5c..d61c2d7 100644 --- a/test/testServer.c +++ b/test/testServer.c @@ -11,8 +11,11 @@ #include #include #include +#include +#include #include #include +#define __USE_POSIX #include #include #include @@ -22,14 +25,24 @@ #include #include -const size_t RECV_BUF_SIZE = 256; -const size_t CONT_BUF_SIZE = 512; -const size_t SEND_BUF_SIZE = 1024; +const size_t RECV_BUF_SIZE = 8 * 1024; +const size_t CONT_BUF_SIZE = 8 * 1024; +const size_t SEND_BUF_SIZE = 8 * 1024; const size_t NUM_PARSERS = 100; // max size for routing & entity header const size_t ROUTING_LINES = 16; const size_t ENTITY_LINES = 32; +static inline +void resetString (psycString *s, uint8_t freeptr) +{ + if (freeptr && s->length) + free((void*)s->ptr); + + s->ptr = NULL; + s->length = 0; +} + // get sockaddr, IPv4 or IPv6: void *get_in_addr (struct sockaddr *sa) { @@ -42,8 +55,14 @@ void *get_in_addr (struct sockaddr *sa) int main (int argc, char **argv) { char *port = argc > 1 ? argv[1] : "4440"; - uint8_t routing_only = argc > 2 && memchr(argv[2], (int)'r', strlen(argv[2])); - uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); + uint8_t routing_only = argc > 2 && memchr(argv[2], (int)'r', strlen(argv[2])); + uint8_t verbose = argc > 2 && memchr(argv[2], (int)'v', strlen(argv[2])); + uint8_t parse_multiple = argc > 2 && memchr(argv[2], (int)'m', strlen(argv[2])); + uint8_t progress = argc > 2 && memchr(argv[2], (int)'p', strlen(argv[2])); + uint8_t stats = argc > 2 && memchr(argv[2], (int)'s', strlen(argv[2])); + size_t recv_buf_size = argc > 3 ? atoi(argv[3]) : 0; + if (recv_buf_size <= 0) + recv_buf_size = RECV_BUF_SIZE; fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() @@ -63,7 +82,7 @@ int main (int argc, char **argv) char remoteIP[INET6_ADDRSTRLEN]; int yes = 1; // for setsockopt() SO_REUSEADDR, below - int i, rv; + int i, j, rv; struct addrinfo hints, *ai, *p; @@ -73,6 +92,8 @@ int main (int argc, char **argv) psycModifier entity[NUM_PARSERS][ENTITY_LINES]; psycModifier *mod = NULL; + struct timeval start[NUM_PARSERS], end[NUM_PARSERS]; + int ret, retl; char oper; psycString name, value, elem; @@ -182,13 +203,19 @@ int main (int argc, char **argv) get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd); + + if (stats) + gettimeofday(&start[newfd], NULL); } } else { // handle data from a client - if ((nbytes = recv(i, recvbuf, RECV_BUF_SIZE, 0)) <= 0) + if ((nbytes = recv(i, recvbuf, recv_buf_size, 0)) <= 0) { + if (stats) + printf("%ld ms\n", (end[i].tv_sec * 1000000 + end[i].tv_usec - start[i].tv_sec * 1000000 - start[i].tv_usec) / 1000); + // got error or connection closed by client if (nbytes == 0) // connection closed printf("socket %d hung up\n", i); @@ -246,25 +273,70 @@ int main (int argc, char **argv) break; case PSYC_PARSE_COMPLETE: - printf("# Done parsing.\n"); + if (verbose) + printf("# Done parsing.\n"); + else if (progress) + write(1, ".", 1); + if (!parse_multiple) // parse multiple packets? + ret = -1; + packets[i].flag = psyc_isParseContentLengthFound(&parsers[i]) ? PSYC_PACKET_NEED_LENGTH : PSYC_PACKET_NO_LENGTH; if (routing_only) - packets[i].method = psyc_newString(PSYC_C2ARG("_packet_content")); + { + packets[i].content = packets[i].data; + resetString(&packets[i].data, 0); + } psyc_setPacketLength(&packets[i]); if (psyc_render(&packets[i], sendbuf, SEND_BUF_SIZE) == PSYC_RENDER_SUCCESS) { if (send(i, sendbuf, packets[i].length, 0) == -1) + { perror("send error"); + ret = -1; + } } else + { perror("render error"); + ret = -1; + } + + // reset packet + packets[i].routingLength = 0; + packets[i].contentLength = 0; + packets[i].length = 0; + packets[i].flag = 0; + + for (j = 0; j < packets[i].routing.lines; j++) + { + resetString(&packets[i].routing.modifiers[j].name, 1); + resetString(&packets[i].routing.modifiers[j].value, 1); + } + packets[i].routing.lines = 0; + + if (routing_only) + { + resetString(&packets[i].content, 1); + } + else + { + for (j = 0; j < packets[i].entity.lines; j++) + { + resetString(&packets[i].entity.modifiers[j].name, 1); + resetString(&packets[i].entity.modifiers[j].value, 1); + } + packets[i].entity.lines = 0; + + resetString(&packets[i].method, 1); + resetString(&packets[i].data, 1); + } - ret = -1; break; + case PSYC_PARSE_INSUFFICIENT: if (verbose) printf("# Insufficient data.\n"); @@ -274,7 +346,7 @@ int main (int argc, char **argv) if (contbytes > 0) // copy end of parsebuf before start of recvbuf { assert(recvbuf - contbytes >= buf); // make sure it's still in the buffer - memcpy(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); + memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); } ret = 0; break; @@ -313,7 +385,7 @@ int main (int argc, char **argv) } if (value.length) { - if (!pvalue->ptr) + if (!pvalue->length) pvalue->ptr = malloc(parsers[i].valueLength ? parsers[i].valueLength : value.length); assert(pvalue->ptr != NULL); memcpy((void*)pvalue->ptr + pvalue->length, value.ptr, value.length); @@ -376,6 +448,12 @@ int main (int argc, char **argv) } while (ret > 0); + if (progress) + write(1, " ", 1); + + if (stats) + gettimeofday(&end[i], NULL); + if (ret < 0) { printf("# Closing connection: %i\n", i);