All pastes #877719 Raw Edit

Mine

public text v1 · immutable
#877719 ·published 2008-01-29 11:27 UTC
rendered paste body
Index: src/mangosd/Master.cpp
===================================================================
--- src/mangosd/Master.cpp	(revision 5031)
+++ src/mangosd/Master.cpp	(working copy)
@@ -21,8 +21,7 @@
 */
 
 #include "Master.h"
-#include "Network/SocketHandler.h"
-#include "Network/ListenSocket.h"
+#include "Network/Network.h"
 #include "WorldSocket.h"
 #include "WorldSocketMgr.h"
 #include "WorldRunnable.h"
@@ -39,29 +38,21 @@
 #include "ScriptCalls.h"
 #include "Util.h"
 
-#include "Network/TcpSocket.h"
-#include "Network/Utility.h"
-#include "Network/Parse.h"
-#include "Network/Socket.h"
+#ifdef WIN32
+#include <crtdbg.h> 
+#endif
 
+
 #ifdef WIN32
 #include "ServiceWin32.h"
 extern int m_ServiceStatus;
 #endif
 
 /// \todo Warning disabling not useful under VC++2005. Can somebody say on which compiler it is useful?
-#pragma warning(disable:4305)
+//#pragma warning(disable:4305)
 
 INSTANTIATE_SINGLETON_1( Master );
 
-Master::Master()
-{
-}
-
-Master::~Master()
-{
-}
-
 /// Main function
 void Master::Run()
 {
@@ -93,6 +84,23 @@
 
         sLog.outString( "Daemon PID: %u\n", pid );
     }
+#ifdef USE_LEVENT
+	//show version of libevent at start
+	sLog.outBasic("Using %s version of LibEvent",event_get_version());
+	bool isvalid_vlibevent=false;
+    const char* accepted_vlibevent[]=REQ_LEVENT_VER;
+    for(int i=0;accepted_vlibevent[i];i++)
+    if(!strcmp(event_get_version(),accepted_vlibevent[i]))
+    {
+        isvalid_vlibevent=true;
+        break;
+    }
+    if(!isvalid_vlibevent)
+    {
+		sLog.outError("Version of libevent is wrong, shutdown now");
+		return;
+     }
+#endif//USE_LEVENT
 
     ///- Start the databases
     if (!_StartDB())
@@ -101,21 +109,6 @@
     ///- Initialize the World
     sWorld.SetInitialWorldSettings();
 
-    ///- Launch the world listener socket
-    port_t wsport = sWorld.getConfig(CONFIG_PORT_WORLD);
-
-    SocketHandler h;
-
-    ListenSocket<WorldSocket> worldListenSocket(h);
-    if (worldListenSocket.Bind(wsport))
-    {
-        clearOnlineAccounts();
-        sLog.outError("MaNGOS cannot bind to port %d", wsport);
-        return;
-    }
-
-    h.Add(&worldListenSocket);
-
     ///- Catch termination signals
     _HookSignals();
 
@@ -137,22 +130,17 @@
     }
 
     ///- Launch the RA listener socket
-    ListenSocket<RASocket> RAListenSocket(h);
+    ListenSocket<RASocket>* pRAListenSocket = NULL;
     if (sConfig.GetBoolDefault("Ra.Enable", false))
     {
-        port_t raport = sConfig.GetIntDefault( "Ra.Port", 3443 );
+        uint32 raport = sConfig.GetIntDefault( "Ra.Port", 3443 );
         std::string stringip = sConfig.GetStringDefault( "Ra.IP", "0.0.0.0" );
-        ipaddr_t raip;
-        if(!Utility::u2ip(stringip, raip))
-            sLog.outError( "MaNGOS RA can not bind to ip %s", stringip.c_str());
-        else if (RAListenSocket.Bind(raip, raport))
-            sLog.outError( "MaNGOS RA can not bind to port %d on %s", raport, stringip.c_str());
+        pRAListenSocket = new ListenSocket<RASocket>(stringip.c_str(), raport);
+		if (!pRAListenSocket->IsListernPortOpened())
+			sLog.outString("Remote access lister on port %d on %s - FAILED", raport, stringip.c_str());
         else
-        {
-            h.Add(&RAListenSocket);
-
-            sLog.outString("Starting Remote access listner on port %d on %s", raport, stringip.c_str());
-        }
+    {
+			sLog.outString("Starting Remote access lister on port %d on %s", raport, stringip.c_str());
     }
 
     ///- Handle affinity for multiple processors and process priority on Windows
@@ -199,42 +187,45 @@
     }
     #endif
 
