OregonCore  revision 3611e8a-git
Your Favourite TBC server
WorldSocket Class Reference

#include <WorldSocket.h>

+ Inheritance diagram for WorldSocket:

Public Types

typedef ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR > Acceptor
 
typedef ACE_Thread_Mutex LockType
 
typedef ACE_Guard< LockTypeGuardType
 
typedef ACE_Unbounded_Queue< WorldPacket * > PacketQueueT
 

Public Member Functions

bool IsClosed (void) const
 
void CloseSocket (void)
 
const std::string & GetRemoteAddress (void) const
 
int SendPacket (const WorldPacket &pct)
 
long AddReference (void)
 
long RemoveReference (void)
 

Protected Member Functions

 WorldSocket (void)
 
virtual ~WorldSocket (void)
 
virtual int open (void *)
 
virtual int close (u_long)
 
virtual int handle_input (ACE_HANDLE=ACE_INVALID_HANDLE)
 
virtual int handle_output (ACE_HANDLE=ACE_INVALID_HANDLE)
 
virtual int handle_close (ACE_HANDLE=ACE_INVALID_HANDLE, ACE_Reactor_Mask=ACE_Event_Handler::ALL_EVENTS_MASK)
 
int Update (void)
 

Private Member Functions

int handle_input_header (void)
 
int handle_input_payload (void)
 
int handle_input_missing_data (void)
 
int cancel_wakeup_output (GuardType &g)
 
int schedule_wakeup_output (GuardType &g)
 
int ProcessIncoming (WorldPacket *new_pct)
 
int HandleAuthSession (WorldPacket &recvPacket)
 
int HandlePing (WorldPacket &recvPacket)
 
int iSendPacket (const WorldPacket &pct)
 
bool iFlushPacketQueue ()
 

Private Attributes

ACE_Time_Value m_LastPingTime
 
uint32 m_OverSpeedPings
 
std::string m_Address
 
AuthCrypt m_Crypt
 
LockType m_SessionLock
 
WorldSessionm_Session
 
WorldPacketm_RecvWPct
 
ACE_Message_Block m_RecvPct
 
ACE_Message_Block m_Header
 
LockType m_OutBufferLock
 
ACE_Message_Block * m_OutBuffer
 
size_t m_OutBufferSize
 
PacketQueueT m_PacketQueue
 
bool m_OutActive
 
uint32 m_Seed
 

Friends

class ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR >
 
class WorldSocketMgr
 
class ReactorRunnable
 

Detailed Description

WorldSocket.

This class is responsible for the communication with remote clients. Most methods return -1 on failure. The class uses reference counting.

For output the class uses one buffer (64K usually) and a queue where it stores packet if there is no place on the queue. The reason this is done, is because the server does really a lot of small-size writes to it, and it doesn't scale well to allocate memory for every. When something is written to the output buffer the socket is not immediately activated for output (again for the same reason), there is 10ms celling (thats why there is Update() method). This concept is similar to TCP_CORK, but TCP_CORK uses 200ms celling. As result overhead generated by sending packets from "producer" threads is minimal, and doing a lot of writes with small size is tolerated.

The calls to Update() method are managed by WorldSocketMgr and ReactorRunnable.

For input ,the class uses one 1024 bytes buffer on stack to which it does recv() calls. And then received data is distributed where its needed. 1024 matches pretty well the traffic generated by client for now.

The input/output do speculative reads/writes (AKA it tryes to read all data available in the kernel buffer or tryes to write everything available in userspace buffer), which is ok for using with Level and Edge Triggered IO notification.

Definition at line 82 of file WorldSocket.h.

Member Typedef Documentation

typedef ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR > WorldSocket::Acceptor

Definition at line 91 of file WorldSocket.h.

typedef ACE_Guard<LockType> WorldSocket::GuardType

Definition at line 95 of file WorldSocket.h.

typedef ACE_Thread_Mutex WorldSocket::LockType

Definition at line 94 of file WorldSocket.h.

typedef ACE_Unbounded_Queue< WorldPacket* > WorldSocket::PacketQueueT

Definition at line 98 of file WorldSocket.h.

Constructor & Destructor Documentation

WorldSocket::WorldSocket ( void  )
protected

Definition at line 69 of file WorldSocket.cpp.

