/*
* ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
- *
- * Connection compression using ZLIB
*/
+#define CONN_MODULE
+
#include "portab.h"
-#define CONN_MODULE
+/**
+ * @file
+ * Connection compression using ZLIB
+ */
-#ifdef ZLIB
+/* Additionan debug messages related to ZIP compression: 0=off / 1=on */
+#define DEBUG_ZIP 0
-/* enable more zlib related debug messages: */
-/* #define DEBUG_ZLIB */
+#ifdef ZLIB
-#include "imp.h"
#include <assert.h>
#include <string.h>
#include <zlib.h>
#include "conn.h"
#include "conn-func.h"
#include "log.h"
-
#include "array.h"
-#include "exp.h"
+
#include "conn-zip.h"
* compression ratios.
* If the (pre-)compression buffer is full, we try to flush it ("actually
* compress some data") and to add the new (uncompressed) data afterwards.
+ * This function closes the connection on error.
* @param Idx Connection handle.
* @param Data Pointer to the data.
* @param Len Length of the data to add.
- * @return true on success, false otherwise. */
+ * @return true on success, false otherwise.
+ */
GLOBAL bool
Zip_Buffer( CONN_ID Idx, const char *Data, size_t Len )
{
/* check again; if zip buf is still too large do not append data:
* otherwise the zip wbuf would grow too large */
buflen = array_bytes(&My_Connections[Idx].zip.wbuf);
- if (buflen + Len >= WRITEBUFFER_SLINK_LEN)
+ if (buflen + Len >= WRITEBUFFER_SLINK_LEN) {
+ Log(LOG_ALERT, "Zip Write buffer space exhausted: %lu bytes", buflen + Len);
+ Conn_Close(Idx, "Zip Write buffer space exhausted", NULL, false);
return false;
-
+ }
return array_catb(&My_Connections[Idx].zip.wbuf, Data, Len);
} /* Zip_Buffer */
/**
* Compress data in ZIP buffer and move result to the write buffer of
* the connection.
+ * This function closes the connection on error.
* @param Idx Connection handle.
* @return true on success, false otherwise.
*/
out->next_out = zipbuf;
out->avail_out = (uInt)sizeof zipbuf;
-#ifdef DEBUG_ZIP
+#if DEBUG_ZIP
Log(LOG_DEBUG, "out->avail_in %d, out->avail_out %d",
out->avail_in, out->avail_out);
#endif
if (out->avail_out <= 0) {
/* Not all data was compressed, because data became
* bigger while compressing it. */
- Log (LOG_ALERT, "Compression error: buffer overvlow!?");
+ Log(LOG_ALERT, "Compression error: buffer overflow!?");
Conn_Close(Idx, "Compression error!", NULL, false);
return false;
}
assert(out->avail_out <= WRITEBUFFER_SLINK_LEN);
zipbuf_used = WRITEBUFFER_SLINK_LEN - out->avail_out;
-#ifdef DEBUG_ZIP
+#if DEBUG_ZIP
Log(LOG_DEBUG, "zipbuf_used: %d", zipbuf_used);
#endif
if (!array_catb(&My_Connections[Idx].wbuf,
* uncompress data and copy it to read buffer.
* Returns true if data has been unpacked or no
* compressed data is currently pending in the zread buffer.
+ * This function closes the connection on error.
* @param Idx Connection handle.
* @return true on success, false otherwise.
*/
in->next_out = unzipbuf;
in->avail_out = (uInt)sizeof unzipbuf;
-#ifdef DEBUG_ZIP
+#if DEBUG_ZIP
Log(LOG_DEBUG, "in->avail_in %d, in->avail_out %d",
in->avail_in, in->avail_out);
#endif
assert(z_rdatalen >= in->avail_in);
in_len = z_rdatalen - in->avail_in;
unzipbuf_used = READBUFFER_LEN - in->avail_out;
-#ifdef DEBUG_ZIP
+#if DEBUG_ZIP
Log(LOG_DEBUG, "unzipbuf_used: %d - %d = %d", READBUFFER_LEN,
in->avail_out, unzipbuf_used);
#endif
assert(unzipbuf_used <= READBUFFER_LEN);
if (!array_catb(&My_Connections[Idx].rbuf, (char*) unzipbuf,
- (size_t)unzipbuf_used))
+ (size_t)unzipbuf_used)) {
+ Log (LOG_ALERT, "Decompression error: can't copy data!?");
+ Conn_Close(Idx, "Decompression error!", NULL, false);
return false;
-
+ }
if( in->avail_in > 0 ) {
array_moveleft(&My_Connections[Idx].zip.rbuf, 1, in_len );
} else {