All pastes #928281 Raw Edit

Mine

public text v1 · immutable
·published 2008-03-04 22:33 UTC
rendered paste body
Index: src/realmd/Main.cpp
===================================================================
--- src/realmd/Main.cpp	(revision 23)
+++ src/realmd/Main.cpp	(working copy)
@@ -256,10 +256,10 @@
 
     ///- Wait for termination signal
 	ListenSocket<AuthSocket> authListenSocket("0.0.0.0", rmport);
-	if(authListenSocket.IsListernPortOpened())
+	if(authListenSocket.IsListenPortOpened())
 		sSocketManager.StartSocketThreads();
     ///- Wait for termination signal or listen socket closing
-    while (!stopEvent && authListenSocket.IsListernPortOpened())
+    while (!stopEvent && authListenSocket.IsListenPortOpened())
     {
 		Sleep(time_to_sleep);
 		if (RestToPing - time_to_sleep < 0)
Index: src/realmd/realmd.conf
===================================================================
--- src/realmd/realmd.conf	(revision 23)
+++ src/realmd/realmd.conf	(working copy)
@@ -1,58 +1,103 @@
-# MaNGOS realmd configuration file
+############################################
+# MaNGOS realmd configuration file         #
+############################################
 ConfVersion=2007062001
 
-# Database connection settings for the realm server.
-# Default: hostname;port;username;password;database
-#          .;somenumber;username;password;database - use named pipes at Windows
-#                Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini
-#          .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux
-#                Unix sockets: experimental, not tested
-LoginDatabaseInfo = "127.0.0.1;3306;mangos;mangos;realmd"
+###################################################################################################################
+# REALMD SETTINGS
+#
+#    LoginDatabaseInfo
+#        Database connection settings for the realm server.
+#        Default: hostname;port;username;password;database
+#                 .;somenumber;username;password;database - use named pipes at Windows
+#                       Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini
+#                 .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux
+#                       Unix sockets: experimental, not tested
+#
+#    LogsDir
+#         Logs directory setting.
+#         Important: Logs dir must exists, or all logs be disable
+#         Default: "" - no log directory prefix, if used log names isn't absolute path then logs will be 
+#                       stored in current directory for run program.
+#
+#    MaxPingTime
+#         Settings for maximum database-ping interval (minutes between pings)
+#
+#    RealmServerPort
+#         Default RealmServerPort
+#
+#    BindIP
+#         Bind Realm Server to IP/hostname
+#
+#    PidFile
+#        Realmd daemon PID file
+#        Default: ""             - do not create PID file
+#                 "./realmd.pid" - create PID file (recommended name)
+#
+#    LogLevel
+#        Server console level of logging
+#        0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug
+#        Default: 0
+#
+#    LogTime
+#        Include time in server console output [hh:mm:ss]
+#        Default: 0 (no time)
+#                 1 (print time)
+#
+#    LogFile
+#        Logfile name
+#        Default: "Realmd.log"
+#                 "" - empty name disable creating log file
+#
+#    LogTimestamp
+#        Logfile with timestamp of server start in name
+#        Default: 0 - no timestamp in name
+#                 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext
+#
+#    LogFileLevel
+#        Server file level of logging
+#        0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug
+#        Default: 0
+#
+#    LogColors
+#        Color for messages (format "normal_color details_color debug_color error_color)
+#        Colors: 0 - BLACK, 1 - RED, 2 - GREEN,  3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 -  CYAN, 7 - GREY,
+#                8 - YELLOW, 9 - LRED, 10 - LGREEN, 11 - LBLUE, 12 - LMAGENTA, 13 - LCYAN, 14 - WHITE
+#        Default: "" - none colors
+#                 "13 7 11 9" - for example :)
+#
+#    UseProcessors
+#        Used processors mask for multi-processors system (Used only at Windows)
+#        Default: 0 (selected by OS)
+#                 number (bitmask value of selected processors)
+#
+#    ProcessPriority
+#        Process proirity setting (Used only at Windows)
+#        Default: 1 (HIGH)
+#                 0 (Normal)
+#
+#    RealmsStateUpdateDelay
+#        Realm list Update up delay (updated at realm list request if delay expired).
+#        Default: 20 
+#                 0  (Disabled)
+#
+#
+#	
+#
+###################################################################################################################
 
-# Logs directory setting.
-# Important: Logs dir must exists, or all logs be disable
-# Default: "" - no log directory prefix, if used log names isn't absolute path then logs will be stored in current directory for run program.
+LoginDatabaseInfo = "127.0.0.1;3306;root;mangos;realmd"
 LogsDir = ""
-
-# Settings for maximum database-ping interval (minutes between pings)
 MaxPingTime = 30
-
-# Default RealmServerPort
 RealmServerPort = 3724
-
-# Server console level of logging
-# 0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug
-# Default: 0
+BindIP = "0.0.0.0"
+PidFile = ""
 LogLevel = 0
-
-# Logfile name 
-#    empty name disable creating log file: LogFile = 
-# Default: "Server.log" - not recommended.
+LogTime = 0
 LogFile = "Realmd.log"
-
-# Logfile with timestamp of server start in name
-# Default: 0 - no timestamp in name
-#          1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext
 LogTimestamp = 0
-
-# Server file level of logging
-# 0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug
-# Default: 0
 LogFileLevel = 0
-
-# Color for messages (format "normal_color details_color debug_color error_color)
-# Colors: 0 - BLACK, 1 - RED, 2 - GREEN,  3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 -  CYAN, 7 - GREY, 
-#         8 - YELLOW, 9 - LRED, 10 - LGREEN, 11 - LBLUE, 12 - LMAGENTA, 13 - LCYAN, 14 - WHITE
-# Default: "" - none colors
-#          "13 7 11 9" - for example :)
 LogColors = ""
-
-# Used processors mask for multi-processors system (Used only at Windows)
-# Default: 0 (selected by OS)
-#          number (bitmask value of selected processors)
 UseProcessors = 0
-
-# Process proirity setting (Used only at Windows)
-#          0 (Normal)
-# Default: 1 (HIGH)
 ProcessPriority = 1
+RealmsStateUpdateDelay = 20
Index: src/realmd/Makefile.am
===================================================================
--- src/realmd/Makefile.am	(revision 23)
+++ src/realmd/Makefile.am	(working copy)
@@ -30,7 +30,7 @@
 	RealmList.h
 
 ## Link realm list daemon against the shared library
-mangos_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/Network/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la
+mangos_realmd_LDADD = ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/NetworkNew/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la
 mangos_realmd_LDFLAGS = -L../../dep/src/zthread $(MYSQL_LIBS) $(LEVENT_LIB) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB)
 
 ## Additional files to include when running 'make dist'