69  :
70  WorldHandler(),
71  m_LastPingTime(ACE_Time_Value::zero),
73  m_Session(0),
74  m_RecvWPct(0),
75  m_RecvPct(),
76  m_Header(sizeof (ClientPktHeader)),
77  m_OutBuffer(0),
78  m_OutBufferSize(65536),
79  m_OutActive(false),
80  m_Seed(static_cast<uint32> (rand32()))
81 {
82  reference_counting_policy().value (ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
83 }
ACE_Message_Block m_Header
Definition: WorldSocket.h:203
ACE_Time_Value m_LastPingTime
Definition: WorldSocket.h:177
uint32 m_Seed
Definition: WorldSocket.h:221
WorldSession * m_Session
Definition: WorldSocket.h:192
size_t m_OutBufferSize
Definition: WorldSocket.h:212
bool m_OutActive
Definition: WorldSocket.h:219
ACE_Message_Block m_RecvPct
Definition: WorldSocket.h:200
WorldPacket * m_RecvWPct
Definition: WorldSocket.h:195
ACE_Message_Block * m_OutBuffer
Definition: WorldSocket.h:209
int32 rand32()
Definition: Util.cpp:81
uint32 m_OverSpeedPings
Definition: WorldSocket.h:180
ACE_Svc_Handler< ACE_SOCK_STREAM, ACE_NULL_SYNCH > WorldHandler
Definition: WorldSocket.h:41
WorldSocket::~WorldSocket ( void  )
protectedvirtual

Definition at line 85 of file WorldSocket.cpp.

References m_OutBuffer, m_PacketQueue, and m_RecvWPct.

86 {
87  delete m_RecvWPct;
88 
89  if (m_OutBuffer)
90  m_OutBuffer->release();
91 
92  closing_ = true;
93 
94  peer().close();
95 
96  WorldPacket* pct;
97  while (m_PacketQueue.dequeue_head (pct) == 0)
98  delete pct;
99 }
PacketQueueT m_PacketQueue
Definition: WorldSocket.h:216
WorldPacket * m_RecvWPct
Definition: WorldSocket.h:195
ACE_Message_Block * m_OutBuffer
Definition: WorldSocket.h:209

Member Function Documentation

long WorldSocket::AddReference ( void  )

Definition at line 176 of file WorldSocket.cpp.

Referenced by ReactorRunnable::AddSocket(), and WorldSession::WorldSession().

177 {
178  return static_cast<long> (add_reference());
179 }
int WorldSocket::cancel_wakeup_output ( GuardType g)
private

Definition at line 515 of file WorldSocket.cpp.

References m_OutActive, and sLog.

Referenced by handle_output().

516 {
517  if (!m_OutActive)
518  return 0;
519 
520  m_OutActive = false;
521 
522  g.release();
523 
524  if (reactor()->cancel_wakeup
525  (this, ACE_Event_Handler::WRITE_MASK) == -1)
526  {
527  // would be good to store errno from reactor with errno guard
528  sLog.outError ("WorldSocket::cancel_wakeup_output");
529  return -1;
530  }
531 
532  return 0;
533 }
#define sLog
Log class singleton.
Definition: Log.h:187
bool m_OutActive
Definition: WorldSocket.h:219
int WorldSocket::close ( u_long  )
protectedvirtual

Definition at line 236 of file WorldSocket.cpp.

237 {
238  shutdown();
239 
240  closing_ = true;
241 
242  remove_reference();
243 
244  return 0;
245 }
void WorldSocket::CloseSocket ( void  )

Definition at line 106 of file WorldSocket.cpp.

References Oregon::Guard(), m_OutBufferLock, m_Session, and m_SessionLock.

Referenced by WorldSession::KickPlayer(), WorldSession::SendPacket(), WorldSession::Update(), and WorldSession::~WorldSession().

107 {
108  {
109  ACE_GUARD (LockType, Guard, m_OutBufferLock);
110 
111  if (closing_)
112  return;
113 
114  closing_ = true;
115  peer().close_writer();
116  }
117 
118  {
119  ACE_GUARD (LockType, Guard, m_SessionLock);
120 
121  m_Session = NULL;
122  }
123 }
WorldSession * m_Session
Definition: WorldSocket.h:192
LockType m_SessionLock
Definition: WorldSocket.h:189
LockType
LockType m_OutBufferLock
Definition: WorldSocket.h:206
void Guard(void *)
const std::string & WorldSocket::GetRemoteAddress ( void  ) const

Definition at line 125 of file WorldSocket.cpp.

References m_Address.

Referenced by HandleAuthSession(), HandlePing(), ProcessIncoming(), and WorldSession::WorldSession().

126 {
127  return m_Address;
128 }
std::string m_Address
Definition: WorldSocket.h:183
int WorldSocket::handle_close ( ACE_HANDLE  h = ACE_INVALID_HANDLE,
ACE_Reactor_Mask  = ACE_Event_Handler::ALL_EVENTS_MASK 
)
protectedvirtual

Definition at line 332 of file WorldSocket.cpp.

References Oregon::Guard(), m_OutBufferLock, m_Session, and m_SessionLock.

333 {
334  // Critical section
335  {
336  ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
337 
338  closing_ = true;
339 
340  if (h == ACE_INVALID_HANDLE)
341  peer().close_writer();
342  }
343 
344  // Critical section
345  {
346  ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
347 
348  m_Session = NULL;
349  }
350 
351  reactor()->remove_handler(this, ACE_Event_Handler::DONT_CALL | ACE_Event_Handler::ALL_EVENTS_MASK);
352  return 0;
353 }
WorldSession * m_Session
Definition: WorldSocket.h:192
LockType m_SessionLock
Definition: WorldSocket.h:189
LockType
LockType m_OutBufferLock
Definition: WorldSocket.h:206
void Guard(void *)
int WorldSocket::handle_input ( ACE_HANDLE  = ACE_INVALID_HANDLE)
protectedvirtual

Definition at line 247 of file WorldSocket.cpp.

References DEBUG_LOG, handle_input_missing_data(), and Update().

248 {
249  if (closing_)
250  return -1;
251 
252  switch (handle_input_missing_data())
253  {
254  case -1 :
255  {
256  if ((errno == EWOULDBLOCK) ||
257  (errno == EAGAIN))
258  {
259  return Update(); // interesting line ,isn't it ?
260  }
261 
262  DEBUG_LOG("WorldSocket::handle_input: Peer error closing connection errno = %s", ACE_OS::strerror (errno));
263 
264  errno = ECONNRESET;
265  return -1;
266  }
267  case 0:
268  {
269  DEBUG_LOG("WorldSocket::handle_input: Peer has closed connection");
270 
271  errno = ECONNRESET;
272  return -1;
273  }
274  case 1:
275  return 1;
276  default:
277  return Update(); // another interesting line ;)
278  }
279 
280  ACE_NOTREACHED(return -1);
281 }
int handle_input_missing_data(void)
int Update(void)
#define DEBUG_LOG(...)
Definition: Log.h:194
int WorldSocket::handle_input_header ( void  )
private

Definition at line 366 of file WorldSocket.cpp.

References ClientPktHeader::cmd, ByteBuffer::contents(), AuthCrypt::DecryptRecv(), EndianConvert(), EndianConvertReverse(), m_Crypt, m_Header, m_RecvPct, m_RecvWPct, ByteBuffer::resize(), ClientPktHeader::size, ByteBuffer::size(), and sLog.

Referenced by handle_input_missing_data().

367 {
368  ACE_ASSERT (m_RecvWPct == NULL);
369 
370  ACE_ASSERT (m_Header.length() == sizeof(ClientPktHeader));
371 
372  m_Crypt.DecryptRecv ((ACE_UINT8*) m_Header.rd_ptr (), sizeof (ClientPktHeader));
373 
374  ClientPktHeader& header = *((ClientPktHeader*) m_Header.rd_ptr());
375 
376  EndianConvertReverse(header.size);
377  EndianConvert(header.cmd);
378 
379  if ((header.size < 4) || (header.size > 10240) || (header.cmd > 10240))
380  {
381  sLog.outError ("WorldSocket::handle_input_header: client sent malformed packet size = %d , cmd = %d",
382  header.size, header.cmd);
383 
384  errno = EINVAL;
385  return -1;
386  }
387 
388  header.size -= 4;
389 
390  ACE_NEW_RETURN (m_RecvWPct, WorldPacket ((uint16) header.cmd, header.size), -1);
391 
392  if (header.size > 0)
393  {
394  m_RecvWPct->resize (header.size);
395  m_RecvPct.base ((char*) m_RecvWPct->contents(), m_RecvWPct->size());
396  }
397  else
398  ACE_ASSERT(m_RecvPct.space() == 0);
399 
400  return 0;
401 }
ACE_Message_Block m_Header
Definition: WorldSocket.h:203
const uint8 * contents() const
Definition: ByteBuffer.h:331
void DecryptRecv(uint8 *, size_t)
Definition: AuthCrypt.cpp:32
void resize(size_t newsize)
Definition: ByteBuffer.h:345
void EndianConvert(T &val)
Definition: ByteConverter.h:48
#define sLog
Log class singleton.
Definition: Log.h:187
ACE_Message_Block m_RecvPct
Definition: WorldSocket.h:200
void EndianConvertReverse(T &)
Definition: ByteConverter.h:52
size_t size() const
Definition: ByteBuffer.h:336
WorldPacket * m_RecvWPct
Definition: WorldSocket.h:195
ACE_UINT16 uint16
Definition: Define.h:72
AuthCrypt m_Crypt
Definition: WorldSocket.h:186
int WorldSocket::handle_input_missing_data ( void  )
private

Definition at line 426 of file WorldSocket.cpp.

References handle_input_header(), handle_input_payload(), m_Header, m_RecvPct, m_RecvWPct, and sLog.

Referenced by handle_input().

427 {
428  char buf [1024];
429 
430  ACE_Data_Block db (sizeof (buf),
431  ACE_Message_Block::MB_DATA,
432  buf,
433  0,
434  0,
435  ACE_Message_Block::DONT_DELETE,
436  0);
437 
438  ACE_Message_Block message_block(&db,
439  ACE_Message_Block::DONT_DELETE,
440  0);
441 
442  const size_t recv_size = message_block.space();
443 
444  const ssize_t n = peer().recv (message_block.wr_ptr(),
445  recv_size);
446 
447  if (n <= 0)
448  return n;
449 
450  message_block.wr_ptr (n);
451 
452  while (message_block.length() > 0)
453  {
454  if (m_Header.space() > 0)
455  {
456  //need to receive the header
457  const size_t to_header = (message_block.length() > m_Header.space() ? m_Header.space() : message_block.length());
458  m_Header.copy (message_block.rd_ptr(), to_header);
459  message_block.rd_ptr (to_header);
460 
461  if (m_Header.space() > 0)
462  {
463  // Couldn't receive the whole header this time.
464  ACE_ASSERT (message_block.length() == 0);
465  errno = EWOULDBLOCK;
466  return -1;
467  }
468 
469  // We just received nice new header
470  if (handle_input_header() == -1)
471  {
472  ACE_ASSERT ((errno != EWOULDBLOCK) && (errno != EAGAIN));
473  return -1;
474  }
475  }
476 
477  // Its possible on some error situations that this happens
478  // for example on closing when epoll receives more chunked data and stuff
479  // hope this is not hack ,as proper m_RecvWPct is asserted around
480  if (!m_RecvWPct)
481  {
482  sLog.outError ("Forcing close on input m_RecvWPct = NULL");
483  errno = EINVAL;
484  return -1;
485  }
486 
487  // We have full read header, now check the data payload
488  if (m_RecvPct.space() > 0)
489  {
490  //need more data in the payload
491  const size_t to_data = (message_block.length() > m_RecvPct.space() ? m_RecvPct.space() : message_block.length());
492  m_RecvPct.copy (message_block.rd_ptr(), to_data);
493  message_block.rd_ptr (to_data);
494 
495  if (m_RecvPct.space() > 0)
496  {
497  // Couldn't receive the whole data this time.
498  ACE_ASSERT (message_block.length() == 0);
499  errno = EWOULDBLOCK;
500  return -1;
501  }
502  }
503 
504  //just received fresh new payload
505  if (handle_input_payload() == -1)
506  {
507  ACE_ASSERT ((errno != EWOULDBLOCK) && (errno != EAGAIN));
508  return -1;
509  }
510  }
511 
512  return size_t(n) == recv_size ? 1 : 2;
513 }
ACE_Message_Block m_Header
Definition: WorldSocket.h:203
#define sLog
Log class singleton.
Definition: Log.h:187
ACE_Message_Block m_RecvPct
Definition: WorldSocket.h:200
int handle_input_header(void)
WorldPacket * m_RecvWPct
Definition: WorldSocket.h:195
int handle_input_payload(void)
int WorldSocket::handle_input_payload ( void  )
private

Definition at line 403 of file WorldSocket.cpp.

References m_Header, m_RecvPct, m_RecvWPct, and ProcessIncoming().

Referenced by handle_input_missing_data().

404 {
405  // set errno properly here on error !!!
406  // now have a header and payload
407 
408  ACE_ASSERT (m_RecvPct.space() == 0);
409  ACE_ASSERT (m_Header.space() == 0);
410  ACE_ASSERT (m_RecvWPct != NULL);
411 
412  const int ret = ProcessIncoming (m_RecvWPct);
413 
414  m_RecvPct.base (NULL, 0);
415  m_RecvPct.reset();
416  m_RecvWPct = NULL;
417 
418  m_Header.reset();
419 
420  if (ret == -1)
421  errno = EINVAL;
422 
423  return ret;
424 }
ACE_Message_Block m_Header
Definition: WorldSocket.h:203
ACE_Message_Block m_RecvPct
Definition: WorldSocket.h:200
WorldPacket * m_RecvWPct
Definition: WorldSocket.h:195
int ProcessIncoming(WorldPacket *new_pct)
int WorldSocket::handle_output ( ACE_HANDLE  = ACE_INVALID_HANDLE)
protectedvirtual

Definition at line 283 of file WorldSocket.cpp.

References cancel_wakeup_output(), Oregon::Guard(), iFlushPacketQueue(), m_OutBuffer, m_OutBufferLock, MSG_NOSIGNAL, and schedule_wakeup_output().

Referenced by Update().

284 {
285  ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
286 
287  if (closing_)
288  return -1;
289 
290  const size_t send_len = m_OutBuffer->length ();
291 
292  if (send_len == 0)
293  return cancel_wakeup_output (Guard);
294 
295  #ifdef MSG_NOSIGNAL
296  ssize_t n = peer().send (m_OutBuffer->rd_ptr(), send_len, MSG_NOSIGNAL);
297  #else
298  ssize_t n = peer().send (m_OutBuffer->rd_ptr(), send_len);
299  #endif // MSG_NOSIGNAL
300 
301  if (n == 0)
302  return -1;
303  else if (n == -1)
304  {
305  if (errno == EWOULDBLOCK || errno == EAGAIN)
306  return schedule_wakeup_output (Guard);
307 
308  return -1;
309  }
310  else if (size_t(n) < send_len) //now n > 0
311  {
312  m_OutBuffer->rd_ptr (static_cast<size_t> (n));
313 
314  // move the data to the base of the buffer
315  m_OutBuffer->crunch();
316 
317  return schedule_wakeup_output (Guard);
318  }
319  else //now n == send_len
320  {
321  m_OutBuffer->reset();
322 
323  if (!iFlushPacketQueue ())
324  return cancel_wakeup_output (Guard);
325  else
326  return schedule_wakeup_output (Guard);
327  }
328 
329  ACE_NOTREACHED (return 0);
330 }
LockType
LockType m_OutBufferLock
Definition: WorldSocket.h:206
int cancel_wakeup_output(GuardType &g)
void Guard(void *)
ACE_Message_Block * m_OutBuffer
Definition: WorldSocket.h:209
int schedule_wakeup_output(GuardType &g)
#define MSG_NOSIGNAL
bool iFlushPacketQueue()
int WorldSocket::HandleAuthSession ( WorldPacket recvPacket)
private

Definition at line 645 of file WorldSocket.cpp.

References BigNumber::AsHexStr(), AUTH_BANNED, AUTH_FAILED, AUTH_UNAVAILABLE, AUTH_UNKNOWN_ACCOUNT, AUTH_VERSION_MISMATCH, CONFIG_EXPANSION, CONFIG_SESSION_ADD_DELAY, CONFIG_WARDEN_ENABLED, DEBUG_LOG, Database::escape_string(), Sha1Hash::Finalize(), Sha1Hash::GetDigest(), GetRemoteAddress(), Field::GetString(), AuthCrypt::Init(), WorldPacket::Initialize(), WorldSession::InitWarden(), IsAcceptableClientBuild(), LOCALE_enUS, LoginDatabase, m_Crypt, m_Seed, m_Session, MAX_LOCALE, Database::PExecute(), Database::PQuery(), ByteBuffer::read(), realmID, sAddOnHandler, SEC_PLAYER, SendPacket(), BigNumber::SetDword(), BigNumber::SetHexStr(), AuthCrypt::SetKey(), sLog, SMSG_AUTH_RESPONSE, sWorld, Sha1Hash::UpdateBigNumbers(), and Sha1Hash::UpdateData().

Referenced by ProcessIncoming().

646 {
647  // NOTE: ATM the socket is singlethread, have this in mind ...
648  uint8 digest[20];
649  uint32 clientSeed;
650  uint32 unk2;
651  uint32 BuiltNumberClient;
652  uint32 id, security;
653  //uint8 expansion = 0;
654  LocaleConstant locale;
655  std::string account;
656  Sha1Hash sha1;
657  BigNumber v, s, g, N;
658  WorldPacket packet, SendAddonPacked;
659 
660  BigNumber K;
661 
662  // Read the content of the packet
663  recvPacket >> BuiltNumberClient;
664  recvPacket >> unk2;
665  recvPacket >> account;
666 
667  recvPacket >> clientSeed;
668  recvPacket.read (digest, 20);
669 
670  DEBUG_LOG ("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, clientseed %u",
671  BuiltNumberClient,
672  unk2,
673  account.c_str (),
674  clientSeed);
675 
676  // Check the version of client trying to connect
677  if (!IsAcceptableClientBuild(BuiltNumberClient))
678  {
679  packet.Initialize (SMSG_AUTH_RESPONSE, 1);
680  packet << uint8 (AUTH_VERSION_MISMATCH);
681 
682  SendPacket (packet);
683 
684  sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (version mismatch).");
685  return -1;
686  }
687 
688  // Get the account information from the realmd database
689  std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below
690  LoginDatabase.escape_string (safe_account);
691  // No SQL injection, username escaped.
692 
693  QueryResult_AutoPtr result = LoginDatabase.PQuery ("SELECT "
694  "id, " //0
695  "sessionkey, " //1
696  "last_ip, " //2
697  "locked, " //3
698  "v, " //4
699  "s, " //5
700  "expansion, " //6
701  "mutetime, " //7
702  "locale, " //8
703  "os " //9
704  "FROM account "
705  "WHERE username = '%s'",
706  safe_account.c_str ());
707 
708  // Stop if the account is not found
709  if (!result)
710  {
711  packet.Initialize (SMSG_AUTH_RESPONSE, 1);
712  packet << uint8 (AUTH_UNKNOWN_ACCOUNT);
713 
714  SendPacket (packet);
715 
716  sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account).");
717  return -1;
718  }
719 
720  Field* fields = result->Fetch ();
721 
722  uint8 expansion = fields[6].GetUInt8();
723  uint32 world_expansion = sWorld.getConfig(CONFIG_EXPANSION);
724  if (expansion > world_expansion)
725  expansion = world_expansion;
726  //expansion = ((sWorld.getConfig(CONFIG_EXPANSION) > fields[6].GetUInt8()) ? fields[6].GetUInt8() : sWorld.getConfig(CONFIG_EXPANSION));
727 
728  N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
729  g.SetDword (7);
730 
731  v.SetHexStr(fields[4].GetString());
732  s.SetHexStr (fields[5].GetString ());
733 
734  const char* sStr = s.AsHexStr (); //Must be freed by OPENSSL_free()
735  const char* vStr = v.AsHexStr (); //Must be freed by OPENSSL_free()
736 
737  DEBUG_LOG ("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s",
738  sStr,
739  vStr);
740 
741  OPENSSL_free ((void*) sStr);
742  OPENSSL_free ((void*) vStr);
743 
744  // Re-check ip locking (same check as in realmd).
745  if (fields[3].GetUInt8 () == 1) // if ip is locked
746  {
747  if (strcmp (fields[2].GetString (), GetRemoteAddress ().c_str ()))
748  {
749  packet.Initialize (SMSG_AUTH_RESPONSE, 1);
750  packet << uint8 (AUTH_FAILED);
751  SendPacket (packet);
752 
753  sLog.outBasic ("WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs).");
754  return -1;
755  }
756  }
757 
758  id = fields[0].GetUInt32 ();
759  K.SetHexStr (fields[1].GetString ());
760 
761  time_t mutetime = time_t (fields[7].GetUInt64 ());
762  std::string os = fields[9].GetString();
763 
764  locale = LocaleConstant (fields[8].GetUInt8 ());
765  if (locale >= MAX_LOCALE)
766  locale = LOCALE_enUS;
767 
768  // Checks gmlevel per Realm
769  result =
770  LoginDatabase.PQuery ("SELECT "
771  "RealmID, " //0
772  "gmlevel " //1
773  "FROM account_access "
774  "WHERE id = '%d'"
775  " AND (RealmID = '%d'"
776  " OR RealmID = '-1')",
777  id, realmID);
778  if (!result)
779  security = 0;
780  else
781  {
782  fields = result->Fetch ();
783  security = fields[1].GetInt32();
784  }
785 
786  // Re-check account ban (same check as in realmd)
787  QueryResult_AutoPtr banresult = LoginDatabase.PQuery ("SELECT "
788  "bandate, "
789  "unbandate "
790  "FROM account_banned "
791  "WHERE id = '%u' "
792  "AND active = 1",
793  id);
794 
795  if (banresult) // if account banned
796  {
797  packet.Initialize (SMSG_AUTH_RESPONSE, 1);
798  packet << uint8 (AUTH_BANNED);
799  SendPacket (packet);
800 
801  sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned).");
802  return -1;
803  }
804 
805  // Check locked state for server
806  sWorld.UpdateAllowedSecurity();
807  AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit ();
808  sLog.outDebug("Allowed Level: %u Player Level %u", allowedAccountType, AccountTypes(security));
809  if (allowedAccountType > SEC_PLAYER && security < allowedAccountType)
810  {
811  WorldPacket Packet (SMSG_AUTH_RESPONSE, 1);
812  Packet << uint8 (AUTH_UNAVAILABLE);
813 
814  SendPacket (packet);
815 
816  sLog.outDetail ("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough");
817  return -1;
818  }
819 
820  // Check that Key and account name are the same on client and server
821  Sha1Hash sha;
822 
823  uint32 t = 0;
824  uint32 seed = m_Seed;
825 
826  sha.UpdateData (account);
827  sha.UpdateData ((uint8*) & t, 4);
828  sha.UpdateData ((uint8*) & clientSeed, 4);
829  sha.UpdateData ((uint8*) & seed, 4);
830  sha.UpdateBigNumbers (&K, NULL);
831  sha.Finalize ();
832 
833  if (memcmp (sha.GetDigest (), digest, 20))
834  {
835  packet.Initialize (SMSG_AUTH_RESPONSE, 1);
836  packet << uint8 (AUTH_FAILED);
837 
838  SendPacket (packet);
839 
840  sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed).");
841  return -1;
842  }
843 
844  std::string address = GetRemoteAddress();
845 
846  DEBUG_LOG ("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.",
847  account.c_str(),
848  address.c_str());
849 
850  // Update the last_ip in the database
851  // No SQL injection, username escaped.
852  LoginDatabase.escape_string (address);
853 
854  LoginDatabase.PExecute ("UPDATE account "
855  "SET last_ip = '%s' "
856  "WHERE username = '%s'",
857  address.c_str(),
858  safe_account.c_str());
859 
860  // NOTE ATM the socket is single-threaded, have this in mind ...
861  ACE_NEW_RETURN (m_Session, WorldSession (id, this, security, expansion, mutetime, locale), -1);
862 
863  m_Crypt.SetKey(&K);
864  m_Crypt.Init();
865 
866  // Initialize Warden system only if it is enabled by config
867  if (sWorld.getConfig(CONFIG_WARDEN_ENABLED))
868  m_Session->InitWarden(&K, os);
869 
870  // Sleep this Network thread for
871  uint32 sleepTime = sWorld.getConfig(CONFIG_SESSION_ADD_DELAY);
872  ACE_OS::sleep(ACE_Time_Value (0, sleepTime));
873 
874  sWorld.AddSession (m_Session);
875 
876  // Create and send the Addon packet
877  if (sAddOnHandler.BuildAddonPacket (&recvPacket, &SendAddonPacked))
878  SendPacket(SendAddonPacked);
879 
880  return 0;
881 }
void Init()
Definition: AuthCrypt.cpp:26
uint32 m_Seed
Definition: WorldSocket.h:221
QueryResult_AutoPtr PQuery(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:400
void SetKey(BigNumber *)
Definition: AuthCrypt.cpp:61
AccountTypes
Definition: Common.h:188
Definition: Field.h:24
#define sLog
Log class singleton.
Definition: Log.h:187
int SendPacket(const WorldPacket &pct)
unsigned long escape_string(char *to, const char *from, unsigned long length)
Definition: Database.cpp:212
void Initialize(uint16 opcode, size_t newres=200)
Definition: WorldPacket.h:37
WorldSession * m_Session
Definition: WorldSocket.h:192
uint8 * GetDigest(void)
Definition: Sha1.h:41
const char * GetString() const
Definition: Field.h:41
ACE_UINT8 uint8
Definition: Define.h:73
void Finalize()
Definition: Sha1.cpp:61
#define sAddOnHandler
Definition: AddonHandler.h:36
const char * AsHexStr()
Definition: BigNumber.cpp:204
const uint8 MAX_LOCALE
Definition: Common.h:224
void SetHexStr(const char *str)
Definition: BigNumber.cpp:66
DatabaseType LoginDatabase
Accessor to the realm/login database.
Definition: Main.cpp:55
void UpdateBigNumbers(BigNumber *bn0,...)
Definition: Sha1.cpp:41
#define DEBUG_LOG(...)
Definition: Log.h:194
bool IsAcceptableClientBuild(uint32 build)
Definition: DBCStores.cpp:158
bool PExecute(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:441
void SetDword(uint32)
Definition: BigNumber.cpp:47
void InitWarden(BigNumber *K, std::string os)
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
uint32 realmID
Id of the realm.
Definition: Main.cpp:57
void UpdateData(const uint8 *dta, int len)
Definition: Sha1.cpp:31
LocaleConstant
Definition: Common.h:211
#define sWorld
Definition: World.h:860
ACE_UINT32 uint32
Definition: Define.h:71
const std::string & GetRemoteAddress(void) const
AuthCrypt m_Crypt
Definition: WorldSocket.h:186
Definition: Sha1.h:26
int WorldSocket::HandlePing ( WorldPacket recvPacket)
private

Definition at line 883 of file WorldSocket.cpp.

References CONFIG_MAX_OVERSPEED_PINGS, GetRemoteAddress(), WorldSession::GetSecurity(), Oregon::Guard(), m_LastPingTime, m_OverSpeedPings, m_Session, m_SessionLock, WorldSession::ResetClientTimeDelay(), SEC_PLAYER, SendPacket(), WorldSession::SetLatency(), sLog, SMSG_PONG, and sWorld.

Referenced by ProcessIncoming().

884 {
885  uint32 ping;
886  uint32 latency;
887 
888  // Get the ping packet content
889  recvPacket >> ping;
890  recvPacket >> latency;
891 
892  if (m_LastPingTime == ACE_Time_Value::zero)
893  m_LastPingTime = ACE_OS::gettimeofday(); // for 1st ping
894  else
895  {
896  ACE_Time_Value cur_time = ACE_OS::gettimeofday();
897  ACE_Time_Value diff_time (cur_time);
898  diff_time -= m_LastPingTime;
899  m_LastPingTime = cur_time;
900 
901  if (diff_time < ACE_Time_Value (27))
902  {
904 
905  uint32 max_count = sWorld.getConfig (CONFIG_MAX_OVERSPEED_PINGS);
906 
907  if (max_count && m_OverSpeedPings > max_count)
908  {
909  ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
910 
912  {
913  sLog.outError ("WorldSocket::HandlePing: Player kicked for "
914  "over-speed pings address = %s",
915  GetRemoteAddress().c_str());
916 
917  return -1;
918  }
919  }
920  }
921  else
922  m_OverSpeedPings = 0;
923  }
924 
925  // critical section
926  {
927  ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
928 
929  if (m_Session)
930  {
931  m_Session->SetLatency (latency);
933  }
934  else
935  {
936  sLog.outError ("WorldSocket::HandlePing: peer sent CMSG_PING, "
937  "but is not authenticated or got recently kicked,"
938  " address = %s",
939  GetRemoteAddress().c_str());
940  return -1;
941  }
942  }
943 
944  WorldPacket packet (SMSG_PONG, 4);
945  packet << ping;
946  return SendPacket (packet);
947 }
ACE_Time_Value m_LastPingTime
Definition: WorldSocket.h:177
#define sLog
Log class singleton.
Definition: Log.h:187
int SendPacket(const WorldPacket &pct)
WorldSession * m_Session
Definition: WorldSocket.h:192
LockType m_SessionLock
Definition: WorldSocket.h:189
LockType
void Guard(void *)
void SetLatency(uint32 latency)
Definition: WorldSession.h:247
void ResetClientTimeDelay()
Definition: WorldSession.h:251
#define sWorld
Definition: World.h:860
void uint32 GetSecurity() const
Definition: WorldSession.h:96
ACE_UINT32 uint32
Definition: Define.h:71
const std::string & GetRemoteAddress(void) const
uint32 m_OverSpeedPings
Definition: WorldSocket.h:180
bool WorldSocket::iFlushPacketQueue ( )
private

Definition at line 977 of file WorldSocket.cpp.

References iSendPacket(), m_PacketQueue, and sLog.

Referenced by handle_output().

978 {
979  WorldPacket* pct;
980  bool haveone = false;
981 
982  while (m_PacketQueue.dequeue_head (pct) == 0)
983  {
984  if (iSendPacket (*pct) == -1)
985  {
986  if (m_PacketQueue.enqueue_head (pct) == -1)
987  {
988  delete pct;
989  sLog.outError ("WorldSocket::iFlushPacketQueue m_PacketQueue->enqueue_head");
990  return false;
991  }
992 
993  break;
994  }
995  else
996  {
997  haveone = true;
998  delete pct;
999  }
1000  }
1001 
1002  return haveone;
1003 }
PacketQueueT m_PacketQueue
Definition: WorldSocket.h:216
#define sLog
Log class singleton.
Definition: Log.h:187
int iSendPacket(const WorldPacket &pct)
bool WorldSocket::IsClosed ( void  ) const

Definition at line 101 of file WorldSocket.cpp.

Referenced by ReactorRunnable::AddNewSockets(), WorldSession::KickPlayer(), and WorldSession::Update().

102 {
103  return closing_;
104 }
int WorldSocket::iSendPacket ( const WorldPacket pct)
private

Definition at line 949 of file WorldSocket.cpp.

References ServerPktHeader::cmd, ByteBuffer::contents(), ByteBuffer::empty(), AuthCrypt::EncryptSend(), EndianConvert(), EndianConvertReverse(), WorldPacket::GetOpcode(), m_Crypt, m_OutBuffer, ServerPktHeader::size, and ByteBuffer::size().

Referenced by iFlushPacketQueue(), and SendPacket().

950 {
951  if (m_OutBuffer->space () < pct.size () + sizeof (ServerPktHeader))
952  {
953  errno = ENOBUFS;
954  return -1;
955  }
956 
957  ServerPktHeader header;
958 
959  header.cmd = pct.GetOpcode ();
960  EndianConvert(header.cmd);
961 
962  header.size = (uint16) pct.size () + 2;
963  EndianConvertReverse(header.size);
964 
965  m_Crypt.EncryptSend ((uint8*) & header, sizeof (header));
966 
967  if (m_OutBuffer->copy ((char*) & header, sizeof (header)) == -1)
968  ACE_ASSERT (false);
969 
970  if (!pct.empty ())
971  if (m_OutBuffer->copy ((char*) pct.contents (), pct.size ()) == -1)
972  ACE_ASSERT (false);
973 
974  return 0;
975 }
uint16 GetOpcode() const
Definition: WorldPacket.h:44
const uint8 * contents() const
Definition: ByteBuffer.h:331
void EncryptSend(uint8 *, size_t)
Definition: AuthCrypt.cpp:47
void EndianConvert(T &val)
Definition: ByteConverter.h:48
ACE_UINT8 uint8
Definition: Define.h:73
void EndianConvertReverse(T &)
Definition: ByteConverter.h:52
bool empty() const
Definition: ByteBuffer.h:340
size_t size() const
Definition: ByteBuffer.h:336
ACE_Message_Block * m_OutBuffer
Definition: WorldSocket.h:209
ACE_UINT16 uint16
Definition: Define.h:72
AuthCrypt m_Crypt
Definition: WorldSocket.h:186
int WorldSocket::open ( void *  a)
protectedvirtual

Definition at line 186 of file WorldSocket.cpp.

References m_Address, m_OutActive, m_OutBuffer, m_OutBufferSize, m_Seed, SendPacket(), sLog, SMSG_AUTH_CHALLENGE, and sWorldSocketMgr.

187 {
188  ACE_UNUSED_ARG (a);
189 
190  // Prevent double call to this func.
191  if (m_OutBuffer)
192  return -1;
193 
194  // This will also prevent the socket from being Updated
195  // while we are initializing it.
196  m_OutActive = true;
197 
198  // Hook for the manager.
199  if (sWorldSocketMgr->OnSocketOpen(this) == -1)
200  return -1;
201 
202  // Allocate the buffer.
203  ACE_NEW_RETURN (m_OutBuffer, ACE_Message_Block (m_OutBufferSize), -1);
204 
205  // Store peer address.
206  ACE_INET_Addr remote_addr;
207 
208  if (peer().get_remote_addr(remote_addr) == -1)
209  {
210  sLog.outError ("WorldSocket::open: peer().get_remote_addr errno = %s", ACE_OS::strerror (errno));
211  return -1;
212  }
213 
214  m_Address = remote_addr.get_host_addr();
215 
216  // Send startup packet.
217  WorldPacket packet (SMSG_AUTH_CHALLENGE, 4);
218  packet << m_Seed;
219 
220  if (SendPacket (packet) == -1)
221  return -1;
222 
223  // Register with ACE Reactor
224  if (reactor()->register_handler(this, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::WRITE_MASK) == -1)
225  {
226  sLog.outError ("WorldSocket::open: unable to register client handler errno = %s", ACE_OS::strerror (errno));
227  return -1;
228  }
229 
230  // reactor takes care of the socket from now on
231  remove_reference();
232 
233  return 0;
234 }
#define sWorldSocketMgr
uint32 m_Seed
Definition: WorldSocket.h:221
#define sLog
Log class singleton.
Definition: Log.h:187
int SendPacket(const WorldPacket &pct)
size_t m_OutBufferSize
Definition: WorldSocket.h:212
bool m_OutActive
Definition: WorldSocket.h:219
std::string m_Address
Definition: WorldSocket.h:183
ACE_Message_Block * m_OutBuffer
Definition: WorldSocket.h:209
int WorldSocket::ProcessIncoming ( WorldPacket new_pct)
private

Definition at line 554 of file WorldSocket.cpp.

References CMSG_AUTH_SESSION, CMSG_KEEP_ALIVE, CMSG_PING, DEBUG_LOG, WorldSession::GetAccountId(), WorldPacket::GetOpcode(), GetRemoteAddress(), Oregon::Guard(), HandleAuthSession(), HandlePing(), ByteBuffer::hexlike(), LOG_TYPE_NETWORK, LookupOpcodeName(), m_Session, m_SessionLock, WorldSession::QueuePacket(), WorldSession::ResetTimeOutTime(), ByteBuffer::size(), and sLog.

Referenced by handle_input_payload().

555 {
556  ACE_ASSERT (new_pct);
557 
558  // manage memory ;)
559  ACE_Auto_Ptr<WorldPacket> aptr (new_pct);
560 
561  const ACE_UINT16 opcode = new_pct->GetOpcode();
562 
563  if (closing_)
564  return -1;
565 
566  // Dump received packet.
567  if (sLog.IsLogTypeEnabled(LOG_TYPE_NETWORK))
568  {
569  sLog.outNetwork ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
570  (uint32) get_handle(),
571  new_pct->size(),
572  LookupOpcodeName (new_pct->GetOpcode()),
573  new_pct->GetOpcode());
574 
575  uint32 p = 0;
576  while (p < new_pct->size())
577  {
578  for (uint32 j = 0; j < 16 && p < new_pct->size(); j++)
579  sLog.outNetwork ("%.2X ", (*new_pct)[p++]);
580 
581  sLog.outNetwork ("");
582  }
583  sLog.outNetwork ("");
584  }
585 
586  try
587  {
588  switch (opcode)
589  {
590  case CMSG_PING:
591  return HandlePing (*new_pct);
592  case CMSG_AUTH_SESSION:
593  if (m_Session)
594  {
595  sLog.outError ("WorldSocket::ProcessIncoming: Player send CMSG_AUTH_SESSION again");
596  return -1;
597  }
598 
599  return HandleAuthSession (*new_pct);
600  case CMSG_KEEP_ALIVE:
601  DEBUG_LOG ("CMSG_KEEP_ALIVE ,size: %lu", new_pct->size());
602 
603  return 0;
604  default:
605  {
606  ACE_GUARD_RETURN (LockType, Guard, m_SessionLock, -1);
607 
608  if (m_Session != NULL)
609  {
610  // Our Idle timer will reset on any non PING opcodes.
611  // Catches people idling on the login screen and any lingering ingame connections.
613 
614  // OK ,give the packet to WorldSession
615  aptr.release();
616  // WARNINIG here we call it with locks held.
617  // Its possible to cause deadlock if QueuePacket calls back
618  m_Session->QueuePacket (new_pct);
619  return 0;
620  }
621  else
622  {
623  sLog.outError ("WorldSocket::ProcessIncoming: Client not authed opcode = %u", uint32(opcode));
624  return -1;
625  }
626  }
627  }
628  }
629  catch (ByteBufferException&)
630  {
631  sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
632  opcode, GetRemoteAddress().c_str(), m_Session ? m_Session->GetAccountId() : -1);
633  if (sLog.IsOutDebug())
634  {
635  sLog.outDebug("Dumping error causing packet:");
636  new_pct->hexlike();
637  }
638 
639  return -1;
640  }
641 
642  ACE_NOTREACHED (return 0);
643 }
uint16 GetOpcode() const
Definition: WorldPacket.h:44
void QueuePacket(WorldPacket *new_packet)
#define sLog
Log class singleton.
Definition: Log.h:187
void ResetTimeOutTime()
Definition: WorldSession.h:265
uint32 GetAccountId() const
Definition: WorldSession.h:100
WorldSession * m_Session
Definition: WorldSocket.h:192
LockType m_SessionLock
Definition: WorldSocket.h:189
LockType
size_t size() const
Definition: ByteBuffer.h:336
void Guard(void *)
#define DEBUG_LOG(...)
Definition: Log.h:194
const char * LookupOpcodeName(uint16 id)
Definition: Opcodes.h:1119
int HandleAuthSession(WorldPacket &recvPacket)
void hexlike() const
Definition: ByteBuffer.h:451
int HandlePing(WorldPacket &recvPacket)
ACE_UINT32 uint32
Definition: Define.h:71
const std::string & GetRemoteAddress(void) const
long WorldSocket::RemoveReference ( void  )