-    uint32 realCurrTime, realPrevTime;
-    realCurrTime = realPrevTime = getMSTime();
+    //	sSocketManager.SetupIOWorkers();
+	///- Launch the world listener socket
 
-    uint32 socketSelecttime = sWorld.getConfig(CONFIG_SOCKET_SELECTTIME);
+	uint32 wsport = sWorld.getConfig(CONFIG_PORT_WORLD);
+	ListenSocket<WorldSocket> worldListenSocket("0.0.0.0", wsport);
+ 	bool bListenPortOpened = worldListenSocket.IsListernPortOpened();
 
     // maximum counter for next ping
-    uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / socketSelecttime));
-    uint32 loopCounter = 0;
+	uint32 PingInterval = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * MINUTE * 1000);
+	uint32 RestToPing = PingInterval;
+	uint32 time_to_sleep = 100;
 
     ///- Wait for termination signal
-    while (!World::m_stopEvent)
+    while (!World::m_stopEvent && bListenPortOpened)
     {
 #ifdef WIN32
         if (m_ServiceStatus == 0) World::m_stopEvent = true;
         while (m_ServiceStatus == 2) Sleep(1000);
 #endif
-        if (realPrevTime > realCurrTime)
-            realPrevTime = 0;
+		Sleep(time_to_sleep);
+		if (RestToPing - time_to_sleep < 0)
+			RestToPing = 0;
+		else
+			RestToPing -= time_to_sleep;
+		if (RestToPing)
+			continue;
 
-        realCurrTime = getMSTime();
-        sWorldSocketMgr.Update( realCurrTime - realPrevTime );
-        realPrevTime = realCurrTime;
-
-        h.Select(0, socketSelecttime);
-
-        // ping if need
-        if( (++loopCounter) == numLoops )
-        {
-            loopCounter = 0;
+        RestToPing = PingInterval;
             sLog.outDetail("Ping MySQL to keep connection alive");
             delete WorldDatabase.Query("SELECT 1 FROM `command` LIMIT 1");
             delete loginDatabase.Query("SELECT 1 FROM `realmlist` LIMIT 1");
             delete CharacterDatabase.Query("SELECT 1 FROM `bugreport` LIMIT 1");
         }
-    }
 
+	worldListenSocket.StopListening();
+	sSocketManager.DisconnectAll();
+	sSocketManager.StopIOWorkers();
+	sAuthSocketManagerCleaner.Stop();
+
     // set server offline
     loginDatabase.PExecute("UPDATE `realmlist` SET `color` = 2 WHERE `id` = '%d'",realmID);
 
Index: src/mangosd/RASocket.cpp
===================================================================
--- src/mangosd/RASocket.cpp	(revision 5031)
+++ src/mangosd/RASocket.cpp	(working copy)
@@ -27,23 +27,19 @@
 #include "World.h"
 #include "Config/ConfigEnv.h"
 
+uint32 iSession=0;                                          ///< Session number (incremented each time a new connection is made)
+unsigned int iUsers=0;                                      ///< Number of active administrators
+typedef int(* pPrintf)(const char*,...);
 /// \todo Make this thread safe if in the future 2 admins should be able to log at the same time.
-SOCKET r;
-
+SOCKET r=NULL;
 #define dropclient {Sendf("I'm busy right now, come back later."); \
-        SetCloseAndDelete(); \
+        Disconnect(); \
         return; \
     }
-
-uint32 iSession=0;                                          ///< Session number (incremented each time a new connection is made)
-unsigned int iUsers=0;                                      ///< Number of active administrators
-
-typedef int(* pPrintf)(const char*,...);
-
 void ParseCommand(pPrintf zprintf, char*command);
 
 /// RASocket constructor
-RASocket::RASocket(ISocketHandler &h): TcpSocket(h)
+RASocket::RASocket(SOCKET s): Socket(s)
 {
 
     ///- Increment the session number
@@ -72,7 +68,7 @@
 }
 
 /// Accept an incoming connection
