~ubuntu-branches/debian/experimental/lftp/experimental

« back to all changes in this revision

Viewing changes to src/TorrentTracker.h

  • Committer: Package Import Robot
  • Author(s): Noël Köthe
  • Date: 2015-08-21 16:06:22 UTC
  • mfrom: (1.1.20) (24.1.38 sid)
  • Revision ID: package-import@ubuntu.com-20150821160622-lckdmbiqx16wefgy
Tags: 4.6.4-1
new upstream release 2015-08-21

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lftp - file transfer program
 
3
 *
 
4
 * Copyright (c) 1996-2014 by Alexander V. Lukyanov (lav@yars.free.net)
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 3 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#ifndef TORRENTTRACKER_H
 
21
#define TORRENTTRACKER_H
 
22
 
 
23
#include "url.h"
 
24
 
 
25
class TrackerBackend;
 
26
class TorrentTracker : public SMTask, protected ProtoLog
 
27
{
 
28
   friend class Torrent;
 
29
   friend class TrackerBackend;
 
30
 
 
31
   Torrent *parent;
 
32
 
 
33
   xarray_p<xstring> tracker_urls;
 
34
   int current_tracker;
 
35
   SMTaskRef<TrackerBackend> backend;
 
36
   Timer tracker_timer;
 
37
   Timer tracker_timeout_timer;
 
38
   xstring tracker_id;
 
39
   bool started;
 
40
   Ref<Error> error;
 
41
   int tracker_no;
 
42
 
 
43
   TorrentTracker(Torrent *p,const char *url);
 
44
   void AddURL(const char *url);
 
45
   int Do();
 
46
 
 
47
   void Start();
 
48
   void Shutdown();
 
49
 
 
50
   void SendTrackerRequest(const char *event);
 
51
 
 
52
   void SetError(const char *e);
 
53
   bool Failed() const { return error!=0 || tracker_urls.count()==0; }
 
54
   const char *ErrorText() const { return error->Text(); }
 
55
 
 
56
   void NextTracker();
 
57
   void CreateTrackerBackend();
 
58
   const char *GetLogContext() { return GetURL(); }
 
59
 
 
60
public:
 
61
   ~TorrentTracker() {}
 
62
   const char *NextRequestIn() const {
 
63
      return tracker_timer.TimeLeft().toString(
 
64
         TimeInterval::TO_STR_TRANSLATE|TimeInterval::TO_STR_TERSE);
 
65
   }
 
66
   const char *GetURL() const {
 
67
      return tracker_urls[current_tracker]->get();
 
68
   }
 
69
   const char *Status() const;
 
70
   bool IsActive() const;
 
71
   void TrackerRequestFinished() { tracker_timer.Reset(); }
 
72
   void SetInterval(unsigned i) {
 
73
      if(i<30)
 
74
         i=30;
 
75
      tracker_timer.Set(i);
 
76
      LogNote(4,"Tracker interval is %u",i);
 
77
   }
 
78
   void SetTrackerID(const xstring& id) {
 
79
      if(id)
 
80
         tracker_id.set(id);
 
81
   }
 
82
   bool AddPeerCompact(const char *a,int len) const;
 
83
   bool AddPeer(const xstring& addr,int port) const;
 
84
   bool ShuttingDown();
 
85
};
 
86
 
 
87
class TrackerBackend : public SMTask, protected ProtoLog
 
