Crypto++  5.6.3
Free C++ class library of cryptographic schemes
socketft.h
1 #ifndef CRYPTOPP_SOCKETFT_H
2 #define CRYPTOPP_SOCKETFT_H
3 
4 #ifdef SOCKETS_AVAILABLE
5 
6 #include "cryptlib.h"
7 #include "network.h"
8 #include "queue.h"
9 
10 #ifdef USE_WINDOWS_STYLE_SOCKETS
11 # if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
12 # error Winsock 1 is not supported by this library. Please include this file or winsock2.h before windows.h.
13 # endif
14 #include <winsock2.h>
15 #include "winpipes.h"
16 #else
17 #include <sys/time.h>
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <unistd.h>
21 #endif
22 
23 NAMESPACE_BEGIN(CryptoPP)
24 
25 #ifdef USE_WINDOWS_STYLE_SOCKETS
26 typedef ::SOCKET socket_t;
27 #else
28 typedef int socket_t;
29 const socket_t INVALID_SOCKET = -1;
30 // cygwin 1.1.4 doesn't have SHUT_RD
31 const int SD_RECEIVE = 0;
32 const int SD_SEND = 1;
33 const int SD_BOTH = 2;
34 const int SOCKET_ERROR = -1;
35 #endif
36 
37 #ifndef socklen_t
38 typedef TYPE_OF_SOCKLEN_T socklen_t; // see config.h
39 #endif
40 
41 //! wrapper for Windows or Berkeley Sockets
42 class Socket
43 {
44 public:
45  //! exception thrown by Socket class
46  class Err : public OS_Error
47  {
48  public:
49  Err(socket_t s, const std::string& operation, int error);
50  socket_t GetSocket() const {return m_s;}
51 
52  private:
53  socket_t m_s;
54  };
55 
56  Socket(socket_t s = INVALID_SOCKET, bool own=false) : m_s(s), m_own(own) {}
57  Socket(const Socket &s) : m_s(s.m_s), m_own(false) {}
58  virtual ~Socket();
59 
60  bool GetOwnership() const {return m_own;}
61  void SetOwnership(bool own) {m_own = own;}
62 
63  operator socket_t() {return m_s;}
64  socket_t GetSocket() const {return m_s;}
65  void AttachSocket(socket_t s, bool own=false);
66  socket_t DetachSocket();
67  void CloseSocket();
68 
69  void Create(int nType = SOCK_STREAM);
70  void Bind(unsigned int port, const char *addr=NULL);
71  void Bind(const sockaddr* psa, socklen_t saLen);
72  void Listen(int backlog=5);
73  // the next three functions return false if the socket is in nonblocking mode
74  // and the operation cannot be completed immediately
75  bool Connect(const char *addr, unsigned int port);
76  bool Connect(const sockaddr* psa, socklen_t saLen);
77  bool Accept(Socket& s, sockaddr *psa=NULL, socklen_t *psaLen=NULL);
78  void GetSockName(sockaddr *psa, socklen_t *psaLen);
79  void GetPeerName(sockaddr *psa, socklen_t *psaLen);
80  unsigned int Send(const byte* buf, size_t bufLen, int flags=0);
81  unsigned int Receive(byte* buf, size_t bufLen, int flags=0);
82  void ShutDown(int how = SD_SEND);
83 
84  void IOCtl(long cmd, unsigned long *argp);
85  bool SendReady(const timeval *timeout);
86  bool ReceiveReady(const timeval *timeout);
87 
88  virtual void HandleError(const char *operation) const;
89  void CheckAndHandleError_int(const char *operation, int result) const
90  {if (result == SOCKET_ERROR) HandleError(operation);}
91  void CheckAndHandleError(const char *operation, socket_t result) const
92  {if (result == static_cast<socket_t>(SOCKET_ERROR)) HandleError(operation);}
93 #ifdef USE_WINDOWS_STYLE_SOCKETS
94  void CheckAndHandleError(const char *operation, BOOL result) const
95  {assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);}
96  void CheckAndHandleError(const char *operation, bool result) const
97  {if (!result) HandleError(operation);}
98 #endif
99 
100  //! look up the port number given its name, returns 0 if not found
101  static unsigned int PortNameToNumber(const char *name, const char *protocol="tcp");
102  //! start Windows Sockets 2
103  static void StartSockets();
104  //! calls WSACleanup for Windows Sockets
105  static void ShutdownSockets();
106  //! returns errno or WSAGetLastError
107  static int GetLastError();
108  //! sets errno or calls WSASetLastError
109  static void SetLastError(int errorCode);
110 
111 protected:
112  virtual void SocketChanged() {}
113 
114  socket_t m_s;
115  bool m_own;
116 };
117 
118 class SocketsInitializer
119 {
120 public:
121  SocketsInitializer() {Socket::StartSockets();}
122  ~SocketsInitializer() {try {Socket::ShutdownSockets();} catch (const Exception&) {assert(0);}}
123 };
124 
125 class SocketReceiver : public NetworkReceiver
126 {
127 public:
128  SocketReceiver(Socket &s);
129 
130 #ifdef USE_BERKELEY_STYLE_SOCKETS
131  bool MustWaitToReceive() {return true;}
132 #else
133  ~SocketReceiver();
134  bool MustWaitForResult() {return true;}
135 #endif
136  bool Receive(byte* buf, size_t bufLen);
137  unsigned int GetReceiveResult();
138  bool EofReceived() const {return m_eofReceived;}
139 
140  unsigned int GetMaxWaitObjectCount() const {return 1;}
141  void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
142 
143 private:
144  Socket &m_s;
145  bool m_eofReceived;
146 
147 #ifdef USE_WINDOWS_STYLE_SOCKETS
148  WindowsHandle m_event;
149  OVERLAPPED m_overlapped;
150  bool m_resultPending;
151  DWORD m_lastResult;
152 #else
153  unsigned int m_lastResult;
154 #endif
155 };
156 
157 class SocketSender : public NetworkSender
158 {
159 public:
160  SocketSender(Socket &s);
161 
162 #ifdef USE_BERKELEY_STYLE_SOCKETS
163  bool MustWaitToSend() {return true;}
164 #else
165  ~SocketSender();
166  bool MustWaitForResult() {return true;}
167  bool MustWaitForEof() { return true; }
168  bool EofSent();
169 #endif
170  void Send(const byte* buf, size_t bufLen);
171  unsigned int GetSendResult();
172  void SendEof();
173 
174  unsigned int GetMaxWaitObjectCount() const {return 1;}
175  void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack);
176 
177 private:
178  Socket &m_s;
179 #ifdef USE_WINDOWS_STYLE_SOCKETS
180  WindowsHandle m_event;
181  OVERLAPPED m_overlapped;
182  bool m_resultPending;
183  DWORD m_lastResult;
184 #else
185  unsigned int m_lastResult;
186 #endif
187 };
188 
189 //! socket-based implementation of NetworkSource
190 class SocketSource : public NetworkSource, public Socket
191 {
192 public:
193  SocketSource(socket_t s = INVALID_SOCKET, bool pumpAll = false, BufferedTransformation *attachment = NULL)
194  : NetworkSource(attachment), Socket(s), m_receiver(*this)
195  {
196  if (pumpAll)
197  PumpAll();
198  }
199 
200 private:
201  NetworkReceiver & AccessReceiver() {return m_receiver;}
202  SocketReceiver m_receiver;
203 };
204 
205 //! socket-based implementation of NetworkSink
206 class SocketSink : public NetworkSink, public Socket
207 {
208 public:
209  SocketSink(socket_t s=INVALID_SOCKET, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024)
210  : NetworkSink(maxBufferSize, autoFlushBound), Socket(s), m_sender(*this) {}
211 
212  void SendEof() {ShutDown(SD_SEND);}
213 
214 private:
215  NetworkSender & AccessSender() {return m_sender;}
216  SocketSender m_sender;
217 };
218 
219 NAMESPACE_END
220 
221 #endif // #ifdef SOCKETS_AVAILABLE
222 
223 #endif
Network Source.
Definition: network.h:165
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:139
container of wait objects
Definition: wait.h:154
The operating system reported an error.
Definition: cryptlib.h:217
void PumpAll()
Pump all data to attached transformation.
Definition: filters.h:1165
Abstract base classes that provide a uniform interface to this library.
Interface for buffered transformations.
Definition: cryptlib.h:1352
Classes for an unlimited queue to store bytes.
virtual void GetWaitObjects(WaitObjectContainer &container, CallStack const &callStack)=0
Retrieves waitable objects.
virtual bool Receive(byte *buf, size_t bufLen)=0
receive data from network source, returns whether result is immediately available ...
Crypto++ library namespace.
Network Receiver.
Definition: network.h:94
virtual unsigned int GetMaxWaitObjectCount() const =0
Maximum number of wait objects that this object can return.
Network Sink.
Definition: network.h:188
Network Sender.
Definition: network.h:152