ProtoBSDIP.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. // ProtoBSDIP.h
  19. // Project: Postal
  20. //
  21. // History:
  22. // 08/04/97 BRH Started.
  23. //
  24. //////////////////////////////////////////////////////////////////////////////
  25. //
  26. // This is the BSD sockets/winsock tcpip plugin protocol for our sockets
  27. // interface.
  28. //
  29. //////////////////////////////////////////////////////////////////////////////
  30. #ifndef PROTOBSDIP_H
  31. #define PROTOBSDIP_H
  32. #ifdef WIN32
  33. #include <winsock.h>
  34. #else
  35. // (that should just about cover it... --ryan.)
  36. #include <stdio.h>
  37. #include <unistd.h>
  38. #include <sys/types.h>
  39. #include <sys/socket.h>
  40. #include <netinet/in.h>
  41. #include <arpa/inet.h>
  42. #include <netdb.h>
  43. #include <sys/uio.h>
  44. #include <sys/ioctl.h>
  45. #include <sys/time.h>
  46. #include <errno.h>
  47. #include <pthread.h>
  48. #include <fcntl.h>
  49. // WinSock will define these, but BSD sockets don't...
  50. #if 0 //PLATFORM_MACOSX
  51. typedef int socklen_t;
  52. #endif
  53. typedef struct sockaddr_in SOCKADDR_IN;
  54. typedef SOCKADDR_IN *PSOCKADDR_IN;
  55. typedef int SOCKET;
  56. typedef struct hostent HOSTENT;
  57. typedef in_addr IN_ADDR;
  58. typedef struct sockaddr SOCKADDR;
  59. typedef struct sockaddr_in SOCKADDR_IN;
  60. typedef struct linger LINGER;
  61. typedef struct timeval TIMEVAL;
  62. typedef socklen_t SOCKLEN;
  63. typedef int WSADATA; // not used in BSD sockets.
  64. #define WSAStartup(a, b) (0)
  65. #define WSACleanup() (0)
  66. #define WSAGetLastError() (errno)
  67. #define INVALID_SOCKET -1
  68. #define SOCKET_ERROR -1
  69. #define closesocket(s) close(s)
  70. #define ioctlsocket(s, t, v) ioctl(s, t, v)
  71. #endif
  72. #include "socket.h"
  73. class RProtocolBSDIP : public RSocket::RProtocol
  74. {
  75. //------------------------------------------------------------------------------
  76. // Types, enums, etc.
  77. //------------------------------------------------------------------------------
  78. public:
  79. // This protocol's specific address, which MUST BE EXACTLY THE SAME SIZE
  80. // as RProtocol::Address, and the first fields prior to the address field
  81. // MUST BE THE SAME as RProtocol::Address. Any necessary padding should be
  82. // added after the address field.
  83. typedef struct tAddressIP
  84. {
  85. public:
  86. RSocket::ProtoType prototype; // Type of protocol
  87. long lAddressLen; // Actual address length (always <= MaxAddressSize)
  88. SOCKADDR_IN address; // Address
  89. bool operator==(const tAddressIP& rhs) const
  90. {
  91. // Note that we ignore the zero stuff, which doesn't matter if it's different
  92. if ( (prototype == rhs.prototype) &&
  93. (lAddressLen == rhs.lAddressLen) &&
  94. (address.sin_family == rhs.address.sin_family) &&
  95. (address.sin_port == rhs.address.sin_port) &&
  96. (memcmp(&address.sin_addr, &rhs.address.sin_addr, sizeof(address.sin_addr)) == 0) )
  97. return true;
  98. return false;
  99. }
  100. } AddressIP;
  101. //------------------------------------------------------------------------------
  102. // Variables
  103. //------------------------------------------------------------------------------
  104. public:
  105. SOCKET m_sock; // Socket
  106. short m_sType; // Type of socket (RSocket::typ*)
  107. //------------------------------------------------------------------------------
  108. // Static Variables
  109. //------------------------------------------------------------------------------
  110. public:
  111. static bool ms_bDidStartup; // Whether Startup was called successfully
  112. static bool ms_bWSAStartup; // Whether WSAStartup() was called
  113. static WSADATA ms_WSAData; // Data regarding current socket implimentation
  114. #ifdef WIN32
  115. static bool ms_bWSASetBlockingHook; // Whether WSASetBlockingHook() was called
  116. static RSocket::BLOCK_CALLBACK ms_callback; // Blocking hook callback
  117. static RSocket::FuncNum ms_funcnum; // Which socket function, if any, is being executed
  118. #endif
  119. //------------------------------------------------------------------------------
  120. // Functions
  121. //------------------------------------------------------------------------------
  122. public:
  123. // Constructor
  124. RProtocolBSDIP();
  125. // Destructor
  126. virtual ~RProtocolBSDIP();
  127. // Restart the object without deleting it.
  128. // NOTE: Derived classes MUST call base class implimentation!
  129. void Reset(void);
  130. // Open a new connection
  131. // A return value of RSocket::errNotSupported means this protocol is
  132. // not supported.
  133. virtual short Open( // Returns 0 if connection was opened
  134. unsigned short usPort, // In: Port number on which to make a connection
  135. short sType, // In: Any one RSocket::typ* enum
  136. short sOptionFlags, // In: Any combo of RSocket::opt* enums
  137. RSocket::BLOCK_CALLBACK callback = NULL); // In: Blocking callback (or NULL to keep current callback)
  138. // Close a connection
  139. virtual short Close( // Returns 0 if successfull, non-zero otherwise
  140. bool bForceNow = true); // In: 'true' means do it now, false follows normal rules
  141. // Set socket to broadcast mode
  142. virtual short Broadcast(void); // Returns 0 if successfull, non-zero otherwise
  143. // Listen for connection requests
  144. virtual short Listen( // Returns 0 if listen port established
  145. short sMaxQueued); // In: Maximum number of queueued connection requests
  146. // Accept request for connection
  147. virtual short Accept( // Returns 0 if accepted
  148. RSocket::RProtocol* pProtocol, // Out: Client's protocol
  149. RSocket::Address* paddress); // Out: Client's address returned here
  150. // Connect to address.
  151. // If the RSocket::optDontBlock option was set on this socket, then this
  152. // function may return RSocket::errWouldBlock, which indicates that it is
  153. // still trying to connect, but has not yet managed to do so. In that case,
  154. // this function should be called repeatedly (polled) until it returns either
  155. // an actual error message other than RSocket::errWouldBlock, which would
  156. // indicate that the connection attempt has failed, or 0, which indicates
  157. // that it has actually connected successfully.
  158. virtual short Connect( // Returns 0 if connected
  159. RSocket::Address* paddress); // In: Remote address to connect to
  160. // Send data - only valid with connected sockets
  161. virtual short Send( // Returns 0 if data was sent
  162. void * pBuf, // In: Pointer to data buffer
  163. long lNumBytes, // In: Number of bytes to send
  164. long *plActualBytes); // Out: Acutal number of bytes sent
  165. // SendTo - send data to specified address - for unconnected sockets
  166. virtual short SendTo( // Returns 0 if data was sent
  167. void* pBuf, // In: Pointer to data buffer
  168. long lNumBytes, // In: Number of bytes to send
  169. long* plActualBytes, // Out: Actual number of bytes sent
  170. RSocket::Address* paddress); // In: Address to send to
  171. // Receive data - only valid for connected sockets
  172. virtual short Receive( // Returns 0 if data was received
  173. void* pBuf, // In: Pointer to data buffer
  174. long lMaxBytes, // In: Maximum number of bytes that fit in the buffer
  175. long* plActualBytes); // Out: Actual number of bytes received into buffer
  176. // RecieveFrom - receive data from given address
  177. virtual short ReceiveFrom( // Returns 0 if data was received
  178. void* pBuf, // In: Pointer to data buffer
  179. long lMaxBytes, // In: Maximum bytes that can fit in buffer
  180. long* plActualBytes, // Out: Actual number of bytes received into buffer
  181. RSocket::Address* paddress); // Out: Source address returned here
  182. // Check if connection can be accepted without blocking
  183. virtual bool CanAcceptWithoutBlocking(void);
  184. // Check if connection can send without blocking
  185. virtual bool CanSendWithoutBlocking(void);
  186. // Check if connection can receive without blocking
  187. virtual bool CanReceiveWithoutBlocking(void);
  188. // See how much data can be received without blocking
  189. virtual long CheckReceivableBytes(void);
  190. // Report error status
  191. virtual bool IsError(void);
  192. // Set callback function
  193. virtual void SetCallback(
  194. RSocket::BLOCK_CALLBACK callback);
  195. // Get callback function
  196. virtual RSocket::BLOCK_CALLBACK GetCallback(void);
  197. // Startup - Do any one time initialization needed for the protocol
  198. static short Startup(void); // Return 0 if there were no errors on startup
  199. // Shutdown - Do any clean up after all objects of a protocol have shut down
  200. static void Shutdown(void);
  201. // Get the maximum datagram size supported by this socket
  202. static short GetMaxDatagramSize( // Returns 0 if info is available
  203. long* plSize); // Out: Maximum datagram size (in bytes)
  204. // Get maximum number of sockets
  205. static short GetMaxSockets( // Returns 0 if successfull, non-zero otherwise
  206. long* plNum);
  207. // Get address from the socket
  208. static short GetAddress( // Returns 0 if successfull, non-zero otherwise
  209. char* pszName, // In: Host's name or dotted address
  210. USHORT usPort, // In: Host's port number
  211. RSocket::Address* paddress); // Out: Address
  212. // Create broadcast address using specified port
  213. static void CreateBroadcastAddress(
  214. unsigned short usPort, // In: Port to broadcast to
  215. RSocket::Address* paddress); // Out: Broadcast address returned here
  216. // Get port from address
  217. static unsigned short GetAddressPort( // Returns port number
  218. RSocket::Address* paddress); // In: Address from which to get port
  219. // Set port for address
  220. static void SetAddressPort(
  221. USHORT usPort, // In: New port number
  222. RSocket::Address* paddress); // I/O:Address who's port is to be set
  223. protected:
  224. #ifdef WIN32
  225. // This is a blocking-hook callback function.
  226. static int CALLBACK BlockingHook(void);
  227. #endif
  228. // Do the initialization stuff
  229. // NOTE: Derived classes MUST call base class implimentation!
  230. void Init(void);
  231. };
  232. #endif //PROTOBSDIP_H
  233. //////////////////////////////////////////////////////////////////////////////
  234. // eof
  235. //////////////////////////////////////////////////////////////////////////////