88
{
 
89
protected:
 
90
   TorrentTracker *master;
 
91
   void SetError(const char *e) { master->SetError(e); }
 
92
 
 
93
   const char *GetURL() const { return master->GetURL(); }
 
94
   const xstring& GetInfoHash() const;
 
95
   const xstring& GetMyPeerId() const;
 
96
   int GetPort() const;
 
97
   unsigned long long GetTotalSent() const;
 
98
   unsigned long long GetTotalRecv() const;
 
99
   unsigned long long GetTotalLeft() const;
 
100
   bool HasMetadata() const;
 
101
   bool Complete() const;
 
102
   int GetWantedPeersCount() const;
 
103
   const xstring& GetMyKey() const;
 
104
   unsigned GetMyKeyNum() const;
 
105
   const char *GetTrackerId() const;
 
106
   void SetTrackerID(const xstring& id) const { master->SetTrackerID(id); }
 
107
   void SetInterval(unsigned i) const { master->SetInterval(i); }
 
108
   bool AddPeerCompact(const char *a,int len) const { return master->AddPeerCompact(a,len); }
 
109
   bool AddPeer(const xstring& addr,int port) const { return master->AddPeer(addr,port); }
 
110
   void NextTracker() const { master->NextTracker(); }
 
111
   bool ShuttingDown() const;
 
112
   void Started() const;
 
113
   void TrackerRequestFinished() const;
 
114
   const char *GetLogContext() { return master->GetLogContext(); }
 
115
 
 
116
public:
 
117
   TrackerBackend(TorrentTracker *m) : master(m) {}
 
118
   virtual ~TrackerBackend() {}
 
119
   virtual bool IsActive() const = 0;
 
120
   virtual void SendTrackerRequest(const char *event) = 0;
 
121
   virtual const char *Status() const = 0;
 
122
};
 
123
class HttpTracker : public TrackerBackend
 
124
{
 
125
   FileAccessRef t_session;
 
126
   SMTaskRef<IOBuffer> tracker_reply;
 
127
   int HandleTrackerReply();
 
128
public:
 
129
   bool IsActive() const { return tracker_reply!=0; }
 
130
   void SendTrackerRequest(const char *event);
 
131
   HttpTracker(TorrentTracker *m,ParsedURL *u)
 
132
      : TrackerBackend(m), t_session(FileAccess::New(u)) {}
 
133
   ~HttpTracker() {}
 
134
   int Do();
 
135
   const char *Status() const { return t_session->CurrentStatus(); }
 
136
};
 
137
class UdpTracker : public TrackerBackend, protected Networker
 
138
{
 
139
   xstring_c hostname;
 
140
   xstring_c portname;
 
141
 
 
142
   SMTaskRef<Resolver> resolver;
 
143
 
 
144
   xarray<sockaddr_u> peer;
 
145
   int peer_curr;
 
146
   void  NextPeer();
 
147
 
 
148
   int sock;   // udp socket for packet exchange
 
149
 
 
150
   Timer timeout_timer;
 
151
   int try_number;   // timeout = 60 * 2^try_number
 
152
 
 
153
   bool has_connection_id;
 
154
   unsigned long long connection_id;
 
155
 
 
156
   enum action_t {
 
157
      a_none=-1,
 
158
      a_connect=0,
 
159
      a_announce=1,
 
160
      a_scrape=2,
 
161
      a_error=3,
 
162
      a_announce6=4,
 
163
   };
 
164
   enum event_t {
 
165
      ev_idle=-1,
 
166
      ev_none=0,
 
167
      ev_completed=1,
 
168
      ev_started=2,
 
169
      ev_stopped=3,
 
170
   };
 
171
   enum magic_t {
 
172
      connect_magic=0x41727101980ULL,
 
173
   };
 
174
   static const char *EventToString(event_t e);
 
175
 
 
176
   unsigned transaction_id;
 
177
   action_t current_action;
 
178
   event_t current_event;
 
179
 
 
180
   bool SendPacket(Buffer& req);
 
181
   bool SendConnectRequest();
 
182
   bool SendEventRequest();
 
183
   bool RecvReply();
 
184
 
 
185
   unsigned NewTransactionId() { return transaction_id=random(); }
 
186
 
 
187
public:
 
188
   UdpTracker(TorrentTracker *m,ParsedURL *u)
 
189
      : TrackerBackend(m),
 
190
        hostname(u->host.get()), portname(u->port.get()),
 
191
        peer_curr(0), sock(-1), timeout_timer(60), try_number(0),
 
192
        has_connection_id(false), connection_id(0),
 
193
        current_action(a_none), current_event(ev_idle) {}
 
194
   ~UdpTracker() {
 
195
      if(sock!=-1)
 
196
         close(sock);
 
197
   }
 
198
   int Do();
 
199
   bool IsActive() const { return current_event!=ev_idle; }
 
200
   void SendTrackerRequest(const char *event);
 
201
   const char *Status() const;
 
202
};
 
203
 
 
204
#endif // TORRENTTRACKER_H