1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
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 Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef NL_FE_RECEIVE_SUB_H
20 #define NL_FE_RECEIVE_SUB_H
22 #include "nel/misc/types_nl.h"
23 #include "nel/misc/buf_fifo.h"
25 #include "nel/net/login_cookie.h"
28 #include "client_host.h"
29 #include "fe_receive_task.h"
30 #include "client_id_lookup.h"
35 extern bool verbosePacketLost
;
38 #define LOG_PACKET_LOST ;
40 #define LOG_PACKET_LOST if (!verbosePacketLost) {} else nldebug
50 /// Type of remove list
51 typedef std::list
< std::pair
<TClientId
,uint8
> > TClientsToRemove
;
53 /// Types of message invalidity (used for THackingDesc::Reasons bitfield)
54 enum TBadMessageFormatType
{ InsufficientSize
=1, NotSystemLoginCode
=2, BadCookie
=4, BadSystemCode
=8, HackedSizeInBuffer
=16, AccessClosed
=32, IrrelevantSystemMessage
=64, MalformedAction
=128, UnknownExceptionType
=256, UnknownFormatType
=512, UnauthorizedCharacterSlot
=1024 };
56 /// Return the string for the message invalidity reasons
57 std::string
getBadMessageString( uint32 reasons
);
59 /// Hacking description
62 THackingDesc() : InvalidMsgCounter(1), UserId(0), Reasons(0) {}
64 /// Number of invalid messages received
65 uint32 InvalidMsgCounter
;
70 /// Reason(s) of the invalidities (bitfield: see TBadMessageFormatType)
74 /// Type of address set with counter
75 typedef CHashMap
<NLNET::CInetAddress
,THackingDesc
,CInetAddressHashMapTraits
> THackingAddrSet
;
77 /// Type of map of ip -> user id
78 typedef std::map
<uint32
,TUid
> TAutoUidMap
;
82 * Front-end Receive Subsystem
83 * \author Olivier Cado
84 * \author Nevrax France
100 _CurrentReadQueue(NULL
),
107 _RemovedClientEntities(),
109 ConnectionStatLog(NULL
),
110 _ConnectionStatDisp(NULL
)
114 void init( uint16 firstAcceptableFrontendPort
, uint16 lastAcceptableFrontendPort
, uint32 dgrammaxlength
, CHistory
*history
, TClientIdCont
*clientidcont
);
123 CClientHost
*addClient( const NLNET::CInetAddress
& addrfrom
, TUid userId
, const std::string
&userName
, const std::string
&userPriv
, const std::string
& userExtended
, const std::string
& languageId
, const NLNET::CLoginCookie
&cookie
, uint32 instanceId
, uint8 authorisedCharSlot
, bool sendCLConnect
=true );
125 /// Add to the list of clients which will be removed by addr at the three cycles later (leaving the time to send an impulsion to the client)
126 void addToRemoveList( TClientId clientid
) { _ClientsToRemove
.push_back( std::make_pair(clientid
,3) ); }
128 /// Remove from the list of clients
129 void removeFromRemoveList( TClientId clientid
);
131 /// Return the number of connecged client
132 uint32
getNbClient();
134 // Remove a client by iterator on THostMap (see also byId)
135 //void removeClientByAddr( THostMap::iterator iclient );
137 void setClientInLimboMode( CClientHost
*client
);
139 CClientHost
*exitFromLimboMode( const CLimboClient
& client
);
141 void removeClientFromMap( CClientHost
*client
);
143 /// Remove a client by clientid
144 /// all remove are supposed to be a client crashed. it s false only on the case we receive really the client message
145 void removeClientById( TClientId clientid
, bool crashed
= true );
147 /// After a client has been removed from the tables, free its identifier
148 void freeIdsOfRemovedClients();
150 THostMap
& clientMap() { return _ClientMap
; }
151 TClientIdCont
& clientIdCont() { return *_ClientIdCont
; }
152 CClientHost
* getClientHost(TClientId id
) { return (*_ClientIdCont
)[id
]; }
153 NLNET::CUdpSock
*dataSock() { return _ReceiveTask
->DataSock
; }
156 // Swap receive queues (to avoid high contention between the receive thread and the reading thread)
157 void swapReadQueues();
159 // Read incoming data from the current read queue
160 void readIncomingData();
162 /// Open or close the access for new clients
163 void openAccess( bool b
) { _AccessOpen
= b
; }
165 /// Return the current access state
166 bool accessOpen() const { return _AccessOpen
; }
168 /// Find a client host by Uid (slow)
169 CClientHost
*findClientHostByUid( TUid uid
, bool exitFromLimbo
=false );
171 /// Remove client in tables
172 void removeClientLinks( CClientHost
*clienthost
);
174 /// Delete a client object
175 void deleteClient( CClientHost
*clienthost
);
178 bool acceptUserIdConnection( TUid userId
);
180 /// Do not accept the current message (hacking detection)
181 void rejectReceivedMessage( TBadMessageFormatType bmft
, TUid userId
=0 );
184 CClientIdLookup EntityToClient
;
186 NLMISC::CLog
*ConnectionStatLog
;
188 std::map
<TUid
,CLimboClient
> LimboClients
;
192 /** Process current incoming message (handles client addition/removal/identification,
193 * then calls handleReceivedMsg() if not removal)
195 void handleIncomingMsg();
197 /// Process current received message (called by handleIncomingMsg())
198 void handleReceivedMsg( CClientHost
*clienthost
);
200 /// Compute stats about received datagrams
201 void computeStats( CClientHost
*clienthost
, uint32 currentcounter
, uint32 currentsize
, bool updateAcknowledge
);
203 /// Display lost statistics
204 void displayDatagramStats( NLMISC::TTime lastdisplay
);
206 /// Utility method to remove a client
207 void doRemoveClient( CClientHost
*client
, bool crashed
);
211 /// Receive socket from the clients
212 CFEReceiveTask
*_ReceiveTask
;
215 NLMISC::IThread
*_ReceiveThread
;
217 /// Client map by address
220 /// Client map by id (belonging to the send subsystem)
221 TClientIdCont
*_ClientIdCont
;
224 NLMISC::CBufFIFO _Queue1
;
227 NLMISC::CBufFIFO _Queue2
;
229 /// Current read queue
230 NLMISC::CBufFIFO
*_CurrentReadQueue
;
232 /// Current incoming message
233 TReceivedMessage
*_CurrentInMsg
;
235 /// Number of messages received (stat)
236 volatile uint32 _RcvCounter
;
238 /// Receive bytes in UDP (stat)
239 volatile uint32 _RcvBytes
;
241 /// Previous RcvBytes (stat)
242 volatile uint32 _PrevRcvBytes
;
245 CClientIdPool _ClientIdPool
;
247 /// Packet History access
250 /// Clients to remove (iterator and game cycle left to wait before removing) (used to temporize removal when an impulsion needs to be sent before removal)
251 TClientsToRemove _ClientsToRemove
;
253 /// Clients to free (not a TEntityIndex because they are not set for client who do not see anyone)
254 std::vector
<CClientHost
*> _RemovedClientEntities
;
256 /// Set of addresses of unidentified clients
257 THackingAddrSet _UnidentifiedFlyingClients
;
259 /// Do clients have the right to connect? (does not affect clients already connected)
262 NLMISC::CFileDisplayer
*_ConnectionStatDisp
;
264 /// Persistent map to auto-allocate a dev user id
265 TAutoUidMap _AutoUidMap
;
269 #endif // NL_FE_RECEIVE_SUB_H
271 /* End of fe_receive_sub.h */