-void RASocket::OnAccept()
+void RASocket::OnConnect()
 {
     std::string ss=GetRemoteAddress();
     sLog.outRALog("Incoming connection from %s.\n",ss.c_str());
@@ -87,14 +83,11 @@
 /// Read data from the network
 void RASocket::OnRead()
 {
-    ///- Read data and check input length
-    TcpSocket::OnRead();
-
-    unsigned int sz=ibuf.GetLength();
+    unsigned int sz = ReadBuffer()->get_data_size();
     if(iInputLength+sz>=RA_BUFF_SIZE)
     {
         sLog.outRALog("Input buffer overflow, possible DOS attack.\n");
-        SetCloseAndDelete();
+        Disconnect();
         return;
     }
 
@@ -103,7 +96,7 @@
         dropclient
 
             char *inp = new char [sz+1];
-    ibuf.Read(inp,sz);
+    ReadBuffer()->extract((uint8*)inp, sz);
 
     /// \todo Can somebody explain this 'Linux bugfix'?
     if(stage==NONE)
@@ -153,7 +146,8 @@
                     {
                         Sendf("-No such user.\r\n");
                         sLog.outRALog("User %s does not exist.\n",szLogin.c_str());
-                        if(bSecure)SetCloseAndDelete();
+                        if(bSecure)
+							Disconnect();
                     }
                     else
                     {
@@ -166,7 +160,7 @@
                         {
                             Sendf("-Not enough privileges.\r\n");
                             sLog.outRALog("User %s has no privilege.\n",szLogin.c_str());
-                            if(bSecure)SetCloseAndDelete();
+                            if(bSecure)Disconnect();
                         }   else
                         {
                             stage=LG;
@@ -201,7 +195,7 @@
                         ///- Else deny access
                         Sendf("-Wrong pass.\r\n");
                         sLog.outRALog("User %s has failed to log in.\n",szLogin.c_str());
-                        if(bSecure)SetCloseAndDelete();
+                        if(bSecure)Disconnect();
                     }
                 }
                 break;
@@ -227,13 +221,11 @@
     if( !szText ) return 0;
     va_list ap;
     va_start(ap, szText);
-    /// \todo Remove buffer length here. Can be >1024 (e.g. list of users)
-    char *megabuffer=new char[1024];
-    unsigned int sz=vsnprintf(megabuffer,1024,szText,ap);
+    char *megabuffer=new char[sizeof(szText)];
+    unsigned int sz=vsnprintf(megabuffer,sizeof(szText),szText,ap);
     #ifdef RA_CRYPT
     Encrypt(megabuffer,sz);
     #endif
-
     send(r,megabuffer,sz,0);
     delete [] megabuffer;
     va_end(ap);
Index: src/realmd/AuthSocket.cpp
===================================================================
--- src/realmd/AuthSocket.cpp	(revision 5031)
+++ src/realmd/AuthSocket.cpp	(working copy)
@@ -212,7 +212,7 @@
 Patcher PatchesCache;
 
 /// Constructor - set the N and g values for SRP6
-AuthSocket::AuthSocket(ISocketHandler &h) : TcpSocket(h)
+AuthSocket::AuthSocket(SOCKET h) : Socket(h)
 {
     N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
     g.SetDword(7);
@@ -229,35 +229,30 @@
         fclose(pPatch);
 }
 
+void AuthSocket::OnDisconnect()
+{
+	sAuthSocketManagerCleaner.Add(this);//will be removed after 200 ms
+}
+
 /// Accept the connection and set the s random value for SRP6
-void AuthSocket::OnAccept()
+void AuthSocket::OnConnect()
 {
-    sLog.outBasic("Accepting connection from '%s:%d'",
-        GetRemoteAddress().c_str(), GetRemotePort());
-
-    s.SetRand(s_BYTE_SIZE * 8);
+   sLog.outBasic("Accepting connection from '%s'", GetRemoteAddress().c_str());
+   s.SetRand(s_BYTE_SIZE * 8);
 }
 
 /// Read the packet from the client
 void AuthSocket::OnRead()
 {
     ///- Read the packet
-    TcpSocket::OnRead();
     uint8 _cmd;
     while (1)
     {
-        if (!ibuf.GetLength())
+        if (!ReadBuffer()->get_data_size())
             return;
 
         ///- Get the command out of it
-        ibuf.SoftRead((char *)&_cmd, 1);                    // UQ1: No longer exists in new net code ???
-        //ibuf.Read((char *)&_cmd, 1);
-        /*char *command = (char *)malloc(1);
-
-        ibuf.Read(command, 1);
-
-        _cmd = (uint8)command;*/
-        //      assert(0);
+        ReadBuffer()->peek((uint8*)&_cmd, 1); // UQ1: No longer exists in new net code ???
         size_t i;
 
         ///- Circle through known commands and call the correct command handler
@@ -267,11 +262,11 @@
                 (table[i].status == STATUS_CONNECTED ||
                 (_authed && table[i].status == STATUS_AUTHED)))
             {
-                DEBUG_LOG("[Auth] got data for cmd %u ibuf length %u", (uint32)_cmd, ibuf.GetLength());
+                DEBUG_LOG("[Auth] got data for cmd %u ibuf length %u", (uint32)_cmd, ReadBuffer()->get_data_size());
 
                 if (!(*this.*table[i].handler)())
                 {
-                    DEBUG_LOG("Command handler failed for cmd %u ibuf length %u", (uint32)_cmd, ibuf.GetLength());
+                    DEBUG_LOG("Command handler failed for cmd %u ibuf length %u", (uint32)_cmd, ReadBuffer()->get_data_size());
                     return;
                 }
                 break;
@@ -321,19 +316,22 @@
 bool AuthSocket::_HandleLogonChallenge()
 {
     DEBUG_LOG("Entering _HandleLogonChallenge");
-    if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C))
+    if (ReadBuffer()->get_data_size() < sizeof(sAuthLogonChallenge_C))
         return false;
 
     ///- Read the first 4 bytes (header) to get the length of the remaining of the packet
     std::vector<uint8> buf;
     buf.resize(4);
 
-    ibuf.Read((char *)&buf[0], 4);
+    LockReading();
+    ReadBuffer()->extract((uint8* )&buf[0], 4);
+    UnlockReading();
+
     uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
     DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining);
 
-    if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining))
-        return false;
+ if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ReadBuffer()->get_data_size() < remaining))
+         return false;
 
     //No big fear of memory outage (size is int16, i.e. < 65536)
     buf.resize(remaining + buf.size() + 1);
