Crypto++  5.6.3
Free C++ class library of cryptographic schemes
network.h
1 #ifndef CRYPTOPP_NETWORK_H
2 #define CRYPTOPP_NETWORK_H
3 
4 #include "config.h"
5 
6 #ifdef HIGHRES_TIMER_AVAILABLE
7 
8 #include "filters.h"
9 #include "hrtimer.h"
10 
11 #include <deque>
12 
13 NAMESPACE_BEGIN(CryptoPP)
14 
16 {
17 public:
18  LimitedBandwidth(lword maxBytesPerSecond = 0)
19  : m_maxBytesPerSecond(maxBytesPerSecond), m_timer(Timer::MILLISECONDS)
20  , m_nextTransceiveTime(0)
21  { m_timer.StartTimer(); }
22 
23  lword GetMaxBytesPerSecond() const
24  { return m_maxBytesPerSecond; }
25 
26  void SetMaxBytesPerSecond(lword v)
27  { m_maxBytesPerSecond = v; }
28 
29  lword ComputeCurrentTransceiveLimit();
30 
31  double TimeToNextTransceive();
32 
33  void NoteTransceive(lword size);
34 
35 public:
36  /*! GetWaitObjects() must be called despite the 0 return from GetMaxWaitObjectCount();
37  the 0 is because the ScheduleEvent() method is used instead of adding a wait object */
38  unsigned int GetMaxWaitObjectCount() const { return 0; }
39  void GetWaitObjects(WaitObjectContainer &container, const CallStack &callStack);
40 
41 private:
42  lword m_maxBytesPerSecond;
43 
44  typedef std::deque<std::pair<double, lword> > OpQueue;
45  OpQueue m_ops;
46 
47  Timer m_timer;
48  double m_nextTransceiveTime;
49 
50  void ComputeNextTransceiveTime();
51  double GetCurTimeAndCleanUp();
52 };
53 
54 //! a Source class that can pump from a device for a specified amount of time.
55 class CRYPTOPP_NO_VTABLE NonblockingSource : public AutoSignaling<Source>, public LimitedBandwidth
56 {
57 public:
59  : m_messageEndSent(false) , m_doPumpBlocked(false), m_blockedBySpeedLimit(false) {Detach(attachment);}
60 
61  //! \name NONBLOCKING SOURCE
62  //@{
63 
64  //! pump up to maxSize bytes using at most maxTime milliseconds
65  /*! If checkDelimiter is true, pump up to delimiter, which itself is not extracted or pumped. */
66  size_t GeneralPump2(lword &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n');
67 
68  lword GeneralPump(lword maxSize=LWORD_MAX, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n')
69  {
70  GeneralPump2(maxSize, true, maxTime, checkDelimiter, delimiter);
71  return maxSize;
72  }
73  lword TimedPump(unsigned long maxTime)
74  {return GeneralPump(LWORD_MAX, maxTime);}
75  lword PumpLine(byte delimiter='\n', lword maxSize=1024)
76  {return GeneralPump(maxSize, INFINITE_TIME, true, delimiter);}
77 
78  size_t Pump2(lword &byteCount, bool blocking=true)
79  {return GeneralPump2(byteCount, blocking, blocking ? INFINITE_TIME : 0);}
80  size_t PumpMessages2(unsigned int &messageCount, bool blocking=true);
81  //@}
82 
83 protected:
84  virtual size_t DoPump(lword &byteCount, bool blockingOutput,
85  unsigned long maxTime, bool checkDelimiter, byte delimiter) =0;
86 
87  bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; }
88 
89 private:
90  bool m_messageEndSent, m_doPumpBlocked, m_blockedBySpeedLimit;
91 };
92 
93 //! Network Receiver
94 class CRYPTOPP_NO_VTABLE NetworkReceiver : public Waitable
95 {
96 public:
97  virtual bool MustWaitToReceive() {return false;}
98  virtual bool MustWaitForResult() {return false;}
99  //! receive data from network source, returns whether result is immediately available
100  virtual bool Receive(byte* buf, size_t bufLen) =0;
101  virtual unsigned int GetReceiveResult() =0;
102  virtual bool EofReceived() const =0;
103 };
104 
105 class CRYPTOPP_NO_VTABLE NonblockingSinkInfo
106 {
107 public:
108  virtual ~NonblockingSinkInfo() {}
109  virtual size_t GetMaxBufferSize() const =0;
110  virtual size_t GetCurrentBufferSize() const =0;
111  virtual bool EofPending() const =0;
112  //! compute the current speed of this sink in bytes per second
113  virtual float ComputeCurrentSpeed() =0;
114  //! get the maximum observed speed of this sink in bytes per second
115  virtual float GetMaxObservedSpeed() const =0;
116 };
117 
118 //! a Sink class that queues input and can flush to a device for a specified amount of time.
119 class CRYPTOPP_NO_VTABLE NonblockingSink : public Sink, public NonblockingSinkInfo, public LimitedBandwidth
120 {
121 public:
122  NonblockingSink() : m_blockedBySpeedLimit(false) {}
123 
124  bool IsolatedFlush(bool hardFlush, bool blocking);
125 
126  //! flush to device for no more than maxTime milliseconds
127  /*! This function will repeatedly attempt to flush data to some device, until
128  the queue is empty, or a total of maxTime milliseconds have elapsed.
129  If maxTime == 0, at least one attempt will be made to flush some data, but
130  it is likely that not all queued data will be flushed, even if the device
131  is ready to receive more data without waiting. If you want to flush as much data
132  as possible without waiting for the device, call this function in a loop.
133  For example: while (sink.TimedFlush(0) > 0) {}
134  \return number of bytes flushed
135  */
136  lword TimedFlush(unsigned long maxTime, size_t targetSize = 0);
137 
138  virtual void SetMaxBufferSize(size_t maxBufferSize) =0;
139  //! set a bound which will cause sink to flush if exceeded by GetCurrentBufferSize()
140  virtual void SetAutoFlushBound(size_t bound) =0;
141 
142 protected:
143  virtual lword DoFlush(unsigned long maxTime, size_t targetSize) = 0;
144 
145  bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; }
146 
147 private:
148  bool m_blockedBySpeedLimit;
149 };
150 
151 //! Network Sender
152 class CRYPTOPP_NO_VTABLE NetworkSender : public Waitable
153 {
154 public:
155  virtual bool MustWaitToSend() {return false;}
156  virtual bool MustWaitForResult() {return false;}
157  virtual void Send(const byte* buf, size_t bufLen) =0;
158  virtual unsigned int GetSendResult() =0;
159  virtual bool MustWaitForEof() {return false;}
160  virtual void SendEof() =0;
161  virtual bool EofSent() {return false;} // implement if MustWaitForEof() == true
162 };
163 
164 //! Network Source
165 class CRYPTOPP_NO_VTABLE NetworkSource : public NonblockingSource
166 {
167 public:
169 
170  unsigned int GetMaxWaitObjectCount() const;
171  void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
172 
173  bool SourceExhausted() const {return m_dataBegin == m_dataEnd && GetReceiver().EofReceived();}
174 
175 protected:
176  size_t DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter);
177 
178  virtual NetworkReceiver & AccessReceiver() =0;
179  const NetworkReceiver & GetReceiver() const {return const_cast<NetworkSource *>(this)->AccessReceiver();}
180 
181 private:
182  SecByteBlock m_buf;
183  size_t m_putSize, m_dataBegin, m_dataEnd;
184  bool m_waitingForResult, m_outputBlocked;
185 };
186 
187 //! Network Sink
188 class CRYPTOPP_NO_VTABLE NetworkSink : public NonblockingSink
189 {
190 public:
191  NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound);
192 
193  unsigned int GetMaxWaitObjectCount() const;
194  void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
195 
196  size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
197 
198  void SetMaxBufferSize(size_t maxBufferSize) {m_maxBufferSize = maxBufferSize; m_buffer.SetNodeSize(UnsignedMin(maxBufferSize, 16U*1024U+256U));}
199  void SetAutoFlushBound(size_t bound) {m_autoFlushBound = bound;}
200 
201  size_t GetMaxBufferSize() const {return m_maxBufferSize;}
202  size_t GetCurrentBufferSize() const {return (size_t)m_buffer.CurrentSize();}
203 
204  void ClearBuffer() { m_buffer.Clear(); }
205 
206  bool EofPending() const { return m_eofState > EOF_NONE && m_eofState < EOF_DONE; }
207 
208  //! compute the current speed of this sink in bytes per second
209  float ComputeCurrentSpeed();
210  //! get the maximum observed speed of this sink in bytes per second
211  float GetMaxObservedSpeed() const;
212 
213 protected:
214  lword DoFlush(unsigned long maxTime, size_t targetSize);
215 
216  virtual NetworkSender & AccessSender() =0;
217  const NetworkSender & GetSender() const {return const_cast<NetworkSink *>(this)->AccessSender();}
218 
219 private:
220  enum EofState { EOF_NONE, EOF_PENDING_SEND, EOF_PENDING_DELIVERY, EOF_DONE };
221 
222  size_t m_maxBufferSize, m_autoFlushBound;
223  bool m_needSendResult, m_wasBlocked;
224  EofState m_eofState;
225  ByteQueue m_buffer;
226  size_t m_skipBytes;
227  Timer m_speedTimer;
228  float m_byteCountSinceLastTimerReset, m_currentSpeed, m_maxObservedSpeed;
229 };
230 
231 NAMESPACE_END
232 
233 #endif // #ifdef HIGHRES_TIMER_AVAILABLE
234 
235 #endif
Network Source.
Definition: network.h:165
container of wait objects
Definition: wait.h:154
high resolution timer
Definition: hrtimer.h:53
virtual float GetMaxObservedSpeed() const =0
get the maximum observed speed of this sink in bytes per second
virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)=0
Input multiple bytes for processing.
void SetAutoFlushBound(size_t bound)
set a bound which will cause sink to flush if exceeded by GetCurrentBufferSize()
Definition: network.h:199
virtual float ComputeCurrentSpeed()=0
compute the current speed of this sink in bytes per second
Library configuration file.
SecBlock typedef.
Definition: secblock.h:730
Interface for buffered transformations.
Definition: cryptlib.h:1352
Interface for objects that can be waited on.
Definition: cryptlib.h:1295
a Sink class that queues input and can flush to a device for a specified amount of time...
Definition: network.h:119
bool SourceExhausted() const
Determines if the Source is exhausted.
Definition: network.h:173
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:433
Data structure used to store byte strings.
Definition: queue.h:20
const unsigned long INFINITE_TIME
Represents infinite time.
Definition: cryptlib.h:110
virtual bool IsolatedFlush(bool hardFlush, bool blocking)=0
Flushes data buffered by this object, without signal propagation.
Implementation of BufferedTransformation's attachment interface.
unsigned int GetMaxWaitObjectCount() const
Definition: network.h:38
size_t Pump2(lword &byteCount, bool blocking=true)
Pump data to attached transformation.
Definition: network.h:78
Implementation of BufferedTransformation's attachment interface.
Definition: simple.h:276
Provides auto signaling support.
Definition: simple.h:226
Crypto++ library namespace.
Network Receiver.
Definition: network.h:94
a Source class that can pump from a device for a specified amount of time.
Definition: network.h:55
Network Sink.
Definition: network.h:188
Network Sender.
Definition: network.h:152