Show
Ignore:
Timestamp:
11/19/08 13:44:02 (17 years ago)
Author:
yumileroy
Message:

[svn] Merge from Mangos:
3c7ac5bd3e20c33a22ac57c5c3bac23a0798dc9e 2008-10-23 19:06:27
Some endianess related fixes and cleanups. By VladimirMangos?.

Original author: megamage
Date: 2008-11-06 16:10:28-06:00

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/game/WorldSocket.h

    r102 r181  
    1111 * This program is distributed in the hope that it will be useful, 
    1212 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1414 * GNU General Public License for more details. 
    1515 * 
    1616 * You should have received a copy of the GNU General Public License 
    1717 * along with this program; if not, write to the Free Software 
    18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
     18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
    1919 */ 
    2020 
     
    2626 
    2727#ifndef _WORLDSOCKET_H 
    28 #define _WORLDSOCKET_H 
     28#define _WORLDSOCKET_H 
    2929 
    3030#include <ace/Basic_Types.h> 
     
    4444 
    4545#include "Common.h" 
    46 #include "Auth/AuthCrypt.h"  
     46#include "Auth/AuthCrypt.h" 
    4747 
    4848class ACE_Message_Block; 
     
    5555/** 
    5656 * WorldSocket. 
    57  *  
    58  * This class is responsible for the comunication with  
     57 * 
     58 * This class is responsible for the comunication with 
    5959 * remote clients. 
    60  * Most methods return -1 on failure.  
     60 * Most methods return -1 on failure. 
    6161 * The class uses refferece counting. 
    6262 * 
    63  * For output the class uses one buffer (64K usually) and  
    64  * a queue where it stores packet if there is no place on  
    65  * the queue. The reason this is done, is because the server  
    66  * does realy a lot of small-size writes to it, and it doesn't  
    67  * scale well to allocate memory for every. When something is  
    68  * writen to the output buffer the socket is not immideately  
    69  * activated for output (again for the same reason), there  
    70  * is 10ms celling (thats why there is Update() method).  
    71  * This concept is simmilar to TCP_CORK, but TCP_CORK  
    72  * usses 200ms celling. As result overhead generated by  
    73  * sending packets from "producer" threads is minimal,  
     63 * For output the class uses one buffer (64K usually) and 
     64 * a queue where it stores packet if there is no place on 
     65 * the queue. The reason this is done, is because the server 
     66 * does realy a lot of small-size writes to it, and it doesn't 
     67 * scale well to allocate memory for every. When something is 
     68 * writen to the output buffer the socket is not immideately 
     69 * activated for output (again for the same reason), there 
     70 * is 10ms celling (thats why there is Update() method). 
     71 * This concept is simmilar to TCP_CORK, but TCP_CORK 
     72 * usses 200ms celling. As result overhead generated by 
     73 * sending packets from "producer" threads is minimal, 
    7474 * and doing a lot of writes with small size is tollerated. 
    75  *  
     75 * 
    7676 * The calls to Upate () method are managed by WorldSocketMgr 
    7777 * and ReactorRunnable. 
    78  *  
    79  * For input ,the class uses one 1024 bytes buffer on stack  
    80  * to which it does recv() calls. And then recieved data is  
    81  * distributed where its needed. 1024 matches pritey well the  
     78 * 
     79 * For input ,the class uses one 1024 bytes buffer on stack 
     80 * to which it does recv() calls. And then recieved data is 
     81 * distributed where its needed. 1024 matches pritey well the 
    8282 * traffic generated by client for now. 
    83  *   
    84  * The input/output do speculative reads/writes (AKA it tryes  
    85  * to read all data avaible in the kernel buffer or tryes to  
    86  * write everything avaible in userspace buffer),  
    87  * which is ok for using with Level and Edge Trigered IO  
     83 * 
     84 * The input/output do speculative reads/writes (AKA it tryes 
     85 * to read all data avaible in the kernel buffer or tryes to 
     86 * write everything avaible in userspace buffer), 
     87 * which is ok for using with Level and Edge Trigered IO 
    8888 * notification. 
    89  *  
     89 * 
    9090 */ 
    9191class WorldSocket : protected WorldHandler 
    9292{ 
    93 public: 
    94   /// Declare some friends 
    95   friend class ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR >; 
    96   friend class WorldSocketMgr; 
    97   friend class ReactorRunnable; 
    98  
    99   /// Declare the acceptor for this class 
    100   typedef ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR > Acceptor; 
    101  
    102   /// Mutex type used for various syncronizations. 
    103   typedef ACE_Thread_Mutex LockType; 
    104   typedef ACE_Guard<LockType> GuardType; 
    105  
    106   /// Queue for storing packets for which there is no space. 
    107   typedef ACE_Unbounded_Queue< WorldPacket* > PacketQueueT; 
    108  
    109   /// Check if socket is closed. 
    110   bool IsClosed (void) const; 
    111  
    112   /// Close the socket. 
    113   void CloseSocket (void); 
    114  
    115   /// Get address of connected peer. 
    116   const std::string& GetRemoteAddress (void) const; 
    117  
    118   /// Send A packet on the socket, this function is reentrant. 
    119   /// @param pct packet to send 
    120   /// @return -1 of failure 
    121   int SendPacket (const WorldPacket& pct); 
    122  
    123   /// Add refference to this object. 
    124   long AddReference (void); 
    125  
    126   /// Remove refference to this object. 
    127   long RemoveReference (void); 
    128  
    129 protected: 
    130   /// things called by ACE framework. 
    131   WorldSocket (void); 
    132   virtual ~WorldSocket (void); 
    133  
    134   /// Called on open ,the void* is the acceptor. 
    135   virtual int open (void *); 
    136  
    137   /// Called on failures inside of the acceptor, don't call from your code. 
    138   virtual int close (int); 
    139  
    140   /// Called when we can read from the socket. 
    141   virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); 
    142  
    143   /// Called when the socket can write. 
    144   virtual int handle_output (ACE_HANDLE = ACE_INVALID_HANDLE); 
    145  
    146   /// Called when connection is closed or error happens. 
    147   virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, 
    148                             ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); 
    149  
    150   /// Called by WorldSocketMgr/ReactorRunnable. 
    151   int Update (void); 
    152  
    153 private: 
    154   /// Helper functions for processing incoming data. 
    155   int handle_input_header (void); 
    156   int handle_input_payload (void); 
    157   int handle_input_missing_data (void); 
    158  
    159   /// Help functions to mark/unmark the socket for output. 
    160   /// @param g the guard is for m_OutBufferLock, the function will release it 
    161   int cancel_wakeup_output (GuardType& g); 
    162   int schedule_wakeup_output (GuardType& g); 
    163  
    164   /// process one incoming packet. 
    165   /// @param new_pct received packet ,note that you need to delete it.  
    166   int ProcessIncoming (WorldPacket* new_pct); 
    167  
    168   /// Called by ProcessIncoming() on CMSG_AUTH_SESSION. 
    169   int HandleAuthSession (WorldPacket& recvPacket); 
    170  
    171   /// Called by ProcessIncoming() on CMSG_PING. 
    172   int HandlePing (WorldPacket& recvPacket); 
    173  
    174   /// Try to write WorldPacket to m_OutBuffer ,return -1 if no space 
    175   /// Need to be called with m_OutBufferLock lock held 
    176   int iSendPacket (const WorldPacket& pct); 
    177  
    178   /// Flush m_PacketQueue if there are packets in it 
    179   /// Need to be called with m_OutBufferLock lock held 
    180   /// @return true if it wrote to the buffer ( AKA you need  
    181   /// to mark the socket for output ). 
    182   bool iFlushPacketQueue (); 
    183  
    184 private: 
    185   /// Time in which the last ping was received 
    186   ACE_Time_Value m_LastPingTime; 
    187    
    188   /// Keep track of overspeed pings ,to prevent ping flood. 
    189   uint32 m_OverSpeedPings; 
    190  
    191   /// Address of the remote peer 
    192   std::string m_Address; 
    193  
    194   /// Class used for managing encryption of the headers 
    195   AuthCrypt m_Crypt; 
    196  
    197   /// Mutex lock to protect m_Session 
    198   LockType m_SessionLock; 
    199  
    200   /// Session to which recieved packets are routed 
    201   WorldSession* m_Session; 
    202  
    203   /// here are stored the fragmens of the recieved data 
    204   WorldPacket* m_RecvWPct; 
    205  
    206   /// This block actually refers to m_RecvWPct contents, 
    207   /// which alows easy and safe writing to it.  
    208   /// It wont free memory when its deleted. m_RecvWPct takes care of freeing. 
    209   ACE_Message_Block m_RecvPct; 
    210  
    211   /// Fragment of the recieved header. 
    212   ACE_Message_Block m_Header; 
    213  
    214   /// Mutex for protecting otuput related data. 
    215   LockType m_OutBufferLock; 
    216  
    217   /// Buffer used for writing output. 
    218   ACE_Message_Block *m_OutBuffer; 
    219  
    220   /// Size of the m_OutBuffer. 
    221   size_t m_OutBufferSize; 
    222  
    223   /// Here are stored packets for which there was no space on m_OutBuffer, 
    224   /// this alows not-to kick player if its buffer is overflowed. 
    225   PacketQueueT m_PacketQueue; 
    226  
    227   /// True if the socket is registered with the reactor for output 
    228   bool m_OutActive; 
    229  
    230   uint32 m_Seed; 
     93    public: 
     94        /// Declare some friends 
     95        friend class ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR >; 
     96        friend class WorldSocketMgr; 
     97        friend class ReactorRunnable; 
     98 
     99        /// Declare the acceptor for this class 
     100        typedef ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR > Acceptor; 
     101 
     102        /// Mutex type used for various syncronizations. 
     103        typedef ACE_Thread_Mutex LockType; 
     104        typedef ACE_Guard<LockType> GuardType; 
     105 
     106        /// Queue for storing packets for which there is no space. 
     107        typedef ACE_Unbounded_Queue< WorldPacket* > PacketQueueT; 
     108 
     109        /// Check if socket is closed. 
     110        bool IsClosed (void) const; 
     111 
     112        /// Close the socket. 
     113        void CloseSocket (void); 
     114 
     115        /// Get address of connected peer. 
     116        const std::string& GetRemoteAddress (void) const; 
     117 
     118        /// Send A packet on the socket, this function is reentrant. 
     119        /// @param pct packet to send 
     120        /// @return -1 of failure 
     121        int SendPacket (const WorldPacket& pct); 
     122 
     123        /// Add refference to this object. 
     124        long AddReference (void); 
     125 
     126        /// Remove refference to this object. 
     127        long RemoveReference (void); 
     128 
     129    protected: 
     130        /// things called by ACE framework. 
     131        WorldSocket (void); 
     132        virtual ~WorldSocket (void); 
     133 
     134        /// Called on open ,the void* is the acceptor. 
     135        virtual int open (void *); 
     136 
     137        /// Called on failures inside of the acceptor, don't call from your code. 
     138        virtual int close (int); 
     139 
     140        /// Called when we can read from the socket. 
     141        virtual int handle_input (ACE_HANDLE = ACE_INVALID_HANDLE); 
     142 
     143        /// Called when the socket can write. 
     144        virtual int handle_output (ACE_HANDLE = ACE_INVALID_HANDLE); 
     145 
     146        /// Called when connection is closed or error happens. 
     147        virtual int handle_close (ACE_HANDLE = ACE_INVALID_HANDLE, 
     148            ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK); 
     149 
     150        /// Called by WorldSocketMgr/ReactorRunnable. 
     151        int Update (void); 
     152 
     153    private: 
     154        /// Helper functions for processing incoming data. 
     155        int handle_input_header (void); 
     156        int handle_input_payload (void); 
     157        int handle_input_missing_data (void); 
     158 
     159        /// Help functions to mark/unmark the socket for output. 
     160        /// @param g the guard is for m_OutBufferLock, the function will release it 
     161        int cancel_wakeup_output (GuardType& g); 
     162        int schedule_wakeup_output (GuardType& g); 
     163 
     164        /// process one incoming packet. 
     165        /// @param new_pct received packet ,note that you need to delete it. 
     166        int ProcessIncoming (WorldPacket* new_pct); 
     167 
     168        /// Called by ProcessIncoming() on CMSG_AUTH_SESSION. 
     169        int HandleAuthSession (WorldPacket& recvPacket); 
     170 
     171        /// Called by ProcessIncoming() on CMSG_PING. 
     172        int HandlePing (WorldPacket& recvPacket); 
     173 
     174        /// Try to write WorldPacket to m_OutBuffer ,return -1 if no space 
     175        /// Need to be called with m_OutBufferLock lock held 
     176        int iSendPacket (const WorldPacket& pct); 
     177 
     178        /// Flush m_PacketQueue if there are packets in it 
     179        /// Need to be called with m_OutBufferLock lock held 
     180        /// @return true if it wrote to the buffer ( AKA you need 
     181        /// to mark the socket for output ). 
     182        bool iFlushPacketQueue (); 
     183 
     184    private: 
     185        /// Time in which the last ping was received 
     186        ACE_Time_Value m_LastPingTime; 
     187 
     188        /// Keep track of overspeed pings ,to prevent ping flood. 
     189        uint32 m_OverSpeedPings; 
     190 
     191        /// Address of the remote peer 
     192        std::string m_Address; 
     193 
     194        /// Class used for managing encryption of the headers 
     195        AuthCrypt m_Crypt; 
     196 
     197        /// Mutex lock to protect m_Session 
     198        LockType m_SessionLock; 
     199 
     200        /// Session to which recieved packets are routed 
     201        WorldSession* m_Session; 
     202 
     203        /// here are stored the fragmens of the recieved data 
     204        WorldPacket* m_RecvWPct; 
     205 
     206        /// This block actually refers to m_RecvWPct contents, 
     207        /// which alows easy and safe writing to it. 
     208        /// It wont free memory when its deleted. m_RecvWPct takes care of freeing. 
     209        ACE_Message_Block m_RecvPct; 
     210 
     211        /// Fragment of the recieved header. 
     212        ACE_Message_Block m_Header; 
     213 
     214        /// Mutex for protecting otuput related data. 
     215        LockType m_OutBufferLock; 
     216 
     217        /// Buffer used for writing output. 
     218        ACE_Message_Block *m_OutBuffer; 
     219 
     220        /// Size of the m_OutBuffer. 
     221        size_t m_OutBufferSize; 
     222 
     223        /// Here are stored packets for which there was no space on m_OutBuffer, 
     224        /// this alows not-to kick player if its buffer is overflowed. 
     225        PacketQueueT m_PacketQueue; 
     226 
     227        /// True if the socket is registered with the reactor for output 
     228        bool m_OutActive; 
     229 
     230        uint32 m_Seed; 
    231231}; 
    232232 
    233 #endif  /* _WORLDSOCKET_H */ 
     233#endif  /* _WORLDSOCKET_H */ 
    234234 
    235235/// @}