Definition at line 181 of file WorldSocket.cpp.

Referenced by ReactorRunnable::AddNewSockets(), WorldSession::Update(), and WorldSession::~WorldSession().

182 {
183  return static_cast<long> (remove_reference());
184 }
int WorldSocket::schedule_wakeup_output ( GuardType g)
private

Definition at line 535 of file WorldSocket.cpp.

References m_OutActive, and sLog.

Referenced by handle_output().

536 {
537  if (m_OutActive)
538  return 0;
539 
540  m_OutActive = true;
541 
542  g.release();
543 
544  if (reactor()->schedule_wakeup
545  (this, ACE_Event_Handler::WRITE_MASK) == -1)
546  {
547  sLog.outError ("WorldSocket::schedule_wakeup_output");
548  return -1;
549  }
550 
551  return 0;
552 }
#define sLog
Log class singleton.
Definition: Log.h:187
bool m_OutActive
Definition: WorldSocket.h:219
int WorldSocket::SendPacket ( const WorldPacket pct)

Definition at line 130 of file WorldSocket.cpp.

References WorldPacket::GetOpcode(), Oregon::Guard(), iSendPacket(), LOG_TYPE_NETWORK, LookupOpcodeName(), m_OutBufferLock, m_PacketQueue, ByteBuffer::size(), and sLog.