@@ -341,7 +339,9 @@
     sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];
 
     ///- Read the remaining of the packet
-    ibuf.Read((char *)&buf[4], remaining);
+    LockReading();
+    ReadBuffer()->extract((uint8*)&buf[4], remaining);
+    UnlockReading();
     DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size);
     DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I);
 
@@ -522,19 +522,19 @@
 
             ///- Send a packet to the client with the file length and MD5 hash
             uint8 data[2]={AUTH_LOGON_PROOF,REALM_AUTH_UPDATE_CLIENT};
-            SendBuf((const char*)data,sizeof(data));
+            Send((const uint8*)data,sizeof(data));
 
             memcpy(&xferh,"0\x05Patch",7);
             xferh.cmd=XFER_INITIATE;
             fseek(pPatch,0,SEEK_END);
             xferh.file_size=ftell(pPatch);
 
-            SendBuf((const char*)&xferh,sizeof(xferh));
+            Send((const uint8*)&xferh,sizeof(xferh));
             return true;
         }
     }
     /// </ul>
-    SendBuf((char const*)pkt.contents(), pkt.size());
+    Send((uint8*)pkt.contents(), pkt.size());
     return true;
 }
 
@@ -543,11 +543,13 @@
 {
     DEBUG_LOG("Entering _HandleLogonProof");
     ///- Read the packet
-    if (ibuf.GetLength() < sizeof(sAuthLogonProof_C))
+    if (ReadBuffer()->get_data_size() < sizeof(sAuthLogonProof_C))
         return false;
 
     sAuthLogonProof_C lp;
-    ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));
+    LockReading();
+    ReadBuffer()->extract((uint8*)&lp, sizeof(sAuthLogonProof_C));
+    UnlockReading();
 
     ///- Continue the SRP6 calculation based on data received from the client
     BigNumber A;
@@ -639,7 +641,7 @@
         proof.unk2 = 0;
         proof.unk3 = 0;
 
-        SendBuf((char *)&proof, sizeof(proof));
+        Send((uint8*)&proof, sizeof(proof));
 
         ///- Set _authed to true!
         _authed = true;
@@ -647,7 +649,7 @@
     else
     {
         char data[4]={AUTH_LOGON_PROOF,REALM_AUTH_NO_MATCH,3,0};
-        SendBuf(data,sizeof(data));
+        Send((uint8*)data,sizeof(data));
     }
     return true;
 }
