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