Google
Web alhem.net

MyHandler.cpp

Go to the documentation of this file.
00001 
00005 /*
00006 Copyright (C) 2004  grymse@alhem.net
00007 
00008 This program is free software; you can redistribute it and/or
00009 modify it under the terms of the GNU General Public License
00010 as published by the Free Software Foundation; either version 2
00011 of the License, or (at your option) any later version.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with this program; if not, write to the Free Software
00020 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00021 */
00022 //#include <stdio.h>
00023 #include <Utility.h>
00024 #include <Uid.h>
00025 #include "MyHandler.h"
00026 
00027 
00028 
00029 
00030 MyHandler::MyHandler(const std::string& f)
00031 :MinderHandler()
00032 ,m_config(f)
00033 {
00034 }
00035 
00036 
00037 MyHandler::~MyHandler()
00038 {
00039         for (peer_m::iterator it = m_peers.begin(); it != m_peers.end(); it++)
00040         {
00041                 std::string hash = (*it).first;
00042                 peer_v& ref = (*it).second;
00043                 for (peer_v::iterator it = ref.begin(); it != ref.end(); it++)
00044                 {
00045                         PEER *p = *it;
00046                         delete p;
00047                 }
00048         }
00049 }
00050 
00051 
00052 int MyHandler::GetInt(const std::string& path)
00053 {
00054         xmlNodePtr p = m_config.Find(m_config.GetRootElement(),path);
00055         if (p)
00056         {
00057                 m_config.SetCurrent(p);
00058                 std::string str = m_config.GetProperty("value");
00059                 return atoi(str.c_str());
00060         }
00061         else
00062         {
00063                 fprintf(stderr,"config path not found: %s\n",path.c_str());
00064         }
00065         return 0;
00066 }
00067 
00068 
00069 std::string MyHandler::GetString(const std::string& path)
00070 {
00071         xmlNodePtr p = m_config.Find(m_config.GetRootElement(),path);
00072         if (p)
00073         {
00074                 m_config.SetCurrent(p);
00075                 std::string str = m_config.GetProperty("value");
00076                 return str;
00077         }
00078         fprintf(stderr,"config path not found: %s\n",path.c_str());
00079         return "";
00080 }
00081 
00082 
00083 bool MyHandler::GetBoolean(const std::string& path)
00084 {
00085         xmlNodePtr p = m_config.Find(m_config.GetRootElement(),path);
00086         std::string str;
00087         if (p)
00088         {
00089                 m_config.SetCurrent(p);
00090                 str = m_config.GetProperty("value");
00091                 if (str.size() && (str[0] == '1' ||
00092                         str[0] == 'y' || str[0] == 'Y' ||
00093                         str[0] == 't' || str[0] == 'T'))
00094                 {
00095                         return true;
00096                 }
00097                 return false;
00098         }
00099         fprintf(stderr,"config path not found: %s\n",path.c_str());
00100         return false;
00101 }
00102 
00103 
00104 std::string MyHandler::escape(const std::string& in)
00105 {
00106         std::string out;
00107         for (size_t i = 0; i < in.size(); i++)
00108         {
00109                 if (in[i] == '%')
00110                 {
00111                         out += in.substr(i,3);
00112                         i += 2;
00113                 }
00114                 else
00115                 {
00116                         char slask[100];
00117                         sprintf(slask,"%02x",in[i]);
00118                         out += '%';
00119                         out += slask;
00120                 }
00121         }
00122         for (size_t i = 0; i < out.size(); i++)
00123         {
00124                 if (out[i] >= 'a' && out[i] <= 'z')
00125                 {
00126                         out[i] = (char)out[i] - 32;
00127                 }
00128         }
00129         return out;
00130 }
00131 
00132 
00133 MyHandler::PEER *MyHandler::reg_peer(const std::string& hash,
00134         const std::string& peer_id,
00135         const std::string& ip,
00136         port_t port)
00137 {
00138         std::string escaped_hash = escape(hash);
00139         std::string escaped_id = escape(peer_id);
00140         for (peer_v::iterator it = m_peers[escaped_hash].begin(); it != m_peers[escaped_hash].end(); it++)
00141         {
00142                 PEER *p = *it;
00143                 if (p -> escaped_peer_id == escaped_id)
00144                 {
00145                         p -> last_contact = time(NULL);
00146                         return p;
00147                 }
00148         }
00149         PEER *p = new PEER(escaped_id,ip,port);
00150         m_peers[escaped_hash].push_back(p);
00151         printf("Added new peer, id = %s\n",escaped_id.c_str());
00152         return p;
00153 }
00154 
00155 
00156 //#define MIN(a,b) a < b ? a : b
00157 
00158 void MyHandler::CreatePeers(TcpSocket *sock,const std::string& hash,size_t numwant)
00159 {
00160         char slask[100];
00161         size_t response_size = MIN((size_t)GetInt("server/max_give"),numwant);
00162         std::vector<PEER *> vec;
00163         size_t q = 0;
00164         for (peer_v::iterator it = m_peers[hash].begin(); it != m_peers[hash].end(); it++)
00165         {
00166                 PEER *p = *it;
00167                 vec.push_back(p);
00168                 q++;
00169         }
00170         while (response_size && q)
00171         {
00172                 size_t nr = random() % q;
00173                 PEER *p = vec[nr];
00174 
00175                 // dictionary
00176                 sock -> Send("d");
00177                 sock -> Send("2:ip");                   // ip
00178                 sprintf(slask,"%d:%s",p -> ip.size(),p -> ip.c_str());
00179                 sock -> Send(slask);
00180                 sock -> Send("7:peer id" "20:");        // peer id
00181                 sock -> SendBuf( (char *)p -> peer_id,20);
00182                 sock -> Send("4:port");                 // port
00183                 sprintf(slask,"i%de",p -> port);
00184                 sock -> Send(slask);
00185                 // end dictionary
00186                 sock -> Send("e");
00187 
00188                 vec[nr] = vec[q - 1];
00189                 q--;
00190                 response_size--;
00191         }
00192 }
00193 
00194 
00195 void MyHandler::SendList()
00196 {
00197         // send changes to peer list
00198         for (peer_m::iterator it = m_peers.begin(); it != m_peers.end(); it++)
00199         {
00200                 std::string hash = (*it).first;
00201                 peer_v& ref = (*it).second;
00202                 for (peer_v::iterator it = ref.begin(); it != ref.end(); it++)
00203                 {
00204                         PEER *p = *it;
00205                         if (p -> updated)
00206                         {
00207                                 std::string msg = p -> stopped ? "delete" : "update";
00208                                 msg += ":" + hash;
00209                                 msg += ":" + p -> escaped_peer_id;
00210                                 msg += ":" + p -> ip;
00211                                 msg += ":" + Utility::l2string(p -> port);
00212                                 msg += ":" + Utility::bigint2string(p -> uploaded);
00213                                 msg += ":" + Utility::bigint2string(p -> downloaded);
00214                                 msg += ":" + Utility::bigint2string(p -> left);
00215                                 SendMessage(Utility::base64(msg));
00216                                 p -> updated = false;
00217                         }
00218                 }
00219         }
00220         // clear peer list from stopped peers
00221         bool repeat;
00222         do
00223         {
00224                 repeat = false;
00225                 for (peer_m::iterator it = m_peers.begin(); it != m_peers.end(); it++)
00226                 {
00227                         std::string hash = (*it).first;
00228                         peer_v& ref = (*it).second;
00229                         for (peer_v::iterator it = ref.begin(); it != ref.end(); it++)
00230                         {
00231                                 PEER *p = *it;
00232                                 if (p -> stopped && !p -> updated)
00233                                 {
00234                                         delete p;
00235                                         ref.erase(it);
00236                                         repeat = true;
00237                                         break;
00238                                 }
00239                         }
00240                 }
00241         } while (repeat);
00242 }
00243 
00244 
00245 void MyHandler::CheckDropped()
00246 {
00247         time_t tnow = time(NULL);
00248         for (peer_m::iterator it = m_peers.begin(); it != m_peers.end(); it++)
00249         {
00250                 std::string hash = (*it).first;
00251                 peer_v& ref = (*it).second;
00252                 for (peer_v::iterator it = ref.begin(); it != ref.end(); it++)
00253                 {
00254                         PEER *p = *it;
00255                         if (tnow - p -> last_contact > GetInt("server/timeout_downloaders_interval"))
00256                         {
00257                                 p -> stop();
00258                         }
00259                 }
00260         }
00261 }
00262 
00263 
00264 void MyHandler::SendInit(MyMinionSocket *ps)
00265 {
00266         // send changes to peer list
00267         for (peer_m::iterator it = m_peers.begin(); it != m_peers.end(); it++)
00268         {
00269                 std::string hash = (*it).first;
00270                 peer_v& ref = (*it).second;
00271                 for (peer_v::iterator it = ref.begin(); it != ref.end(); it++)
00272                 {
00273                         PEER *p = *it;
00274                         if (!p -> stopped)
00275                         {
00276                                 Uid ruid(ps -> GetRemoteId());
00277 
00278                                 std::string msg = p -> stopped ? "delete" : "update";
00279                                 msg += ":" + hash;
00280                                 msg += ":" + p -> escaped_peer_id;
00281                                 msg += ":" + p -> ip;
00282                                 msg += ":" + Utility::l2string(p -> port);
00283                                 msg += ":" + Utility::bigint2string(p -> uploaded);
00284                                 msg += ":" + Utility::bigint2string(p -> downloaded);
00285                                 msg += ":" + Utility::bigint2string(p -> left);
00286 //                              SendMessage(Utility::base64(msg));
00287                                 memcpy(GetKey_m2minion() + 8,ruid.GetBuf(),16);
00288                                 ps -> Send( ps -> encrypt(GetKey_m2minion(),msg) + "\n" );
00289                         }
00290                 }
00291         }
00292 }
00293 
00294 
00295 size_t MyHandler::MapSize()
00296 {
00297         size_t q = 0;
00298         for (peer_m::iterator it = m_peers.begin(); it != m_peers.end(); it++)
00299         {
00300                 q++;
00301         }
00302         return q;
00303 }
00304 
00305 

Generated on Thu Sep 27 12:58:27 2007 for distributed bittorrent tracker by  doxygen 1.5.2