source: trunk/src/halTorrent.hpp @ 380

Revision 380, 14.5 KB checked in by Eoin, 12 years ago (diff)

Added singaling, fixed UPnP bug.

Line 
1
2//         Copyright Eóin O'Callaghan 2006 - 2007.
3// Distributed under the Boost Software License, Version 1.0.
4//    (See accompanying file LICENSE_1_0.txt or copy at
5//          http://www.boost.org/LICENSE_1_0.txt)
6
7#pragma once
8
9#include <string>
10#include <vector>
11#include <set>
12
13#include <boost/foreach.hpp>
14#include <boost/format.hpp>
15#include <boost/array.hpp>
16#include <boost/lexical_cast.hpp>
17#include <boost/bind.hpp>
18
19#include <boost/thread/thread.hpp>
20#include <boost/thread/recursive_mutex.hpp>
21#include <boost/smart_ptr.hpp>
22
23#include <boost/noncopyable.hpp>
24
25#include <boost/tuple/tuple.hpp>
26#include <boost/signal.hpp>
27#include <boost/optional.hpp>
28#include <boost/function.hpp>
29
30#include <boost/date_time/posix_time/posix_time.hpp>
31#include <boost/smart_ptr.hpp>
32#include <boost/algorithm/string.hpp>
33
34#include <boost/filesystem/path.hpp>
35#include <boost/filesystem/operations.hpp>
36#include <boost/filesystem/fstream.hpp>
37
38#include <asio/ip/tcp.hpp>
39#include <asio/ip/udp.hpp>
40
41namespace libtorrent { struct peer_info; }
42
43namespace hal
44{
45
46typedef boost::recursive_mutex mutex_t;
47typedef boost::thread thread_t;
48       
49struct torrentBriefDetail
50{
51        std::wstring filename;
52        std::wstring status;
53        std::pair<float,float> speed;
54        float completion;
55        int peers;
56        int seeds;
57};
58
59struct PeerDetail
60{
61        PeerDetail(const std::wstring& ip_address) :
62                ipAddress(ip_address)
63        {}
64        PeerDetail(libtorrent::peer_info& peerInfo);
65       
66        bool operator==(const PeerDetail& peer) const
67        {
68                return (ipAddress == peer.ipAddress);
69        }
70       
71        bool operator<(const PeerDetail& peer) const
72        {
73                return (ipAddress < peer.ipAddress);
74        }
75       
76        std::wstring ipAddress;
77        std::wstring country;
78        std::pair<float,float> speed;
79        bool seed;
80        std::wstring client;
81        std::wstring status;
82};
83
84typedef boost::shared_ptr<PeerDetail> PeerDetail_ptr;
85typedef std::vector<PeerDetail> PeerDetails;
86
87struct FileDetail
88{
89        FileDetail(boost::filesystem::wpath p, boost::int64_t s=0, float pg=0, int pr=1, size_t o=0, unsigned t=FileDetail::file) :
90                branch(p.branch_path()),
91                filename(p.leaf()),
92                type(t),
93                size(s),
94                progress(pg),
95                priority(pr),
96                order_(o)
97        {}
98       
99        bool operator==(const FileDetail& file) const
100        {
101                return (branch == file.branch);
102        }
103       
104        bool operator<(const FileDetail& file) const
105        {
106                return (branch < file.branch);
107        }
108       
109        enum FileType
110        {
111                folder,
112                file
113        };
114       
115        size_t order() const { return order_; }
116       
117        boost::filesystem::wpath branch;
118        std::wstring filename;
119        unsigned type;
120        boost::int64_t size;
121        float progress;
122        int priority;
123       
124private:
125        size_t order_;
126};
127
128inline bool FileDetailNamesEqual(const FileDetail& l, const FileDetail& r)
129{
130        return l.filename == r.filename;
131}
132
133inline bool FileDetailNamesLess(const FileDetail& l, const FileDetail& r)
134{
135        return l.filename < r.filename;
136}
137
138typedef std::vector<FileDetail> FileDetails;
139
140class TorrentDetail 
141{
142public:
143        TorrentDetail(std::wstring n, std::wstring f, std::wstring s, std::wstring cT, std::pair<float,float> sp=std::pair<float,float>(0,0),
144                        float c=0, float d=0, boost::int64_t tWD=0, boost::int64_t tW=0, boost::int64_t tU=0, boost::int64_t tpU=0, boost::int64_t tD=0, boost::int64_t tpD=0, boost::tuple<size_t, size_t, size_t, size_t> connections = boost::tuple<size_t, size_t, size_t, size_t>(0,0,0,0), float r=0, 
145                        boost::posix_time::time_duration eta=boost::posix_time::seconds(0), boost::posix_time::time_duration uIn=boost::posix_time::seconds(0),
146                        boost::posix_time::time_duration actve=boost::posix_time::seconds(0), boost::posix_time::time_duration seding=boost::posix_time::seconds(0), boost::posix_time::ptime srt=boost::posix_time::second_clock::universal_time(), boost::posix_time::ptime fin=boost::posix_time::second_clock::universal_time()) :
147                filename_(f),
148                name_(n),
149                state_(s),
150                currentTracker_(cT),
151                speed_(sp),
152                completion_(c),
153                distributed_copies_(d),
154                totalWantedDone_(tWD),
155                totalWanted_(tW),
156                totalUploaded_(tU),
157                totalPayloadUploaded_(tpU),
158                totalDownloaded_(tD),
159                totalPayloadDownloaded_(tpD),
160                peers_(connections.get<0>()),
161                connectedPeers_(connections.get<1>()),
162                seeds_(connections.get<2>()),
163                connectedSeeds_(connections.get<3>()),
164                ratio_(r),
165                estimatedTimeLeft_(eta),
166                updateTrackerIn_(uIn),
167                peerDetailsFilled_(false),
168                fileDetailsFilled_(false),
169                active_(actve),
170                seeding_(seding),
171                startTime_(srt),
172                finishTime_(fin)
173        {}
174
175        TorrentDetail() :       
176                peerDetailsFilled_(false),
177                fileDetailsFilled_(false)
178        {};     
179       
180        enum state
181        {
182                torrent_active = 0,
183                torrent_paused,
184                torrent_stopped,
185                torrent_pausing,
186                torrent_stopping
187        };
188       
189//      const std::wstring& filename() const { return filename_; }
190        const std::wstring& name() const { return name_; }
191        const std::wstring& state() const { return state_; }
192        const std::wstring& currentTracker() const { return currentTracker_; }
193       
194        std::pair<float,float> speed() const { return speed_; }
195        const float& completion() const { return completion_; }
196        const float& distributedCopies() const { return distributed_copies_; }
197       
198        const boost::int64_t& totalUploaded() const { return totalUploaded_; }
199        const boost::int64_t& totalPayloadUploaded() const { return totalPayloadUploaded_; }
200        const boost::int64_t& totalDownloaded() const { return totalDownloaded_; }
201        const boost::int64_t& totalPayloadDownloaded() const { return totalPayloadDownloaded_; }
202        const boost::int64_t& totalWantedDone() const { return totalWantedDone_; }
203        const boost::int64_t& totalWanted() const { return totalWanted_; }
204       
205        int peers() const { return peers_; }
206        int peersConnected() const { return connectedPeers_; }
207        int seeds() const { return seeds_; }
208        int seedsConnected() const { return connectedSeeds_; }
209       
210        float ratio() { return ratio_; }
211       
212        const boost::posix_time::time_duration& estimatedTimeLeft() { return estimatedTimeLeft_; }
213        const boost::posix_time::time_duration& updateTrackerIn() { return updateTrackerIn_; }
214       
215        const PeerDetails& peerDetails() const;
216        const FileDetails& fileDetails() const;
217       
218        const boost::posix_time::time_duration& active() { return active_; }
219        const boost::posix_time::time_duration& seeding() { return seeding_; }
220        const boost::posix_time::ptime& startTime() { return startTime_; }
221        const boost::posix_time::ptime& finishTime() { return finishTime_; }
222       
223public:
224        std::wstring filename_;
225        std::wstring name_;
226        std::wstring state_;
227        std::wstring currentTracker_;
228
229        std::pair<float,float> speed_;         
230        float completion_;     
231        float distributed_copies_;
232       
233        boost::int64_t totalWantedDone_;
234        boost::int64_t totalWanted_;
235        boost::int64_t totalUploaded_;
236        boost::int64_t totalPayloadUploaded_;
237        boost::int64_t totalDownloaded_;
238        boost::int64_t totalPayloadDownloaded_;
239       
240        int peers_;
241        int connectedPeers_;
242        int seeds_;
243        int connectedSeeds_;
244       
245        float ratio_;
246       
247        boost::posix_time::time_duration estimatedTimeLeft_;
248        boost::posix_time::time_duration updateTrackerIn_;
249       
250        boost::posix_time::time_duration active_;
251        boost::posix_time::time_duration seeding_;
252        boost::posix_time::ptime startTime_;
253        boost::posix_time::ptime finishTime_;
254       
255private:
256        mutable bool peerDetailsFilled_;
257        mutable PeerDetails peerDetails_;
258       
259        mutable bool fileDetailsFilled_;
260        mutable FileDetails fileDetails_;
261};
262
263typedef boost::shared_ptr<TorrentDetail> TorrentDetail_ptr;
264typedef boost::scoped_ptr<TorrentDetail> TorrentDetail_sptr;
265typedef boost::weak_ptr<TorrentDetail> TorrentDetail_wptr;
266typedef std::vector<TorrentDetail_ptr> TorrentDetail_vec;
267typedef std::map<std::wstring, TorrentDetail_ptr> TorrentDetail_map;
268
269class TorrentDetails
270{
271public: 
272        void sort(boost::function<bool (const TorrentDetail_ptr&, const TorrentDetail_ptr&)> fn) const;
273       
274        const TorrentDetail_vec torrents() const 
275        {
276                mutex_t::scoped_lock l(mutex_); 
277                return torrents_; 
278        }
279       
280        const TorrentDetail_vec selectedTorrents() const 
281        { 
282                mutex_t::scoped_lock l(mutex_); 
283                return selectedTorrents_; 
284        }
285       
286        const TorrentDetail_ptr focusedTorrent() const 
287        {
288                mutex_t::scoped_lock l(mutex_); 
289                return selectedTorrent_; 
290        }
291       
292        const TorrentDetail_ptr get(std::wstring filename) const
293        {
294                mutex_t::scoped_lock l(mutex_); 
295               
296                TorrentDetail_map::const_iterator i = torrentMap_.find(filename);
297               
298                if (i != torrentMap_.end())
299                        return i->second;
300                else
301                        return TorrentDetail_ptr();
302        }
303       
304        friend class BitTorrent;
305
306private:
307        void clearAll(const mutex_t::scoped_lock&)
308        {
309                // !! No mutex lock, it should only be call from functions which
310                // have the lock themselves, hence the unused function param
311               
312                torrents_.clear();
313                torrentMap_.clear();
314                selectedTorrents_.clear();
315                selectedTorrent_.reset();
316        }
317
318        mutable TorrentDetail_vec torrents_;
319       
320        TorrentDetail_map torrentMap_;
321        TorrentDetail_vec selectedTorrents_;
322        TorrentDetail_ptr selectedTorrent_;
323       
324        mutable mutex_t mutex_;
325};
326
327struct TrackerDetail
328{
329        TrackerDetail() {}
330        TrackerDetail(std::wstring u, int t) : url(u), tier(t) {}
331       
332        bool operator<(const TrackerDetail& t) const
333        {
334                return (tier < t.tier);
335        }
336       
337        std::wstring url;
338        int tier;
339};
340
341class EventDetail;
342
343struct SessionDetail
344{
345        int port;
346       
347        std::pair<double, double> speed;
348       
349        bool dht_on;
350        size_t dht_nodes;
351        size_t dht_torrents;
352       
353        bool ip_filter_on;
354        size_t ip_ranges_filtered;
355};
356
357typedef boost::function<bool (size_t, size_t, size_t)> filterCallback;
358typedef boost::function<bool (size_t)> progressCallback;
359
360class BitTorrent_impl;
361
362class BitTorrent
363{
364public: 
365        enum mappings
366        {
367                mappingNone = 0,
368                mappingUPnP,
369                mappingNatPMP
370        };
371
372        void shutDownSession();
373        void saveTorrentData();
374       
375        bool listenOn(std::pair<int, int> const& portRange);
376        int isListeningOn();
377        void stopListening();
378       
379        bool ensureDhtOn();
380        void ensureDhtOff();
381       
382        void ensurePeOn(int enc_level, int in_enc_policy, int out_enc_policy, bool prefer_rc4);
383        void ensurePeOff();
384       
385        void ensureIpFilterOn(progressCallback fn);
386        void ensureIpFilterOff();
387
388        void setMapping(int mapping);
389
390        void ip_v4_filter_block(asio::ip::address_v4 first, asio::ip::address_v4 last);
391        void ip_v6_filter_block(asio::ip::address_v6 first, asio::ip::address_v6 last);
392        void ip_filter_import_dat(boost::filesystem::path file, progressCallback fn, bool octalFix);
393        size_t ip_filter_size();
394        void clearIpFilter();
395       
396       
397        void setSessionHalfOpenLimit(int halfConn);
398        void setSessionLimits(int maxConn, int maxUpload);
399        void setSessionSpeed(float download, float upload);
400        void setDhtSettings(int max_peers_reply, int search_branching, 
401                int service_port, int max_fail_count);
402        void setTimeouts(int peers, int tracker);
403       
404        const SessionDetail getSessionDetails();
405
406        void setTorrentDefaults(int maxConn, int maxUpload, float download, float upload);     
407        void newTorrent(boost::filesystem::wpath filename, boost::filesystem::wpath files);
408        void addTorrent(boost::filesystem::wpath file, boost::filesystem::wpath saveDirectory, 
409                bool startPaused=false, bool compactStorage=false);
410       
411        void setTorrentRatio(const std::string&, float ratio);
412        void setTorrentRatio(const std::wstring&, float ratio);
413        float getTorrentRatio(const std::string&);
414        float getTorrentRatio(const std::wstring&);
415       
416        void getAllPeerDetails(const std::string& filename, PeerDetails& peerContainer);
417        void getAllPeerDetails(const std::wstring& filename, PeerDetails& peerContainer);
418        void getAllFileDetails(const std::string& filename, FileDetails& fileDetails);
419        void getAllFileDetails(const std::wstring& filename, FileDetails& fileDetails);
420       
421        void resumeAll();
422        void closeAll();
423       
424        bool isTorrent(const std::string& filename);
425        bool isTorrent(const std::wstring& filename);   
426       
427        void pauseTorrent(const std::string& filename);
428        void pauseTorrent(const std::wstring& filename);
429        void resumeTorrent(const std::string& filename);
430        void resumeTorrent(const std::wstring& filename);
431        void stopTorrent(const std::string& filename);
432        void stopTorrent(const std::wstring& filename);
433        bool isTorrentActive(const std::string& filename);
434        bool isTorrentActive(const std::wstring& filename);
435        void reannounceTorrent(const std::string& filename);
436        void reannounceTorrent(const std::wstring& filename);
437       
438        void pauseAllTorrents();
439        void unpauseAllTorrents();
440       
441        void removeTorrent(const std::string& filename);
442        void removeTorrent(const std::wstring&  filename);
443        void removeTorrentWipeFiles(const std::string& filename);
444        void removeTorrentWipeFiles(const std::wstring&  filename);
445       
446        void setTorrentLogin(const std::string& filename, std::wstring username, std::wstring password);
447        void setTorrentLogin(const std::wstring& filename, std::wstring username, std::wstring password);
448        std::pair<std::wstring, std::wstring> getTorrentLogin(const std::string& filename);
449        std::pair<std::wstring, std::wstring> getTorrentLogin(const std::wstring&  filename);
450       
451        void setTorrentLimit(const std::string& filename, int maxConn, int maxUpload);
452        void setTorrentLimit(const std::wstring& filename, int maxConn, int maxUpload);
453        void setTorrentSpeed(const std::string& filename, float download, float upload);
454        void setTorrentSpeed(const std::wstring& filename, float download, float upload);
455        std::pair<int, int> getTorrentLimit(const std::string& filename);
456        std::pair<int, int> getTorrentLimit(const std::wstring& filename);
457        std::pair<float, float> getTorrentSpeed(const std::string& filename);
458        std::pair<float, float> getTorrentSpeed(const std::wstring& filename);
459       
460        void setTorrentTrackers(const std::string& filename, const std::vector<TrackerDetail>& trackers);
461        void setTorrentTrackers(const std::wstring& filename, const std::vector<TrackerDetail>& trackers);
462        void resetTorrentTrackers(const std::string& filename);
463        void resetTorrentTrackers(const std::wstring& filename);
464        std::vector<TrackerDetail> getTorrentTrackers(const std::string& filename);
465        std::vector<TrackerDetail> getTorrentTrackers(const std::wstring& filename);
466       
467        void setTorrentFilePriorities(const std::string& filename, std::vector<int> fileIndices, int priority);
468        void setTorrentFilePriorities(const std::wstring& filename, std::vector<int> fileIndices, int priority);
469
470        void startEventReceiver();
471        void stopEventReceiver();
472       
473        friend BitTorrent& bittorrent();
474       
475        int defTorrentMaxConn();
476        int defTorrentMaxUpload();
477        float defTorrentDownload();
478        float defTorrentUpload();       
479
480        const TorrentDetails& torrentDetails();
481        const TorrentDetails& updateTorrentDetails(const std::wstring& focused, const std::set<std::wstring>& selected);
482       
483private:
484        BitTorrent();
485        boost::scoped_ptr<BitTorrent_impl> pimpl;
486       
487        TorrentDetails torrentDetails_;
488};
489
490BitTorrent& bittorrent();
491
492};
Note: See TracBrowser for help on using the repository browser.