Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
5.9 KiB

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