From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../x-cvsweb-markup&sortby=date/index.html | 569 +++++++++++++++++++++ 1 file changed, 569 insertions(+) create mode 100644 cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date/index.html (limited to 'cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date') diff --git a/cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date/index.html b/cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date/index.html new file mode 100644 index 00000000..8f7e28a2 --- /dev/null +++ b/cvs/cvsweb.cgi/code/nel/src/net/naming_client.cpp?rev=1.48&content-type=text/x-cvsweb-markup&sortby=date/index.html @@ -0,0 +1,569 @@ + + + +code/nel/src/net/naming_client.cpp - view - 1.48 + +
[BACK] Return to naming_client.cpp + CVS log [TXT][DIR] Up to Nevrax / code / nel / src / net

File: Nevrax / code / nel / src / net / naming_client.cpp (download)
+Revision 1.48, Thu Jul 18 15:00:43 2002 UTC (10 days, 18 hours ago) by lecroart +
Branch: MAIN +
CVS Tags: HEAD
Changes since 1.47: +15 -1 + lines
+ADDED: quit if the NS ask it
+
+

/** \file naming_client.cpp
+ * CNamingClient
+ *
+ * $Id: naming_client.cpp,v 1.48 2002/07/18 15:00:43 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.
+ */
+
+//
+// Includes
+//
+
+#include "stdnet.h"
+
+#include "nel/net/naming_client.h"
+#include "nel/net/callback_client.h"
+#include "nel/net/service.h"
+
+
+//
+// Namespaces
+//
+
+using namespace std;
+using namespace NLMISC;
+
+
+namespace NLNET {
+
+//
+// Variables
+//
+
+CCallbackClient *CNamingClient::_Connection = NULL;
+CNamingClient::TRegServices CNamingClient::_RegisteredServices;
+
+static TBroadcastCallback _RegistrationBroadcastCallback = NULL;
+static TBroadcastCallback _UnregistrationBroadcastCallback = NULL;
+
+uint    CNamingClient::_ThreadId = 0xFFFFFFFF;
+
+TServiceId CNamingClient::_MySId = 0;
+
+
+std::list<CNamingClient::CServiceEntry> CNamingClient::RegisteredServices;
+NLMISC::CMutex CNamingClient::RegisteredServicesMutex("CNamingClient::RegisteredServicesMutex");
+
+void CNamingClient::setRegistrationBroadcastCallback (TBroadcastCallback cb)
+{
+        _RegistrationBroadcastCallback = cb;        
+}
+
+void CNamingClient::setUnregistrationBroadcastCallback (TBroadcastCallback cb)
+{
+        _UnregistrationBroadcastCallback = cb;        
+}
+
+//
+
+//
+
+static bool Registered;
+static TServiceId RegisteredSuccess;
+static TServiceId RegisteredSID;
+
+static void cbRegister (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+{
+        msgin.serial (RegisteredSuccess);
+        if (RegisteredSuccess) msgin.serial (RegisteredSID);
+        Registered = true;
+}
+
+//
+
+static bool QueryPort;
+static uint16 QueryPortPort;
+
+static void cbQueryPort (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+{
+        msgin.serial (QueryPortPort);
+        QueryPort = true;
+}
+
+//
+
+static bool FirstRegisteredBroadcast;
+
+void cbRegisterBroadcast (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+{
+        TServiceId size;
+        string name;
+        TServiceId sid;
+        CInetAddress addr;
+
+        msgin.serial (size);
+
+        for (TServiceId i = 0; i < size; i++)
+        {
+                msgin.serial (name);
+                msgin.serial (sid);
+                msgin.serial (addr);
+
+                // add it in the list
+
+                std::vector<CInetAddress> addrs;
+                CNamingClient::find (sid, addrs);
+
+                if (addrs.size() == 0)
+                {
+                        CNamingClient::RegisteredServicesMutex.enter ();
+                        CNamingClient::RegisteredServices.push_back (CNamingClient::CServiceEntry (name, sid, addr));
+                        CNamingClient::RegisteredServicesMutex.leave ();
+
+                        nlinfo ("NC: Registration Broadcast of the service %s-%hu '%s'", name.c_str(), (uint16)sid, addr.asString().c_str());
+
+                        if (_RegistrationBroadcastCallback != NULL)
+                                _RegistrationBroadcastCallback (name, sid, addr);
+                }
+                else if (addrs.size() == 1)
+                {
+                        CNamingClient::RegisteredServicesMutex.enter ();
+                        for (std::list<CNamingClient::CServiceEntry>::iterator it = CNamingClient::RegisteredServices.begin(); it != CNamingClient::RegisteredServices.end (); it++)
+                        {
+                                if (sid == (*it).SId)
+                                {
+                                        (*it).Name = name;
+                                        (*it).Addr = addr;
+                                        break;
+                                }
+                        }
+                        CNamingClient::RegisteredServicesMutex.leave ();
+                        nlinfo ("NC: Registration Broadcast (update) of the service %s-%hu '%s'", name.c_str(), (uint16)sid, addr.asString().c_str());
+                }
+                else
+                {
+                        nlstop;
+                }
+        }
+
+        FirstRegisteredBroadcast = true;
+
+        //CNamingClient::displayRegisteredServices ();
+}
+        
+//
+
+void cbUnregisterBroadcast (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+{
+        string name;
+        TServiceId sid;
+        CInetAddress addr;
+
+        msgin.serial (name);
+        msgin.serial (sid);
+        msgin.serial (addr);
+
+        // remove it in the list, if the service is not found, ignore it
+
+        CNamingClient::RegisteredServicesMutex.enter ();
+        for (std::list<CNamingClient::CServiceEntry>::iterator it = CNamingClient::RegisteredServices.begin(); it != CNamingClient::RegisteredServices.end (); it++)
+        {
+                if ((*it).SId == sid)
+                {
+                        // check the structure
+                        nlassertex ((*it).Name == name, ("%s %s",(*it).Name.c_str(), name.c_str()));
+                        nlassertex ((*it).Addr == addr, ("%d %d",(*it).Addr.asString().c_str(), addr.asString().c_str()));
+
+                        CNamingClient::RegisteredServices.erase (it);
+                        break;
+                }
+        }
+        CNamingClient::RegisteredServicesMutex.leave ();
+
+        nlinfo ("NC: Unregistration Broadcast of the service %s-%hu", name.c_str(), (uint16)sid);
+
+        // send the ACK to the NS
+
+        CMessage msgout (CNamingClient::_Connection->getSIDA(), "ACK_UNI");
+        msgout.serial (sid);
+        CNamingClient::_Connection->send (msgout);
+
+        // oh my god, it s my sid! but i m alive, why this f*cking naming service want to kill me? ok, i leave it alone!
+        if(CNamingClient::_MySId == sid)
+        {
+                nlwarning ("Naming Service asked me to leave, I leave!");
+                IService::getInstance()->exit();
+                return;
+        }
+
+        if (_UnregistrationBroadcastCallback != NULL)
+                _UnregistrationBroadcastCallback (name, sid, addr);
+
+        //CNamingClient::displayRegisteredServices ();
+}
+
+//
+
+static TCallbackItem NamingClientCallbackArray[] =
+{
+        { "RG", cbRegister },
+        { "QP", cbQueryPort },
+
+        { "RGB", cbRegisterBroadcast },
+        { "UNB", cbUnregisterBroadcast },
+};
+
+void CNamingClient::connect( const CInetAddress &addr, CCallbackNetBase::TRecordingState rec )
+{
+        nlassert (_Connection == NULL || _Connection != NULL && !_Connection->connected ());
+        _ThreadId = getThreadId ();
+
+        if (_Connection == NULL)
+        {
+                _Connection = new CCallbackClient( rec, "naming_client.nmr" );
+                _Connection->addCallbackArray (NamingClientCallbackArray, sizeof (NamingClientCallbackArray) / sizeof (NamingClientCallbackArray[0]));
+        }
+
+        _Connection->connect (addr);
+
+        // now we are connected, clear the old registered service table
+/*
+        CNamingClient::RegisteredServicesMutex.enter ();
+        CNamingClient::RegisteredServices.clear ();
+        CNamingClient::RegisteredServicesMutex.leave ();
+*/
+        // wait the message that contains all already connected services
+
+        FirstRegisteredBroadcast = false;
+        while (!FirstRegisteredBroadcast && _Connection->connected ())
+        {
+                _Connection->update (-1);
+                nlSleep (1);
+        }
+}
+
+
+void CNamingClient::disconnect ()
+{
+        checkThreadId ();
+        
+        if (_Connection != NULL)
+        {
+                if (_Connection->connected ())
+                {
+                        _Connection->disconnect ();
+                }
+                delete _Connection;
+                _Connection = NULL;
+        }
+
+        // we don't call unregisterAllServices because when the naming service will see the disconnection,
+        // it'll automatically unregister all services registered by this client.
+}
+
+string CNamingClient::info ()
+{
+        string res;
+
+        if (connected ())
+        {
+                res = "connected to ";
+                res += _Connection->remoteAddress().asString();
+        }
+        else
+        {
+                res = "Not connected";
+        }
+
+        return res;
+}
+
+TServiceId CNamingClient::registerService (const std::string &name, const CInetAddress &addr)
+{
+        checkThreadId ();
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        CMessage msgout (_Connection->getSIDA(), "RG");
+        msgout.serial (const_cast<std::string&>(name));
+        msgout.serial (const_cast<CInetAddress&>(addr));
+        TServiceId sid = 0;
+        msgout.serial (sid);
+        _Connection->send (msgout);
+
+        // wait the answer of the naming service "RG"
+        Registered = false;
+        while (!Registered)
+        {
+                _Connection->update (-1);
+                nlSleep (1);
+        }
+
+        if (RegisteredSuccess)
+        {
+                _MySId = RegisteredSID;
+                _RegisteredServices.insert (make_pair (RegisteredSID, name));
+                nldebug ("NC: Registered service %s-%hu at %s", name.c_str(), (uint16)RegisteredSID, addr.asString().c_str());
+        }
+        else
+        {
+                nlerror ("NC: Naming service refused to register service %s at %s", name.c_str(), addr.asString().c_str());
+        }
+
+        return RegisteredSID;
+}
+
+bool CNamingClient::registerServiceWithSId (const std::string &name, const CInetAddress &addr, TServiceId sid)
+{
+        checkThreadId ();
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        CMessage msgout (_Connection->getSIDA(), "RG");
+        msgout.serial (const_cast<std::string&>(name));
+        msgout.serial (const_cast<CInetAddress&>(addr));
+        msgout.serial (sid);
+        _Connection->send (msgout);
+
+        // wait the answer of the naming service "RGI"
+        Registered = false;
+        while (!Registered)
+        {
+                _Connection->update (-1);
+                nlSleep (1);
+        }
+
+        if (RegisteredSuccess)
+        {
+                _MySId = sid;
+                _RegisteredServices.insert (make_pair (RegisteredSID, name));
+                nldebug ("NC: Registered service with sid %s-%hu at %s", name.c_str(), (uint16)RegisteredSID, addr.asString().c_str());
+        }
+        else
+        {
+                nlerror ("NC: Naming service refused to register service with sid %s at %s", name.c_str(), addr.asString().c_str());
+        }
+
+        return RegisteredSuccess == 1;
+}
+
+void CNamingClient::resendRegisteration (const std::string &name, const CInetAddress &addr, TServiceId sid)
+{
+        checkThreadId ();
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        CMessage msgout (_Connection->getSIDA(), "RRG");
+        msgout.serial (const_cast<std::string&>(name));
+        msgout.serial (const_cast<CInetAddress&>(addr));
+        msgout.serial (sid);
+        _Connection->send (msgout);
+}
+
+void CNamingClient::unregisterService (TServiceId sid)
+{
+        checkThreadId ();
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        CMessage msgout (_Connection->getSIDA(), "UNI");
+        msgout.serial (sid);
+        _Connection->send (msgout);
+
+        nldebug ("NC: Unregistering service %s-%hu", _RegisteredServices[sid].c_str(), sid);
+        _RegisteredServices.erase (sid);
+}
+
+void CNamingClient::unregisterAllServices ()
+{
+        checkThreadId ();
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        while (!_RegisteredServices.empty())
+        {
+                TRegServices::iterator irs = _RegisteredServices.begin();
+                TServiceId sid = (*irs).first;
+                unregisterService (sid);
+        }
+}
+
+uint16 CNamingClient::queryServicePort ()
+{
+        checkThreadId ();
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        CMessage msgout (_Connection->getSIDA(), "QP");
+        _Connection->send (msgout);
+
+        // wait the answer of the naming service "QP"
+        QueryPort = false;
+        while (!QueryPort)
+        {
+                _Connection->update (-1);
+                nlSleep (1);
+        }
+
+        nlinfo ("NC: Received the answer of the query port (%hu)", QueryPortPort);
+
+        return QueryPortPort;
+}
+
+bool CNamingClient::lookup (const std::string &name, CInetAddress &addr)
+{
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        vector<CInetAddress> addrs;
+        find (name, addrs);
+
+        if (addrs.size()==0)
+                return false;
+
+        nlassert (addrs.size()==1);
+        addr = addrs[0];
+
+        return true;
+}
+
+bool CNamingClient::lookup (TServiceId sid, CInetAddress &addr)
+{
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        vector<CInetAddress> addrs;
+        find (sid, addrs);
+
+        if (addrs.size()==0)
+                return false;
+
+        nlassert (addrs.size()==1);
+        addr = addrs[0];
+        
+        return true;
+}
+
+/// \todo ace: now the lookupAlternate doesn't say to the naming service that this addr is bad so the NS can't remove it from his list. find a solution
+bool CNamingClient::lookupAlternate (const std::string &name, CInetAddress &addr)
+{
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        // remove it from his local list
+        
+        RegisteredServicesMutex.enter ();
+        for (std::list<CServiceEntry>::iterator it = RegisteredServices.begin(); it != RegisteredServices.end (); it++)
+        {
+                if ((*it).Addr == addr)
+                {
+                        RegisteredServices.erase (it);
+                        break;
+                }
+        }
+        RegisteredServicesMutex.leave ();
+
+        vector<CInetAddress> addrs;
+        find (name, addrs);
+
+        if (addrs.size()==0)
+                return false;
+
+        nlassert (addrs.size()==1);
+        addr = addrs[0];
+
+        return true;
+}
+
+void CNamingClient::lookupAll (const std::string &name, std::vector<CInetAddress> &addrs)
+{
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        find (name, addrs);
+}
+
+bool CNamingClient::lookupAndConnect (const std::string &name, CCallbackClient &sock)
+{
+        nlassert (_Connection != NULL && _Connection->connected ());
+
+        // look up for service
+        CInetAddress servaddr;
+        
+        // if service not found, return false
+        if (!CNamingClient::lookup (name, servaddr))
+                return false;
+
+        do
+        {
+                try
+                {
+                        // try to connect to the server
+                        sock.connect (servaddr);
+
+                        // connection succeeded
+                        return true;
+                }
+                catch (ESocketConnectionFailed &e)
+                {
+                        nldebug( "Connection to %s failed: %s, tring another service if available", servaddr.asString().c_str(), e.what() );
+
+                        // try another server and if service is not found, return false
+                        if (!CNamingClient::lookupAlternate (name, servaddr))
+                                return false;
+                }
+        }
+        while (true);
+}
+
+
+
+void CNamingClient::update ()
+{
+        checkThreadId ();
+        // get message for naming service (new registration for example)
+        if (_Connection != NULL && _Connection->connected ())
+                _Connection->update ();
+}
+
+void CNamingClient::checkThreadId ()
+{
+        if (getThreadId () != _ThreadId)
+        {
+                nlerror ("You try to access to the CNamingClient with 2 differents thread (%d and %d)", _ThreadId, getThreadId());
+        }
+}
+
+
+//
+// Commands
+//
+
+NLMISC_COMMAND(services, "displays registered services", "")
+{
+        if(args.size() != 0) return false;
+
+        log.displayNL ("Display the %d registered services :", CNamingClient::getRegisteredServices().size());
+        for (std::list<CNamingClient::CServiceEntry>::const_iterator it = CNamingClient::getRegisteredServices().begin(); it != CNamingClient::getRegisteredServices().end(); it++)
+        {
+                log.displayNL (" > %s-%hu '%s'", (*it).Name.c_str(), (uint16)(*it).SId, (*it).Addr.asString().c_str());
+        }
+        log.displayNL ("End ot the list");
+
+        return true;
+}
+
+} // NLNET
+
\ No newline at end of file -- cgit v1.2.1