Google
Web alhem.net

tracker.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 <ListenSocket.h>
00023 #include <signal.h>
00024 #include "MyHandler.h"
00025 #include "TrackerSock.h"
00026 #include "MyMinderSocket.h"
00027 #include "MyMinionSocket.h"
00028 
00029 #define DEB(x)
00030 
00031         bool quit = false;
00032 
00033 
00034 void top(MyHandler& h)
00035 {
00036         std::string msg = "Tip_" + Utility::l2string(static_cast<MinderHandler&>(h).GetHostId());
00037         static_cast<MinderHandler&>(h).SendMessage(Utility::base64(msg));
00038         unlink("top_map.dot");
00039         FILE *fil;
00040         if ((fil = fopen("top_map.dot","wt")) != NULL)
00041         {
00042                 fprintf(fil,"digraph \"G\" {\n");
00043                 fprintf(fil,"\tedge [arrowhead=open]\n");
00044 #ifdef _WIN32
00045                 std::string os = "Win32";
00046 #else
00047                 std::string os = "Linux";
00048 #endif
00049                 fprintf(fil,"\t\"%ld\" [label=\"%ld\\n%s\\n%s\" style=filled fillcolor=\"#e0e0e0\"]\n",
00050                         static_cast<MinderHandler&>(h).GetHostId(),
00051                         static_cast<MinderHandler&>(h).GetHostId(),
00052                         h.GetVersion().c_str(),
00053                         os.c_str());
00054                 static_cast<MinderHandler&>(h).Tops(fil);
00055                 fclose(fil);
00056         }
00057 }
00058 
00059 
00060 void sigint(int s) /* save+quit */
00061 {
00062         fprintf(stderr,"shutting down\n");
00063         quit = true;
00064 }
00065 
00066 
00067 void sigpipe(int s)
00068 {
00069 }
00070 
00071 
00072 void reg_minder(MyHandler& h,const std::string& cmd)
00073 {
00074         MyMinderSocket *m = new MyMinderSocket(h,h.GetString("server/announce_url") );
00075         m -> Init();
00076 
00077         m -> Function(cmd); // Hello / Goodbye
00078         m -> SetDeleteByHandler(true);
00079         m -> Open(h.GetString("minder/host"),h.GetInt("minder/port"));
00080         h.Add(m);
00081         m -> SetLocalIpPort(Utility::GetLocalAddress(),h.GetLocalPort());
00082         if (!m -> Connecting()) // connected
00083         {
00084                 m -> SendHello();
00085         }
00086 
00087 }
00088 
00089 
00090 void connect(MyHandler& h)
00091 {
00092         if (h.Count() < h.GetInt("minion/max") )
00093         {
00094                 ipaddr_t a;
00095                 port_t p;
00096                 std::string key;
00097                 long host_id;
00098                 if (h.GetHost(a,p,key,host_id))
00099                 {
00100                         MinionSocket *tmp = new MyMinionSocket(h,key,a,p);
00101                         tmp -> Init();
00102                         ipaddr_t my_ip;
00103                         port_t my_port;
00104                         h.GetMyIpPort(my_ip, my_port);
00105                         tmp -> SetMyIpPort(my_ip,my_port);
00106                         tmp -> SetRemoteHostId(host_id);
00107                         {
00108                                 std::string t;
00109                                 Utility::l2ip(a,t);
00110 DEB(                            printf("Connect to:  %s:%d\n",t.c_str(),p);)
00111                         }
00112                         if (tmp -> Open(a,p))
00113                         {
00114                                 tmp -> SetDeleteByHandler(true);
00115                                 h.Add(tmp);
00116                                 //
00117                                 tmp -> SendHello("Hello");
00118                         }
00119                         else
00120                         if (tmp -> Connecting())
00121                         {
00122                                 tmp -> SetDeleteByHandler(true);
00123                                 // check OnConnect
00124                                 h.Add(tmp);
00125                         }
00126                         else
00127                         {
00128                                 delete tmp;
00129                         }
00130                 }
00131                 else
00132                 {
00133 DEB(                    printf("h.GetHost() failed?\n");)
00134                 }
00135         }
00136 }
00137 
00138 
00140 /*
00141 --port <arg>
00142           Port to listen on. (defaults to 80)
00143           OK
00144 
00145 --dfile <arg>
00146           file to store recent downloader info in
00147 
00148 --bind <arg>
00149           ip to bind to locally (defaults to '')
00150           OK
00151 
00152 --socket_timeout <arg>
00153           timeout for closing connections (defaults to 15)
00154 
00155 --save_dfile_interval <arg>
00156           seconds between saving dfile (defaults to 300)
00157 
00158 --timeout_downloaders_interval <arg>
00159           seconds between expiring downloaders (defaults to 2700)
00160           OK
00161 
00162 --reannounce_interval <arg>
00163           seconds downloaders should wait between reannouncements (defaults to
00164           1800)
00165           OK
00166 
00167 --response_size <arg>
00168           number of peers to send in an info message (defaults to 50)
00169           OK
00170 
00171 --timeout_check_interval <arg>
00172           time to wait between checking if any connections have timed out
00173           (defaults to 5)
00174           OK
00175 
00176 --nat_check <arg>
00177           whether to check back and ban downloaders behind NAT (defaults to 1)
00178 
00179 --min_time_between_log_flushes <arg>
00180           minimum time it must have been since the last flush to do another one
00181           (defaults to 3.0)
00182 
00183 --allowed_dir <arg>
00184           only allow downloads for .torrents in this dir (defaults to '')
00185 
00186 --parse_allowed_interval <arg>
00187           minutes between reloading of allowed_dir (defaults to 15)
00188 
00189 --show_names <arg>
00190           whether to display names from allowed dir (defaults to 1)
00191 
00192 --favicon <arg>
00193           file containing x-icon data to return when browser requests
00194           favicon.ico (defaults to '')
00195 
00196 --only_local_override_ip <arg>
00197           ignore the ip GET parameter from machines which aren't on local
00198           network IPs (defaults to 1)
00199 
00200 --logfile <arg>
00201           file to write the tracker logs, use - for stdout (default) (defaults
00202           to '')
00203 
00204 --allow_get <arg>
00205           use with allowed_dir; adds a /file?hash={hash} url that allows users
00206           to download the torrent file (defaults to 0)
00207 
00208 --keep_dead <arg>
00209           keep dead torrents after they expire (so they still show up on your
00210           /scrape and web page) (defaults to 0)
00211 
00212 --max_give <arg>
00213           maximum number of peers to give with any one request (defaults to
00214           200)
00215 */
00216 
00217 
00218 int main(int argc,char *argv[])
00219 {
00220         MyHandler h( "config.xml" );
00221         ListenSocket<TrackerSock> l(h);
00222         ListenSocket<MyMinionSocket> l3(h);
00223 
00224         signal(SIGINT, (__sighandler_t)sigint);
00225         signal(SIGHUP, (__sighandler_t)sigint);
00226         signal(SIGTERM,(__sighandler_t)sigint);
00227         signal(SIGPIPE, (__sighandler_t)sigpipe);
00228 
00229         // http tracker
00230         if (h.GetString("server/type") == "normal")
00231         {
00232                 std::string bind = h.GetString("server/bind");
00233                 port_t port = h.GetInt("server/port");
00234                 int queue_size = h.GetInt("server/queue_size");
00235                 {
00236                         if (l.Bind(bind,port,queue_size))
00237                         {
00238                                 return -1;
00239                         }
00240                         h.Add(&l);
00241                 }
00242         }
00243         else
00244         if (h.GetString("server/type") == "ssl")
00245         {
00246                 printf("Tracker type not implemented: 'ssl'\n");
00247                 exit(-1);
00248         }
00249         else
00250         {
00251                 printf("Tracker type not supported: '%s'\n",h.GetString("server/type").c_str());
00252                 exit(-1);
00253         }
00254         // minion
00255         {
00256                 std::string bind = h.GetString("minion/bind");
00257                 port_t port = h.GetInt("minion/port");
00258                 while (l3.Bind(port))
00259                 {
00260                         port++;
00261                 }
00262                 h.Add(&l3);
00263                 h.SetLocalPort(port);
00264         }
00265         // main loop
00266         {
00267                 time_t t = time(NULL);  // send peer list (update)
00268                 time_t tc = time(NULL); // connect
00269                 time_t tm = time(NULL); // reg_minder
00270                 time_t tt = time(NULL); // top
00271                 time_t td = time(NULL); // dropped
00272                 reg_minder(h,"Hello");
00273                 h.Select(1,0);
00274                 while (h.GetCount() && !quit)
00275                 {
00276                         h.Select(1,0);
00277                         time_t t2 = time(NULL);
00278                         if (t2 - tc > h.GetInt("minion/connect_interval") && h.GetInt("minion/connect_interval") )
00279                         {
00280                                 tc = t2;
00281                                 connect(h);
00282                         }
00283                         if (t2 - t > h.GetInt("minion/update_interval"))
00284                         {
00285                                 t = t2;
00286                                 h.SendList();
00287                         }
00288                         if (t2 - tm > 15 * 60)
00289                         {
00290                                 tm = t2;
00291                                 reg_minder(h,"Hello");
00292                         }
00293                         if (t2 - tt > h.GetInt("minion/top_interval") && h.GetInt("minion/top_interval") ) // var femte minut
00294                         {
00295                                 tt = t2;
00296                                 top(h);
00297                         }
00298                         if (t2 - td > h.GetInt("server/timeout_check_interval") )
00299                         {
00300                                 td = t2;
00301                                 h.CheckDropped();
00302                         }
00303                 }
00304         }
00305         // shutdown
00306         {
00307                 reg_minder(h,"Goodbye");
00308                 h.Select(1,0);
00309                 while (h.MinderSockets())
00310                 {
00311                         h.Select(1,0);
00312                 }
00313         }
00314 }
00315 
00316 

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