Referenced by HandleAuthSession(), HandlePing(), open(), and WorldSession::SendPacket().

131 {
132  ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
133 
134  if (closing_)
135  return -1;
136 
137  // Dump outgoing packet.
138  if (sLog.IsLogTypeEnabled(LOG_TYPE_NETWORK))
139  {
140  sLog.outNetwork ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
141  (uint32) get_handle(),
142  pct.size(),
143  LookupOpcodeName (pct.GetOpcode()),
144  pct.GetOpcode());
145 
146  uint32 p = 0;
147  while (p < pct.size())
148  {
149  for (uint32 j = 0; j < 16 && p < pct.size(); j++)
150  sLog.outNetwork("%.2X ", const_cast<WorldPacket&>(pct)[p++]);
151 
152  sLog.outNetwork("");
153  }
154  sLog.outNetwork("");
155  }
156 
157  if (iSendPacket (pct) == -1)
158  {
159  WorldPacket* npct;
160 
161  ACE_NEW_RETURN (npct, WorldPacket (pct), -1);
162 
163  // NOTE maybe check of the size of the queue can be good ?
164  // to make it bounded instead of unbounded
165  if (m_PacketQueue.enqueue_tail (npct) == -1)
166  {
167  delete npct;
168  sLog.outError ("WorldSocket::SendPacket: m_PacketQueue.enqueue_tail failed");
169  return -1;
170  }
171  }
172 
173  return 0;
174 }
uint16 GetOpcode() const
Definition: WorldPacket.h:44
PacketQueueT m_PacketQueue
Definition: WorldSocket.h:216
#define sLog
Log class singleton.
Definition: Log.h:187
int iSendPacket(const WorldPacket &pct)
LockType
LockType m_OutBufferLock
Definition: WorldSocket.h:206
size_t size() const
Definition: ByteBuffer.h:336
void Guard(void *)
const char * LookupOpcodeName(uint16 id)
Definition: Opcodes.h:1119
ACE_UINT32 uint32
Definition: Define.h:71
int WorldSocket::Update ( void  )
protected

