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