diff options
author | weidai <weidai11@users.noreply.github.com> | 2003-06-06 02:34:03 +0000 |
---|---|---|
committer | weidai <weidai11@users.noreply.github.com> | 2003-06-06 02:34:03 +0000 |
commit | 6c4437d03df6a1beadfadfc7c5388005c69665db (patch) | |
tree | 22ac172cd2a9920b7d33711a25947c5c98e8cef2 | |
parent | 2f50e8eac958f5a1bf7be05aeac015e5ee400927 (diff) | |
download | cryptopp-git-6c4437d03df6a1beadfadfc7c5388005c69665db.tar.gz |
sync with private branch
-rw-r--r-- | cryptest.dsp | 3 | ||||
-rw-r--r-- | filters.cpp | 38 | ||||
-rw-r--r-- | filters.h | 18 | ||||
-rw-r--r-- | fltrimpl.h | 11 | ||||
-rw-r--r-- | integer.cpp | 23 | ||||
-rw-r--r-- | integer.h | 2 | ||||
-rw-r--r-- | network.cpp | 159 | ||||
-rw-r--r-- | network.h | 13 | ||||
-rw-r--r-- | queue.cpp | 15 | ||||
-rw-r--r-- | queue.h | 14 | ||||
-rw-r--r-- | socketft.cpp | 12 | ||||
-rw-r--r-- | socketft.h | 2 | ||||
-rw-r--r-- | test.cpp | 1 | ||||
-rw-r--r-- | wait.h | 2 | ||||
-rw-r--r-- | winpipes.cpp | 9 | ||||
-rw-r--r-- | winpipes.h | 4 |
16 files changed, 225 insertions, 101 deletions
diff --git a/cryptest.dsp b/cryptest.dsp index b7b826ff..31c21ba3 100644 --- a/cryptest.dsp +++ b/cryptest.dsp @@ -53,7 +53,8 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /OPT:NOWIN98 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /OPT:NOWIN98 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /OPT:NOWIN98 /OPT:REF /OPT:ICF +# SUBTRACT LINK32 /pdb:none # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Cmds=echo This configuration is used to build a static binary for FIPS 140 evaluation by a testing laboratory. echo Crypto++ users should not build this configuration directly. diff --git a/filters.cpp b/filters.cpp index 47b5c93e..576022e3 100644 --- a/filters.cpp +++ b/filters.cpp @@ -98,6 +98,15 @@ void Filter::PropagateInitialize(const NameValuePairs ¶meters, int propagati AttachedTransformation()->ChannelInitialize(channel, parameters, propagation-1); } +unsigned int Filter::OutputModifiable(int outputSite, byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel) +{ + if (messageEnd) + messageEnd--; + unsigned int result = AttachedTransformation()->PutModifiable2(inString, length, messageEnd, blocking); + m_continueAt = result ? outputSite : 0; + return result; +} + unsigned int Filter::Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel) { if (messageEnd) @@ -152,6 +161,27 @@ unsigned int MeterFilter::Put2(const byte *begin, unsigned int length, int messa return 0; } +unsigned int MeterFilter::PutModifiable2(byte *begin, unsigned int length, int messageEnd, bool blocking) +{ + if (m_transparent) + { + FILTER_BEGIN; + m_currentMessageBytes += length; + m_totalBytes += length; + + if (messageEnd) + { + m_currentMessageBytes = 0; + m_currentSeriesMessages++; + m_totalMessages++; + } + + FILTER_OUTPUT_MODIFIABLE(1, begin, length, messageEnd); + FILTER_END_NO_MESSAGE_END; + } + return 0; +} + bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking) { m_currentMessageBytes = 0; @@ -414,12 +444,18 @@ void ProxyFilter::SetFilter(Filter *filter) } } -void ProxyFilter::NextPutMultiple(const byte *s, unsigned int len) +void ProxyFilter::NextPutMultiple(const byte *s, unsigned int len) { if (m_filter.get()) m_filter->Put(s, len); } +void ProxyFilter::NextPutModifiable(byte *s, unsigned int len) +{ + if (m_filter.get()) + m_filter->PutModifiable(s, len); +} + // ************************************************************* unsigned int ArraySink::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking) @@ -39,6 +39,7 @@ protected: void PropagateInitialize(const NameValuePairs ¶meters, int propagation, const std::string &channel=NULL_CHANNEL); unsigned int Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL); + unsigned int OutputModifiable(int outputSite, byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL); bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL); bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL); bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL); @@ -94,7 +95,10 @@ public: unsigned int GetTotalMessages() {return m_totalMessages;} unsigned int GetTotalMessageSeries() {return m_totalMessageSeries;} + byte * CreatePutSpace(unsigned int &size) + {return AttachedTransformation()->CreatePutSpace(size);} unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking); + unsigned int PutModifiable2(byte *inString, unsigned int length, int messageEnd, bool blocking); bool IsolatedMessageSeriesEnd(bool blocking); private: @@ -388,16 +392,23 @@ public: bool GetPassWaitObjects() const {return (m_behavior & PASS_WAIT_OBJECTS) != 0;} void SetPassWaitObjects(bool pass) { if (pass) m_behavior |= PASS_WAIT_OBJECTS; else m_behavior &= ~(word32) PASS_WAIT_OBJECTS; } - unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking) - {return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} + bool CanModifyInput() const + {return m_target ? m_target->CanModifyInput() : false;} + void Initialize(const NameValuePairs ¶meters, int propagation) {ChannelInitialize(NULL_CHANNEL, parameters, propagation);} + byte * CreatePutSpace(unsigned int &size) + {return m_target ? m_target->CreatePutSpace(size) : (size=0, NULL);} + unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking) + {return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;} bool MessageSeriesEnd(int propagation=-1, bool blocking=true) {return m_target && GetPassSignals() ? m_target->MessageSeriesEnd(propagation, blocking) : false;} void ChannelInitialize(const std::string &channel, const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1); + byte * ChannelCreatePutSpace(const std::string &channel, unsigned int &size) + {return m_target ? m_target->ChannelCreatePutSpace(channel, size) : (size=0, NULL);} unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking) {return m_target ? m_target->ChannelPut2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking) @@ -426,6 +437,8 @@ public: bool GetPassSignal() const {return m_passSignal;} void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} + byte * CreatePutSpace(unsigned int &size) + {return m_owner.AttachedTransformation()->CreatePutSpace(size);} unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking) {return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);} unsigned int PutModifiable2(byte *begin, unsigned int length, int messageEnd, bool blocking) @@ -463,6 +476,7 @@ public: void SetFilter(Filter *filter); void NextPutMultiple(const byte *s, unsigned int len); + void NextPutModifiable(byte *inString, unsigned int length); protected: member_ptr<BufferedTransformation> m_filter; @@ -39,4 +39,15 @@ #define FILTER_OUTPUT_BYTE(site, output) \ FILTER_OUTPUT(site, &(const byte &)(byte)output, 1, 0) +#define FILTER_OUTPUT2_MODIFIABLE(site, statement, output, length, messageEnd) \ + {\ + case site: \ + statement; \ + if (OutputModifiable(site, output, length, messageEnd, blocking)) \ + return STDMAX(1U, (unsigned int)length-m_inputPosition);\ + } + +#define FILTER_OUTPUT_MODIFIABLE(site, output, length, messageEnd) \ + FILTER_OUTPUT2_MODIFIABLE(site, 0, output, length, messageEnd) + #endif diff --git a/integer.cpp b/integer.cpp index 7e8e3f8c..260f6f0e 100644 --- a/integer.cpp +++ b/integer.cpp @@ -16,6 +16,8 @@ #ifdef SSE2_INTRINSICS_AVAILABLE #include <emmintrin.h> +#elif defined(_MSC_VER) && defined(_M_IX86) +#pragma message("You do no seem to have the Visual C++ Processor Pack installed, so use of SSE2 intrinsics will be disabled.") #endif #include "algebra.cpp" @@ -31,27 +33,30 @@ bool FunctionAssignIntToInteger(const std::type_info &valueType, void *pInteger, return true; } -static int DummyAssignIntToInteger = (AssignIntToInteger = FunctionAssignIntToInteger, 0); +static const char s_RunAtStartup = (AssignIntToInteger = FunctionAssignIntToInteger, 0); -#ifdef SSE2_INTRINSICS_AVAILABLE +#if defined(SSE2_INTRINSICS_AVAILABLE) || defined(_MSC_VER) template <class T> CPP_TYPENAME AllocatorBase<T>::pointer AlignedAllocator<T>::allocate(size_type n, const void *) { - if (n < 4) - return new T[n]; - else +#ifdef SSE2_INTRINSICS_AVAILABLE + if (n >= 4) return (T *)_mm_malloc(sizeof(T)*n, 16); - + else +#endif + return new T[n]; } template <class T> void AlignedAllocator<T>::deallocate(void *p, size_type n) { memset(p, 0, n*sizeof(T)); - if (n < 4) - delete [] p; - else +#ifdef SSE2_INTRINSICS_AVAILABLE + if (n >= 4) _mm_free(p); + else +#endif + delete [] p; } template class AlignedAllocator<word>; @@ -23,7 +23,7 @@ NAMESPACE_BEGIN(CryptoPP) -#ifdef SSE2_INTRINSICS_AVAILABLE +#if defined(SSE2_INTRINSICS_AVAILABLE) || defined(_MSC_VER) template <class T> class AlignedAllocator : public AllocatorBase<T> { diff --git a/network.cpp b/network.cpp index 72001d4e..f7705a70 100644 --- a/network.cpp +++ b/network.cpp @@ -2,6 +2,7 @@ #include "pch.h" #include "network.h" +#include "wait.h" NAMESPACE_BEGIN(CryptoPP) @@ -33,10 +34,24 @@ bool NonblockingSink::IsolatedFlush(bool hardFlush, bool blocking) #ifdef HIGHRES_TIMER_AVAILABLE NetworkSource::NetworkSource(BufferedTransformation *attachment) - : NonblockingSource(attachment), m_buf(1024*4), m_bufSize(0), m_state(NORMAL) + : NonblockingSource(attachment), m_buf(1024*16) + , m_waitingForResult(false), m_outputBlocked(false) + , m_dataBegin(0), m_dataEnd(0) { } +void NetworkSource::GetWaitObjects(WaitObjectContainer &container) +{ + if (!m_outputBlocked) + { + if (m_dataBegin == m_dataEnd) + AccessReceiver().GetWaitObjects(container); + else + container.SetNoWait(); + } + AttachedTransformation()->GetWaitObjects(container); +} + unsigned int NetworkSource::GeneralPump2(unsigned long &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter) { NetworkReceiver &receiver = AccessReceiver(); @@ -45,80 +60,93 @@ unsigned int NetworkSource::GeneralPump2(unsigned long &byteCount, bool blocking byteCount = 0; bool forever = maxTime == INFINITE_TIME; Timer timer(Timer::MILLISECONDS, forever); - unsigned long timeout; BufferedTransformation *t = AttachedTransformation(); - if (m_state == OUTPUT_BLOCKED) + if (m_outputBlocked) goto DoOutput; while (true) { - if (m_state == WAITING_FOR_RESULT) + if (m_dataBegin == m_dataEnd) { - if (receiver.MustWaitForResult()) + if (receiver.EofReceived()) + break; + + if (m_waitingForResult) { - timeout = SaturatingSubtract(maxTime, timer.ElapsedTime()); - if (!receiver.Wait(timeout)) + if (receiver.MustWaitForResult() && !receiver.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()))) break; + + unsigned int recvResult = receiver.GetReceiveResult(); + m_dataEnd += recvResult; + m_waitingForResult = false; + + if (!receiver.MustWaitToReceive() && !receiver.EofReceived() && m_dataEnd != m_buf.size()) + goto ReceiveNoWait; } + else + { + m_dataEnd = m_dataBegin = 0; - unsigned int recvResult = receiver.GetReceiveResult(); -// assert(recvResult > 0 || receiver.EofReceived()); - m_bufSize += recvResult; - m_state = NORMAL; - } + if (receiver.MustWaitToReceive()) + { + if (!receiver.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()))) + break; - if (m_bufSize == 0) - { - if (receiver.EofReceived()) - break; + receiver.Receive(m_buf+m_dataEnd, m_buf.size()-m_dataEnd); + m_waitingForResult = true; + } + else + { +ReceiveNoWait: + m_waitingForResult = true; + // call Receive repeatedly as long as data is immediately available, + // because some receivers tend to return data in small pieces + while (receiver.Receive(m_buf+m_dataEnd, m_buf.size()-m_dataEnd)) + { + unsigned int recvResult = receiver.GetReceiveResult(); + m_dataEnd += recvResult; + if (receiver.EofReceived() || m_dataEnd == m_buf.size()) + { + m_waitingForResult = false; + break; + } + } + } + } } else { - m_putSize = STDMIN((unsigned long)m_bufSize, maxSize - byteCount); + m_putSize = STDMIN((unsigned long)m_dataEnd-m_dataBegin, maxSize-byteCount); if (checkDelimiter) - m_putSize = std::find(m_buf.begin(), m_buf+m_putSize, delimiter) - m_buf; + m_putSize = std::find(m_buf+m_dataBegin, m_buf+m_dataBegin+m_putSize, delimiter) - (m_buf+m_dataBegin); DoOutput: - unsigned int result = t->PutModifiable2(m_buf, m_putSize, 0, forever || blockingOutput); + unsigned int result = t->PutModifiable2(m_buf+m_dataBegin, m_putSize, 0, forever || blockingOutput); if (result) { - timeout = SaturatingSubtract(maxTime, timer.ElapsedTime()); - if (t->Wait(timeout)) + if (t->Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()))) goto DoOutput; else { - m_state = OUTPUT_BLOCKED; + m_outputBlocked = true; return result; } } - m_state = NORMAL; + m_outputBlocked = false; byteCount += m_putSize; - m_bufSize -= m_putSize; - if (m_bufSize > 0) - { - memmove(m_buf, m_buf+m_putSize, m_bufSize); - if (checkDelimiter && m_buf[0] == delimiter) - break; - } - } - - if (byteCount == maxSize) - break; - - unsigned long elapsed = timer.ElapsedTime(); - if (elapsed > maxTime) - break; // once time limit is reached, return even if there is more data waiting - - if (receiver.MustWaitToReceive()) - { - if (!receiver.Wait(maxTime - elapsed)) + m_dataBegin += m_putSize; + if (checkDelimiter && m_dataBegin < m_dataEnd && m_buf[m_dataBegin] == delimiter) + break; + if (byteCount == maxSize) + break; + // once time limit is reached, return even if there is more data waiting + // but make 0 a special case so caller can request a large amount of data to be + // pumped as long as it is immediately available + if (maxTime > 0 && timer.ElapsedTime() > maxTime) break; } - - receiver.Receive(m_buf+m_bufSize, m_buf.size()-m_bufSize); - m_state = WAITING_FOR_RESULT; } return 0; @@ -126,6 +154,12 @@ DoOutput: // ************************************************************* +NetworkSink::NetworkSink(unsigned int maxBufferSize, bool autoFlush) + : m_maxBufferSize(maxBufferSize), m_autoFlush(autoFlush) + , m_needSendResult(false), m_buffer(STDMIN(16U*1024U, maxBufferSize)), m_blockedBytes(0) +{ +} + unsigned int NetworkSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking) { if (m_blockedBytes) @@ -134,7 +168,7 @@ unsigned int NetworkSink::Put2(const byte *inString, unsigned int length, int me inString += length - m_blockedBytes; length = m_blockedBytes; } - m_buffer.LazyPut(inString, length); + LazyPutter lp(m_buffer, inString, length); unsigned int targetSize = messageEnd ? 0 : m_maxBufferSize; TimedFlush(blocking ? INFINITE_TIME : 0, m_autoFlush ? 0 : targetSize); @@ -144,7 +178,6 @@ unsigned int NetworkSink::Put2(const byte *inString, unsigned int length, int me assert(!blocking); m_blockedBytes = STDMIN(m_buffer.CurrentSize() - targetSize, (unsigned long)length); m_buffer.UndoLazyPut(m_blockedBytes); - m_buffer.FinalizeLazyPut(); return STDMAX(m_blockedBytes, 1U); } m_blockedBytes = 0; @@ -156,51 +189,43 @@ unsigned int NetworkSink::Put2(const byte *inString, unsigned int length, int me unsigned int NetworkSink::TimedFlush(unsigned long maxTime, unsigned int targetSize) { - if (m_buffer.IsEmpty()) - return 0; - NetworkSender &sender = AccessSender(); bool forever = maxTime == INFINITE_TIME; Timer timer(Timer::MILLISECONDS, forever); - unsigned long timeout; unsigned int totalFlushSize = 0; while (true) { + if (m_buffer.CurrentSize() <= targetSize) + break; + if (m_needSendResult) { - if (sender.MustWaitForResult()) - { - timeout = SaturatingSubtract(maxTime, timer.ElapsedTime()); - if (!sender.Wait(timeout)) - break; - } + if (sender.MustWaitForResult() && !sender.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()))) + break; unsigned int sendResult = sender.GetSendResult(); m_buffer.Skip(sendResult); totalFlushSize += sendResult; m_needSendResult = false; - if (m_buffer.CurrentSize() <= targetSize) + if (!m_buffer.AnyRetrievable()) break; } - unsigned long elapsed = timer.ElapsedTime(); - if (elapsed > maxTime) - break; // once time limit is reached, return even if there is more data waiting - - if (sender.MustWaitToSend()) - { - if (!sender.Wait(maxTime - elapsed)) - break; - } + unsigned long timeOut = maxTime ? SaturatingSubtract(maxTime, timer.ElapsedTime()) : 0; + if (sender.MustWaitToSend() && !sender.Wait(timeOut)) + break; unsigned int contiguousSize = 0; const byte *block = m_buffer.Spy(contiguousSize); sender.Send(block, contiguousSize); m_needSendResult = true; + + if (maxTime > 0 && timeOut == 0) + break; // once time limit is reached, return even if there is more data waiting } return totalFlushSize; @@ -45,7 +45,8 @@ class CRYPTOPP_NO_VTABLE NetworkReceiver : public Waitable public: virtual bool MustWaitToReceive() {return false;} virtual bool MustWaitForResult() {return false;} - virtual void Receive(byte* buf, unsigned int bufLen) =0; + //! receive data from network source, returns whether result is immediately available + virtual bool Receive(byte* buf, unsigned int bufLen) =0; virtual unsigned int GetReceiveResult() =0; virtual bool EofReceived() const =0; }; @@ -96,8 +97,7 @@ public: unsigned int GetMaxWaitObjectCount() const {return GetReceiver().GetMaxWaitObjectCount() + AttachedTransformation()->GetMaxWaitObjectCount();} - void GetWaitObjects(WaitObjectContainer &container) - {AccessReceiver().GetWaitObjects(container); AttachedTransformation()->GetWaitObjects(container);} + void GetWaitObjects(WaitObjectContainer &container); unsigned int GeneralPump2(unsigned long &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n'); bool SourceExhausted() const {return GetReceiver().EofReceived();} @@ -107,17 +107,16 @@ protected: const NetworkReceiver & GetReceiver() const {return const_cast<NetworkSource *>(this)->AccessReceiver();} private: - enum {NORMAL, WAITING_FOR_RESULT, OUTPUT_BLOCKED}; SecByteBlock m_buf; - unsigned int m_bufSize, m_putSize, m_state; + unsigned int m_putSize, m_dataBegin, m_dataEnd; + bool m_waitingForResult, m_outputBlocked; }; //! Network Sink class CRYPTOPP_NO_VTABLE NetworkSink : public NonblockingSink { public: - NetworkSink(unsigned int maxBufferSize, bool autoFlush) - : m_maxBufferSize(maxBufferSize), m_autoFlush(autoFlush), m_needSendResult(false), m_blockedBytes(0) {} + NetworkSink(unsigned int maxBufferSize, bool autoFlush); unsigned int GetMaxWaitObjectCount() const {return GetSender().GetMaxWaitObjectCount();} @@ -234,8 +234,18 @@ void ByteQueue::LazyPut(const byte *inString, unsigned int size) { if (m_lazyLength > 0) FinalizeLazyPut(); + m_lazyString = const_cast<byte *>(inString); + m_lazyLength = size; + m_lazyStringModifiable = false; +} + +void ByteQueue::LazyPutModifiable(byte *inString, unsigned int size) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); m_lazyString = inString; m_lazyLength = size; + m_lazyStringModifiable = true; } void ByteQueue::UndoLazyPut(unsigned int size) @@ -309,7 +319,10 @@ unsigned int ByteQueue::TransferTo2(BufferedTransformation &target, unsigned lon unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); if (len) { - target.ChannelPut(channel, m_lazyString, len); + if (m_lazyStringModifiable) + target.ChannelPutModifiable(channel, m_lazyString, len); + else + target.ChannelPut(channel, m_lazyString, len); m_lazyString += len; m_lazyLength -= len; bytesLeft -= len; @@ -52,6 +52,7 @@ public: const byte * Spy(unsigned int &contiguousSize) const; void LazyPut(const byte *inString, unsigned int size); + void LazyPutModifiable(byte *inString, unsigned int size); void UndoLazyPut(unsigned int size); void FinalizeLazyPut(); @@ -100,8 +101,9 @@ private: unsigned int m_nodeSize; ByteQueueNode *m_head, *m_tail; - const byte *m_lazyString; + byte *m_lazyString; unsigned int m_lazyLength; + bool m_lazyStringModifiable; }; //! use this to make sure LazyPut is finalized in event of exception @@ -112,10 +114,20 @@ public: : m_bq(bq) {bq.LazyPut(inString, size);} ~LazyPutter() {try {m_bq.FinalizeLazyPut();} catch(...) {}} +protected: + LazyPutter(ByteQueue &bq) : m_bq(bq) {} private: ByteQueue &m_bq; }; +//! like LazyPutter, but does a LazyPutModifiable instead +class LazyPutterModifiable : public LazyPutter +{ +public: + LazyPutterModifiable(ByteQueue &bq, byte *inString, unsigned int size) + : LazyPutter(bq) {bq.LazyPutModifiable(inString, size);} +}; + NAMESPACE_END NAMESPACE_BEGIN(std) diff --git a/socketft.cpp b/socketft.cpp index 0f7b7eb0..d7515939 100644 --- a/socketft.cpp +++ b/socketft.cpp @@ -311,12 +311,13 @@ SocketReceiver::SocketReceiver(Socket &s) m_overlapped.hEvent = m_event; } -void SocketReceiver::Receive(byte* buf, unsigned int bufLen) +bool SocketReceiver::Receive(byte* buf, unsigned int bufLen) { assert(!m_resultPending && !m_eofReceived); DWORD flags = 0; - WSABUF wsabuf = {bufLen, (char *)buf}; + // don't queue too much at once, or we might use up non-paged memory + WSABUF wsabuf = {STDMIN(bufLen, 128U*1024U), (char *)buf}; if (WSARecv(m_s, &wsabuf, 1, &m_lastResult, &flags, &m_overlapped, NULL) == 0) { if (m_lastResult == 0) @@ -336,6 +337,7 @@ void SocketReceiver::Receive(byte* buf, unsigned int bufLen) m_resultPending = true; } } + return !m_resultPending; } void SocketReceiver::GetWaitObjects(WaitObjectContainer &container) @@ -386,7 +388,8 @@ SocketSender::SocketSender(Socket &s) void SocketSender::Send(const byte* buf, unsigned int bufLen) { DWORD written = 0; - WSABUF wsabuf = {bufLen, (char *)buf}; + // don't queue too much at once, or we might use up non-paged memory + WSABUF wsabuf = {STDMIN(bufLen, 128U*1024U), (char *)buf}; if (WSASend(m_s, &wsabuf, 1, &written, 0, &m_overlapped, NULL) == 0) { m_resultPending = false; @@ -436,11 +439,12 @@ void SocketReceiver::GetWaitObjects(WaitObjectContainer &container) container.AddReadFd(m_s); } -void SocketReceiver::Receive(byte* buf, unsigned int bufLen) +bool SocketReceiver::Receive(byte* buf, unsigned int bufLen) { m_lastResult = m_s.Receive(buf, bufLen); if (bufLen > 0 && m_lastResult == 0) m_eofReceived = true; + return true; } unsigned int SocketReceiver::GetReceiveResult() @@ -130,7 +130,7 @@ public: #else bool MustWaitForResult() {return true;} #endif - void Receive(byte* buf, unsigned int bufLen); + bool Receive(byte* buf, unsigned int bufLen); unsigned int GetReceiveResult(); bool EofReceived() const {return m_eofReceived;} @@ -805,6 +805,7 @@ void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, con sockListen.Create(); sockListen.Bind(sourcePort); + setsockopt(sockListen, IPPROTO_TCP, TCP_NODELAY, "\x01", 1); cout << "Listing on port " << sourcePort << ".\n"; sockListen.Listen(); @@ -9,7 +9,7 @@ #include <vector> #ifdef USE_WINDOWS_STYLE_SOCKETS -#include <windows.h> +#include <winsock2.h> #else #include <sys/types.h> #endif diff --git a/winpipes.cpp b/winpipes.cpp index a195d174..d125a6be 100644 --- a/winpipes.cpp +++ b/winpipes.cpp @@ -86,12 +86,13 @@ WindowsPipeReceiver::WindowsPipeReceiver() m_overlapped.hEvent = m_event; } -void WindowsPipeReceiver::Receive(byte* buf, unsigned int bufLen) +bool WindowsPipeReceiver::Receive(byte* buf, unsigned int bufLen) { assert(!m_resultPending && !m_eofReceived); HANDLE h = GetHandle(); - if (ReadFile(h, buf, bufLen, &m_lastResult, &m_overlapped)) + // don't queue too much at once, or we might use up non-paged memory + if (ReadFile(h, buf, STDMIN(bufLen, 128U*1024U), &m_lastResult, &m_overlapped)) { if (m_lastResult == 0) m_eofReceived = true; @@ -111,6 +112,7 @@ void WindowsPipeReceiver::Receive(byte* buf, unsigned int bufLen) m_resultPending = true; } } + return !m_resultPending; } void WindowsPipeReceiver::GetWaitObjects(WaitObjectContainer &container) @@ -163,7 +165,8 @@ void WindowsPipeSender::Send(const byte* buf, unsigned int bufLen) { DWORD written = 0; HANDLE h = GetHandle(); - if (WriteFile(h, buf, bufLen, &written, &m_overlapped)) + // don't queue too much at once, or we might use up non-paged memory + if (WriteFile(h, buf, STDMIN(bufLen, 128U*1024U), &written, &m_overlapped)) { m_resultPending = false; m_lastResult = written; @@ -7,7 +7,7 @@ #include "network.h" #include "queue.h" -#include <windows.h> +#include <winsock2.h> NAMESPACE_BEGIN(CryptoPP) @@ -64,7 +64,7 @@ public: WindowsPipeReceiver(); bool MustWaitForResult() {return true;} - void Receive(byte* buf, unsigned int bufLen); + bool Receive(byte* buf, unsigned int bufLen); unsigned int GetReceiveResult(); bool EofReceived() const {return m_eofReceived;} |