@@ -656,11 +658,14 @@
 bool AuthSocket::_HandleRealmList()
 {
     DEBUG_LOG("Entering _HandleRealmList");
-    if (ibuf.GetLength() < 5)
+    if (ReadBuffer()->get_data_size() < 5)
         return false;
 
-    ibuf.Remove(5);
+    LockReading();
+    ReadBuffer()->remove(5);
+    UnlockReading();
 
+
     ///- Get the user id (else close the connection)
     // No SQL injection (escaped user name)
 
@@ -668,7 +673,7 @@
     if(!result)
     {
         sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str());
-        SetCloseAndDelete();
+        Disconnect();
         return false;
     }
 
@@ -719,7 +724,7 @@
     hdr << (uint16)pkt.size();
     hdr.append(pkt);
 
-    SendBuf((char const*)hdr.contents(), hdr.size());
+    Send(hdr.contents(), hdr.size());
 
     // Set check field before possable relogin to realm
     _SetVSFields(rI);
@@ -731,7 +736,7 @@
 {
     DEBUG_LOG("Entering _HandleXferResume");
     ///- Check packet length
-    if (ibuf.GetLength()<9)
+    if (ReadBuffer()->get_data_size() < 9)
     {
         sLog.outError("Error while resuming patch transfer (wrong packet)");
         return false;
@@ -739,8 +744,10 @@
 
     ///- Launch a PatcherRunnable thread starting at given patch file offset
     uint64 start;
-    ibuf.Remove(1);
-    ibuf.Read((char*)&start,sizeof(start));
+    LockReading();
+    ReadBuffer()->remove(1);
+    ReadBuffer()->extract((uint8*)&start, sizeof(start));
+    UnlockReading();
     fseek(pPatch,start,0);
 
     ZThread::Thread u(new PatcherRunnable(this));
@@ -753,10 +760,14 @@
     DEBUG_LOG("Entering _HandleXferCancel");
 
     ///- Close and delete the socket
-    ibuf.Remove(1);                                         //clear input buffer
+    LockReading();
+    ReadBuffer()->remove(1);
+    UnlockReading();
+                                         //clear input buffer
 
     //ZThread::Thread::sleep(15);
-    SetCloseAndDelete();
+    /// \todo What is the difference between SetCloseAndDelete() and the this->Close() higher?
+    Disconnect();
 
     return true;
 }
@@ -766,7 +777,10 @@
 {
     DEBUG_LOG("Entering _HandleXferAccept");
     ///- Launch a PatcherRunnable thread, starting at the begining of the patch file
-    ibuf.Remove(1);                                         //clear input buffer
+    LockReading();
+    ReadBuffer()->remove(1);
+    UnlockReading();
+                                         //clear input buffer
     fseek(pPatch,0,0);
 
     ZThread::Thread u(new PatcherRunnable(this));
@@ -777,7 +791,7 @@
 /// Check if there is lag on the connection to the client
 bool AuthSocket::IsLag()
 {
-    return (TCP_BUFSIZE_READ-obuf.GetLength()< 2*ChunkSize);
+    return (SENDBUF_SIZE - WriteBuffer()->get_data_size() < 2 * ChunkSize);
 }
 
 PatcherRunnable::PatcherRunnable(class AuthSocket * as)
@@ -791,16 +805,16 @@
     XFER_DATA_STRUCT xfdata;
     xfdata.opcode = XFER_DATA;
 
-    while(!feof(mySocket->pPatch) && mySocket->Ready())
+    while(!feof(mySocket->pPatch) && mySocket->IsConnected())
     {
         ///- Wait until output buffer is reasonably empty
-        while(mySocket->Ready() && mySocket->IsLag())
+         while(mySocket->IsConnected() && mySocket->IsLag())
         {
             ZThread::Thread::sleep(1);
         }
         ///- And send content of the patch file to the client
         xfdata.data_size=fread(&xfdata.data,1,ChunkSize,mySocket->pPatch);
-        mySocket->SendBuf((const char*)&xfdata,xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize));
+mySocket->Send((const uint8*)&xfdata, xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize));
     }
 }
 
Index: src/realmd/AuthSocket.h
===================================================================
--- src/realmd/AuthSocket.h	(revision 5031)
+++ src/realmd/AuthSocket.h	(working copy)
@@ -25,23 +25,19 @@
 
 #include "Common.h"
 #include "Auth/BigNumber.h"