Definition at line 355 of file WorldSocket.cpp.

References handle_output(), m_OutActive, and m_OutBuffer.

Referenced by handle_input().

356 {
357  if (closing_)
358  return -1;
359 
360  if (m_OutActive || m_OutBuffer->length () == 0)
361  return 0;
362 
363  return handle_output (get_handle ());
364 }
bool m_OutActive
Definition: WorldSocket.h:219
ACE_Message_Block * m_OutBuffer
Definition: WorldSocket.h:209
virtual int handle_output(ACE_HANDLE=ACE_INVALID_HANDLE)

Friends And Related Function Documentation

friend class ACE_Acceptor< WorldSocket, ACE_SOCK_ACCEPTOR >
friend

Definition at line 86 of file WorldSocket.h.

friend class ReactorRunnable
friend

Definition at line 88 of file WorldSocket.h.

friend class WorldSocketMgr
friend

Definition at line 87 of file WorldSocket.h.

Member Data Documentation

std::string WorldSocket::m_Address
private

Definition at line 183 of file WorldSocket.h.

Referenced by GetRemoteAddress(), and open().

AuthCrypt WorldSocket::m_Crypt
private

Definition at line 186 of file WorldSocket.h.

Referenced by handle_input_header(), HandleAuthSession(), and iSendPacket().

