diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/network/Makefile.am | 2 | ||||
-rw-r--r-- | src/network/compressor.cc | 32 | ||||
-rw-r--r-- | src/network/compressor.h | 28 | ||||
-rw-r--r-- | src/network/transportfragment.cc | 34 |
5 files changed, 69 insertions, 29 deletions
diff --git a/configure.ac b/configure.ac index 034ec13..60f63ea 100644 --- a/configure.ac +++ b/configure.ac @@ -155,6 +155,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.])]) + AC_ARG_WITH([skalibs], [AS_HELP_STRING([--with-skalibs[=DIR]], [root directory of skalibs installation])], 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; |