sync with private branch

pull/2/head
weidai 2003-06-06 02:34:03 +00:00
parent 2f50e8eac9
commit 6c4437d03d
16 changed files with 228 additions and 104 deletions

View File

@ -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.

View File

@ -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;
@ -420,6 +450,12 @@ void ProxyFilter::NextPutMultiple(const byte *s, unsigned int len)
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)

View File

@ -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;

View File

@ -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

View File

@ -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>;

View File

@ -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>
{

View File

@ -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 (receiver.MustWaitForResult())
{
timeout = SaturatingSubtract(maxTime, timer.ElapsedTime());
if (!receiver.Wait(timeout))
break;
}
unsigned int recvResult = receiver.GetReceiveResult();
// assert(recvResult > 0 || receiver.EofReceived());
m_bufSize += recvResult;
m_state = NORMAL;
}
if (m_bufSize == 0)
if (m_dataBegin == m_dataEnd)
{
if (receiver.EofReceived())
break;
if (m_waitingForResult)
{
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_putSize = STDMIN((unsigned long)m_bufSize, maxSize - byteCount);
if (checkDelimiter)
m_putSize = std::find(m_buf.begin(), m_buf+m_putSize, delimiter) - m_buf;
DoOutput:
unsigned int result = t->PutModifiable2(m_buf, m_putSize, 0, forever || blockingOutput);
if (result)
{
timeout = SaturatingSubtract(maxTime, timer.ElapsedTime());
if (t->Wait(timeout))
goto DoOutput;
else
{
m_state = OUTPUT_BLOCKED;
return result;
}
}
m_state = NORMAL;
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
m_dataEnd = m_dataBegin = 0;
if (receiver.MustWaitToReceive())
{
if (!receiver.Wait(maxTime - elapsed))
if (!receiver.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime())))
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_dataEnd-m_dataBegin, maxSize-byteCount);
if (checkDelimiter)
m_putSize = std::find(m_buf+m_dataBegin, m_buf+m_dataBegin+m_putSize, delimiter) - (m_buf+m_dataBegin);
receiver.Receive(m_buf+m_bufSize, m_buf.size()-m_bufSize);
m_state = WAITING_FOR_RESULT;
DoOutput:
unsigned int result = t->PutModifiable2(m_buf+m_dataBegin, m_putSize, 0, forever || blockingOutput);
if (result)
{
if (t->Wait(SaturatingSubtract(maxTime, timer.ElapsedTime())))
goto DoOutput;
else
{
m_outputBlocked = true;
return result;
}
}
m_outputBlocked = false;
byteCount += m_putSize;
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;
}
}
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))
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))
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;

View File

@ -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();}

View File

@ -231,11 +231,21 @@ void ByteQueue::CleanupUsedNodes()
}
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,6 +319,9 @@ unsigned int ByteQueue::TransferTo2(BufferedTransformation &target, unsigned lon
unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength);
if (len)
{
if (m_lazyStringModifiable)
target.ChannelPutModifiable(channel, m_lazyString, len);
else
target.ChannelPut(channel, m_lazyString, len);
m_lazyString += len;
m_lazyLength -= len;

14
queue.h
View File

@ -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)

View File

@ -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()

View File

@ -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;}

View File

@ -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();

2
wait.h
View File

@ -9,7 +9,7 @@
#include <vector>
#ifdef USE_WINDOWS_STYLE_SOCKETS
#include <windows.h>
#include <winsock2.h>
#else
#include <sys/types.h>
#endif

View File

@ -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;

View File

@ -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;}