ACE_Message_Block WorldSocket::m_Header
private
ACE_Time_Value WorldSocket::m_LastPingTime
private

Definition at line 177 of file WorldSocket.h.

Referenced by HandlePing().

bool WorldSocket::m_OutActive
private

Definition at line 219 of file WorldSocket.h.

Referenced by cancel_wakeup_output(), open(), schedule_wakeup_output(), and Update().

ACE_Message_Block* WorldSocket::m_OutBuffer
private

Definition at line 209 of file WorldSocket.h.

Referenced by handle_output(), iSendPacket(), open(), Update(), and ~WorldSocket().

LockType WorldSocket::m_OutBufferLock
private

Definition at line 206 of file WorldSocket.h.

Referenced by CloseSocket(), handle_close(), handle_output(), and SendPacket().

size_t WorldSocket::m_OutBufferSize
private

Definition at line 212 of file WorldSocket.h.

Referenced by WorldSocketMgr::OnSocketOpen(), and open().

uint32 WorldSocket::m_OverSpeedPings
private

Definition at line 180 of file WorldSocket.h.

Referenced by HandlePing().

PacketQueueT WorldSocket::m_PacketQueue
private

Definition at line 216 of file WorldSocket.h.

Referenced by iFlushPacketQueue(), SendPacket(), and ~WorldSocket().

ACE_Message_Block WorldSocket::m_RecvPct
private
WorldPacket* WorldSocket::m_RecvWPct
private
uint32 WorldSocket::m_Seed
private

Definition at line 221 of file WorldSocket.h.

Referenced by HandleAuthSession(), and open().

WorldSession* WorldSocket::m_Session
private
LockType WorldSocket::m_SessionLock
private

Definition at line 189 of file WorldSocket.h.

Referenced by CloseSocket(), handle_close(), HandlePing(), and ProcessIncoming().


The documentation for this class was generated from the following files: