Logo
~Sockets~
~Examples~
~Contact~


MinderHandler.cpp

Go to the documentation of this file.
00001 /*
00002  **     File ......... MinderHandler.cpp
00003  **     Published ....  2004-04-17
00004  **     Author ....... grymse@alhem.net
00005 **/
00006 /*
00007 Copyright (C) 2004  Anders Hedstrom
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 */
00023 #ifdef _WIN32
00024 #pragma warning(disable:4786)
00025 #endif
00026 #include "sockets-config.h"
00027 #ifdef HAVE_OPENSSL
00028 
00029 #ifdef _WIN32
00030 #define random rand
00031 #define srandom srand
00032 #endif
00033 #include "Uid.h"
00034 #include "MinderSocket.h"
00035 #include "Utility.h"
00036 #include "MinderHandler.h"
00037 
00038 #ifdef SOCKETS_NAMESPACE
00039 namespace SOCKETS_NAMESPACE {
00040 #endif
00041 
00042 
00043 #ifdef _DEBUG
00044 #define DEB(x) x
00045 #else
00046 #define DEB(x)
00047 #endif
00048 
00049 
00050 
00051 
00052 MinderHandler::MinderHandler()
00053 :SocketHandler()
00054 ,m_id("")
00055 ,m_external_ip("")
00056 ,m_message_id(0)
00057 ,m_host_id(0)
00058 ,m_bDebug(false)
00059 ,m_tMinder(0)
00060 {
00061         GenerateID();
00062 }
00063 
00064 
00065 MinderHandler::~MinderHandler()
00066 {
00067         for (seen_v::iterator it = m_seen.begin(); it != m_seen.end(); it++)
00068         {
00069                 SEEN *p = *it;
00070                 delete p;
00071         }
00072         {
00073                 for (store_v::iterator it = m_store.begin(); it != m_store.end(); it++)
00074                 {
00075                         STORE *p = *it;
00076                         delete p;
00077                 }
00078         }
00079         {
00080                 for (hosts_v::iterator it = m_hosts.begin(); it != m_hosts.end(); it++)
00081                 {
00082                         HOSTS *p = *it;
00083                         delete p;
00084                 }
00085         }
00086 }
00087 
00088 
00089 void MinderHandler::GenerateID()
00090 {
00091         Uid t;
00092         m_id = t.GetUid();
00093 }
00094 
00095 
00096 const std::string& MinderHandler::GetID()
00097 {
00098         return m_id;
00099 }
00100 
00101 
00102 void MinderHandler::SendMessage(const std::string& msg_in,short ttl)
00103 {
00104         std::string msg;
00105         long message_id = m_message_id++;
00106 
00107         msg = "Message_" + Utility::l2string(m_host_id);
00108         msg += ":" + Utility::l2string(message_id);
00109         msg += ":" + Utility::l2string(ttl);
00110         msg += ":" + msg_in;
00111 
00112 DEB(    fprintf(stderr, "Message:\n%s\n",msg.c_str());)
00113 
00114         if (msg.size() > 255) // try is good even here, because of possible bandwidth differences between nodes
00115         {
00116                 Store(m_host_id, message_id, msg);
00117                 msg = "Try_" + Utility::l2string(m_host_id) + ":" + Utility::l2string(message_id);
00118                 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00119                 {
00120                         MinionSocket *p = dynamic_cast<MinionSocket *>((*it).second);
00121                         if (p && p -> Ready() )
00122                         {
00123                                 Uid ruid(p -> GetRemoteId());
00124                                 memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00125                                 p -> Send( p -> encrypt(GetKey_m2minion(),msg) + "\n" );
00126                         }
00127                 }
00128         }
00129         else
00130         {
00131                 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00132                 {
00133                         MinionSocket *p = dynamic_cast<MinionSocket *>((*it).second);
00134                         if (p && p -> Ready() )
00135                         {
00136                                 Uid ruid(p -> GetRemoteId());
00137                                 memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00138 //                              p -> Send( p -> Utility::base64(msg) + "\n" );
00139                                 p -> Send( p -> encrypt(GetKey_m2minion(),msg) + "\n" );
00140                         }
00141                 }
00142         }
00143 }
00144 
00145 
00146 void MinderHandler::SendMessage(const std::string& hid,const std::string& mid,short ttl,const std::string& msg_in,std::list<std::string>& clist,ulong_v& hosts)
00147 {
00148         std::string msg;
00149         long host_id = atol(hid.c_str());
00150         long message_id = atol(mid.c_str());
00151 
00152         msg = "Message_" + hid;
00153         msg += ":" + mid;
00154         msg += ":" + Utility::l2string(ttl); // + ":" + ttlstr;
00155         msg += ":" + msg_in;
00156 
00157         if (msg.size() > 255)
00158         {
00159                 Store(host_id, message_id, msg);
00160                 msg = "Try_" + Utility::l2string(host_id) + ":" + Utility::l2string(message_id);
00161                 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00162                 {
00163                         MinionSocket *p = dynamic_cast<MinionSocket *>((*it).second);
00164                         if (p && p -> Ready() )
00165                         {
00166                                 bool ok = true;
00167                                 for (std::list<std::string>::iterator it = clist.begin(); it != clist.end() && ok; it++)
00168                                 {
00169                                         std::string id = *it;
00170                                         if (!strcmp(p -> GetRemoteId().c_str(),id.c_str()))
00171                                         {
00172                                                 ok = false;
00173                                         }
00174                                 }
00175                                 for (ulong_v::iterator i2 = hosts.begin(); i2 != hosts.end() && ok; i2++)
00176                                 {
00177                                         if (*i2 == static_cast<unsigned long>(p -> GetRemoteHostId()))
00178                                         {
00179                                                 ok = false;
00180                                         }
00181                                 }
00182                                 if (ok)
00183                                 {
00184                                         Uid ruid(p -> GetRemoteId());
00185                                         memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00186                                         p -> Send( p -> encrypt(GetKey_m2minion(), msg) + "\n" );
00187                                 }
00188                         }
00189                 }
00190         }
00191         else
00192         {
00193                 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00194                 {
00195                         MinionSocket *p = dynamic_cast<MinionSocket *>((*it).second);
00196                         if (p && p -> Ready() )
00197                         {
00198                                 bool ok = true;
00199                                 for (std::list<std::string>::iterator it = clist.begin(); it != clist.end(); it++)
00200                                 {
00201                                         std::string id = *it;
00202                                         if (!strcmp(p -> GetRemoteId().c_str(),id.c_str()))
00203                                         {
00204                                                 ok = false;
00205                                                 break;
00206                                         }
00207                                 }
00208                                 if (ok)
00209                                 {
00210                                         Uid ruid(p -> GetRemoteId());
00211                                         memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00212 //                                      p -> Send( p -> Utility::base64(msg) + "\n" );
00213                                         p -> Send( p -> encrypt(GetKey_m2minion(), msg) + "\n" );
00214                                 }
00215                         }
00216                 }
00217         }
00218 }
00219 
00220 
00221 void MinderHandler::KeepAlive()
00222 {
00223         std::string msg;
00224         std::string tmp;
00225         msg = "KeepAlive";
00226         m_b.encode(msg, tmp, false);
00227         SendMessage(tmp);
00228 }
00229 
00230 
00231 void MinderHandler::SendConnectList()
00232 {
00233         std::string msg;
00234         std::string tmp = "_";
00235         msg = "ConnectList";
00236         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00237         {
00238                 MinionSocket *p = dynamic_cast<MinionSocket*>((*it).second);
00239                 if (p && p -> Ready() )
00240                 {
00241                         msg += tmp + p -> GetRemoteId();
00242                         tmp = ":";
00243                 }
00244         }
00245         m_b.encode(msg, tmp, false);
00246 //fprintf(stderr, "ConnectList:\n%s\n",msg.c_str());
00247         SendMessage(tmp, 0);
00248 }
00249 
00250 
00251 bool MinderHandler::MinderSockets()
00252 {
00253         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00254         {
00255                 MinderSocket *p = dynamic_cast<MinderSocket *>((*it).second);
00256                 if (p)
00257                         return true;
00258         }
00259         return false;
00260 }
00261 
00262 
00263 bool MinderHandler::FindMinion(const std::string& id)
00264 {
00265         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00266         {
00267                 MinionSocket *p = dynamic_cast<MinionSocket*>((*it).second);
00268                 if (p && p -> GetRemoteId() == id) 
00269                 {
00270                         return true;
00271                 }
00272         }
00273         for (socket_m::iterator i2 = m_add.begin(); i2 != m_add.end(); i2++)
00274         {
00275                 MinionSocket *p = dynamic_cast<MinionSocket*>((*i2).second);
00276                 if (p && p -> GetRemoteId() == id) 
00277                 {
00278                         return true;
00279                 }
00280         }
00281         return false;
00282 }
00283 
00284 
00285 int MinderHandler::Count()
00286 {
00287         int q = 0;
00288         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00289         {
00290                 MinionSocket *p = dynamic_cast<MinionSocket*>((*it).second);
00291                 if (p)
00292                 {
00293                         q++;
00294                 }
00295         }
00296         for (socket_m::iterator i2 = m_add.begin(); i2 != m_add.end(); i2++)
00297         {
00298                 MinionSocket *p = dynamic_cast<MinionSocket*>((*i2).second);
00299                 if (p)
00300                 {
00301                         q++;
00302                 }
00303         }
00304         return q;
00305 }
00306 
00307 
00308 bool MinderHandler::Seen(unsigned long host_id,unsigned long message_id,bool temp)
00309 {
00310         if (host_id == m_host_id)
00311                 return true;
00312         for (seen_v::iterator it = m_seen.begin(); it != m_seen.end(); it++)
00313         {
00314                 SEEN *p = *it;
00315                 if (p -> Eq(host_id,message_id))
00316                 {
00317                         if (p -> m_temp && !temp)
00318                         {
00319                                 p -> m_temp = temp;
00320                                 return false;
00321                         }
00322                         return true;
00323                 }
00324         }
00325         // %! while time - erase
00326         time_t t = time(NULL);
00327         while (m_seen.size())
00328         {
00329                 SEEN *p = m_seen[0];
00330                 if (t - p -> m_t > 120)
00331                 {
00332                         delete p;
00333                         m_seen.erase(m_seen.begin());
00334                 }
00335                 else
00336                 {
00337                         break;
00338                 }
00339         }
00340         SEEN *p = new SEEN(host_id,message_id);
00341         p -> m_temp = temp;
00342         m_seen.push_back(p);
00343         return false;
00344 }
00345 
00346 
00347 void MinderHandler::Store(long hid,long mid,const std::string& msg)
00348 {
00349         // %! while time - erase
00350         time_t t = time(NULL);
00351         while (m_store.size())
00352         {
00353                 STORE *p = m_store[0];
00354                 if (t - p -> m_t > 10)
00355                 {
00356                         delete p;
00357                         m_store.erase(m_store.begin());
00358                 }
00359                 else
00360                 {
00361                         break;
00362                 }
00363         }
00364         STORE *p = new STORE(hid,mid,msg);
00365         m_store.push_back(p);
00366 }
00367 
00368 
00369 bool MinderHandler::StoreGet(long hid,long mid,std::string& msg)
00370 {
00371         for (store_v::iterator it = m_store.begin(); it != m_store.end(); it++)
00372         {
00373                 STORE *p = *it;
00374                 if (p -> m_hid == hid && p -> m_mid == mid)
00375                 {
00376                         msg = p -> m_message;
00377                         return true;
00378                 }
00379         }
00380         return false;
00381 }
00382 
00383 
00384 void MinderHandler::AddHost(ipaddr_t a,port_t p,const std::string& k,long r)
00385 {
00386 DEB(    fprintf(stderr, "AddHost: size %d\n",m_hosts.size());)
00387         if (m_hosts.size() >= 20)
00388                 return;
00389         for (hosts_v::iterator it = m_hosts.begin(); it != m_hosts.end(); it++)
00390         {
00391                 HOSTS *p2 = *it;
00392                 if (p2 -> ip == a && p2 -> port == p)
00393                 {
00394                         p2 -> key == k;
00395                         return;
00396                 }
00397         }
00398         HOSTS *p2 = new HOSTS(a,p,k,r);
00399         m_hosts.push_back(p2);
00400 }
00401 
00402 
00403 bool MinderHandler::GetHost(ipaddr_t& a,port_t& p,std::string& k,long& r)
00404 {
00405         if (m_hosts.size())
00406         {
00407                 hosts_v::iterator it = m_hosts.begin();
00408                 HOSTS *p2 = *it;
00409                 a = p2 -> ip;
00410                 p = p2 -> port;
00411                 k = p2 -> key;
00412                 r = p2 -> remote_host_id;
00413                 delete p2;
00414                 m_hosts.erase(it);
00415                 return true;
00416         }
00417         return false;
00418 }
00419 
00420 
00421 void MinderHandler::SendTop(const std::string& hid)
00422 {
00423         std::string msg;
00424         std::string tmp;
00425         msg = "Top_" + hid;
00426         msg += ":" + Utility::l2string(GetHostId());
00427         m_b.encode(GetVersion(), tmp, false);
00428         msg += ":" + tmp;
00429 #ifdef _WIN32
00430         msg += ":Win32";
00431 #else
00432         msg += ":Linux";
00433 #endif
00434         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00435         {
00436                 MinionSocket *p = dynamic_cast<MinionSocket*>((*it).second);
00437 //              TelnetSocket *p2 = dynamic_cast<TelnetSocket *>((*it).second);
00438                 if (p && p -> Ready() )
00439                 {
00440                         msg += ":" + Utility::l2string(p -> GetRemoteHostId() );
00441                 }
00442         }
00443 //fprintf(stderr, " Top reply: %s\n",msg.c_str());
00444         m_b.encode(msg, tmp, false);
00445         SendMessage(tmp);
00446 }
00447 
00448 
00449 void MinderHandler::Tops(FILE *fil)
00450 {
00451         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00452         {
00453                 MinionSocket *p = dynamic_cast<MinionSocket*>((*it).second);
00454                 if (p && p -> Ready() )
00455                 {
00456                         fprintf(fil,"\t\"%ld\" -> \"%ld\"\n",
00457                                 GetHostId(),
00458                                 p -> GetRemoteHostId());
00459                 }
00460         }
00461 }
00462 
00463 
00464 
00465 
00466 #ifdef SOCKETS_NAMESPACE
00467 }
00468 #endif
00469 
00470 #endif // HAVE_OPENSSL
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4