diff options
author | Nick Mathewson <nickm@torproject.org> | 2003-04-15 19:10:18 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2003-04-15 19:10:18 +0000 |
commit | 1fa0fc14876357b7f5d36696166d33dc1159b294 (patch) | |
tree | 00553f761f24242c4660b5079ee7025863ee8d08 /src/or | |
parent | 7df5caad0df1644770316d98a289be734029f4c5 (diff) | |
download | tor-1fa0fc14876357b7f5d36696166d33dc1159b294.tar.gz tor-1fa0fc14876357b7f5d36696166d33dc1159b294.zip |
Introduce a few unit tests (from older code), refactor compression setup/teardown
svn:r232
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/buffers.c | 59 | ||||
-rw-r--r-- | src/or/connection.c | 24 | ||||
-rw-r--r-- | src/or/or.h | 18 | ||||
-rw-r--r-- | src/or/test.c | 185 |
4 files changed, 256 insertions, 30 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c index 41889fc9fa..a3fe7ea830 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -136,7 +136,57 @@ int write_to_buf(char *string, int string_len, } -#ifdef USE_ZLIB +z_stream *zstream_new(int compression) +{ + z_stream* stream; + stream = malloc(sizeof(z_stream)); + if (!stream) + return NULL; + memset(stream, 0, sizeof(z_stream)); + if (compression) { + if (deflateInit(stream, Z_DEFAULT_COMPRESSION) != Z_OK) { + log(LOG_ERR, "Error initializing zlib: %s", stream->msg); + free(stream); + return NULL; + } + } else { + if (inflateInit(stream) != Z_OK) { + log(LOG_ERR, "Error initializing zlib: %s", stream->msg); + free(stream); + return NULL; + } + } + return stream; +} + +z_compression *compression_new() +{ + return (z_compression *) zstream_new(1); +} + +z_decompression *decompression_new() +{ + return (z_compression *) zstream_new(0); +} + +void compression_free(z_stream *stream) +{ + int r; + r = deflateEnd(stream); + if (r != Z_OK) + log(LOG_ERR, "while closing zlib: %d (%s)", r, stream->msg); + free(stream); +} + +void decompression_free(z_stream *stream) +{ + int r; + r = inflateEnd(stream); + if (r != Z_OK) + log(LOG_ERR, "while closing zlib: %d (%s)", r, stream->msg); + free(stream); +} + int compress_from_buf(char *string, int string_len, char **buf_in, int *buflen_in, int *buf_datalen_in, z_stream *zstream, int flush) { @@ -209,13 +259,16 @@ int decompress_buf_to_buf(char **buf_in, int *buflen_in, int *buf_datalen_in, return -1; } } -#endif int fetch_from_buf(char *string, int string_len, char **buf, int *buflen, int *buf_datalen) { /* if there are string_len bytes in buf, write them onto string, - * then memmove buf back (that is, remove them from buf) */ + * then memmove buf back (that is, remove them from buf). + * + * If there are not enough bytes on the buffer to fill string, return -1. + * + * Return the number of bytes still on the buffer. */ assert(string && buf && *buf && buflen && buf_datalen); diff --git a/src/or/connection.c b/src/or/connection.c index 576e4962fe..20b29dfa2c 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -130,20 +130,10 @@ connection_t *connection_new(int type) { if (type == CONN_TYPE_AP || type == CONN_TYPE_EXIT) { if (buf_new(&conn->z_outbuf, &conn->z_outbuflen, &conn->z_outbuf_datalen) < 0) return NULL; - if (! (conn->compression = malloc(sizeof(z_stream)))) + if (! (conn->compression = compression_new())) return NULL; - if (! (conn->decompression = malloc(sizeof(z_stream)))) + if (! (conn->decompression = decompression_new())) return NULL; - memset(conn->compression, 0, sizeof(z_stream)); - memset(conn->decompression, 0, sizeof(z_stream)); - if (deflateInit(conn->compression, Z_DEFAULT_COMPRESSION) != Z_OK) { - log(LOG_ERR, "Error initializing zlib: %s", conn->compression->msg); - return NULL; - } - if (inflateInit(conn->decompression) != Z_OK) { - log(LOG_ERR, "Error initializing zlib: %s", conn->decompression->msg); - return NULL; - } } else { conn->compression = conn->decompression = NULL; } @@ -181,14 +171,8 @@ void connection_free(connection_t *conn) { } #ifdef USE_ZLIB if (conn->compression) { - if (inflateEnd(conn->decompression) != Z_OK) - log(LOG_ERR,"connection_free(): while closing zlib: %s", - conn->decompression->msg); - if (deflateEnd(conn->compression) != Z_OK) - log(LOG_ERR,"connection_free(): while closing zlib: %s", - conn->compression->msg); - free(conn->compression); - free(conn->decompression); + decompression_free(conn->decompression); + compression_free(conn->compression); buf_free(conn->z_outbuf); } #endif diff --git a/src/or/or.h b/src/or/or.h index 67606aae5c..cc8f0461e8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -36,11 +36,11 @@ #include <errno.h> #include <assert.h> #include <time.h> -#ifdef USE_ZLIB + #define free_func zlib_free_func #include <zlib.h> #undef free_func -#endif + #include "../common/crypto.h" #include "../common/log.h" @@ -174,6 +174,9 @@ /* legal characters in a filename */ #define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/" +typedef z_stream z_compression; +typedef z_stream z_decompression; + struct config_line { char *key; char *value; @@ -446,10 +449,14 @@ int fetch_from_buf(char *string, int string_len, * then memmove buf back (that is, remove them from buf) */ -#ifdef USE_ZLIB +z_compression* compression_new(); +z_decompression* decompression_new(); +void compression_free(z_compression *); +void decompression_free(z_decompression *); + int compress_from_buf(char *string, int string_len, char **buf_in, int *buflen_in, int *buf_datalen_in, - z_stream *zstream, int flush); + z_compression *compression, int flush); /* read and compress as many characters as possible from buf, writing up to * string_len of them onto string, then memmove buf back. Return number of * characters written. @@ -457,10 +464,9 @@ int compress_from_buf(char *string, int string_len, int decompress_buf_to_buf(char **buf_in, int *buflen_in, int *buf_datalen_in, char **buf_out, int *buflen_out, int *buf_datalen_out, - z_stream *zstream, int flush); + z_decompression *decompression, int flush); /* XXX document this NM */ -#endif int find_on_inbuf(char *string, int string_len, char *buf, int buf_datalen); diff --git a/src/or/test.c b/src/or/test.c index 49877f5d54..5453f4b188 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -2,28 +2,211 @@ /* See LICENSE for licensing information */ /* $Id$ */ +#include <stdio.h> +#include <fcntl.h> + #include "or.h" #include "../common/test.h" void +setup_directory() { + char buf[256]; + sprintf(buf, "/tmp/tor_test"); + if (mkdir(buf, 0700) && errno != EEXIST) + fprintf(stderr, "Can't create directory %s", buf); +} + +void test_buffers() { + char str[256]; + char str2[256]; + char *buf; int buflen, buf_datalen; - if (buf_new(&buf, &buflen, &buf_datalen)) { + char *buf2; + int buf2len, buf2_datalen; + + int s, i, j, eof; + z_compression *comp; + z_decompression *decomp; + + /**** + * buf_new + ****/ + if (buf_new(&buf, &buflen, &buf_datalen)) test_fail(); + + test_eq(buflen, MAX_BUF_SIZE); + test_eq(buf_datalen, 0); + + /**** + * read_to_buf + ****/ + s = open("/tmp/tor_test/data", O_WRONLY|O_CREAT|O_TRUNC, 0600); + for (j=0;j<256;++j) { + str[j] = (char)j; } + write(s, str, 256); + close(s); + + s = open("/tmp/tor_test/data", O_RDONLY, 0); + eof = 0; + i = read_to_buf(s, 10, &buf, &buflen, &buf_datalen, &eof); + test_eq(buflen, MAX_BUF_SIZE); + test_eq(buf_datalen, 10); + test_eq(eof, 0); + test_eq(i, 10); + test_memeq(str, buf, 10); + + /* Test reading 0 bytes. */ + i = read_to_buf(s, 0, &buf, &buflen, &buf_datalen, &eof); + test_eq(buflen, MAX_BUF_SIZE); + test_eq(buf_datalen, 10); + test_eq(eof, 0); + test_eq(i, 0); + /* Now test when buffer is filled exactly. */ + buflen = 16; + i = read_to_buf(s, 6, &buf, &buflen, &buf_datalen, &eof); + test_eq(buflen, 16); + test_eq(buf_datalen, 16); + test_eq(eof, 0); + test_eq(i, 6); + test_memeq(str, buf, 16); + + /* Now test when buffer is filled with more data to read. */ + buflen = 32; + i = read_to_buf(s, 128, &buf, &buflen, &buf_datalen, &eof); + test_eq(buflen, 32); + test_eq(buf_datalen, 32); + test_eq(eof, 0); + test_eq(i, 16); + test_memeq(str, buf, 32); + + /* Now read to eof. */ + buflen = MAX_BUF_SIZE; + test_assert(buflen > 256); + i = read_to_buf(s, 1024, &buf, &buflen, &buf_datalen, &eof); + test_eq(i, (256-32)); test_eq(buflen, MAX_BUF_SIZE); + test_eq(buf_datalen, 256); + test_memeq(str, buf, 256); + test_eq(eof, 0); + + i = read_to_buf(s, 1024, &buf, &buflen, &buf_datalen, &eof); + test_eq(i, 0); + test_eq(buflen, MAX_BUF_SIZE); + test_eq(buf_datalen, 256); + test_eq(eof, 1); + + close(s); + + /**** + * find_on_inbuf + ****/ + + test_eq(((int)'d') + 1, find_on_inbuf("abcd", 4, buf, buf_datalen)); + test_eq(-1, find_on_inbuf("xyzzy", 5, buf, buf_datalen)); + /* Make sure we don't look off the end of the buffef */ + buf[256] = 'A'; + buf[257] = 'X'; + test_eq(-1, find_on_inbuf("\xff" "A", 2, buf, buf_datalen)); + test_eq(-1, find_on_inbuf("AX", 2, buf, buf_datalen)); + /* Make sure we use the string length */ + test_eq(((int)'d')+1, find_on_inbuf("abcdX", 4, buf, buf_datalen)); + + /**** + * fetch_from_buf + ****/ + memset(str2, 255, 256); + test_eq(246, fetch_from_buf(str2, 10, &buf, &buflen, &buf_datalen)); + test_memeq(str2, str, 10); + test_memeq(str+10,buf,246); + test_eq(buf_datalen,246); + + test_eq(-1, fetch_from_buf(str2, 247, &buf, &buflen, &buf_datalen)); + test_memeq(str+10,buf,246); + test_eq(buf_datalen, 246); + + test_eq(0, fetch_from_buf(str2, 246, &buf, &buflen, &buf_datalen)); + test_memeq(str2, str+10, 246); + test_eq(buflen,MAX_BUF_SIZE); + test_eq(buf_datalen,0); + + /**** + * write_to_buf + ****/ + memset(buf, (int)'-', 256); + i = write_to_buf("Hello world", 11, &buf, &buflen, &buf_datalen); + test_eq(i, 11); + test_eq(buf_datalen, 11); + test_memeq(buf, "Hello world", 11); + i = write_to_buf("XYZZY", 5, &buf, &buflen, &buf_datalen); + test_eq(i, 16); + test_eq(buf_datalen, 16); + test_memeq(buf, "Hello worldXYZZY", 16); + /* Test when buffer is overfull. */ + buflen = 18; + test_eq(-1, write_to_buf("This string will not fit.", 25, + &buf, &buflen, &buf_datalen)); + test_eq(buf_datalen, 16); + test_memeq(buf, "Hello worldXYZZY--", 18); + buflen = MAX_BUF_SIZE; + + /**** + * flush_buf + ****/ + + /*** + * compress_from_buf (simple) + ***/ + buf_datalen = 0; + comp = compression_new(); + for (i = 0; i < 20; ++i) { + write_to_buf("Hello world. ", 14, &buf, &buflen, &buf_datalen); + } + i = compress_from_buf(str, 256, &buf, &buflen, &buf_datalen, comp, 1); test_eq(buf_datalen, 0); + /* + for (j = 0; j <i ; ++j) { + printf("%x '%c'\n", ((int) str[j])&0xff, str[j]); + } + */ + /* Now try decompressing. */ + decomp = decompression_new(); + if (buf_new(&buf2, &buf2len, &buf2_datalen)) + test_fail(); + buf_datalen = 0; + test_eq(i, write_to_buf(str, i, &buf, &buflen, &buf_datalen)); + j = decompress_buf_to_buf(&buf, &buflen, &buf_datalen, + &buf2, &buf2len, &buf2_datalen, + decomp, 1); + /*XXXX check result * + + /* Now compress more, into less room. */ + for (i = 0; i < 20; ++i) { + write_to_buf("Hello wxrlx. ", 14, &buf, &buflen, &buf_datalen); + } + i = compress_from_buf(str, 256, &buf, &buflen, &buf_datalen, comp, 1); + + test_eq(buf_datalen, 0); + + + compression_free(comp); + decompression_free(decomp); + buf_free(buf); + buf_free(buf2); } int main(int c, char**v) { + setup_directory(); + test_buffers(); printf("\n"); |