aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--src/network/Makefile.am2
-rw-r--r--src/network/compressor.cc32
-rw-r--r--src/network/compressor.h28
-rw-r--r--src/network/transportfragment.cc34
5 files changed, 69 insertions, 29 deletions
diff --git a/configure.ac b/configure.ac
index 3151992..a177aad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,6 +158,8 @@ AS_IF([test x"$with_utempter" != xno],
[AC_MSG_WARN([Unable to find libutempter; utmp entries will not be made.])],
[AC_MSG_ERROR([--with-utempter was given but libutempter was not found.])])])])
+AC_SEARCH_LIBS([compress], [z], , [AC_MSG_ERROR([Unable to find zlib.])])
+
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h fcntl.h langinfo.h limits.h locale.h netinet/in.h stddef.h stdint.h inttypes.h stdlib.h string.h sys/ioctl.h sys/resource.h sys/socket.h sys/stat.h sys/time.h termios.h unistd.h wchar.h wctype.h], [], [AC_MSG_ERROR([Missing required header file.])])
diff --git a/src/network/Makefile.am b/src/network/Makefile.am
index 2768e6e..3143cc4 100644
--- a/src/network/Makefile.am
+++ b/src/network/Makefile.am
@@ -3,4 +3,4 @@ AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) $(HARDEN_CFLAGS) $(MISC_CXXF
noinst_LIBRARIES = libmoshnetwork.a
-libmoshnetwork_a_SOURCES = network.cc network.h networktransport.cc networktransport.h transportfragment.cc transportfragment.h transportsender.cc transportsender.h transportstate.h
+libmoshnetwork_a_SOURCES = network.cc network.h networktransport.cc networktransport.h transportfragment.cc transportfragment.h transportsender.cc transportsender.h transportstate.h compressor.cc compressor.h
diff --git a/src/network/compressor.cc b/src/network/compressor.cc
new file mode 100644
index 0000000..37c95c5
--- /dev/null
+++ b/src/network/compressor.cc
@@ -0,0 +1,32 @@
+#include <zlib.h>
+
+#include "compressor.h"
+#include "dos_assert.h"
+
+using namespace Network;
+using namespace std;
+
+string Compressor::compress_str( const string &input )
+{
+ long unsigned int len = BUFFER_SIZE;
+ dos_assert( Z_OK == compress( buffer, &len,
+ reinterpret_cast<const unsigned char *>( input.data() ),
+ input.size() ) );
+ return string( reinterpret_cast<char *>( buffer ), len );
+}
+
+string Compressor::uncompress_str( const string &input )
+{
+ long unsigned int len = BUFFER_SIZE;
+ dos_assert( Z_OK == uncompress( buffer, &len,
+ reinterpret_cast<const unsigned char *>( input.data() ),
+ input.size() ) );
+ return string( reinterpret_cast<char *>( buffer ), len );
+}
+
+/* construct on first use */
+Compressor & Network::get_compressor( void )
+{
+ static Compressor the_compressor;
+ return the_compressor;
+}
diff --git a/src/network/compressor.h b/src/network/compressor.h
new file mode 100644
index 0000000..ffeca99
--- /dev/null
+++ b/src/network/compressor.h
@@ -0,0 +1,28 @@
+#ifndef COMPRESSOR_H
+#define COMPRESSOR_H
+
+#include <string>
+
+namespace Network {
+ class Compressor {
+ private:
+ static const int BUFFER_SIZE = 2048 * 2048; /* effective limit on terminal size */
+
+ unsigned char *buffer;
+
+ public:
+ Compressor() : buffer( NULL ) { buffer = new unsigned char[ BUFFER_SIZE ]; }
+ ~Compressor() { if ( buffer ) { delete[] buffer; } }
+
+ std::string compress_str( const std::string &input );
+ std::string uncompress_str( const std::string &input );
+
+ /* unused */
+ Compressor( const Compressor & );
+ Compressor & operator=( const Compressor & );
+ };
+
+ Compressor & get_compressor( void );
+}
+
+#endif
diff --git a/src/network/transportfragment.cc b/src/network/transportfragment.cc
index 53eae91..2aeffd5 100644
--- a/src/network/transportfragment.cc
+++ b/src/network/transportfragment.cc
@@ -17,15 +17,13 @@
*/
#include <assert.h>
-#include <google/protobuf/io/gzip_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
#include "byteorder.h"
#include "transportfragment.h"
#include "transportinstruction.pb.h"
+#include "compressor.h"
#include "fatal_assert.h"
-using namespace google::protobuf::io;
using namespace Network;
using namespace TransportBuffers;
@@ -117,24 +115,15 @@ Instruction FragmentAssembly::get_assembly( void )
{
assert( fragments_arrived == fragments_total );
- ZeroCopyInputStream **streams = new ZeroCopyInputStream *[fragments_total];
+ string encoded;
+
for ( int i = 0; i < fragments_total; i++ ) {
assert( fragments.at( i ).initialized );
- streams[i] = new ArrayInputStream( fragments.at( i ).contents.data(),
- fragments.at( i ).contents.size() );
+ encoded += fragments.at( i ).contents;
}
Instruction ret;
- {
- ConcatenatingInputStream stream( streams, fragments_total );
- GzipInputStream gzip_stream( &stream, GzipInputStream::ZLIB );
- fatal_assert( ret.ParseFromZeroCopyStream( &gzip_stream ) );
- }
-
- for ( int i = 0; i < fragments_total; i++ ) {
- delete streams[i];
- }
- delete[] streams;
+ fatal_assert( ret.ParseFromString( get_compressor().uncompress_str( encoded ) ) );
fragments.clear();
fragments_arrived = 0;
@@ -169,18 +158,7 @@ vector<Fragment> Fragmenter::make_fragments( const Instruction &inst, int MTU )
last_instruction = inst;
last_MTU = MTU;
- string payload;
- {
- StringOutputStream stream( &payload );
- GzipOutputStream::Options gzip_options;
- gzip_options.format = GzipOutputStream::ZLIB;
- GzipOutputStream gzip_stream( &stream, gzip_options );
- fatal_assert( inst.SerializeToZeroCopyStream( &gzip_stream ) );
- if ( !gzip_stream.Close() ) {
- throw std::string( "zlib error: " ) + gzip_stream.ZlibErrorMessage();
- }
- }
-
+ string payload = get_compressor().compress_str( inst.SerializeAsString() );
uint16_t fragment_num = 0;
vector<Fragment> ret;