-#include "Network/TcpSocket.h"
-#include "Network/SocketHandler.h"
-#include "Network/ListenSocket.h"
-#include "Network/Utility.h"
-#include "Network/Parse.h"
-#include "Network/Socket.h"
+#include "Network/Network.h"
 
 /// Handle login commands
-class AuthSocket: public TcpSocket
+class AuthSocket: public Socket
 {
     public:
         const static int s_BYTE_SIZE = 32;
 
-        AuthSocket(ISocketHandler& h);
+        AuthSocket(SOCKET h);
         ~AuthSocket();
 
-        void OnAccept();
+        void OnConnect();
+	void OnDisconnect();
         void OnRead();
 
         bool _HandleLogonChallenge();
Index: src/realmd/Main.cpp
===================================================================
--- src/realmd/Main.cpp	(revision 5031)
+++ src/realmd/Main.cpp	(working copy)
@@ -26,7 +26,7 @@
 
 #include "Config/ConfigEnv.h"
 #include "Log.h"
-#include "Network/ListenSocket.h"
+#include "Network/Network.h"
 #include "AuthSocket.h"
 #include "SystemConfig.h"
 #include "Util.h"
@@ -154,7 +154,23 @@
 
     sLog.outString( "MaNGOS realm daemon %s", _FULLVERSION );
     sLog.outString( "<Ctrl-C> to stop.\n" );
-
+#ifdef USE_LEVENT
+	//show version of libevent at start
+	sLog.outBasic("Using %s version of LibEvent",event_get_version());
+	bool isvalid_vlibevent=false;
+	const char* accepted_vlibevent[]=REQ_LEVENT_VER;
+	for(int i=0;accepted_vlibevent[i];i++)
+		if(!strcmp(event_get_version(),accepted_vlibevent[i]))
+		{
+			isvalid_vlibevent=true;
+			break;
+		}
+		if(!isvalid_vlibevent)
+		{
+			sLog.outError("Version of libevent is wrong, shutdown now");
+		return 1;
+		}
+#endif//USE_LEVENT
     /// realmd PID file creation
     std::string pidfile = sConfig.GetStringDefault("PidFile", "");
     if(!pidfile.empty())
@@ -182,19 +198,6 @@
         return 1;
     }
 
-    ///- Launch the listening network socket
-    port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT );
-
-    SocketHandler h;
-    ListenSocket<AuthSocket> authListenSocket(h);
-    if ( authListenSocket.Bind(rmport))
-    {
-        sLog.outError( "MaNGOS realmd can not bind to port %d", rmport );
-        return 1;
-    }
-
-    h.Add(&authListenSocket);
-
     ///- Catch termination signals
     HookSignals();
 
@@ -242,18 +245,27 @@
     #endif
 
     // maximum counter for next ping
-    uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000));
-    uint32 loopCounter = 0;
+	uint32 PingInterval = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * MINUTE * 1000);
+	uint32 RestToPing = PingInterval;
+	uint32 time_to_sleep = 100;
+	///- Launch the listening network socket
+	uint32 rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT );
 
     ///- Wait for termination signal
-    while (!stopEvent)
+	ListenSocket<AuthSocket> authListenSocket("0.0.0.0", rmport);
+    ///- Wait for termination signal or listen socket closing
+    while (!stopEvent && authListenSocket.IsListernPortOpened())
     {
+		Sleep(time_to_sleep);
+		if (RestToPing - time_to_sleep < 0)
+			RestToPing = 0;
+		else
+			RestToPing -= time_to_sleep;
+		if (RestToPing)
+			continue;
 
-        h.Select(0, 100000);
-
-        if( (++loopCounter) == numLoops )
-        {
-            loopCounter = 0;
+		// ping if need
+		RestToPing = PingInterval;
             sLog.outDetail("Ping MySQL to keep connection alive");
             delete dbRealmServer.Query("SELECT 1 FROM `realmlist` LIMIT 1");
         }
@@ -261,7 +273,10 @@
         if (m_ServiceStatus == 0) stopEvent = true;
         while (m_ServiceStatus == 2) Sleep(1000);
 #endif
-    }
+    authListenSocket.StopListening();
+    sSocketManager.DisconnectAll();
+    sSocketManager.StopIOWorkers();
+	sAuthSocketManagerCleaner.Stop();
 
     ///- Wait for the delay thread to exit
     dbRealmServer.HaltDelayThread();