diff options
Diffstat (limited to 'cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text/x-cvsweb-markup&sortby=date')
-rw-r--r-- | cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text/x-cvsweb-markup&sortby=date/index.html | 506 |
1 files changed, 506 insertions, 0 deletions
diff --git a/cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text/x-cvsweb-markup&sortby=date/index.html b/cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text/x-cvsweb-markup&sortby=date/index.html new file mode 100644 index 00000000..f68bcdc7 --- /dev/null +++ b/cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?rev=1.16&content-type=text/x-cvsweb-markup&sortby=date/index.html @@ -0,0 +1,506 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML> +<HEAD><style> A { color:black }</style> +<!-- hennerik CVSweb $Revision: 1.93 $ --> +<TITLE>code/nel/src/net/login_server.cpp - view - 1.16</TITLE></HEAD> +<BODY BGCOLOR="#eeeeee"> +<table width="100%" border=0 cellspacing=0 cellpadding=1 bgcolor="#aaaaaa"><tr valign=bottom><td><a href="login_server.cpp?sortby=date"><IMG SRC="http://www.nevrax.org/inc/img/picto-up.gif" ALT="[BACK]" BORDER="0" WIDTH="14" HEIGHT="13"></a> <b>Return to <A HREF="login_server.cpp?sortby=date">login_server.cpp</A> + CVS log</b> <IMG SRC="http://www.nevrax.org/inc/img/picto-news.gif" ALT="[TXT]" BORDER="0" WIDTH="13" HEIGHT="15"></td><td align=right><IMG SRC="http://www.nevrax.org/inc/img/picto-dir.gif" ALT="[DIR]" BORDER="0" WIDTH="15" HEIGHT="13"> <b>Up to <a href="/cvs/cvsweb.cgi/?sortby=date">Nevrax</a> / <a href="/cvs/cvsweb.cgi/code/?sortby=date">code</a> / <a href="/cvs/cvsweb.cgi/code/nel/?sortby=date">nel</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/?sortby=date">src</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/net/?sortby=date">net</a></b></td></tr></table><HR noshade><table width="100%"><tr><td bgcolor="#ffffff">File: <a href="/cvs/cvsweb.cgi/?sortby=date">Nevrax</a> / <a href="/cvs/cvsweb.cgi/code/?sortby=date">code</a> / <a href="/cvs/cvsweb.cgi/code/nel/?sortby=date">nel</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/?sortby=date">src</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/net/?sortby=date">net</a> / <a href="/cvs/cvsweb.cgi/code/nel/src/net/login_server.cpp?sortby=date">login_server.cpp</a> (<A HREF="/cvs/cvsweb.cgi/~checkout~/code/nel/src/net/login_server.cpp?rev=1.16&sortby=date" target="cvs_checkout" onClick="window.open('/cvs/cvsweb.cgi/~checkout~/code/nel/src/net/login_server.cpp?rev=1.16','cvs_checkout','resizeable,scrollbars');"><b>download</b></A>)<BR> +Revision <B>1.16</B>, <i>Tue Mar 26 09:44:47 2002 UTC</i> (4 months ago) by <i>lecroart</i> +<BR>Branch: <b>MAIN</b> +<BR>CVS Tags: <b>georges_v2, HEAD</b><BR>Changes since <b>1.15: +57 -20 + lines</b><PRE> +CHANGED: unified the command format +</PRE> +</td></tr></table><HR noshade><PRE>/** \file login_server.cpp + * CLoginServer is the interface used by the front end to accepts authenticate users. + * + * $Id: login_server.cpp,v 1.16 2002/03/26 09:44:47 lecroart Exp $ + * + */ + +/* Copyright, 2000 Nevrax Ltd. + * + * This file is part of NEVRAX NEL. + * NEVRAX NEL 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, or (at your option) + * any later version. + + * NEVRAX NEL 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 NEVRAX NEL; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "stdnet.h" + +#include "nel/net/callback_client.h" +#include "nel/net/service.h" + +#include "nel/net/login_cookie.h" +#include "nel/net/login_server.h" + +#include "nel/net/udp_sock.h" + +using namespace std; +using namespace NLMISC; + +namespace NLNET { + +struct CPendingUser +{ + CPendingUser (const CLoginCookie &cookie) : Cookie (cookie) { } + CLoginCookie Cookie; +}; + +static list<CPendingUser> PendingUsers; + +static CCallbackServer *Server; +static string ListenAddr; + +static TDisconnectClientCallback DisconnectClientCallback = NULL; + +/// contains the correspondance between userid and the sockid +map<uint32, TSockId> UserIdSockAssociations; + +TNewClientCallback NewClientCallback = NULL; + +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// +///////////// CONNECTION TO THE WELCOME SERVICE ////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// + +void cbWSChooseShard (CMessage &msgin, TSockId from, CCallbackNetBase &netbase) +{ + // the WS call me that a new client want to come in my shard + string reason; + CLoginCookie cookie; + + // + // S08: receive "CS" message from WS and send "SCS" message to WS + // + + msgin.serial (cookie); + + list<CPendingUser>::iterator it; + for (it = PendingUsers.begin(); it != PendingUsers.end (); it++) + { + if ((*it).Cookie == cookie) + { + // the cookie already exists, erase it and return false + nlwarning ("cookie %s is already in the pending user list", cookie.toString().c_str()); + PendingUsers.erase (it); + reason = "cookie already exists"; + break; + } + } + if (it == PendingUsers.end ()) + { + // add it to the awaiting client + PendingUsers.push_back (CPendingUser (cookie)); + reason = ""; + } + + CMessage msgout (CNetManager::getSIDA ("WS"), "SCS"); + msgout.serial (reason); + msgout.serial (cookie); + msgout.serial (ListenAddr); + CNetManager::send ("WS", msgout); +} + +void cbWSChooseShard5 (CMessage &msgin, const std::string &serviceName, uint16 sid) +{ + // the WS call me that a new client want to come in my shard + string reason; + CLoginCookie cookie; + + // + // S08: receive "CS" message from WS and send "SCS" message to WS + // + + msgin.serial (cookie); + + list<CPendingUser>::iterator it; + for (it = PendingUsers.begin(); it != PendingUsers.end (); it++) + { + if ((*it).Cookie == cookie) + { + // the cookie already exists, erase it and return false + nlwarning ("cookie %s is already in the pending user list", cookie.toString().c_str()); + PendingUsers.erase (it); + reason = "cookie already exists"; + break; + } + } + if (it == PendingUsers.end ()) + { + // add it to the awaiting client + nlinfo ("New cookie %s inserted in the pending user list (awaiting new client)", cookie.toString().c_str()); + PendingUsers.push_back (CPendingUser (cookie)); + reason = ""; + } + + CMessage msgout ("SCS"); + msgout.serial (reason); + msgout.serial (cookie); + msgout.serial (ListenAddr); + CUnifiedNetwork::getInstance()->send ("WS", msgout); +} + +void cbWSDisconnectClient5 (CMessage &msgin, const std::string &serviceName, uint16 sid) +{ + // the WS tells me that i have to disconnect a client + + uint32 userid; + msgin.serial (userid); + + map<uint32, TSockId>::iterator it = UserIdSockAssociations.find (userid); + if (it == UserIdSockAssociations.end ()) + { + nlwarning ("Can't disconnect the user %d, he is not found", userid); + } + else + { + nlinfo ("Disconnect the user %d", userid); + Server->disconnect ((*it).second); + } + + if (DisconnectClientCallback != NULL) + { + DisconnectClientCallback (userid); + } +} + +void cbWSDisconnectClient (CMessage &msgin, TSockId from, CCallbackNetBase &netbase) +{ + cbWSDisconnectClient5 (msgin, "", 0); +} + +static TCallbackItem WSCallbackArray[] = +{ + { "CS", cbWSChooseShard }, + { "DC", cbWSDisconnectClient }, +}; + +static TUnifiedCallbackItem WSCallbackArray5[] = +{ + { "CS", cbWSChooseShard5 }, + { "DC", cbWSDisconnectClient5 }, +}; + +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// +///////////// CONNECTION TO THE CLIENT /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// + +void cbShardValidation (CMessage &msgin, TSockId from, CCallbackNetBase &netbase) +{ + // + // S13: receive "SV" message from client + // + + // the client send me a cookie + CLoginCookie cookie; + string reason; + msgin.serial (cookie); + + // verify that the user was pending + reason = CLoginServer::isValidCookie (cookie); + + CMessage msgout2 (netbase.getSIDA (), "SV"); + msgout2.serial (reason); + netbase.send (msgout2, from); + + if (!reason.empty()) + { + nlwarning ("User (%s) is not in the pending user list (cookie:%s)", netbase.hostAddress(from).asString().c_str(), cookie.toString().c_str()); + // deconnect him + netbase.disconnect (from); + } + else + { + // add the user association + uint32 userid = cookie.getUserId(); + UserIdSockAssociations.insert (make_pair(userid, from)); + + // identification OK, let's call the user callback + if (NewClientCallback != NULL) + NewClientCallback (from, cookie); + + // ok, now, he can call all callback + Server->authorizeOnly (NULL, from); + } +} + +void ClientConnection (TSockId from, void *arg) +{ + nldebug("new client connection: %s", from->asString ().c_str ()); + + // the client could only call "SV" message + Server->authorizeOnly ("SV", from); +} + + +static const TCallbackItem ClientCallbackArray[] = +{ + { "SV", cbShardValidation }, +}; + +void cfcbListenAddress (CConfigFile::CVar &var) +{ + // set the new ListenAddr + ListenAddr = var.asString(); + + // is the var is empty or not found, take it from the listenAddress() + if (ListenAddr.empty()) + { + ListenAddr = Server->listenAddress ().asIPString(); + } + + nlinfo("Listen Address trapped '%s'", ListenAddr.c_str()); +} + + +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// +///////////// CONNECTION TO THE WELCOME SERVICE ////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////// + +void CLoginServer::init (CCallbackServer &server, TNewClientCallback ncl) +{ + // connect to the welcome service + connectToWS (); + + // add callback to the server + server.addCallbackArray (ClientCallbackArray, sizeof (ClientCallbackArray) / sizeof (ClientCallbackArray[0])); + server.setConnectionCallback (ClientConnection, NULL); + + try + { + cfcbListenAddress (IService::getInstance()->ConfigFile.getVar("ListenAddress")); + IService::getInstance()->ConfigFile.setCallback("ListenAddress", cfcbListenAddress); + } + catch(Exception &) + { + } + + // if the listen addr is not in the config file, try to find it dynamically + if (ListenAddr.empty()) + { + ListenAddr = server.listenAddress ().asIPString(); + } + + nlinfo("Listen Address trapped '%s'", ListenAddr.c_str()); + + NewClientCallback = ncl; + Server = &server; +} + +void CLoginServer::init (CUdpSock &server, TDisconnectClientCallback dc) +{ + // connect to the welcome service + connectToWS (); + + try + { + cfcbListenAddress (IService::getInstance()->ConfigFile.getVar("ListenAddress")); + IService::getInstance()->ConfigFile.setCallback("ListenAddress", cfcbListenAddress); + } + catch(Exception &) + { + } + + // if the listen addr is not in the config file, try to find it dynamically + if (ListenAddr.empty()) + { + ListenAddr = server.localAddr ().asIPString(); + } + + nlinfo("Listen Addresss trapped '%s'", ListenAddr.c_str()); + + DisconnectClientCallback = dc; +} + +string CLoginServer::isValidCookie (const CLoginCookie &lc) +{ + // verify that the user was pending + list<CPendingUser>::iterator it; + for (it = PendingUsers.begin(); it != PendingUsers.end (); it++) + { + if ((*it).Cookie == lc) + { + // ok, it was validate, remove it + PendingUsers.erase (it); + + // warn the WS that the client effectively connected + uint8 con = 1; + CMessage msgout ("CC"); + uint32 userid = lc.getUserId(); + msgout.serial (userid); + msgout.serial (con); + + if (CUnifiedNetwork::isUsed ()) + { + CUnifiedNetwork::getInstance()->send("WS", msgout); + } + else + { + CNetManager::send("WS", msgout); + } + + return ""; + } + } + return "I didn't receive the cookie from WS"; +} + +void CLoginServer::connectToWS () +{ + if (CUnifiedNetwork::isUsed ()) + { + CUnifiedNetwork::getInstance()->addCallbackArray(WSCallbackArray5, sizeof(WSCallbackArray5)/sizeof(WSCallbackArray5[0])); + } + else + { + CNetManager::addClient ("WS"); + CNetManager::addCallbackArray ("WS", WSCallbackArray, sizeof (WSCallbackArray) / sizeof (WSCallbackArray[0])); + + CMessage msg("UN_SIDENT"); + nlassert (IService::getInstance()); + uint16 ssid = IService::getInstance()->getServiceId(); + string name = IService::getInstance()->getServiceShortName(); + msg.serial(name); + msg.serial(ssid); // serializes a 16 bits service id + CNetManager::send("WS", msg); + } +} + +void CLoginServer::clientDisconnected (uint32 userId) +{ + uint8 con = 0; + CMessage msgout ("CC"); + msgout.serial (userId); + msgout.serial (con); + + if (CUnifiedNetwork::isUsed ()) + { + CUnifiedNetwork::getInstance()->send("WS", msgout); + } + else + { + CNetManager::send("WS", msgout); + } + + // remove the user association + UserIdSockAssociations.erase (userId); +} + +// +// Commands +// + +NLMISC_COMMAND (lsUsers, "displays the list of all connected users", "") +{ + if(args.size() != 0) return false; + + log.displayNL ("Display the %d connected users :", UserIdSockAssociations.size()); + for (map<uint32, TSockId>::iterator it = UserIdSockAssociations.begin(); it != UserIdSockAssociations.end (); it++) + { + log.displayNL ("> %u %s", (*it).first, (*it).second->asString().c_str()); + } + log.displayNL ("End ot the list"); + + return true; +} + +NLMISC_COMMAND (lsPending, "displays the list of all pending users", "") +{ + if(args.size() != 0) return false; + + log.displayNL ("Display the %d pending users :", PendingUsers.size()); + for (list<CPendingUser>::iterator it = PendingUsers.begin(); it != PendingUsers.end (); it++) + { + log.displayNL ("> %s", (*it).Cookie.toString().c_str()); + } + log.displayNL ("End ot the list"); + + return true; +} + + +NLMISC_DYNVARIABLE(string, LSListenAddress, "the listen address sended to the client to connect on this front_end") +{ + if (get) + { + *pointer = ListenAddr; + } + else + { + if ((*pointer).find (":") == string::npos) + { + log.displayNL ("You must set the address + port (ie: \"itsalive.nevrax.org:38000\")"); + return; + } + else if ((*pointer).empty()) + { + ListenAddr = Server->listenAddress ().asIPString(); + } + else + { + ListenAddr = *pointer; + } + log.displayNL ("Listen Address trapped '%s'", ListenAddr.c_str()); + } +} + + +} // NLNET + + +///////////////////////////////////////////// +///////////////////////////////////////////// +///////////////////////////////////////////// +/* +#include "v2/service.h" + +using namespace std; +using namespace NLNET; + +void ClientConnection (TSockId from, const CLoginCookie &cookie) +{ + nlinfo("player (%d) comes in", cookie.getUserId()); + from->setAppId (cookie.getUserId()); +} + +void ClientDisconnection (TSockId from, void *arg) +{ + nlinfo("player (%d) leaves", from->appId()); + CLoginServer::clientDisconnected (from->appId()); + +} + +class CFrontEndService : public NLNET::IService +{ +public: + + /// Init the service, load the universal time. + void init () + { + CLoginServer::init (dynamic_cast<CCallbackServer&>(*CNetManager::getNetBase ("FES")), ClientConnection); + CNetManager::getNetBase ("FES")->setDisconnectionCallback (ClientDisconnection, NULL); + } +}; + + +/// Naming Service +NLNET_SERVICE_MAIN (CFrontEndService, "FES", "front_end_service", 0); +*/ +</PRE>
\ No newline at end of file |