PageRenderTime 26ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/src/server/game/Server/WorldSocket.h

http://github.com/ProjectSkyfire/SkyFireEMU
C Header | 212 lines | 67 code | 45 blank | 100 comment | 0 complexity | c0f8f74337de94902de9943f683279b4 MD5 | raw file
Possible License(s): BSD-2-Clause, GPL-2.0, GPL-3.0, CC-BY-SA-3.0
  1. /*
  2. * Copyright (C) 2011-2019 Project SkyFire <http://www.projectskyfire.org/>
  3. * Copyright (C) 2008-2019 TrinityCore <http://www.trinitycore.org/>
  4. * Copyright (C) 2005-2019 MaNGOS <https://getmangos.com/>
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 3 of the License, or (at your
  9. * option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. * more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /** \addtogroup u2w User to World Communication
  20. * @{
  21. * \file WorldSocket.h
  22. * \author Derex <derex101@gmail.com>
  23. */
  24. #ifndef _WORLDSOCKET_H
  25. #define _WORLDSOCKET_H
  26. #include <ace/Basic_Types.h>
  27. #include <ace/Synch_Traits.h>
  28. #include <ace/Svc_Handler.h>
  29. #include <ace/SOCK_Stream.h>
  30. #include <ace/Thread_Mutex.h>
  31. #include <ace/Guard_T.h>
  32. #include <ace/Unbounded_Queue.h>
  33. #include <ace/Message_Block.h>
  34. #if !defined (ACE_LACKS_PRAGMA_ONCE)
  35. #pragma once
  36. #endif /* ACE_LACKS_PRAGMA_ONCE */
  37. #include "Common.h"
  38. #include "AuthCrypt.h"
  39. class ACE_Message_Block;
  40. class WorldPacket;
  41. class WorldSession;
  42. /// Handler that can communicate over stream sockets.
  43. typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> WorldHandler;
  44. /**
  45. * WorldSocket.
  46. *
  47. * This class is responsible for the communication with
  48. * remote clients.
  49. * Most methods return -1 on failure.
  50. * The class uses reference counting.
  51. *
  52. * For output the class uses one buffer (64K usually) and
  53. * a queue where it stores packet if there is no place on
  54. * the queue. The reason this is done, is because the server
  55. * does really a lot of small-size writes to it, and it doesn't
  56. * scale well to allocate memory for every. When something is
  57. * written to the output buffer the socket is not immediately
  58. * activated for output (again for the same reason), there
  59. * is 10ms celling (thats why there is Update() method).
  60. * This concept is similar to TCP_CORK, but TCP_CORK
  61. * uses 200ms celling. As result overhead generated by
  62. * sending packets from "producer" threads is minimal,
  63. * and doing a lot of writes with small size is tolerated.
  64. *
  65. * The calls to Update() method are managed by WorldSocketMgr
  66. * and ReactorRunnable.
  67. *
  68. * For input, the class uses one 1024 bytes buffer on stack
  69. * to which it does recv() calls. And then received data is
  70. * distributed where its needed. 1024 matches pretty well the
  71. * traffic generated by client for now.
  72. *
  73. * The input/output do speculative reads/writes (AKA it tryes
  74. * to read all data available in the kernel buffer or tryes to
  75. * write everything available in userspace buffer),
  76. * which is ok for using with Level and Edge Triggered IO
  77. * notification.
  78. *
  79. */
  80. class WorldSocket : public WorldHandler
  81. {
  82. public:
  83. WorldSocket (void);
  84. virtual ~WorldSocket (void);
  85. friend class WorldSocketMgr;
  86. /// Mutex type used for various synchronizations.
  87. typedef ACE_Thread_Mutex LockType;
  88. typedef ACE_Guard<LockType> GuardType;
  89. /// Check if socket is closed.
  90. bool IsClosed (void) const;
  91. /// Close the socket.
  92. void CloseSocket (void);
  93. /// Get address of connected peer.
  94. const std::string& GetRemoteAddress (void) const;
  95. /// Send A packet on the socket, this function is reentrant.
  96. /// @param pct packet to send
  97. /// @return -1 of failure
  98. int SendPacket (const WorldPacket& pct);
  99. /// Add reference to this object.
  100. long AddReference (void);
  101. /// Remove reference to this object.
  102. long RemoveReference (void);
  103. /// things called by ACE framework.
  104. /// Called on open, the void* is the acceptor.
  105. virtual int open (void *);
  106. /// Called on failures inside of the acceptor, don't call from your code.
  107. virtual int close (int);
  108. /// Called when we can read from the socket.
  109. virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE);
  110. /// Called when the socket can write.
  111. virtual int handle_output (ACE_HANDLE = ACE_INVALID_HANDLE);
  112. /// Called when connection is closed or error happens.
  113. virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE,
  114. ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK);
  115. /// Called by WorldSocketMgr/ReactorRunnable.
  116. int Update (void);
  117. private:
  118. /// Helper functions for processing incoming data.
  119. int handle_input_header (void);
  120. int handle_input_payload (void);
  121. int handle_input_missing_data (void);
  122. /// Help functions to mark/unmark the socket for output.
  123. /// @param g the guard is for m_OutBufferLock, the function will release it
  124. int cancel_wakeup_output (GuardType& g);
  125. int schedule_wakeup_output (GuardType& g);
  126. /// Drain the queue if its not empty.
  127. int handle_output_queue (GuardType& g);
  128. /// process one incoming packet.
  129. /// @param new_pct received packet, note that you need to delete it.
  130. int ProcessIncoming (WorldPacket* new_pct);
  131. /// Called by ProcessIncoming() on CMSG_AUTH_SESSION.
  132. int HandleAuthSession (WorldPacket& recvPacket);
  133. /// Called by ProcessIncoming() on CMSG_PING.
  134. int HandlePing (WorldPacket& recvPacket);
  135. private:
  136. /// Time in which the last ping was received
  137. ACE_Time_Value m_LastPingTime;
  138. /// Keep track of over-speed pings, to prevent ping flood.
  139. uint32 m_OverSpeedPings;
  140. /// Address of the remote peer
  141. std::string m_Address;
  142. /// Class used for managing encryption of the headers
  143. AuthCrypt m_Crypt;
  144. /// Mutex lock to protect m_Session
  145. LockType m_SessionLock;
  146. /// Session to which received packets are routed
  147. WorldSession* m_Session;
  148. /// here are stored the fragments of the received data
  149. WorldPacket* m_RecvWPct;
  150. /// This block actually refers to m_RecvWPct contents,
  151. /// which allows easy and safe writing to it.
  152. /// It wont free memory when its deleted. m_RecvWPct takes care of freeing.
  153. ACE_Message_Block m_RecvPct;
  154. /// Fragment of the received header.
  155. ACE_Message_Block m_Header;
  156. /// Mutex for protecting output related data.
  157. LockType m_OutBufferLock;
  158. /// Buffer used for writing output.
  159. ACE_Message_Block* m_OutBuffer;
  160. /// Size of the m_OutBuffer.
  161. size_t m_OutBufferSize;
  162. /// True if the socket is registered with the reactor for output
  163. bool m_OutActive;
  164. uint32 m_Seed;
  165. };
  166. #endif /* _WORLDSOCKET_H */
  167. /// @}