summaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2003-04-15 19:10:18 +0000
committerNick Mathewson <nickm@torproject.org>2003-04-15 19:10:18 +0000
commit1fa0fc14876357b7f5d36696166d33dc1159b294 (patch)
tree00553f761f24242c4660b5079ee7025863ee8d08 /src/or
parent7df5caad0df1644770316d98a289be734029f4c5 (diff)
downloadtor-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.c59
-rw-r--r--src/or/connection.c24
-rw-r--r--src/or/or.h18
-rw-r--r--src/or/test.c185
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");