00001 #ifndef CRYPTOPP_NETWORK_H
00002 #define CRYPTOPP_NETWORK_H
00003
00004 #include "config.h"
00005
00006 #ifdef HIGHRES_TIMER_AVAILABLE
00007
00008 #include "filters.h"
00009 #include "hrtimer.h"
00010
00011 #include <deque>
00012
00013 NAMESPACE_BEGIN(CryptoPP)
00014
00015 class LimitedBandwidth
00016 {
00017 public:
00018 LimitedBandwidth(lword maxBytesPerSecond = 0)
00019 : m_maxBytesPerSecond(maxBytesPerSecond), m_timer(Timer::MILLISECONDS)
00020 , m_nextTransceiveTime(0)
00021 { m_timer.StartTimer(); }
00022
00023 lword GetMaxBytesPerSecond() const
00024 { return m_maxBytesPerSecond; }
00025
00026 void SetMaxBytesPerSecond(lword v)
00027 { m_maxBytesPerSecond = v; }
00028
00029 lword ComputeCurrentTransceiveLimit();
00030
00031 double TimeToNextTransceive();
00032
00033 void NoteTransceive(lword size);
00034
00035 public:
00036
00037
00038 unsigned int GetMaxWaitObjectCount() const { return 0; }
00039 void GetWaitObjects(WaitObjectContainer &container, const CallStack &callStack);
00040
00041 private:
00042 lword m_maxBytesPerSecond;
00043
00044 typedef std::deque<std::pair<double, lword> > OpQueue;
00045 OpQueue m_ops;
00046
00047 Timer m_timer;
00048 double m_nextTransceiveTime;
00049
00050 void ComputeNextTransceiveTime();
00051 double GetCurTimeAndCleanUp();
00052 };
00053
00054
00055 class CRYPTOPP_NO_VTABLE NonblockingSource : public AutoSignaling<Source>, public LimitedBandwidth
00056 {
00057 public:
00058 NonblockingSource(BufferedTransformation *attachment)
00059 : m_messageEndSent(false) , m_doPumpBlocked(false), m_blockedBySpeedLimit(false) {Detach(attachment);}
00060
00061
00062
00063
00064
00065
00066 size_t GeneralPump2(lword &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n');
00067
00068 lword GeneralPump(lword maxSize=LWORD_MAX, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n')
00069 {
00070 GeneralPump2(maxSize, true, maxTime, checkDelimiter, delimiter);
00071 return maxSize;
00072 }
00073 lword TimedPump(unsigned long maxTime)
00074 {return GeneralPump(LWORD_MAX, maxTime);}
00075 lword PumpLine(byte delimiter='\n', lword maxSize=1024)
00076 {return GeneralPump(maxSize, INFINITE_TIME, true, delimiter);}
00077
00078 size_t Pump2(lword &byteCount, bool blocking=true)
00079 {return GeneralPump2(byteCount, blocking, blocking ? INFINITE_TIME : 0);}
00080 size_t PumpMessages2(unsigned int &messageCount, bool blocking=true);
00081
00082
00083 protected:
00084 virtual size_t DoPump(lword &byteCount, bool blockingOutput,
00085 unsigned long maxTime, bool checkDelimiter, byte delimiter) =0;
00086
00087 bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; }
00088
00089 private:
00090 bool m_messageEndSent, m_doPumpBlocked, m_blockedBySpeedLimit;
00091 };
00092
00093
00094 class CRYPTOPP_NO_VTABLE NetworkReceiver : public Waitable
00095 {
00096 public:
00097 virtual bool MustWaitToReceive() {return false;}
00098 virtual bool MustWaitForResult() {return false;}
00099
00100 virtual bool Receive(byte* buf, size_t bufLen) =0;
00101 virtual unsigned int GetReceiveResult() =0;
00102 virtual bool EofReceived() const =0;
00103 };
00104
00105 class CRYPTOPP_NO_VTABLE NonblockingSinkInfo
00106 {
00107 public:
00108 virtual ~NonblockingSinkInfo() {}
00109 virtual size_t GetMaxBufferSize() const =0;
00110 virtual size_t GetCurrentBufferSize() const =0;
00111 virtual bool EofPending() const =0;
00112
00113 virtual float ComputeCurrentSpeed() =0;
00114
00115 virtual float GetMaxObservedSpeed() const =0;
00116 };
00117
00118
00119 class CRYPTOPP_NO_VTABLE NonblockingSink : public Sink, public NonblockingSinkInfo, public LimitedBandwidth
00120 {
00121 public:
00122 NonblockingSink() : m_blockedBySpeedLimit(false) {}
00123
00124 bool IsolatedFlush(bool hardFlush, bool blocking);
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 lword TimedFlush(unsigned long maxTime, size_t targetSize = 0);
00137
00138 virtual void SetMaxBufferSize(size_t maxBufferSize) =0;
00139
00140 virtual void SetAutoFlushBound(size_t bound) =0;
00141
00142 protected:
00143 virtual lword DoFlush(unsigned long maxTime, size_t targetSize) = 0;
00144
00145 bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; }
00146
00147 private:
00148 bool m_blockedBySpeedLimit;
00149 };
00150
00151
00152 class CRYPTOPP_NO_VTABLE NetworkSender : public Waitable
00153 {
00154 public:
00155 virtual bool MustWaitToSend() {return false;}
00156 virtual bool MustWaitForResult() {return false;}
00157 virtual void Send(const byte* buf, size_t bufLen) =0;
00158 virtual unsigned int GetSendResult() =0;
00159 virtual bool MustWaitForEof() {return false;}
00160 virtual void SendEof() =0;
00161 virtual bool EofSent() {return false;}
00162 };
00163
00164
00165 class CRYPTOPP_NO_VTABLE NetworkSource : public NonblockingSource
00166 {
00167 public:
00168 NetworkSource(BufferedTransformation *attachment);
00169
00170 unsigned int GetMaxWaitObjectCount() const;
00171 void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
00172
00173 bool SourceExhausted() const {return m_dataBegin == m_dataEnd && GetReceiver().EofReceived();}
00174
00175 protected:
00176 size_t DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter);
00177
00178 virtual NetworkReceiver & AccessReceiver() =0;
00179 const NetworkReceiver & GetReceiver() const {return const_cast<NetworkSource *>(this)->AccessReceiver();}
00180
00181 private:
00182 SecByteBlock m_buf;
00183 size_t m_putSize, m_dataBegin, m_dataEnd;
00184 bool m_waitingForResult, m_outputBlocked;
00185 };
00186
00187
00188 class CRYPTOPP_NO_VTABLE NetworkSink : public NonblockingSink
00189 {
00190 public:
00191 NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound);
00192
00193 unsigned int GetMaxWaitObjectCount() const;
00194 void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
00195
00196 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
00197
00198 void SetMaxBufferSize(size_t maxBufferSize) {m_maxBufferSize = maxBufferSize; m_buffer.SetNodeSize(UnsignedMin(maxBufferSize, 16U*1024U+256U));}
00199 void SetAutoFlushBound(size_t bound) {m_autoFlushBound = bound;}
00200
00201 size_t GetMaxBufferSize() const {return m_maxBufferSize;}
00202 size_t GetCurrentBufferSize() const {return (size_t)m_buffer.CurrentSize();}
00203
00204 void ClearBuffer() { m_buffer.Clear(); }
00205
00206 bool EofPending() const { return m_eofState > EOF_NONE && m_eofState < EOF_DONE; }
00207
00208
00209 float ComputeCurrentSpeed();
00210
00211 float GetMaxObservedSpeed() const;
00212
00213 protected:
00214 lword DoFlush(unsigned long maxTime, size_t targetSize);
00215
00216 virtual NetworkSender & AccessSender() =0;
00217 const NetworkSender & GetSender() const {return const_cast<NetworkSink *>(this)->AccessSender();}
00218
00219 private:
00220 enum EofState { EOF_NONE, EOF_PENDING_SEND, EOF_PENDING_DELIVERY, EOF_DONE };
00221
00222 size_t m_maxBufferSize, m_autoFlushBound;
00223 bool m_needSendResult, m_wasBlocked;
00224 EofState m_eofState;
00225 ByteQueue m_buffer;
00226 size_t m_skipBytes;
00227 Timer m_speedTimer;
00228 float m_byteCountSinceLastTimerReset, m_currentSpeed, m_maxObservedSpeed;
00229 };
00230
00231 NAMESPACE_END
00232
00233 #endif // #ifdef HIGHRES_TIMER_AVAILABLE
00234
00235 #endif