network.h
#ifndef CRYPTOPP_NETWORK_H
#define CRYPTOPP_NETWORK_H
#include "config.h"
#if !defined(NO_OS_DEPENDENCE) && defined(SOCKETS_AVAILABLE)
#include "filters.h"
#include "hrtimer.h"
#include "stdcpp.h"
NAMESPACE_BEGIN(CryptoPP)
class LimitedBandwidth
{
public:
LimitedBandwidth(lword maxBytesPerSecond = 0)
: m_maxBytesPerSecond(maxBytesPerSecond), m_timer(Timer::MILLISECONDS)
, m_nextTransceiveTime(0)
{ m_timer.StartTimer(); }
lword GetMaxBytesPerSecond() const
{ return m_maxBytesPerSecond; }
void SetMaxBytesPerSecond(lword v)
{ m_maxBytesPerSecond = v; }
lword ComputeCurrentTransceiveLimit();
double TimeToNextTransceive();
void NoteTransceive(lword size);
public:
/*! GetWaitObjects() must be called despite the 0 return from GetMaxWaitObjectCount();
the 0 is because the ScheduleEvent() method is used instead of adding a wait object */
unsigned int GetMaxWaitObjectCount() const { return 0; }
void GetWaitObjects(WaitObjectContainer &container, const CallStack &callStack);
private:
lword m_maxBytesPerSecond;
typedef std::deque<std::pair<double, lword> > OpQueue;
OpQueue m_ops;
Timer m_timer;
double m_nextTransceiveTime;
void ComputeNextTransceiveTime();
double GetCurTimeAndCleanUp();
};
//! a Source class that can pump from a device for a specified amount of time.
class CRYPTOPP_NO_VTABLE NonblockingSource : public AutoSignaling<Source>, public LimitedBandwidth
{
public:
NonblockingSource(BufferedTransformation *attachment)
: m_messageEndSent(false) , m_doPumpBlocked(false), m_blockedBySpeedLimit(false) {Detach(attachment);}
//! \name NONBLOCKING SOURCE
//@{
//! pump up to maxSize bytes using at most maxTime milliseconds
/*! If checkDelimiter is true, pump up to delimiter, which itself is not extracted or pumped. */
size_t GeneralPump2(lword &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n');
lword GeneralPump(lword maxSize=LWORD_MAX, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n')
{
GeneralPump2(maxSize, true, maxTime, checkDelimiter, delimiter);
return maxSize;
}
lword TimedPump(unsigned long maxTime)
{return GeneralPump(LWORD_MAX, maxTime);}
lword PumpLine(byte delimiter='\n', lword maxSize=1024)
{return GeneralPump(maxSize, INFINITE_TIME, true, delimiter);}
size_t Pump2(lword &byteCount, bool blocking=true)
{return GeneralPump2(byteCount, blocking, blocking ? INFINITE_TIME : 0);}
size_t PumpMessages2(unsigned int &messageCount, bool blocking=true);
//@}
protected:
virtual size_t DoPump(lword &byteCount, bool blockingOutput,
unsigned long maxTime, bool checkDelimiter, byte delimiter) =0;
bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; }
private:
bool m_messageEndSent, m_doPumpBlocked, m_blockedBySpeedLimit;
};
//! Network Receiver
class CRYPTOPP_NO_VTABLE NetworkReceiver : public Waitable
{
public:
virtual bool MustWaitToReceive() {return false;}
virtual bool MustWaitForResult() {return false;}
//! receive data from network source, returns whether result is immediately available
virtual bool Receive(byte* buf, size_t bufLen) =0;
virtual unsigned int GetReceiveResult() =0;
virtual bool EofReceived() const =0;
};
class CRYPTOPP_NO_VTABLE NonblockingSinkInfo
{
public:
virtual ~NonblockingSinkInfo() {}
virtual size_t GetMaxBufferSize() const =0;
virtual size_t GetCurrentBufferSize() const =0;
virtual bool EofPending() const =0;
//! compute the current speed of this sink in bytes per second
virtual float ComputeCurrentSpeed() =0;
//! get the maximum observed speed of this sink in bytes per second
virtual float GetMaxObservedSpeed() const =0;
};
//! a Sink class that queues input and can flush to a device for a specified amount of time.
class CRYPTOPP_NO_VTABLE NonblockingSink : public Sink, public NonblockingSinkInfo, public LimitedBandwidth
{
public:
NonblockingSink() : m_blockedBySpeedLimit(false) {}
bool IsolatedFlush(bool hardFlush, bool blocking);
//! flush to device for no more than maxTime milliseconds
/*! This function will repeatedly attempt to flush data to some device, until
the queue is empty, or a total of maxTime milliseconds have elapsed.
If maxTime == 0, at least one attempt will be made to flush some data, but
it is likely that not all queued data will be flushed, even if the device
is ready to receive more data without waiting. If you want to flush as much data
as possible without waiting for the device, call this function in a loop.
For example: while (sink.TimedFlush(0) > 0) {}
\return number of bytes flushed
*/
lword TimedFlush(unsigned long maxTime, size_t targetSize = 0);
virtual void SetMaxBufferSize(size_t maxBufferSize) =0;
//! set a bound which will cause sink to flush if exceeded by GetCurrentBufferSize()
virtual void SetAutoFlushBound(size_t bound) =0;
protected:
virtual lword DoFlush(unsigned long maxTime, size_t targetSize) = 0;
bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; }
private:
bool m_blockedBySpeedLimit;
};
//! Network Sender
class CRYPTOPP_NO_VTABLE NetworkSender : public Waitable
{
public:
virtual bool MustWaitToSend() {return false;}
virtual bool MustWaitForResult() {return false;}
virtual void Send(const byte* buf, size_t bufLen) =0;
virtual unsigned int GetSendResult() =0;
virtual bool MustWaitForEof() {return false;}
virtual void SendEof() =0;
virtual bool EofSent() {return false;} // implement if MustWaitForEof() == true
};
//! Network Source
class CRYPTOPP_NO_VTABLE NetworkSource : public NonblockingSource
{
public:
NetworkSource(BufferedTransformation *attachment);
unsigned int GetMaxWaitObjectCount() const;
void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
bool SourceExhausted() const {return m_dataBegin == m_dataEnd && GetReceiver().EofReceived();}
protected:
size_t DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter);
virtual NetworkReceiver & AccessReceiver() =0;
const NetworkReceiver & GetReceiver() const {return const_cast<NetworkSource *>(this)->AccessReceiver();}
private:
SecByteBlock m_buf;
size_t 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, unsigned int autoFlushBound);
unsigned int GetMaxWaitObjectCount() const;
void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
void SetMaxBufferSize(size_t maxBufferSize) {m_maxBufferSize = maxBufferSize; m_buffer.SetNodeSize(UnsignedMin(maxBufferSize, 16U*1024U+256U));}
void SetAutoFlushBound(size_t bound) {m_autoFlushBound = bound;}
size_t GetMaxBufferSize() const {return m_maxBufferSize;}
size_t GetCurrentBufferSize() const {return (size_t)m_buffer.CurrentSize();}
void ClearBuffer() { m_buffer.Clear(); }
bool EofPending() const { return m_eofState > EOF_NONE && m_eofState < EOF_DONE; }
//! compute the current speed of this sink in bytes per second
float ComputeCurrentSpeed();
//! get the maximum observed speed of this sink in bytes per second
float GetMaxObservedSpeed() const;
protected:
lword DoFlush(unsigned long maxTime, size_t targetSize);
virtual NetworkSender & AccessSender() =0;
const NetworkSender & GetSender() const {return const_cast<NetworkSink *>(this)->AccessSender();}
private:
enum EofState { EOF_NONE, EOF_PENDING_SEND, EOF_PENDING_DELIVERY, EOF_DONE };
size_t m_maxBufferSize, m_autoFlushBound;
bool m_needSendResult, m_wasBlocked;
EofState m_eofState;
ByteQueue m_buffer;
size_t m_skipBytes;
Timer m_speedTimer;
float m_byteCountSinceLastTimerReset, m_currentSpeed, m_maxObservedSpeed;
};
NAMESPACE_END
#endif // SOCKETS_AVAILABLE
#endif // CRYPTOPP_NETWORK_H
NetworkSource
Network Source.
Definition: network.h:164
NonblockingSinkInfo::GetMaxObservedSpeed
virtual float GetMaxObservedSpeed() const =0
get the maximum observed speed of this sink in bytes per second
NonblockingSinkInfo
Definition: network.h:104
WaitObjectContainer
container of wait objects
Definition: wait.h:169
Timer
high resolution timer
Definition: hrtimer.h:57
BufferedTransformation::Put2
virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)=0
Input multiple bytes for processing.
NetworkSink::SetAutoFlushBound
void SetAutoFlushBound(size_t bound)
set a bound which will cause sink to flush if exceeded by GetCurrentBufferSize()
Definition: network.h:198
LimitedBandwidth::GetMaxWaitObjectCount
unsigned int GetMaxWaitObjectCount() const
Definition: network.h:37
NonblockingSinkInfo::ComputeCurrentSpeed
virtual float ComputeCurrentSpeed()=0
compute the current speed of this sink in bytes per second
config.h
Library configuration file.
SecByteBlock
SecBlock<byte> typedef.
Definition: secblock.h:731
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1352
Waitable
Interface for objects that can be waited on.
Definition: cryptlib.h:1295
NonblockingSink
a Sink class that queues input and can flush to a device for a specified amount of time...
Definition: network.h:118
UnsignedMin
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:503
ByteQueue
Data structure used to store byte strings.
Definition: queue.h:20
INFINITE_TIME
const unsigned long INFINITE_TIME
Represents infinite time.
Definition: cryptlib.h:110
BufferedTransformation::IsolatedFlush
virtual bool IsolatedFlush(bool hardFlush, bool blocking)=0
Flushes data buffered by this object, without signal propagation.
filters.h
Implementation of BufferedTransformation&#39;s attachment interface.
NonblockingSource::Pump2
size_t Pump2(lword &byteCount, bool blocking=true)
Pump data to attached transformation.
Definition: network.h:77
Sink
Implementation of BufferedTransformation&#39;s attachment interface.
Definition: simple.h:276
AutoSignaling
Provides auto signaling support.
Definition: simple.h:226
LimitedBandwidth
Definition: network.h:14
CryptoPP
Crypto++ library namespace.
NetworkReceiver
Network Receiver.
Definition: network.h:93
NetworkSource::SourceExhausted
bool SourceExhausted() const
Determines if the Source is exhausted.
Definition: network.h:172
CallStack
Definition: wait.h:124
NonblockingSource
a Source class that can pump from a device for a specified amount of time.
Definition: network.h:54
NetworkSink
Network Sink.
Definition: network.h:187
NetworkSender
Network Sender.
Definition: network.h:151