TCPInterface.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file
  11. /// \brief A simple TCP based server allowing sends and receives. Can be connected by any TCP client, including telnet.
  12. ///
  13. #include "NativeFeatureIncludes.h"
  14. #if _RAKNET_SUPPORT_TCPInterface==1
  15. #ifndef __SIMPLE_TCP_SERVER
  16. #define __SIMPLE_TCP_SERVER
  17. #include "RakMemoryOverride.h"
  18. #include "DS_List.h"
  19. #include "RakNetTypes.h"
  20. #include "Export.h"
  21. #include "RakThread.h"
  22. #include "DS_Queue.h"
  23. #include "SimpleMutex.h"
  24. #include "RakNetDefines.h"
  25. #include "SocketIncludes.h"
  26. #include "DS_ByteQueue.h"
  27. #include "DS_ThreadsafeAllocatingQueue.h"
  28. #include "LocklessTypes.h"
  29. #include "PluginInterface2.h"
  30. #if OPEN_SSL_CLIENT_SUPPORT==1
  31. #include <openssl/crypto.h>
  32. #include <openssl/x509.h>
  33. #include <openssl/pem.h>
  34. #include <openssl/ssl.h>
  35. #include <openssl/err.h>
  36. #endif
  37. namespace RakNet
  38. {
  39. /// Forward declarations
  40. struct RemoteClient;
  41. /// \internal
  42. /// \brief As the name says, a simple multithreaded TCP server. Used by TelnetTransport
  43. class RAK_DLL_EXPORT TCPInterface
  44. {
  45. public:
  46. // GetInstance() and DestroyInstance(instance*)
  47. STATIC_FACTORY_DECLARATIONS(TCPInterface)
  48. TCPInterface();
  49. virtual ~TCPInterface();
  50. // TODO - add socketdescriptor
  51. /// Starts the TCP server on the indicated port
  52. /// \param[in] port Which port to listen on.
  53. /// \param[in] maxIncomingConnections Max incoming connections we will accept
  54. /// \param[in] maxConnections Max total connections, which should be >= maxIncomingConnections
  55. /// \param[in] threadPriority Passed to the thread creation routine. Use THREAD_PRIORITY_NORMAL for Windows. For Linux based systems, you MUST pass something reasonable based on the thread priorities for your application.
  56. /// \param[in] socketFamily IP version: For IPV4, use AF_INET (default). For IPV6, use AF_INET6. To autoselect, use AF_UNSPEC.
  57. bool Start(unsigned short port, unsigned short maxIncomingConnections, unsigned short maxConnections=0, int _threadPriority=-99999, unsigned short socketFamily=AF_INET, const char *bindAddress=0);
  58. /// Stops the TCP server
  59. void Stop(void);
  60. /// Connect to the specified host on the specified port
  61. SystemAddress Connect(const char* host, unsigned short remotePort, bool block=true, unsigned short socketFamily=AF_INET, const char *bindAddress=0);
  62. #if OPEN_SSL_CLIENT_SUPPORT==1
  63. /// Start SSL on an existing connection, notified with HasCompletedConnectionAttempt
  64. void StartSSLClient(SystemAddress systemAddress);
  65. /// Was SSL started on this socket?
  66. bool IsSSLActive(SystemAddress systemAddress);
  67. #endif
  68. /// Sends a byte stream
  69. virtual void Send( const char *data, unsigned int length, const SystemAddress &systemAddress, bool broadcast );
  70. // Sends a concatenated list of byte streams
  71. virtual bool SendList( const char **data, const unsigned int *lengths, const int numParameters, const SystemAddress &systemAddress, bool broadcast );
  72. // Get how many bytes are waiting to be sent. If too many, you may want to skip sending
  73. unsigned int GetOutgoingDataBufferSize(SystemAddress systemAddress) const;
  74. /// Returns if Receive() will return data
  75. /// Do not use on PacketizedTCP
  76. virtual bool ReceiveHasPackets( void );
  77. /// Returns data received
  78. virtual Packet* Receive( void );
  79. /// Disconnects a player/address
  80. void CloseConnection( SystemAddress systemAddress );
  81. /// Deallocates a packet returned by Receive
  82. void DeallocatePacket( Packet *packet );
  83. /// Fills the array remoteSystems with the SystemAddress of all the systems we are connected to
  84. /// \param[out] remoteSystems An array of SystemAddress structures to be filled with the SystemAddresss of the systems we are connected to. Pass 0 to remoteSystems to only get the number of systems we are connected to
  85. /// \param[in, out] numberOfSystems As input, the size of remoteSystems array. As output, the number of elements put into the array
  86. void GetConnectionList( SystemAddress *remoteSystems, unsigned short *numberOfSystems ) const;
  87. /// Returns just the number of connections we have
  88. unsigned short GetConnectionCount(void) const;
  89. /// Has a previous call to connect succeeded?
  90. /// \return UNASSIGNED_SYSTEM_ADDRESS = no. Anything else means yes.
  91. SystemAddress HasCompletedConnectionAttempt(void);
  92. /// Has a previous call to connect failed?
  93. /// \return UNASSIGNED_SYSTEM_ADDRESS = no. Anything else means yes.
  94. SystemAddress HasFailedConnectionAttempt(void);
  95. /// Queued events of new incoming connections
  96. SystemAddress HasNewIncomingConnection(void);
  97. /// Queued events of lost connections
  98. SystemAddress HasLostConnection(void);
  99. /// Return an allocated but empty packet, for custom use
  100. Packet* AllocatePacket(unsigned dataSize);
  101. // Push a packet back to the queue
  102. virtual void PushBackPacket( Packet *packet, bool pushAtHead );
  103. /// Returns if Start() was called successfully
  104. bool WasStarted(void) const;
  105. void AttachPlugin( PluginInterface2 *plugin );
  106. void DetachPlugin( PluginInterface2 *plugin );
  107. protected:
  108. Packet* ReceiveInt( void );
  109. #if defined(WINDOWS_STORE_RT)
  110. bool CreateListenSocket_WinStore8(unsigned short port, unsigned short maxIncomingConnections, unsigned short socketFamily, const char *hostAddress);
  111. #else
  112. bool CreateListenSocket(unsigned short port, unsigned short maxIncomingConnections, unsigned short socketFamily, const char *hostAddress);
  113. #endif
  114. // Plugins
  115. DataStructures::List<PluginInterface2*> messageHandlerList;
  116. RakNet::LocklessUint32_t isStarted, threadRunning;
  117. __TCPSOCKET__ listenSocket;
  118. DataStructures::Queue<Packet*> headPush, tailPush;
  119. RemoteClient* remoteClients;
  120. int remoteClientsLength;
  121. // Assuming remoteClients is only used by one thread!
  122. // DataStructures::List<RemoteClient*> remoteClients;
  123. // Use this thread-safe queue to add to remoteClients
  124. // DataStructures::Queue<RemoteClient*> remoteClientsInsertionQueue;
  125. // SimpleMutex remoteClientsInsertionQueueMutex;
  126. /*
  127. struct OutgoingMessage
  128. {
  129. unsigned char* data;
  130. SystemAddress systemAddress;
  131. bool broadcast;
  132. unsigned int length;
  133. };
  134. */
  135. // DataStructures::SingleProducerConsumer<OutgoingMessage> outgoingMessages;
  136. // DataStructures::SingleProducerConsumer<Packet> incomingMessages;
  137. // DataStructures::SingleProducerConsumer<SystemAddress> newIncomingConnections, lostConnections, requestedCloseConnections;
  138. // DataStructures::SingleProducerConsumer<RemoteClient*> newRemoteClients;
  139. // DataStructures::ThreadsafeAllocatingQueue<OutgoingMessage> outgoingMessages;
  140. DataStructures::ThreadsafeAllocatingQueue<Packet> incomingMessages;
  141. DataStructures::ThreadsafeAllocatingQueue<SystemAddress> newIncomingConnections, lostConnections, requestedCloseConnections;
  142. DataStructures::ThreadsafeAllocatingQueue<RemoteClient*> newRemoteClients;
  143. SimpleMutex completedConnectionAttemptMutex, failedConnectionAttemptMutex;
  144. DataStructures::Queue<SystemAddress> completedConnectionAttempts, failedConnectionAttempts;
  145. int threadPriority;
  146. DataStructures::List<__TCPSOCKET__> blockingSocketList;
  147. SimpleMutex blockingSocketListMutex;
  148. friend RAK_THREAD_DECLARATION(UpdateTCPInterfaceLoop);
  149. friend RAK_THREAD_DECLARATION(ConnectionAttemptLoop);
  150. // void DeleteRemoteClient(RemoteClient *remoteClient, fd_set *exceptionFD);
  151. // void InsertRemoteClient(RemoteClient* remoteClient);
  152. __TCPSOCKET__ SocketConnect(const char* host, unsigned short remotePort, unsigned short socketFamily, const char *bindAddress);
  153. struct ThisPtrPlusSysAddr
  154. {
  155. TCPInterface *tcpInterface;
  156. SystemAddress systemAddress;
  157. bool useSSL;
  158. char bindAddress[64];
  159. unsigned short socketFamily;
  160. };
  161. #if OPEN_SSL_CLIENT_SUPPORT==1
  162. SSL_CTX* ctx;
  163. SSL_METHOD *meth;
  164. DataStructures::ThreadsafeAllocatingQueue<SystemAddress> startSSL;
  165. DataStructures::List<SystemAddress> activeSSLConnections;
  166. SimpleMutex sharedSslMutex;
  167. #endif
  168. };
  169. /// Stores information about a remote client.
  170. struct RemoteClient
  171. {
  172. RemoteClient() {
  173. #if OPEN_SSL_CLIENT_SUPPORT==1
  174. ssl=0;
  175. #endif
  176. isActive=false;
  177. #if !defined(WINDOWS_STORE_RT)
  178. socket=0;
  179. #endif
  180. }
  181. __TCPSOCKET__ socket;
  182. SystemAddress systemAddress;
  183. DataStructures::ByteQueue outgoingData;
  184. bool isActive;
  185. SimpleMutex outgoingDataMutex;
  186. SimpleMutex isActiveMutex;
  187. #if OPEN_SSL_CLIENT_SUPPORT==1
  188. SSL* ssl;
  189. bool InitSSL(SSL_CTX* ctx, SSL_METHOD *meth);
  190. void DisconnectSSL(void);
  191. void FreeSSL(void);
  192. int Send(const char *data, unsigned int length);
  193. int Recv(char *data, const int dataSize);
  194. #else
  195. int Send(const char *data, unsigned int length);
  196. int Recv(char *data, const int dataSize);
  197. #endif
  198. void Reset(void)
  199. {
  200. outgoingDataMutex.Lock();
  201. outgoingData.Clear(_FILE_AND_LINE_);
  202. outgoingDataMutex.Unlock();
  203. }
  204. void SetActive(bool a);
  205. void SendOrBuffer(const char **data, const unsigned int *lengths, const int numParameters);
  206. };
  207. } // namespace RakNet
  208. #endif
  209. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号