Index: src/shared/NetworkNew/Network.h
===================================================================
--- src/shared/NetworkNew/Network.h	(revision 0)
+++ src/shared/NetworkNew/Network.h	(revision 0)
@@ -0,0 +1,24 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __NETWORK_H__
+#define __NETWORK_H__
+
+#include "Common.h"
+#include "Socket.h"
+#include "SocketManager.h"
+#endif//__NETWORK_H__
Index: src/shared/NetworkNew/Mutex.cpp
===================================================================
--- src/shared/NetworkNew/Mutex.cpp	(revision 0)
+++ src/shared/NetworkNew/Mutex.cpp	(revision 0)
@@ -0,0 +1,185 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "Common.h"
+#include "Mutex.h"
+
+#ifdef WIN32
+#include <winbase.h>
+
+Mutex::Mutex(MutexType type)
+{
+    /*The InitializeCriticalSection function initializes
+    a critical section object.*/
+    ::InitializeCriticalSection(&m_cs);
+}
+
+Mutex::~Mutex()
+{
+    /*The DeleteCriticalSection function releases all
+    resources used by an unowned critical section object.*/
+    ::DeleteCriticalSection(&m_cs);
+}
+
+void Mutex::Lock()
+{
+    /*The EnterCriticalSection function waits for ownership of
+    the specified critical section object. The function returns
+    when the calling thread is granted ownership.*/
+    ::EnterCriticalSection(&m_cs);
+}
+
+void Mutex::Unlock()
+{
+    /*The LeaveCriticalSection function releases ownership of
+    the specified critical section object.*/
+    ::LeaveCriticalSection(&m_cs);
+}
+
+bool Mutex::TryLock()
+{
+    #if(_WIN32_WINNT >= 0x0400)
+    /*The TryEnterCriticalSection function attempts to enter a
+    critical section without blocking. If the call is successful,
+    the calling thread takes ownership of the critical section.*/
+    return ::TryEnterCriticalSection(&m_cs);
+    #else
+    return false;
+    #endif
+}
+
+#else
+/*
+Was used pthreadcc Library Version 1.01
+------------------------------
+Author: Jason But
+jason.but@eng.monash.edu.au
+*/
+
+/******************************************************************************/
+/* Mutex Constructor.														  */
+/*                                                                            */
+/* We must create the internal MutEx of the right type.  Based on the setup   */
+/* parameter type, we set the mutexTheMutEx variable to be initialized with   */
+/* the appropriate type parameters.                                           */
+/******************************************************************************/
+Mutex::Mutex(MutexType type)
+{
+    pthread_mutexattr_t     mattrDetails;
+    pthread_mutexattr_init(&mattrDetails);
+    switch (type)
+    {
+        case fastMutEx:         pthread_mutexattr_settype(&mattrDetails, PTHREAD_MUTEX_NORMAL);
+        break;
+        case recursiveMutEx:    pthread_mutexattr_settype(&mattrDetails, PTHREAD_MUTEX_RECURSIVE);
+        break;
+        case errorcheckMutEx:   pthread_mutexattr_settype(&mattrDetails, PTHREAD_MUTEX_ERRORCHECK);
+        break;
+    }
+    pthread_mutex_init(&m_mutex, &mattrDetails);
+    pthread_mutexattr_destroy(&mattrDetails);
+}
+
+/******************************************************************************/
+/* Mutex Destructor.				                                          */
+/*                                                                            */
+/* The class cannot be destroyed until the internal MutEx is also destroyed.  */
+/* We do this by calling pthread_mutex_destroy() until it returns a success   */
+/* code.  If the MutEx is currently locked then we attempt to lock the MutEx  */
+/* to wait for it to become free, we then immediately Unlock the mutex and    */
+/* try to destroy it again.                                                   */
+/******************************************************************************/
+Mutex::~Mutex()
+{
+    while (pthread_mutex_destroy(&m_mutex) == EBUSY)
+    {
+        Lock();
+        Unlock();
+    }
+}
+
+/******************************************************************************/
+/* void Lock()                                                                */
+/*                                                                            */
+/* This method attempts to lock the MutEx and returns true if successful, or  */
+/* throws an exception on error.  If the MutEx is of an error checking type   */
+/* and the MutEx is already locked by the calling thread, a MutexWouldDeadlock*/
+/* exception is thrown.  The lock is done by calling the pthread_mutex_lock() */
+/* function.  If 0 is returned, the MutEx is now locked and we can return, if */
+/* EDEADLK is returned then we cannot lock the error checking MutEx without   */
+/* causing a deadlock and we throw the exception.  Any other return values    */
+/* signifies either an unknown error type or that the MutEx has not been      */
+/* properly initialized, which CANNOT happen within this class, an Unknown    */
+/* MutEx exception is thrown.                                                 */
+/******************************************************************************/
+void Mutex::Lock()
+{
+    pthread_mutex_lock(&m_mutex);
+    /*
+    case 0:         return;
+    case EDEADLK:   throw ThreadException(ThreadException::errMutexWouldDeadlock);
+    default:        throw ThreadException(ThreadException::errMutexUnknown);
+    */
+}
+
+/******************************************************************************/
+/* void UnLock()                                                              */
+/*                                                                            */
+/* This method attempts to unlock the MutEx and returns if successful, or     */
+/* throws an exception on error.  If the MutEx is of an error checking type   */
+/* and the calling thread did not lock the MutEx, a MutExNotOwned exception   */
+/* is thrown.  This is done by calling the pthread_mutex_unlock() function.   */
+/* If 0 is returned, the MutEx is now unlocked and we can return, if EPERM is */
+/* returned then we cannot unlock the error checking MutEx and we throw the   */
+/* exception.  Any other return values signifies either an unknown error type */
+/* or that the MutEx has not been properly initialized, which CANNOT happen   */
+/* within this class, an Unknown MutEx exception is thrown.                   */
+/******************************************************************************/
+void Mutex::Unlock()
+{
+    pthread_mutex_unlock(&m_mutex);
+    /*
+    case 0:         return;
+    case EPERM:     throw ThreadException(ThreadException::errMutexNotOwned);
+    default:        throw ThreadException(ThreadException::errMutexUnknown);
+    */
+}
+
+/******************************************************************************/
+/* bool TryLock()                                                             */
+/*                                                                            */
+/* This method attempts to lock the MutEx and returns true if successful and  */
+/* false if the MutEx is already locked.  This is done by calling the         */
+/* pthread_mutex_trylock() function.  If 0 is returned, the MutEx is now      */
+/* locked and we can return true, if EBUSY is returned then we cannot lock    */
+/* the MutEx and we return false.  Any other return values signifies either   */
+/* an unknown error type or that the MutEx has not been properly initialized, */
+/* which CANNOT happen within this class so we report a major error and       */
+/* terminate the program.                                                     */
+/******************************************************************************/
+bool Mutex::TryLock()
+{
+    return pthread_mutex_trylock(&m_mutex) == 0;
+    /*
+    case 0:         return true;
+    case EBUSY:     return false;
+    default:        throw ThreadException(ThreadException::errMutexUnknown);
+    */
+}
+#endif //!WIN32
+
+//@
Index: src/shared/NetworkNew/SocketManager.cpp
===================================================================
--- src/shared/NetworkNew/SocketManager.cpp	(revision 0)
+++ src/shared/NetworkNew/SocketManager.cpp	(revision 0)
@@ -0,0 +1,233 @@
+#include "SocketManager.h"
+#include "Policies/SingletonImp.h"
+#include "Util.h"
+
+#include "evutil.h"
+typedef struct bufferevent* PBUFFEREVENT;
+
+void
+io_handle_write(int fd, short event, void *arg);
+void
+io_handle_read(int fd, short event, void *arg);
+
+#ifndef WIN32
+	#define WSAECONNRESET 104
+#endif
+
+INSTANTIATE_SINGLETON_1(SocketManager);
+INSTANTIATE_SINGLETON_1(SocketManagerCleaner);
+
+timeval tv = {0, 50000};
+
+void event_log(int severity, const char *msg)
+{
+	if(!msg)
+		return;
+	switch (severity)
+	{
+	case _EVENT_LOG_DEBUG:
+		sLog.outDebug("<Libevent> %s", msg);
+		break;
+	case _EVENT_LOG_MSG:
+		sLog.outDetail("<Libevent> %s", msg);
+		break;
+	case _EVENT_LOG_WARN:
+		sLog.outDetail("<Libevent> %s", msg);
+		break;
+	case _EVENT_LOG_ERR:
+		sLog.outError("<Libevent> %s", msg);
+		break;
+	default:
+		sLog.outDetail("<Libevent> %s", msg);
+	}
+	return;
+}
+
+void SocketReaderRunnable::run()
+{
+	if(!sSocketManager.GetEventBase())
+	{
+		sLog.outError("<Socket manager> Couldn't start Socket worker thread. Event_base is wrong!");
+		return;
+	}
+
+	sLog.outBasic("<Socket manager> Socket worker thread is started");
+
+	while(1)
+	{
+		Sleep(10);
+		if( event_base_loop(sSocketManager.GetEventBase(), 0) == -1 )
+		{
+			sLog.outError("<Socket manager> Critical error is occured in event_loot. Exit.");
+			sSocketManager.DisconnectAll();
+			return;
+		}
+	}
+	sLog.outBasic("<Socket manager> Socket worker thread is finished");
+}
+
+SocketManager::SocketManager()
+{
+    m_event_base = (event_base*)event_init();
+    if(!m_event_base)
+        sLog.outError("<Socket manager> FATAL ERROR! Couldn't start libevent!");
+    else
+    {
+        event_set_log_callback(event_log);
+        sLog.outBasic("<Socket manager> MaNGOS network uses [%s] event mechanism", event_get_method());
+	}
+	event_base_dispatch(GetEventBase());
+}
+
+SocketManager::~SocketManager()
+{
+    event_base_free(GetEventBase());
+}
+
+bool SocketManager::AddSocket(SocketBase* pSocket)
+{
+    m_Mutex.Lock();
+    m_sockets.insert(pSocket);
+    m_Mutex.Unlock();
+
+
+	event_set(&pSocket->m_ev_read, (int)pSocket->GetSocket(), EV_READ | EV_PERSIST, io_handle_read, pSocket);
+	event_base_set(GetEventBase(), &pSocket->m_ev_read);
+	
+	if(event_add(&pSocket->m_ev_read, &tv) == -1)
+		return false;
+
+	event_set(&pSocket->m_ev_write, (int)pSocket->GetSocket(), EV_WRITE, io_handle_write, pSocket);
+	event_base_set(GetEventBase(), &pSocket->m_ev_write);
+
+    return true;
+}
+
+bool SocketManager::RemoveSocket(SocketBase* pSocket)
+{
+    //Don't call "delete" for socket!
+    if(!pSocket)
+        return false;
+    m_Mutex.Lock();
+    m_sockets.erase(pSocket);
+    m_Mutex.Unlock();
+    sLog.outDebug("<Socket %u> Removed from manager", pSocket->GetSocket());
+	event_del(&pSocket->m_ev_read);
+	event_del(&pSocket->m_ev_write);
+    return true;
+}
+
+void SocketManager::DisconnectAll()
+{
+    m_Mutex.Lock();
+    SocketSet _tempSocketSet(m_sockets.begin(), m_sockets.end());
+    m_Mutex.Unlock();
+    for (SocketSet::iterator _it = _tempSocketSet.begin(); _it != _tempSocketSet.end(); ++_it)
+    {
+        Socket* pSocket = (Socket*)(*_it);
+        if(pSocket)
+            pSocket->Disconnect();
+    }
+    _tempSocketSet.clear();
+}
+
+#ifdef USE_LEVENT
+
+void io_handle_read(int fd, short event, void *arg)
+{
+	if(!arg)
+    {
+        sLog.outError("<Socket unknown> Bad (null) param in read callback.");
+        return;
+    }
+
+	Socket* pSocket = (Socket*)arg;
+	if(!pSocket->IsConnected())
+		return;
+
+	if(event & EV_TIMEOUT)
+	{
+		event_add(&pSocket->m_ev_read, &tv);
+		return;
+	}
+
+	pSocket->OnReadEvent();
+	if(!pSocket->IsConnected()) //Socket can be disconnected after read callback, 
+		return;					//so we mast check it
+	event_add(&pSocket->m_ev_read, &tv);
+}
+
+void
+io_handle_write(int fd, short event, void *arg)
+{
+	if(!arg)
+	{
+		sLog.outError("<Socket unknown> Bad (null) param in read callback.");
+		return;
+	}
+
+	Socket* pSocket = (Socket*)arg;
+	if(!pSocket->IsConnected())
+		return;
+
+	//Lock buffer to send
+	pSocket->LockWriting();
+	int n = send(
+		pSocket->GetSocket(), 
+		(char*)pSocket->WriteBuffer()->get_buffer(), 
+		pSocket->WriteBuffer()->get_data_size(), 0);
+
+	if(n != SOCKET_ERROR) 
+	{
+		//for DEBUG only!
+		if(n == 0)
+			sLog.outError("DEBUG.Rognar: sent in socket [%u] zero bytes!", pSocket->GetSocket());
+
+		//Remove sent data from output buffer
+		pSocket->WriteBuffer()->remove(n); 
+
+		if (pSocket->WriteBuffer()->get_data_size())
+		{//We still have data. reschedule sending
+			if(event_add(&pSocket->m_ev_write, NULL) == -1)
+			{
+				sLog.outError("<Socket %u> Couldn't reschedule sending.", pSocket->GetSocket());
+				pSocket->UnlockWriting();
+				pSocket->Disconnect(true);
+				return;
+			}
+		}
+	}
+	pSocket->UnlockWriting();
+	if (n == -1) 
+	{
+		if (errno == EAGAIN || errno == EINTR) 
+		{
+			//"Resource temporarily unavailable"
+			//This error is returned from operations on nonblocking sockets that cannot be completed immediately, 
+			//for example recv when no data is queued to be read from the socket. 
+			//It is a nonfatal error, and the operation should be retried later. 
+			//It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect 
+			//on a nonblocking SOCK_STREAM socket, since some time must elapse for the connection to be established. 
+			if(event_add(&pSocket->m_ev_write, NULL) == -1)
+			{
+				pSocket->Disconnect(true);
+				return;
+			}
+		}
+		pSocket->Disconnect(true);
+		return;
+	}
+}
+
+
+void SocketManager::StartSocketThreads()
+{
+	ZThread::Thread SocketCleaner(new SocketManagerCleaner);
+	ZThread::Thread tSocketReader(new SocketReaderRunnable);
+}
+
+void SocketManager::StopSocketThreads()
+{
+	//event_base_loopbreak(GetEventBase());
+}
+#endif                                                      //USE_LEVENT
Index: src/shared/NetworkNew/Mutex.h
===================================================================
--- src/shared/NetworkNew/Mutex.h	(revision 0)
+++ src/shared/NetworkNew/Mutex.h	(revision 0)
@@ -0,0 +1,101 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __MUTEX_07072007__H__
+#define __MUTEX_07072007__H__
+#include "Common.h"
+class Mutex
+{
+    public:
+        friend class Condition;
+
+        //Only for Non-Win32/Non-Win64 OS !!
+        enum MutexType
+        { fastMutEx, recursiveMutEx, errorcheckMutEx };
+        //Description
+        /******************************************************************************/
+        /* class Mutax.			                                                      */
+        /*                                                                            */
+        /* This class encapsulates the basic MutEx functionality into a C++ class.    */
+        /* The constructor is used to create the MutEx of a certain type, the default */
+        /* type being fastMutEx.  The destructor will destroy the MutEx.  The Lock()  */
+        /* and Unlock() methods do as expected while TryLock() will lock the MutEx if */
+        /* possible but will not block if locking is not possible.  Details of these  */
+        /* member methods are:                                                        */
+        /*                                                                            */
+        /*----------------------------------------------------------------------------*/
+        /* MutEx Type |                     |                     |                   */
+        /*---------   |      fastMutEx      |   recursiveMutEx    |  errorcheckMutEx  */
+        /* Method |   |                     |                     |                   */
+        /*----------------------------------------------------------------------------*/
+        /* Lock()     | Block until MutEx   | Block until MutEx   | Block until MutEx */
+        /*            | is free.  If MutEx  | is free.  If Mutex  | is free. If Mutex */
+        /*            | is owned by calling | is owned by calling | is owned by the   */
+        /*            | thread, Deadlock    | thread, return true | calling thread,   */
+        /*            | occurs.             | and increment count | throw a MutEx     */
+        /*            |                     | of number of locks. | Would Deadlock    */
+        /*            |                     |                     | exception.        */
+        /*----------------------------------------------------------------------------*/
+        /* Unlock()   | Unlock the MutEx.   | Decrement count of  | If the MutEx is   */
+        /*            |                     | locks, if 0, unlock | currently locked  */
+        /*            |                     | the MutEx.          | by the calling    */
+        /*            |                     |                     | thread then       */
+        /*            |                     |                     | unlock the MutEx, */
+        /*            |                     |                     | otherwise throw a */
+        /*            |                     |                     | MutEx Not Owned   */
+        /*            |                     |                     | exception.        */
+        /*----------------------------------------------------------------------------*/
+        /* TryLock()  | Try to lock the     | Same functionality  | Try to lock the   */
+        /*            | MutEx, return true  | as Lock()           | MutEx, return true*/
+        /*            | if successful, or   |                     | if successful, or */
+        /*            | false if MutEx is   |                     | false if MutEx is */
+        /*            | already locked.     |                     | already locked.   */
+        /*----------------------------------------------------------------------------*/
+        /*                                                                            */
+        /* NOTE: The Condition Class is a friend of the MutualExclusion class since   */
+        /* it needs access to the private mutexTheMutex member variable.              */
+        /******************************************************************************/
+
+        Mutex(MutexType type = recursiveMutEx);
+        ~Mutex();
+
+        void Lock();
+        void Unlock();
+        bool TryLock();
+
+    protected:
+    #ifdef WIN32
+        CRITICAL_SECTION m_cs;
+    #else
+        pthread_mutex_t m_mutex;
+    #endif
+};
+
+//AutoLock _AutoLock(var)
+class AutoLock
+{
+public:
+	AutoLock(Mutex& _mutex): mMutex(_mutex) { mMutex.Lock(); }
+	~AutoLock() { mMutex.Unlock(); }
+private:
+	Mutex& mMutex;
+};
+
+
+#endif//__MUTEX_07072007__H__
+
+//@
Index: src/shared/NetworkNew/Socket.cpp
===================================================================
--- src/shared/NetworkNew/Socket.cpp	(revision 0)
+++ src/shared/NetworkNew/Socket.cpp	(revision 0)
@@ -0,0 +1,483 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "Socket.h"
+#include "SocketManager.h"
+#include <stdarg.h>
+
+namespace MaNGOS_Network
+{
+    std::string GetHostIP()
+    {
+        std::string sRet= "<unknown host>";
+        hostent* pThisHost = gethostbyname("");
+        if (!pThisHost)
+            return sRet;
+
+        char* pIP = inet_ntoa (*(struct in_addr *)*pThisHost->h_addr_list);
+        if (!pIP)
+            return sRet;
+
+        sRet = std::string(pIP);
+        return sRet;
+    }
+};
+
+//////////////////////////////////////////////////////////////////////////
+//DataBuffer class implementation
+DataBuffer::DataBuffer():
+m_pBuffer(NULL), m_bInitialized(false){}
+
+DataBuffer::~DataBuffer()
+{
+	if(m_bInitialized)
+		Destroy();
+}
+
+void DataBuffer::Destroy()
+{
+    m_bInitialized = false;
+    if (m_pBuffer)
+    {
+		free(m_pBuffer);
+		m_pBuffer = NULL;
+    }
+}
+
+bool DataBuffer::Initialize(IN uint32 unDefSize)
+{
+    if (m_bInitialized)
+        return true;
+
+    m_pBuffer = (uint8*)malloc(unDefSize);
+    m_unDefSize = unDefSize;
+    m_Offset = 0;
+	m_bInitialized = (m_pBuffer != NULL);
+    return m_bInitialized;
+}
+
+bool DataBuffer::append(IN const uint8* pSource, IN uint32 unSize)
+{
+    if (!m_bInitialized || !pSource)
+        return false;
+
+    if (unSize == 0)
+        return true;
+
+
+	while (unSize > get_free_size())
+	{
+		// Reallocate
+		uint8* pTempBuffer = m_pBuffer; // save pointer in case realloc fails
+
+		m_unDefSize += CHUNK*((unSize - get_free_size())/CHUNK) + CHUNK;
+
+		m_pBuffer = (uint8*)realloc(m_pBuffer, m_unDefSize);
+		if(!m_pBuffer)
+		{
+			sLog.outError("Reallocation of socket buffer is failed");
+			m_pBuffer = pTempBuffer;
+			Destroy();
+			return false;
+		}
+	}
+    //copies to destination buffer
+    memcpy(m_pBuffer + m_Offset, (void*)pSource, unSize);
+    m_Offset += unSize;
+    return true;
+}
+
+// Retrieves and removes data from the buffer.
+void DataBuffer::extract(OUT uint8* pDest, IN uint32 unSize)
+{
+    if (!m_bInitialized || !pDest || unSize == 0)
+    {
+        unSize = 0;
+        return;
+    }
+
+    uint32 unBytes = std::min(unSize, m_Offset);
+
+    //copies to destination buffer
+    memcpy(pDest, (void*)m_pBuffer, unBytes);
+    //	ASSERT(unBytes <= m_Offset);
+
+    //moves the rest to the begin
+    memmove(m_pBuffer, m_pBuffer + unBytes, m_Offset - unBytes);
+
+    //change offset according to count of copied bytes
+    m_Offset -= unBytes;
+}
+
+void DataBuffer::peek(OUT uint8* pDest, INOUT uint32 unSize)
+{
+    if (!m_bInitialized || !pDest || unSize == 0)
+    {
+        unSize = 0;
+        return;
+    }
+
+    uint32 unBytes = std::min(unSize, m_Offset);
+    //copies to destination buffer
+    memcpy(pDest, (void*)m_pBuffer, unBytes);
+}
+
+uint32 DataBuffer::get_data_size() const
+{
+    return m_Offset;
+}
+
+uint32 DataBuffer::get_free_size() const
+{
+    return m_unDefSize - m_Offset;
+}
+
+void DataBuffer::remove(IN uint32 unSize)
+{
+    if (!m_bInitialized || unSize == 0)
+        return;
+
+    uint32 unBytes = std::min(unSize, m_Offset);
+    if (unBytes == m_Offset)
+    {
+        m_Offset = 0;
+        return;
+    }
+    memmove(m_pBuffer, m_pBuffer + unBytes, m_Offset - unBytes);
+    m_Offset -= unBytes;
+}
+
+bool DataBuffer::has_data() const
+{
+    return get_data_size() != 0;
+}
+
+uint8* DataBuffer::get_buffer()
+{
+    return m_pBuffer;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//Socket base class implementation
+Socket::Socket(SOCKET hSocket, uint32 unInputBufferSize, uint32 unOutputBufferSize): 
+	SocketBase(hSocket), m_bAbleToSend(true)
+{
+    WriteBuffer()->Initialize(unOutputBufferSize);
+    ReadBuffer()->Initialize(unInputBufferSize);
+
+	if (m_SocketHandle == INVALID_SOCKET)
+        m_SocketHandle = socket(AF_INET, SOCK_STREAM, 0);
+
+	u_long arg = 1;
+	if(ioctlsocket(GetSocket(), FIONBIO, &arg) == SOCKET_ERROR)
+		sLog.outError("<Socket %u> Couldn't set nonblocking mode.", GetSocket());
+}
+
+Socket::~Socket()
+{
+    sLog.outDebug("Calls Socket::~Socket()\n");
+    WriteBuffer()->Destroy();
+    ReadBuffer()->Destroy();
+    if (m_bConnected)
+    {
+        m_bConnected = false;
+        if(m_SocketHandle != INVALID_SOCKET)
+        {
+            ::shutdown(m_SocketHandle, SD_BOTH);
+            ::closesocket(m_SocketHandle);
+        }
+        m_SocketHandle = INVALID_SOCKET;
+        sSocketManager.RemoveSocket(this);
+    }
+}
+
+bool Socket::Connect(const char* szAddress, uint32 unPort)
+{
+    //Function retrieves host information corresponding to a host name from a host database
+    struct hostent* pHostInfo = ::gethostbyname(szAddress);
+    if(!pHostInfo)
+    {
+        //Log "Could'n connect to [%s:%u], szAddress, unPort"
+        return false;
+    }
+
+    m_client.sin_family = pHostInfo->h_addrtype;
+    m_client.sin_port = ntohs((u_short)unPort);
+    memcpy(&m_client.sin_addr.s_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
+
+    //Function establishes a connection to a specified socket
+    if(connect(GetSocket(), (const sockaddr*)&m_client, sizeof(m_client)) == SOCKET_ERROR)
+    {
+    #ifdef WIN32
+        sLog.outError("<Socket %u> Couldn't connect to [%s]. Error [%u]", GetSocket(), GetRemoteAddress().c_str(), ::WSAGetLastError());
+	#else
+		sLog.outError("<Socket %u> Couldn't connect to [%s].", GetSocket(), GetRemoteAddress().c_str());
+    #endif//WIN32
+        return false;
+    }
+
+    sLog.outDebug("<Socket %u> Connected to [%s:%u] successfully", (uint32)GetSocket(), szAddress, unPort);
+    SetOptions();
+	m_bConnected = true;
+    if(!sSocketManager.AddSocket(this))
+		return false;
+    //Notify "child"
+    OnConnect();
+    return true;
+}
+
+//New socket connection accepted
+bool Socket::Accept(IN sockaddr_in* psAddress)
+{
+    if (!psAddress)
+        return false;
+
+    sLog.outDebug("<Socket %u> New connection accepted.", GetSocket());
+
+    //Assign client information
+    memcpy(&m_client, psAddress, sizeof(*psAddress));
+    //SetOptions();
+    m_bConnected = true;
+    if(!sSocketManager.AddSocket(this))
+		return false;
+    //Notify "child"
+    OnConnect();
+    return true;
+}
+
+void Socket::SetOptions()
+{
+    //////////////////////////////////////////////////////////////////////////
+    // "Microsoft Press - 1999 - Network Programming For MS Windows"
+    //
+    //In order to increase performance and throughput by minimizing overhead,
+    //the system implements the Nagle algorithm. When an application requests
+    //to send a chunk of data, the system might hold on to that data for a while
+    //and wait for other data to accumulate before actually sending it on the wire.
+    //Of course, if no other data accumulates in a given period of time, the data
+    //will be sent regardless. This results in more data in a single TCP packet,
+    //as opposed to smaller chunks of data in multiple TCP packets.
+    //The overhead is that the TCP header for each packet is 20 bytes long.
+    //Sending a couple bytes here and there with a 20-byte header is wasteful.
+    //The other part of this algorithm is the delayed acknowledgments.
+    //Once a system receives TCP data it must send an ACK to the peer.
+    //However, the host will wait to see whether it has data it is sending to
+    //the peer so that it can piggyback the ACK on the data to be sent resulting in one less packet on the network.
+    //The purpose of this option is to disable the Nagle algorithm, as its behavior can be detrimental in a few cases.
+    //This algorithm can adversely affect any network application that sends relatively small amounts of data and expects
+    //a timely response. A classic example is Telnet. Telnet is an interactive application that allows the user
+    //to log on to a remote machine and send it commands. Typically the user hits only a few keystrokes per second.
+    //The Nagle algorithm would make such a session seem sluggish and unresponsive.
+	int arg2 = 1;
+	if(setsockopt(GetSocket(), IPPROTO_TCP, TCP_NODELAY, (char*)&arg2, sizeof(arg2)) == SOCKET_ERROR)
+#ifdef WIN32
+		sLog.outError("<Socket %u> Couldn't set option TCP_NODELAY. Error [%u]", GetSocket(), WSAGetLastError());
+#else
+		sLog.outError("<Socket %u> Couldn't set option TCP_NODELAY", GetSocket());
+#endif//WIN32
+}
+
+void Socket::Disconnect(bool bAbort)
+{
+    if(!m_bConnected)
+        return;
+    if(bAbort)
+        sLog.outError("<Socket %u> Abortively disconnected.", GetSocket());
+    else
+        sLog.outDetail("<Socket %u> Gracefully disconnected.", GetSocket());
+    m_bConnected = false;
+    if(m_SocketHandle != INVALID_SOCKET)
+    {
+        //////////////////////////////////////////////////////////////////////////
+        //shutdown
+        //To ensure that all data an application sends is received by the peer,
+        //a well-written application should notify the receiver that no more data is to be sent.
+        //SD_BOTH disables both sends and receives
+        ::shutdown(m_SocketHandle, SD_BOTH);
+
+        //////////////////////////////////////////////////////////////////////////
+        //closesocket
+        //The closesocket function closes a socket
+        //Calling closesocket releases the socket descriptor and any further calls using the socket fail with WSAENOTSOCK.
+        //If there are no other references to this socket, all resources associated with the descriptor are released.
+        //This includes discarding any queued data.
+        ::closesocket(m_SocketHandle);
+    }
+    sSocketManager.RemoveSocket(this);
+    m_SocketHandle = INVALID_SOCKET;
+    OnDisconnect();
+}
+
+//////////////////////////////////////////////////////////////////////////
+//LibEvent implementation
+#ifdef USE_LEVENT
+
+bool Socket::Send(IN const uint8* pSrc, INOUT uint32 unSize)
+{
+    if(!m_bConnected)
+        return false;
+
+	LockWriting();
+	WriteBuffer()->append(pSrc, unSize);
+	int res = event_add(&m_ev_write, NULL);
+	UnlockWriting();
+	if(res == -1)
+	{
+		sLog.outError("Socket::Send couldn't add write event");
+	}
+	return (res != -1);
+}
+
+void Socket::OnReadEvent()
+{
+    if(!m_bConnected)
+        return;
+
+	//TODO peak MSG_PEEK
+	LockReading();
+	uint32 iosize = recv(GetSocket(),
+		(char*)(ReadBuffer()->get_buffer() + ReadBuffer()->get_data_size()),
+		ReadBuffer()->get_free_size(), 0); 
+
+	if (iosize == 0 || iosize == -1)
+	{//If the connection has been gracefully closed, the return value is zero.
+		//If the connection has been abortively closed, the return value is SOCKET_ERROR.
+		UnlockReading();
+		Disconnect(iosize == -1);
+		return;
+	}
+
+	ReadBuffer()->get_offset() += iosize;
+	UnlockReading();
+	OnRead();
+}
+
+#endif//USE_LEVENT
+//////////////////////////////////////////////////////////////////////////
+
+void Socket::Sendf(const char *format, ...)
+{
+	va_list ap;
+	va_start(ap, format);
+	char slask[5000];                                       // vsprintf / vsnprintf temporary
+#ifdef _WIN32
+	vsprintf(slask, format, ap);
+#else
+	vsnprintf(slask, 5000, format, ap);
+#endif
+	va_end(ap);
+	Send((uint8*)slask, strlen(slask));
+}
+
+
+std::string Socket::GetRemoteAddress()
+{
+	char* szIP = (char*)inet_ntoa(m_client.sin_addr);
+	std::string sRemoteAddress = "<unknown>";
+	if (szIP)
+		sRemoteAddress = std::string(szIP);
+	return sRemoteAddress;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//IOCP implementation
+#ifdef USE_IOCP
+bool Socket::Send(IN const uint8* pSrc, INOUT uint32 unSize)
+{
+	if(!unSize)
+		return false;
+
+	LockWriting();
+	if(!WriteBuffer()->append(pSrc, unSize))
+	{
+		UnlockWriting();
+		return false;
+	}
+
+	if (!m_bAbleToSend)
+	{
+		UnlockWriting();
+		return true;
+	}
+	m_bAbleToSend = false;
+	bool bres = SendBuffer();
+	UnlockWriting();
+	return bres;
+}
+
+void Socket::SendComplete(uint32 dwIoSize)
+{
+    if (!dwIoSize)
+    {
+        Disconnect(true);
+        return;
+    }
+
+    LockWriting();
+    WriteBuffer()->remove(dwIoSize);
+    if (WriteBuffer()->get_data_size())
+        SendBuffer();
+    else
+        m_bAbleToSend = true;
+    UnlockWriting();
+}
+
+void Socket::ReadComplete(uint32 dwIoSize)
+{
+    if (dwIoSize > ReadBuffer()->get_free_size())
+    {
+		sLog.outError("<Socket %u> Read buffer is overflowed", GetSocket());
+        Disconnect(true);
+        return;
+    }
+    ReadBuffer()->get_offset() += dwIoSize;
+    OnRead();
+}
+
+bool Socket::SendBuffer()
+{
+	if(WriteBuffer()->get_data_size())
+	{
+		ULONG ulFlags = 0;
+		DWORD dwSendNumBytes = 0;
+		IOCPBuffer *pOverlapBuff = new IOCPBuffer();
+		pOverlapBuff->SetupWrite((char*)WriteBuffer()->get_buffer(), WriteBuffer()->get_data_size());
+		int err = WSA_IO_PENDING;
+		if(::WSASend(GetSocket(), pOverlapBuff->GetWSABuffer(), 1, &dwSendNumBytes,  ulFlags, &pOverlapBuff->m_ol, NULL) == SOCKET_ERROR &&
+			WSAGetLastError() != WSA_IO_PENDING
+			//The error code WSA_IO_PENDING indicates that the overlapped
+			//operation has been successfully initiated and that completion
+			//will be indicated at a later time. Any other error code
+			//indicates that the overlapped operation was not successfully
+			//initiated and no completion indication will occur.
+			)
+		{
+			Disconnect();
+			delete pOverlapBuff;
+			pOverlapBuff = NULL;
+		}
+		return true;
+	}
+	else
+	{
+		IOCPBuffer *pOverlapBuff = new IOCPBuffer(IOWriteCompleted);
+		return TRUE == ::PostQueuedCompletionStatus(GetIOCompletionPort(), 0, (DWORD)this, &pOverlapBuff->m_ol);
+	}
+}
+#endif//USE_IOCP
+//////////////////////////////////////////////////////////////////////////
Index: src/shared/NetworkNew/SocketManager.h
===================================================================
--- src/shared/NetworkNew/SocketManager.h	(revision 0)
+++ src/shared/NetworkNew/SocketManager.h	(revision 0)
@@ -0,0 +1,133 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __SOCKET_MANAGER_H__
+#define __SOCKET_MANAGER_H__
+
+#include "Mutex.h"
+#include "Policies/Singleton.h"
+#include "Network.h"
+#include "../Log.h"
+
+#define WORKER_THREADS_PER_PROCESSOR 2
+typedef std::set<SocketBase*> SocketSet;
+
+class SocketManager : public MaNGOS::Singleton<SocketManager, MaNGOS::ClassLevelLockable<SocketManager, ZThread::FastMutex> >
+{
+    public:
+        SocketManager();
+        ~SocketManager();
+
+    public:
+        bool AddSocket(SocketBase* pSocket);
+        bool RemoveSocket(SocketBase* pSocket);
+        void DisconnectAll();
+
+        void StartSocketThreads();
+        void StopSocketThreads();
+
+    public:
+		event_base* GetEventBase() {return m_event_base;}
+
+    private:
+		struct event_base* m_event_base;
+        Mutex m_Mutex;
+        int m_iIOWorkersCount;
+        SocketSet m_sockets;
+};
+
+#define sSocketManager MaNGOS::Singleton<SocketManager>::Instance()
+
+class SocketReaderRunnable : public ZThread::Runnable
+{
+public:
+    void run();
+};
+
+class SocketWriterRunnable : public ZThread::Runnable
+{
+public:
+	void run();
+};
+//Temporary, but necessary :(
+class SocketManagerCleaner :
+	public MaNGOS::Singleton<SocketManagerCleaner, MaNGOS::ClassLevelLockable<SocketManagerCleaner, ZThread::FastMutex> >,
+	public ZThread::Runnable
+{
+    public:
+        SocketManagerCleaner()
+        {
+            m_stopEvent = false;
+        }
+        ~SocketManagerCleaner()
+        {
+            MapToClean::iterator it;
+            while (!toClean.empty())
+            {
+                it = toClean.begin();
+                delete it->first;
+                toClean.erase(it);
+            }
+        }
+
+        typedef std::map<SocketBase*, time_t> MapToClean;
+        void Add(SocketBase* pSocket)
+        {
+            if(!pSocket)
+				return;
+            if(pSocket->IsConnected())
+			{
+                sLog.outError("Abnormal!! Connected socket is marked to delete. Skipped");
+				return;
+			}
+
+            mMutex.Lock();
+            time_t _time = time(NULL);
+            toClean[pSocket] = _time + 5;
+            mMutex.Unlock();
+        }
+
+		void run()                                             // WIN32
+        {
+            while (!m_stopEvent)
+            {
+                Sleep(100);
+                mMutex.Lock();
+                time_t _current_time = time(NULL);
+                MapToClean::iterator it1, it2;
+                for (it1 = toClean.begin(); it1 != toClean.end();)
+                {
+                    it2 = it1++;
+                    if (it2->second < _current_time)
+                    {
+                        delete it2->first;
+                        toClean.erase(it2);
+                    }
+                }
+                mMutex.Unlock();
+            }
+			toClean.clear();
+        }
+
+        void Stop(){ m_stopEvent = true; }
+        bool m_stopEvent;
+        Mutex mMutex;
+        MapToClean toClean;
+};
+
+#define sAuthSocketManagerCleaner MaNGOS::Singleton<SocketManagerCleaner>::Instance()
+#endif                                                      //__SOCKET_MANAGER_H__
Index: src/shared/NetworkNew/ListenSocket.h
===================================================================
--- src/shared/NetworkNew/ListenSocket.h	(revision 0)
+++ src/shared/NetworkNew/ListenSocket.h	(revision 0)
@@ -0,0 +1,114 @@
+#ifndef __LISTER_SOCKET_NWIN32_H__
+#define __LISTER_SOCKET_NWIN32_H__
+
+#include "Common.h"
+#include "Log.h"
+
+template<class T>
+class ListenSocket: 
+	public SocketBase
+{
+public:
+	ListenSocket(const char* szListenAddress, int unPort):
+	  m_bSocketCreated(false)
+	  {
+		  do
+		  {
+			  if((m_SocketHandle = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
+			  {
+				  sLog.outError("<Listen socket> Couldn't create socket");
+				  break;
+			  }
+
+			  int on = 1;
+			  if (setsockopt(m_SocketHandle, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)) == SOCKET_ERROR)
+			  {
+				  sLog.outError("<Listen socket %u> Couldn't set option SO_REUSEADDR", 
+					  m_SocketHandle);
+				  break;
+			  }
+
+			  u_long arg = 1;
+			  if(ioctlsocket(m_SocketHandle, FIONBIO, &arg) == SOCKET_ERROR)
+			  {
+				  sLog.outError("<Listen socket %u> Couldn't set nonblocking mode", 
+					  m_SocketHandle);
+				  break;
+			  }
+
+			  sockaddr_in address;
+			  if(!strcmp(szListenAddress, "0.0.0.0"))
+				  address.sin_addr.s_addr = htonl(INADDR_ANY);
+			  else
+			  {
+				  hostent* h = gethostbyname(szListenAddress);
+				  if(!h)
+				  {
+					  sLog.outError("<Listen socket %u> Couldn't retrieve host information corresponding "
+						  "to a host name from a host database", 
+						  m_SocketHandle);
+					  break;
+				  }
+
+				  memcpy(&address.sin_addr, h->h_addr_list[0], sizeof(in_addr));
+			  }
+
+			  address.sin_family = AF_INET;
+			  address.sin_port = ntohs(unPort);
+			  if (bind(m_SocketHandle, (const sockaddr*)&address, sizeof(sockaddr_in)) == SOCKET_ERROR)
+			  {
+				  sLog.outError("<Listen socket %u> Couldn't associate a local address with a socket", 
+					  m_SocketHandle);
+				  break;
+			  }
+
+			  if (listen(m_SocketHandle, 1024) == SOCKET_ERROR)
+			  {
+				  sLog.outError("<Listen socket %u> Couldn't place a socket in a state in which it"
+					  " is listening for an incoming connection", 
+					  m_SocketHandle);
+				  break;
+			  }
+			  m_bSocketCreated = true;
+		  }
+		  while(false);
+
+		  if (m_bSocketCreated && sSocketManager.AddSocket(this))
+			  sLog.outBasic("<Listen socket %u> Listening started...", m_SocketHandle);
+		  else
+		  {
+			  sLog.outError("<Listen socket %u> Creating failed", m_SocketHandle);
+			  StopListening();
+		  }
+	  }
+
+	  void Disconnect(bool bAbort = false) { StopListening(); }
+	  bool IsConnected() { return IsListenPortOpened(); }
+	  bool IsListenPortOpened() { return m_bSocketCreated;}
+
+	  void OnReadEvent()
+	  {
+		  struct sockaddr_in ClientAddress;
+		  socklen_t addrlen = sizeof(ClientAddress);
+		  SOCKET client_sock;
+		  if ((client_sock = accept(m_SocketHandle, (sockaddr*)&ClientAddress, &addrlen)) == INVALID_SOCKET) 
+		  {	
+			  sLog.outError("<Listen socket %u> Couldn't accept connection. Some error. Skipped.", m_SocketHandle);
+			  return;
+		  }
+		  T* pSocket = new T(client_sock);
+		  pSocket->Accept(&ClientAddress);
+	  }
+
+	void StopListening()
+	{
+		sLog.outBasic("<Listen socket %u> Listen socket closed", m_SocketHandle);
+		sSocketManager.RemoveSocket(this);
+		::closesocket(m_SocketHandle);
+		m_bSocketCreated = false;
+	}
+
+private:
+	bool m_bSocketCreated;
+};
+#endif//__LISTER_SOCKET_NWIN32_H__
Index: src/shared/NetworkNew/Socket.h
===================================================================
--- src/shared/NetworkNew/Socket.h	(revision 0)
+++ src/shared/NetworkNew/Socket.h	(revision 0)
@@ -0,0 +1,236 @@
+/* 
+ * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __SOCKET_BASE_IMPL_H__
+#define __SOCKET_BASE_IMPL_H__
+
+#include "Common.h"
+#include "Mutex.h"
+#include <fcntl.h>
+
+//Returns the local IP Address
+namespace MaNGOS_Network
+{
+    std::string GetHostIP();
+};
+
+//Input
+#define IN
+
+//Output
+#define OUT
+
+//In/Out
+#define INOUT
+
+#ifndef note
+#define _note_str(x)    #x
+#define note_str(x) _note_str(x)
+#define note(desc)  message(__FILE__ "(" note_str(__LINE__) ") : Note: " ##desc)
+#endif                                                      //note
+//How to use it: #pragma note("Message text")
+
+//////////////////////////////////////////////////////////////////////////
+//DataBuffer class declaration
+#define CHUNK (16384)
+class DataBuffer
+{
+    public:
+        //Constructor
+        DataBuffer();
+
+        // Destruction.
+        virtual ~DataBuffer();
+
+        // Allocates memory.
+        bool Initialize(IN uint32 unDefSize);
+
+        // Deallocates memory.
+        void Destroy();
+
+        // Appends data to the buffer.
+        bool append(IN const uint8* pSrc, IN uint32 unSize);
+
+        // Retrieves and removes data from the buffer.
+        void extract(OUT uint8* pDest, IN uint32 unSize);
+
+        // Retrieves data from the buffer, does not remove.
+        void peek(OUT uint8* pDest, INOUT uint32 unSize);
+
+        // Returns the number of bytes available for extraction.
+        uint32 get_data_size() const;
+
+        // Returns the number of bytes available for appending.
+        uint32 get_free_size() const;
+
+        // Removes a number of bytes from the buffer.
+        void remove(IN uint32 size);
+
+        // Checks whether the buffer has data.
+        bool has_data() const;
+
+        uint32& get_offset(){return m_Offset;}
+
+        // Retrieves buffer.
+        uint8* get_buffer();
+
+    private:
+        bool m_bInitialized;
+        uint8* m_pBuffer;
+        uint32 m_Offset;
+        uint32 m_unDefSize;
+};
+
+//////////////////////////////////////////////////////////////////////////
+//Socket base class declaration
+#define RECVBUF_SIZE (16384)
+#define SENDBUF_SIZE (65536)
+
+class SocketBase
+{
+public:
+	SocketBase(SOCKET hSocket = INVALID_SOCKET) : m_SocketHandle(hSocket), m_bConnected(false), m_pBufEvent(NULL)
+	{}
+	~SocketBase()
+	{
+		m_SocketHandle = INVALID_SOCKET;
+		m_bConnected = false;
+		m_pBufEvent =NULL;
+	}
+	SOCKET GetSocket() { return m_SocketHandle; }
+	virtual void OnReadEvent() = 0;
+	virtual bool IsConnected() = 0;
+	virtual void Disconnect(bool bAbort = false) = 0;
+
+
+	SOCKET m_SocketHandle;                              //Socket handler
+	bool m_bConnected;                                  //Is socket connected
+
+	struct event m_ev_read;
+	struct event m_ev_write;
+	struct bufferevent* m_pBufEvent;
+};
+
+class Socket : public SocketBase
+{
+    public:
+        //////////////////////////////////////////////////////////////////////////
+        // Constructor/Destructor
+        Socket(SOCKET hSocket = INVALID_SOCKET,
+            uint32 unInputBufferSize = RECVBUF_SIZE,
+            uint32 unOutputBufferSize = SENDBUF_SIZE);
+        ~Socket();
+        //////////////////////////////////////////////////////////////////////////
+
+        //////////////////////////////////////////////////////////////////////////
+        // Operations
+        bool Connect(const char* szAddress, uint32 unPort);
+        bool Accept(sockaddr_in* address);
+        void Disconnect(bool bAbort = false);
+        bool Send(IN const uint8* pSrc, INOUT uint32 unSize);
+        void Sendf(const char *format, ...);
+        //////////////////////////////////////////////////////////////////////////
+
+        //IOCP "Callback"
+#ifdef USE_IOCP
+        void ReadComplete(uint32 dwIoSize);
+        void SendComplete(uint32 dwIoSize);
+#endif//USE_IOCP
+
+        //////////////////////////////////////////////////////////////////////////
+        // Virtual notification methods for Socket's "child"
+        virtual void OnRead() {}
+        virtual void OnConnect() {}
+        virtual void OnDisconnect() {}
+        //////////////////////////////////////////////////////////////////////////
+
+#ifdef USE_LEVENT
+        void OnReadEvent();
+
+#endif//USE_LEVENT
+
+        //////////////////////////////////////////////////////////////////////////
+        // Socket's buffers
+        DataBuffer* WriteBuffer() {return &m_WriteBuffer;}
+        DataBuffer* ReadBuffer() {return &m_ReadBuffer;}
+        //////////////////////////////////////////////////////////////////////////
+        void SetOptions();
+        //////////////////////////////////////////////////////////////////////////
+        //Win32 specific functional
+    #ifdef WIN32
+        void AssignIOCompletionPort(HANDLE hIOCP)
+        {
+            m_IOCompletitionPort = hIOCP;
+        }
+
+        HANDLE GetIOCompletionPort()
+        {
+            return m_IOCompletitionPort;
+        }
+    private:
+        HANDLE m_IOCompletitionPort;
+    public:
+    #endif                                                  //WIN32
+        bool m_bAbleToSend;
+        //////////////////////////////////////////////////////////////////////////
+
+        //////////////////////////////////////////////////////////////////////////
+        //Socket's helpers
+        std::string GetRemoteAddress();                     //Retrieves connected client IP address
+        bool IsConnected()                           // Retrieves connection status
+        {
+            return m_bConnected;
+        }
+
+        //////////////////////////////////////////////////////////////////////////
+
+        //////////////////////////////////////////////////////////////////////////
+        // Socket mutex helper
+        void LockWriting()                                  //Locks writing
+        {
+            m_WriteMutex.Lock();
+        }
+        void UnlockWriting()                                //Unlocks writing
+        {
+            m_WriteMutex.Unlock();
+        }
+
+        void LockReading()                                  //Locks reading
+        {
+            m_ReadMutex.Lock();
+        }
+        void UnlockReading()                                //Unlocks reading
+        {
+            m_ReadMutex.Unlock();
+        }
+        //////////////////////////////////////////////////////////////////////////
+
+    private:
+        bool SendBuffer();
+
+        //Mutex for send/recv operation
+        Mutex m_WriteMutex;
+        Mutex m_ReadMutex;
+
+        sockaddr_in m_client;                               //Name of the socket in the sockaddr structure to which the connection should be established.
+
+        //////////////////////////////////////////////////////////////////////////
+        //Socket data buffers
+        DataBuffer m_ReadBuffer;                            //Input buffer
+        DataBuffer m_WriteBuffer;                           //Output buffer
+};
+#endif                                                      //__SOCKET_BASE_IMPL_H__
Index: src/mangosd/Makefile.am
===================================================================
--- src/mangosd/Makefile.am	(revision 23)
+++ src/mangosd/Makefile.am	(working copy)
@@ -33,7 +33,7 @@
 	WorldRunnable.h
 
 ## Link world daemon against the shared library
-mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../shared/Network/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
+mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/Database/libmangosdatabase.a ../shared/Config/libmangosconfig.a ../shared/Auth/libmangosauth.a ../shared/libmangosshared.a ../shared/vmap/libmangosvmaps.a ../shared/NetworkNew/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a
 mangos_worldd_LDFLAGS = -L../../dep/src/zthread  -L../../dep/src/g3dlite -L../bindings/universal/ $(MYSQL_LIBS) $(LEVENT_LIB) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic
 
 ## Additional files to include when running 'make dist'
Index: src/mangosd/Master.cpp
===================================================================
--- src/mangosd/Master.cpp	(revision 23)
+++ src/mangosd/Master.cpp	(working copy)
@@ -136,7 +136,7 @@
         uint32 raport = sConfig.GetIntDefault( "Ra.Port", 3443 );
         std::string stringip = sConfig.GetStringDefault( "Ra.IP", "0.0.0.0" );
         pRAListenSocket = new ListenSocket<RASocket>(stringip.c_str(), raport);
-		if (!pRAListenSocket->IsListernPortOpened())
+		if (!pRAListenSocket->IsListenPortOpened())
 			sLog.outString("Remote access lister on port %d on %s - FAILED", raport, stringip.c_str());
         else
 			sLog.outString("Starting Remote access lister on port %d on %s", raport, stringip.c_str());
@@ -191,7 +191,7 @@
 	uint32 wsport = sWorld.getConfig(CONFIG_PORT_WORLD);
 	ListenSocket<WorldSocket> worldListenSocket("0.0.0.0", wsport);
 
-	if(worldListenSocket.IsListernPortOpened())
+	if(worldListenSocket.IsListenPortOpened())
 		sSocketManager.StartSocketThreads();
 
     // maximum counter for next ping
@@ -200,7 +200,7 @@
 	uint32 time_to_sleep = 100;
 
     ///- Wait for termination signal
-    while (!World::m_stopEvent && worldListenSocket.IsListernPortOpened())
+    while (!World::m_stopEvent && worldListenSocket.IsListenPortOpened())
     {
 #ifdef WIN32
         if (m_ServiceStatus == 0) World::m_stopEvent = true;
Index: src/game/Makefile.am
===================================================================
--- src/game/Makefile.am	(revision 23)
+++ src/game/Makefile.am	(working copy)
@@ -256,7 +256,7 @@
 	GroupRefManager.h
 
 ## Link against shared library
-libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/Network/libmangosnetwork.a ../shared/vmap/libmangosvmaps.a
+libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/NetworkNew/libmangosnetwork.a ../shared/vmap/libmangosvmaps.a
 
 ## Additional files to include when running 'make dist'
 #  Nothing yet.