summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorweidai <weidai11@users.noreply.github.com>2003-06-06 02:34:03 +0000
committerweidai <weidai11@users.noreply.github.com>2003-06-06 02:34:03 +0000
commit6c4437d03df6a1beadfadfc7c5388005c69665db (patch)
tree22ac172cd2a9920b7d33711a25947c5c98e8cef2
parent2f50e8eac958f5a1bf7be05aeac015e5ee400927 (diff)
downloadcryptopp-git-6c4437d03df6a1beadfadfc7c5388005c69665db.tar.gz
sync with private branch
-rw-r--r--cryptest.dsp3
-rw-r--r--filters.cpp38
-rw-r--r--filters.h18
-rw-r--r--fltrimpl.h11
-rw-r--r--integer.cpp23
-rw-r--r--integer.h2
-rw-r--r--network.cpp159
-rw-r--r--network.h13
-rw-r--r--queue.cpp15
-rw-r--r--queue.h14
-rw-r--r--socketft.cpp12
-rw-r--r--socketft.h2
-rw-r--r--test.cpp1
-rw-r--r--wait.h2
-rw-r--r--winpipes.cpp9
-rw-r--r--winpipes.h4
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 &parameters, 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)
diff --git a/filters.h b/filters.h
index 22994c95..cc33e28d 100644
--- a/filters.h
+++ b/filters.h
@@ -39,6 +39,7 @@ protected:
void PropagateInitialize(const NameValuePairs &parameters, 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 &parameters, 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 &parameters=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;
diff --git a/fltrimpl.h b/fltrimpl.h
index a35e68b0..60c827be 100644
--- a/fltrimpl.h
+++ b/fltrimpl.h
@@ -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>;
diff --git a/integer.h b/integer.h
index fcf3ebef..503a74f9 100644
--- a/integer.h
+++ b/integer.h
@@ -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;
diff --git a/network.h b/network.h
index e2ec59a6..790a00e1 100644
--- a/network.h
+++ b/network.h
@@ -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();}
diff --git a/queue.cpp b/queue.cpp
index b5ac16de..976bb0c5 100644
--- a/queue.cpp
+++ b/queue.cpp
@@ -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;
diff --git a/queue.h b/queue.h
index e247d9f6..b9641bc4 100644
--- a/queue.h
+++ b/queue.h
@@ -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()
diff --git a/socketft.h b/socketft.h
index 2ce54549..e8baef0f 100644
--- a/socketft.h
+++ b/socketft.h
@@ -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;}
diff --git a/test.cpp b/test.cpp
index 63218f20..fafcb2d6 100644
--- a/test.cpp
+++ b/test.cpp
@@ -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();
diff --git a/wait.h b/wait.h
index c1435221..db9caa6f 100644
--- a/wait.h
+++ b/wait.h
@@ -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;
diff --git a/winpipes.h b/winpipes.h
index 3260e196..29a3717a 100644
--- a/winpipes.h
+++ b/winpipes.h
@@ -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;}