Logo
~Sockets~
~Examples~
~Contact~


MinionSocket.cpp

Go to the documentation of this file.
00001 /*
00002  **     File ......... MinionSocket.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 #include <vector>
00030 
00031 #include "MinderHandler.h"
00032 #include "Uid.h"
00033 #include "Utility.h"
00034 
00035 #ifdef SOCKETS_NAMESPACE
00036 namespace SOCKETS_NAMESPACE {
00037 #endif
00038 
00039 
00040 #ifdef _DEBUG
00041 #define DEB(x) x
00042 #else
00043 #define DEB(x) 
00044 #endif
00045 
00046 
00047 
00048 // statics
00049 //MinionSocket::connect_v MinionSocket::m_connect;
00050 
00051 
00052 MinionSocket::MinionSocket(ISocketHandler& h) : CTcpSocket(h)
00053 ,m_remote_id("")
00054 ,m_ip(0)
00055 ,m_port(0)
00056 ,m_bIDVerified(false)
00057 ,m_bStopMessage(false)
00058 ,m_messagecount(0)
00059 ,m_seencount(0)
00060 ,m_remote_host_id(0)
00061 {
00062         SetLineProtocol();
00063 }
00064 
00065 
00066 MinionSocket::MinionSocket(ISocketHandler& h,const std::string& id,ipaddr_t l,port_t s)
00067 :CTcpSocket(h)
00068 ,m_remote_id(id)
00069 ,m_ip(l)
00070 ,m_port(s)
00071 ,m_bIDVerified(true)
00072 ,m_bStopMessage(false)
00073 ,m_messagecount(0)
00074 ,m_seencount(0)
00075 ,m_remote_host_id(0)
00076 {
00077         SetLineProtocol();
00078 
00079         std::string str;
00080         Utility::l2ip(l,str);
00081 DEB(    fprintf(stderr, " new connect: %s:%d\n",str.c_str(),s);)
00082 }
00083 
00084 
00085 MinionSocket::~MinionSocket()
00086 {
00087 }
00088 
00089 
00090 /*
00091 ICrypt *MinionSocket::AllocateCrypt()
00092 {
00093         return new HCrypt;
00094 }
00095 */
00096 
00097 
00098 void MinionSocket::OnDelete()
00099 {
00100         // %! avregistrera i connection-lista
00101 //      Remove(m_remote_id,m_ip,m_port);
00102         SendConnectList();
00103 }
00104 
00105 
00106 void MinionSocket::OnConnect()
00107 {
00108 //      fprintf(stderr, "Connected to: %s\n",GetRemoteAddress().c_str());
00109         SendHello("Hello");
00110 }
00111 
00112 
00113 void MinionSocket::SendHello(const std::string& cmd)
00114 {
00115         std::string str;
00116         Utility::l2ip(my_ip,str);
00117         char msg[200];
00118         sprintf(msg,"%s_%s:%s:%d:%s:%ld\n",cmd.c_str(),m_remote_id.c_str(),str.c_str(),my_port,
00119                 static_cast<MinderHandler&>(Handler()).GetID().c_str(),
00120                 static_cast<MinderHandler&>(Handler()).GetHostId() );
00121         {
00122                 Uid ruid(m_remote_id);
00123 //fprintf(stderr, "encrypt with remote id '%s'\n",m_remote_id.c_str());
00124                 memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00125 //              Send( Utility::base64(msg) + "\n" );
00126                 Send( encrypt(GetKey_m2minion(), msg) + "\n" );
00127         }
00128 }
00129 
00130 
00131 void MinionSocket::SendConnectList()
00132 {
00133         static_cast<MinderHandler&>(Handler()).SendConnectList();
00134 }
00135 
00136 
00137 void MinionSocket::OnLine(const std::string& line)
00138 {
00139         std::string line_decrypt;
00140         std::string cmd;
00141         Uid myid(static_cast<MinderHandler&>(Handler()).GetID());
00142 
00143         memcpy(GetKey_m2minion() + 8,myid.GetBuf(),16);
00144         if (!decrypt(GetKey_m2minion(),line,line_decrypt))
00145         {
00146                 SetCloseAndDelete();
00147                 return;
00148         }
00149 //      Parse pa(decrypt(GetKey_m2minion(),line),"_:");
00150         Parse pa(line_decrypt, "_:");
00151 
00152         m_messagecount++;
00153         pa.getword(cmd);
00154         if (!m_bIDVerified)
00155         {
00156                 if (cmd == "Hello")
00157                 {
00158                         std::string id; // supposed to be my id
00159                         std::string ipstr; // remote ip
00160                         std::string remote_id;
00161                         pa.getword(id);
00162                         pa.getword(ipstr);
00163                         port_t port = (port_t)pa.getvalue(); // remote listen port
00164                         pa.getword(remote_id);
00165                         long remote_host_id = pa.getvalue();
00166                         ipaddr_t ip;
00167                         int max = GetMaxConnections(); //atoi(config["max_connections"].c_str());
00168                         max = (max == 0) ? 4 : max;
00169 
00170                         Utility::u2ip(ipstr, ip);
00171 
00172                         if (id == static_cast<MinderHandler&>(Handler()).GetID() &&
00173                                 !static_cast<MinderHandler&>(Handler()).FindMinion(remote_id) &&
00174                                 static_cast<MinderHandler&>(Handler()).Count() < max * 2 + 1)
00175                         {
00176 DEB(                            fprintf(stderr, "My ID verified!\n");)
00177                                 m_remote_id = remote_id;
00178                                 m_ip = ip; // remote ip
00179                                 m_port = port; // remote listen port
00180                                 m_bIDVerified = true;
00181                                 m_remote_host_id = remote_host_id;
00182                                 SendHello("Hi");
00183                         }
00184                         else
00185                         {
00186                                 {
00187                                         Uid ruid(remote_id);
00188                                         memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00189                                         Send( encrypt(GetKey_m2minion(), "Bye") + "\n" );
00190                                 }
00191                                 SetCloseAndDelete(true);
00192                         }
00193                 }
00194                 else
00195                 {
00196 DEB(                    fprintf(stderr,"Ignoring message\n");)
00197                 }
00198         }
00199         else
00200         {
00201                 if (!OnVerifiedLine(cmd, pa))
00202                 {
00203                         // %! notify?
00204                         SetCloseAndDelete();
00205                 }
00206         }
00207 }
00208 
00209 bool MinionSocket::OnVerifiedLine(const std::string& cmd,Parse& pa)
00210 {
00211         std::string str;
00212 
00213         if (static_cast<MinderHandler&>(Handler()).Debug() )
00214         {
00215                 str = "&l&fCommand: " + cmd + "&n\n";
00216                 Notify( str );
00217         }
00218 
00219 DEB(            fprintf(stderr, "Incoming command: '%s'\n",cmd.c_str());)
00220         if (cmd == "Tip")
00221         {
00222                 // Tip _ host id
00223                 std::string hid = pa.getword();
00224 //fprintf(stderr, "Tip from: %s\n",hid.c_str());
00225                 static_cast<MinderHandler&>(Handler()).SendTop( hid );
00226         }
00227         else
00228         if (cmd == "Top")
00229         {
00230                 unsigned long hid = pa.getvalue();
00231 //fprintf(stderr, "Top to: %ld\n",hid);
00232                 if (hid == static_cast<MinderHandler&>(Handler()).GetHostId())
00233                 {
00234                         std::string src = pa.getword();
00235                         std::string vstr = Utility::base64d(pa.getword());
00236                         std::string os = pa.getword();
00237 //fprintf(stderr, " (Top from: %s)\n",src.c_str());
00238                         std::string dst;
00239                         if (isdigit(os[0]))
00240                         {
00241                                 dst = os;
00242                                 os = "";
00243                         }
00244                         else
00245                         {
00246                                 dst = pa.getword();
00247                         }
00248                         FILE *fil = fopen("top_map.dot","at");
00249                         if (!fil)
00250                                 fil = fopen("top_map.dot","wt");
00251                         if (fil)
00252                         {
00253                                 fprintf(fil,"\t\"%s\" [label=\"%s\\n%s\\n%s\"]\n",
00254                                         src.c_str(),
00255                                         src.c_str(),
00256                                         vstr.c_str(),
00257                                         os.c_str());
00258                                 while (dst.size())
00259                                 {
00260                                         fprintf(fil,"\t\"%s\" -> \"%s\"\n",
00261                                                 src.c_str(),
00262                                                 dst.c_str());
00263                                         //
00264                                         pa.getword(dst);
00265                                 }
00266                                 fclose(fil);
00267                         }
00268                 }
00269                 else
00270                 {
00271 //fprintf(stderr, "Top ignored: %ld != %ld\n",hid,static_cast<MinderHandler&>(Handler()).GetHostId());
00272                 }
00273         }
00274         else
00275         if (cmd == "Accept")
00276         {
00277                 long hid = pa.getvalue();
00278                 long mid = pa.getvalue();
00279                 std::string msg;
00280                 if (static_cast<MinderHandler&>(Handler()).StoreGet(hid,mid,msg))
00281                 {
00282                         Uid ruid(m_remote_id);
00283                         memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00284                         Send( encrypt(GetKey_m2minion(), msg) + "\n" );
00285                 }
00286         }
00287         else
00288         if (cmd == "Try")
00289         {
00290                 long hid = pa.getvalue();
00291                 long mid = pa.getvalue();
00292                 if (!static_cast<MinderHandler&>(Handler()).Seen(hid,mid,true))
00293                 {
00294                         std::string msg;
00295                         msg = "Accept_" + Utility::l2string(hid);
00296                         msg += ":" + Utility::l2string(mid);
00297                         Uid ruid(m_remote_id);
00298                         memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00299                         Send( encrypt(GetKey_m2minion(), msg) + "\n" );
00300                 }
00301                 else
00302                 {
00303                         m_seencount++;
00304                 }
00305         }
00306         else
00307         if (cmd == "KeepAlive")
00308         {
00309                 // good for you
00310                 m_bStopMessage = true;
00311         }
00312         else
00313         if (cmd == "ConnectList")
00314         {
00315                 std::string id;
00316                 while (m_clist.size())
00317                 {
00318                         std::list<std::string>::iterator it = m_clist.begin();
00319                         m_clist.erase(it);
00320                 }
00321                 pa.getword(id);
00322                 while (id.size())
00323                 {
00324                         m_clist.push_back(id);
00325                         //
00326                         pa.getword(id);
00327                 }
00328         }
00329         else
00330         if (cmd == "Message")
00331         {
00332                 std::string hid = pa.getword();
00333                 std::string mid = pa.getword();
00334                 int ttl = pa.getvalue();
00335                 std::string msg_in = pa.getword();
00336                 unsigned long host_id = atol(hid.c_str());
00337                 unsigned long message_id = atol(mid.c_str());
00338                 ulong_v hosts;
00339 
00340                 if (!static_cast<MinderHandler&>(Handler()).Seen(host_id,message_id))
00341                 {
00342 DEB(                            fprintf(stderr, "Message\n hostid: %ld\n messageid: %ld\n ttl: %d\n message:\n%s\n--end of message\n", host_id, message_id, ttl, msg_in.c_str());)
00343 DEB(                            fprintf(stderr, "Message:\n%s\n--End of Message\n",Utility::base64d(msg_in).c_str());)
00344                         if (static_cast<MinderHandler&>(Handler()).Debug() )
00345                         {
00346                                 str = "&l&fMessage: Not Seen&n\n";
00347                                 Notify( str );
00348                         }
00349                         std::string msg = Utility::base64d(msg_in);
00350                         m_bStopMessage = false;
00351                         {
00352                                 Uid myid(static_cast<MinderHandler&>(Handler()).GetID());
00353                                 memcpy(GetKey_m2minion() + 8,myid.GetBuf(),16);
00354                                 OnLine( encrypt(GetKey_m2minion(), msg ) );
00355                         }
00356                         if (!m_bStopMessage && ttl--)
00357                         {
00358                                 while (host_id > 0)
00359                                 {
00360                                         hosts.push_back(host_id);
00361                                         //
00362                                         host_id = pa.getvalue();
00363                                 }
00364 //                              Parse pa(msg,"_");
00365 //                              std::string cmd = pa.getword();
00366 //                              if (cmd == "Pong")
00367                                 // always add host id to message before forwarding
00368                                 {
00369                                         msg += ":" + Utility::l2string(static_cast<MinderHandler&>(Handler()).GetHostId());
00370                                         msg_in = Utility::base64(msg);
00371                                 }
00372                                 static_cast<MinderHandler&>(Handler()).SendMessage(hid, mid, ttl, msg_in, m_clist, hosts);
00373                         }
00374                 }
00375                 else
00376                 {
00377                         m_seencount++;
00378                         if (static_cast<MinderHandler&>(Handler()).Debug() )
00379                         {
00380                                 str = "&l&fMessage: Seen&n\n";
00381                                 Notify( str );
00382                         }
00383                 }
00384         }
00385         else
00386         if (cmd == "Hi")
00387         {
00388                 SendConnectList();
00389         }
00390         else
00391         if (cmd == "Bye")
00392         {
00393                 SetCloseAndDelete(true);
00394         }
00395         else
00396         {
00397                 return false;
00398         }
00399         return true;
00400 }
00401 
00402 
00403 void MinionSocket::OnAccept()
00404 {
00405 DEB(    fprintf(stderr, "Incoming connection from: %s\n",GetRemoteAddress().c_str());)
00406 }
00407 
00408 
00409 #ifdef SOCKETS_NAMESPACE
00410 }
00411 #endif
00412 
00413 #endif // HAVE_OPENSSL
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4