00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00049
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
00092
00093
00094
00095
00096
00097
00098 void MinionSocket::OnDelete()
00099 {
00100
00101
00102 SendConnectList();
00103 }
00104
00105
00106 void MinionSocket::OnConnect()
00107 {
00108
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
00124 memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00125
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
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;
00159 std::string ipstr;
00160 std::string remote_id;
00161 pa.getword(id);
00162 pa.getword(ipstr);
00163 port_t port = (port_t)pa.getvalue();
00164 pa.getword(remote_id);
00165 long remote_host_id = pa.getvalue();
00166 ipaddr_t ip;
00167 int max = GetMaxConnections();
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;
00179 m_port = 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
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
00223 std::string hid = pa.getword();
00224
00225 static_cast<MinderHandler&>(Handler()).SendTop( hid );
00226 }
00227 else
00228 if (cmd == "Top")
00229 {
00230 unsigned long hid = pa.getvalue();
00231
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
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
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
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
00365
00366
00367
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