source: trunk/src/halSession.cpp @ 746

Revision 746, 23.1 KB checked in by Eoin, 11 years ago (diff)

Adding a session state_machine.

Line 
1
2//         Copyright Eóin O'Callaghan 2006 - 2009.
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#include "stdAfx.hpp"
8
9#define TORRENT_MAX_ALERT_TYPES 32
10
11#include <boost/utility/in_place_factory.hpp>
12#include <boost/none.hpp>
13
14#include "win32_exception.hpp"
15
16#include "global/wtl_app.hpp"
17#include "global/string_conv.hpp"
18#include "global/ini_adapter.hpp"
19
20#include "halIni.hpp"
21#include "halTypes.hpp"
22#include "halEvent.hpp"
23#include "halSignaler.hpp"
24#include "halSession.hpp"
25
26#pragma warning (push, 1)
27#       include <libtorrent/create_torrent.hpp>
28#pragma warning (pop)
29
30namespace hal
31{
32
33bit_impl::bit_impl() :
34        keepChecking_(false),
35        bittorrent_ini_(L"BitTorrent.xml"),
36        the_torrents_(bittorrent_ini_),
37        default_torrent_max_connections_(-1),
38        default_torrent_max_uploads_(-1),
39        default_torrent_download_(-1),
40        default_torrent_upload_(-1),
41        resolve_countries_(true),
42        ip_filter_on_(false),
43        ip_filter_loaded_(false),
44        ip_filter_changed_(false),
45        ip_filter_count_(0),
46        dht_on_(false)
47{
48        session_ = boost::in_place(libt::fingerprint(HALITE_FINGERPRINT));
49
50        try
51        {
52
53        torrent_internal::the_session_ = &session_;
54
55        session_->session::set_alert_mask(libt::alert::all_categories);         
56        session_->add_extension(&libt::create_metadata_plugin);
57        session_->add_extension(&libt::create_ut_pex_plugin);
58        session_->set_max_half_open_connections(10);
59       
60        hal::event_log().post(shared_ptr<hal::EventDetail>(
61                new hal::EventMsg(L"Loading BitTorrent.xml.", hal::event_logger::info)));               
62        bittorrent_ini_.load_data();
63        hal::event_log().post(shared_ptr<hal::EventDetail>(
64                new hal::EventMsg(L"Loading torrent parameters.", hal::event_logger::info)));   
65        the_torrents_.load_from_ini();
66        hal::event_log().post(shared_ptr<hal::EventDetail>(
67                new hal::EventMsg(L"Loading done!", hal::event_logger::info)));
68       
69#       if 0
70        try
71        {                                               
72        if (fs::exists(hal::app().get_working_directory()/L"Torrents.xml"))
73        {
74                assert(false);
75                {
76                fs::wifstream ifs(hal::app().get_working_directory()/L"Torrents.xml");
77       
78                event_log().post(shared_ptr<EventDetail>(new EventMsg(L"Loading old Torrents.xml")));
79       
80                TorrentMap torrents;
81                boost::archive::xml_wiarchive ia(ifs); 
82                ia >> boost::serialization::make_nvp("torrents", torrents);
83               
84                the_torrents_ = torrents;
85                }
86               
87                event_log().post(shared_ptr<EventDetail>(new EventMsg(
88                        hal::wform(L"Total %1%.") % the_torrents_.size())));                           
89               
90                fs::rename(hal::app().get_working_directory()/L"Torrents.xml", hal::app().get_working_directory()/L"Torrents.xml.safe.to.delete");
91
92        }                       
93        }
94        catch(const std::exception& e)
95        {
96                event_log().post(shared_ptr<EventDetail>(
97                        new EventStdException(event_logger::fatal, e, L"Loading Old Torrents.xml")));
98        }               
99#       endif
100
101        if (exists(hal::app().get_working_directory()/L"DHTState.bin"))
102        {
103                try
104                {
105                        dht_state_ = haldecode(hal::app().get_working_directory()/L"DHTState.bin");
106                }               
107                catch(const std::exception& e)
108                {
109                        event_log().post(shared_ptr<EventDetail>(
110                                new EventStdException(event_logger::critical, e, L"Loading DHTState.bin")));
111                }
112        }
113       
114        {       libt::session_settings settings = session_->settings();
115                settings.user_agent = string("Halite ") + HALITE_VERSION_STRING;
116                session_->set_settings(settings);
117        }
118       
119        start_alert_handler();
120
121        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"bit_impl::bit_impl()")
122}
123
124bit_impl::~bit_impl()
125{       
126        try
127        {
128        HAL_DEV_MSG(L"Commence ~BitTorrent_impl"); 
129
130        stop_alert_handler();   
131        //save_torrent_data();
132       
133        HAL_DEV_MSG(L"Handler stopped!"); 
134        if (ip_filter_changed_)
135        {       
136                HAL_DEV_MSG(L"IP Filter needs saving."); 
137
138                fs::ofstream ofs(hal::app().get_working_directory()/L"IPFilter.bin", std::ios::binary);
139//              boost::archive::binary_oarchive oba(ofs);
140               
141                libt::ip_filter::filter_tuple_t vectors = ip_filter_.export_filter();   
142               
143                std::vector<libt::ip_range<boost::asio::ip::address_v4> > v4(vectors.get<0>());
144                std::vector<libt::ip_range<boost::asio::ip::address_v6> > v6(vectors.get<1>());
145               
146                v4.erase(std::remove(v4.begin(), v4.end(), 0), v4.end());
147                v6.erase(std::remove(v6.begin(), v6.end(), 0), v6.end());
148
149                write_vec_range(ofs, v4);
150//              write_vec_range(ofs, v6);
151        }       
152
153        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"~BitTorrent_impl")
154}
155
156void bit_impl::ip_filter_count()
157{
158        libt::ip_filter::filter_tuple_t vectors = ip_filter_.export_filter();
159       
160        vectors.get<0>().erase(std::remove(vectors.get<0>().begin(), vectors.get<0>().end(), 0),
161                vectors.get<0>().end());
162        vectors.get<1>().erase(std::remove(vectors.get<1>().begin(), vectors.get<1>().end(), 0),
163                vectors.get<1>().end());
164        ip_filter_count_ = vectors.get<0>().size() + vectors.get<1>().size();
165}
166
167void bit_impl::ip_filter_load(progress_callback fn)
168{
169        fs::ifstream ifs(hal::app().get_working_directory()/L"IPFilter.bin", std::ios::binary);
170        if (ifs)
171        {
172                size_t v4_size;
173                ifs >> v4_size;
174               
175                size_t total = v4_size/100;
176                size_t previous = 0;
177               
178                for(unsigned i=0; i<v4_size; ++i)
179                {
180                        if (i-previous > total)
181                        {
182                                previous = i;
183
184                                if (fn) if (fn(i, v4_size, hal::app().res_wstr(HAL_TORRENT_LOAD_FILTERS))) break;
185                        }
186                       
187                        read_range_to_filter<boost::asio::ip::address_v4>(ifs, ip_filter_);
188                }
189        }       
190}
191
192void bit_impl::ip_filter_import(std::vector<libt::ip_range<boost::asio::ip::address_v4> >& v4,
193        std::vector<libt::ip_range<boost::asio::ip::address_v6> >& v6)
194{
195        for(std::vector<libt::ip_range<boost::asio::ip::address_v4> >::iterator i=v4.begin();
196                i != v4.end(); ++i)
197        {
198                ip_filter_.add_rule(i->first, i->last, libt::ip_filter::blocked);
199        }
200/*      for(std::vector<libt::ip_range<boost::asio::ip::address_v6> >::iterator i=v6.begin();
201                i != v6.end(); ++i)
202        {
203                ip_filter_.add_rule(i->first, i->last, libt::ip_filter::blocked);
204        }
205*/     
206        /* Note here we do not set ip_filter_changed_ */
207}
208
209bool bit_impl::ip_filter_import_dat(boost::filesystem::path file, progress_callback fn, bool octalFix)
210{
211        try
212        {
213
214        fs::ifstream ifs(file); 
215        if (ifs)
216        {
217                boost::uintmax_t total = fs::file_size(file);
218                boost::uintmax_t progress = 0;
219                boost::uintmax_t previous = 0;
220               
221                boost::regex reg("\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s*-\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s*.*");
222                boost::regex ip_reg("0*(\\d*)\\.0*(\\d*)\\.0*(\\d*)\\.0*(\\d*)");
223                boost::smatch m;
224               
225                string ip_address_line;         
226                while (!std::getline(ifs, ip_address_line).eof())
227                {               
228                        progress += (ip_address_line.length() + 2);
229                        if (progress-previous > total)
230                        {
231                                previous = progress;
232                                if (fn)
233                                {
234                                        if (fn(boost::numeric_cast<size_t>(progress), boost::numeric_cast<size_t>(total), 
235                                                        hal::app().res_wstr(HAL_TORRENT_IMPORT_FILTERS))) 
236                                                break;
237                                }
238                        }
239                       
240                        if (boost::regex_match(ip_address_line, m, reg))
241                        {
242                                string first = m[1];
243                                string last = m[2];
244                               
245                                if (octalFix)
246                                {
247                                        if (boost::regex_match(first, m, ip_reg))
248                                        {
249                                                first = ((m.length(1) != 0) ? m[1] : string("0")) + "." +
250                                                                ((m.length(2) != 0) ? m[2] : string("0")) + "." +
251                                                                ((m.length(3) != 0) ? m[3] : string("0")) + "." +
252                                                                ((m.length(4) != 0) ? m[4] : string("0"));
253                                        }                                       
254                                        if (boost::regex_match(last, m, ip_reg))
255                                        {
256                                                last = ((m.length(1) != 0) ? m[1] : string("0")) + "." +
257                                                           ((m.length(2) != 0) ? m[2] : string("0")) + "." +
258                                                           ((m.length(3) != 0) ? m[3] : string("0")) + "." +
259                                                           ((m.length(4) != 0) ? m[4] : string("0"));
260                                        }
261                                }
262                               
263                                try
264                                {                       
265                                        ip_filter_.add_rule(boost::asio::ip::address_v4::from_string(first),
266                                                boost::asio::ip::address_v4::from_string(last), libt::ip_filter::blocked);     
267                                }
268                                catch(...)
269                                {
270                                        hal::event_log().post(shared_ptr<hal::EventDetail>(
271                                                new hal::EventDebug(hal::event_logger::info, 
272                                                from_utf8((boost::format("Invalid IP range: %1%-%2%.") % first % last).str()))));
273                                }
274                        }
275                }
276        }
277       
278        ip_filter_changed_ = true;
279        ip_filter_count();
280       
281        }
282        catch(const std::exception& e)
283        {
284                event_log().post(shared_ptr<EventDetail>(
285                        new EventStdException(event_logger::critical, e, L"ip_filter_import_dat")));
286        }
287
288        return false;
289}
290
291bool bit_impl::create_torrent(const create_torrent_params& params, fs::wpath out_file, progress_callback fn)
292{               
293        try
294        {
295        libt::file_storage fs;
296        libt::file_pool f_pool;
297
298        HAL_DEV_MSG(L"Files");
299        for (file_size_pairs_t::const_iterator i = params.file_size_pairs.begin(), e = params.file_size_pairs.end();
300                        i != e; ++i)
301        {
302                HAL_DEV_MSG(hal::wform(L"file path: %1%, size: %2%") % (*i).first % (*i).second);
303                fs.add_file(to_utf8((*i).first.string()), (*i).second);
304        }
305
306        int piece_size = params.piece_size;
307        HAL_DEV_MSG(hal::wform(L"piece size: %1%") % piece_size);
308       
309        libt::create_torrent t(fs, piece_size);
310       
311/*      boost::scoped_ptr<libt::storage_interface> store(
312                libt::default_storage_constructor(t_info, to_utf8(params.root_path.string()),
313                        f_pool));
314*/
315        HAL_DEV_MSG(L"Trackers");
316        for (tracker_details_t::const_iterator i = params.trackers.begin(), e = params.trackers.end();
317                        i != e; ++i)
318        {
319                HAL_DEV_MSG(hal::wform(L"URL: %1%, Tier: %2%") % (*i).url % (*i).tier);
320                t.add_tracker(to_utf8((*i).url), (*i).tier);
321        }
322
323        HAL_DEV_MSG(L"Web Seeds");
324        for (web_seed_details_t::const_iterator i = params.web_seeds.begin(), e = params.web_seeds.end();
325                        i != e; ++i)
326        {
327                HAL_DEV_MSG(hal::wform(L"URL: %1%") % (*i).url);
328                t.add_url_seed(to_utf8((*i).url));
329        }
330
331        HAL_DEV_MSG(L"DHT Nodes");
332        for (dht_node_details_t::const_iterator i = params.dht_nodes.begin(), e = params.dht_nodes.end();
333                        i != e; ++i)
334        {
335                HAL_DEV_MSG(hal::wform(L"URL: %1%, port: %2%") % (*i).url % (*i).port);
336                t.add_node(hal::make_pair(to_utf8((*i).url), (*i).port));
337        }
338
339        HAL_DEV_MSG(hal::wform(L"root_path: %1%") % params.root_path.string());
340
341        set_piece_hashes(t, to_utf8(params.root_path.string()),
342                boost::bind(fn, _1, t.num_pieces(), hal::app().res_wstr(HAL_NEWT_HASHING_PIECES)));
343
344        t.set_creator(to_utf8(params.creator).c_str());
345        t.set_comment(to_utf8(params.comment).c_str());
346       
347        t.set_priv(params.private_torrent);
348
349        // create the torrent and print it to out
350        libt::entry e = t.generate();
351       
352        HAL_DEV_MSG(hal::wform(L"Writing to: %1%") % out_file);
353        fs::ofstream out(out_file, std::ios_base::binary);
354        libt::bencode(std::ostream_iterator<char>(out), t.generate());
355
356        } HAL_GENERIC_FN_EXCEPTION_CATCH(L"bit_impl::create_torrent()")
357       
358        HAL_DEV_MSG(L"Torrent creation completed!");
359
360        return false;
361}
362
363void bit_impl::start_alert_handler()
364{
365        mutex_t::scoped_lock l(mutex_);
366
367        if (alert_checker_ == boost::none)
368        {       
369                HAL_DEV_MSG(hal::wform(L"start_alert_handler"));
370
371                boost::function<void (void)> f = bind(&bit_impl::alert_handler, this);
372
373                keepChecking_ = true;
374                alert_checker_ = boost::in_place<boost::function<void (void)> >(bind(&bit_impl::alert_handler, this));
375        }
376}
377       
378void bit_impl::stop_alert_handler()
379{
380        mutex_t::scoped_lock l(mutex_);
381
382        keepChecking_ = false;
383
384        if (alert_checker_)
385        {
386                HAL_DEV_MSG(hal::wform(L"Interrupting alert handler"));
387
388                alert_checker_->interrupt();
389                alert_checker_->join();
390                alert_checker_ = boost::none;
391        }
392        else
393        {
394                HAL_DEV_MSG(hal::wform(L"Alert handler already stopped"));
395        }
396}
397       
398void bit_impl::alert_handler()
399{
400        win32_exception::install_handler();
401
402        try
403        {
404
405        while (keepChecking_)
406        {
407       
408        std::auto_ptr<libt::alert> p_alert = session_->pop_alert();
409       
410        class AlertHandler
411        {
412        public:
413        AlertHandler(bit_impl& bit_impl) :
414                bit_impl_(bit_impl)
415        {}
416
417        void operator()(libt::external_ip_alert const& a) const
418        {
419                event_log().post(shared_ptr<EventDetail>(
420                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
421                                hal::wform(hal::app().res_wstr(HAL_EXTERNAL_IP_ALERT))
422                                        % hal::from_utf8_safe(a.message())
423                                        % hal::from_utf8_safe(a.external_address.to_string()))
424                )       );                             
425        }
426
427        void operator()(libt::portmap_error_alert const& a) const
428        {
429                event_log().post(shared_ptr<EventDetail>(
430                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
431                                hal::wform(hal::app().res_wstr(HAL_PORTMAP_ERROR_ALERT))
432                                % (a.type == 0 ? 
433                                        hal::app().res_wstr(HAL_PORTMAP_TYPE_PMP) : 
434                                        hal::app().res_wstr(HAL_PORTMAP_TYPE_UPNP)))
435                )       );                             
436        }
437
438        void operator()(libt::portmap_alert const& a) const
439        {
440                event_log().post(shared_ptr<EventDetail>(
441                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
442                                hal::wform(hal::app().res_wstr(HAL_PORTMAP_ALERT))
443                                % (a.type == 0 ? 
444                                        hal::app().res_wstr(HAL_PORTMAP_TYPE_PMP) : 
445                                        hal::app().res_wstr(HAL_PORTMAP_TYPE_UPNP))
446                                % a.external_port)
447                )       );                             
448        }
449       
450        void operator()(libt::file_error_alert const& a) const
451        {
452                event_log().post(shared_ptr<EventDetail>(
453                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
454                                hal::wform(hal::app().res_wstr(HAL_FILE_ERROR_ALERT))
455                                % hal::from_utf8_safe(a.file)
456                                % hal::from_utf8_safe(a.msg))
457                )       );                             
458        }
459       
460        void operator()(libt::dht_reply_alert const& a) const
461        {
462                event_log().post(shared_ptr<EventDetail>(
463                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
464                                hal::wform(hal::app().res_wstr(HAL_DHT_REPLY_ALERT))
465                                        % a.num_peers
466                                        % get(a.handle)->name())
467                )       );                             
468        }
469
470        void operator()(libt::torrent_finished_alert const& a) const
471        {
472                event_log().post(shared_ptr<EventDetail>(
473                        new EventMsg((hal::wform(hal::app().res_wstr(LBT_EVENT_TORRENT_FINISHED)) 
474                                        % get(a.handle)->name()), 
475                                event_logger::info, a.timestamp())));
476               
477                get(a.handle)->finished();     
478        }
479       
480        void operator()(libt::torrent_paused_alert const& a) const
481        {
482                get(a.handle)->signals().torrent_paused();
483
484                wstring err = get(a.handle)->check_error();
485
486                if (err == L"")
487                {
488                        event_log().post(shared_ptr<EventDetail>(
489                                new EventMsg((hal::wform(hal::app().res_wstr(LBT_EVENT_TORRENT_PAUSED)) 
490                                                % get(a.handle)->name()), 
491                                        event_logger::debug, a.timestamp())));
492                       
493                        HAL_DEV_MSG(hal::wform(L"Torrent Paused alert, %1%.") % get(a.handle)->name());
494
495                        get(a.handle)->locked_process_event(ev_paused_alert());
496                }
497                else
498                {
499                        HAL_DEV_MSG(hal::wform(L"Torrent Error alert %2%, %1%.") % get(a.handle)->name() % err);
500
501                        event_log().post(shared_ptr<EventDetail>(
502                                new EventMsg((hal::wform(hal::app().res_wstr(HAL_TORRENT_ERROR_PAUSE_ALERT)) 
503                                                % err
504                                                % get(a.handle)->name()), 
505                                        event_logger::warning, a.timestamp())));
506
507                        get(a.handle)->locked_process_event(ev_error_alert(err));
508                }
509        }
510       
511        void operator()(libt::torrent_resumed_alert const& a) const
512        {
513                event_log().post(shared_ptr<EventDetail>(
514                        new EventMsg((hal::wform(hal::app().res_wstr(HAL_TORRENT_RESUME_ALERT)) 
515                                        % get(a.handle)->name()), 
516                                event_logger::debug, a.timestamp())));
517
518                get(a.handle)->locked_process_event(ev_resumed_alert());
519        }
520       
521        void operator()(libt::save_resume_data_alert const& a) const
522        {
523                event_log().post(shared_ptr<EventDetail>(
524                        new EventMsg((hal::wform(hal::app().res_wstr(HAL_WRITE_RESUME_ALERT)) 
525                                        % get(a.handle)->name()), 
526                                event_logger::info, a.timestamp())));
527
528                if (a.resume_data)
529                        get(a.handle)->write_resume_data(*a.resume_data);
530
531                get(a.handle)->signals().resume_data();
532                get(a.handle)->locked_process_event(ev_resume_data_alert());
533        }
534       
535        void operator()(libt::save_resume_data_failed_alert const& a) const
536        {
537                event_log().post(shared_ptr<EventDetail>(
538                        new EventMsg((hal::wform(hal::app().res_wstr(HAL_WRITE_RESUME_FAIL_ALERT)) 
539                                        % get(a.handle)->name()), 
540                                event_logger::warning, a.timestamp())));
541
542                get(a.handle)->locked_process_event(ev_resume_data_failed_alert());
543        }
544       
545        void operator()(libt::peer_error_alert const& a) const
546        {
547                event_log().post(shared_ptr<EventDetail>(
548                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
549                                hal::wform(hal::app().res_wstr(HAL_PEER_ALERT))
550                                        % hal::from_utf8_safe(a.message())
551                                        % hal::from_utf8_safe(a.ip.address().to_string()))
552                )       );                             
553        }
554               
555        void operator()(libt::peer_ban_alert const& a) const
556        {
557                event_log().post(shared_ptr<EventDetail>(
558                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
559                                hal::wform(hal::app().res_wstr(HAL_PEER_BAN_ALERT))
560                                        % get(a.handle)->name()
561                                        % hal::from_utf8_safe(a.ip.address().to_string()))
562                )       );                             
563        }
564               
565        void operator()(libt::hash_failed_alert const& a) const
566        {
567                event_log().post(shared_ptr<EventDetail>(
568                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
569                                hal::wform(hal::app().res_wstr(HAL_HASH_FAIL_ALERT))
570                                        % get(a.handle)->name()
571                                        % a.piece_index)
572                )       );                             
573        }
574               
575        void operator()(libt::url_seed_alert const& a) const
576        {
577                event_log().post(shared_ptr<EventDetail>(
578                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
579                                hal::wform(hal::app().res_wstr(HAL_URL_SEED_ALERT))
580                                        % get(a.handle)->name()
581                                        % hal::from_utf8_safe(a.url)
582                                        % hal::from_utf8_safe(a.message()))
583                )       );                             
584        }
585       
586        void operator()(libt::tracker_warning_alert const& a) const
587        {
588                event_log().post(shared_ptr<EventDetail>(
589                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
590                                hal::wform(hal::app().res_wstr(HAL_TRACKER_WARNING_ALERT))
591                                        % get(a.handle)->name()
592                                        % hal::from_utf8_safe(a.message()))
593                )       );                             
594        }
595       
596        void operator()(libt::tracker_announce_alert const& a) const
597        {
598                event_log().post(shared_ptr<EventDetail>(
599                        new EventMsg((hal::wform(hal::app().res_wstr(HAL_TRACKER_ANNOUNCE_ALERT)) 
600                                        % get(a.handle)->name()), 
601                                event_logger::info, a.timestamp())));
602        }
603       
604        void operator()(libt::tracker_error_alert const& a) const
605        {
606                event_log().post(shared_ptr<EventDetail>(
607                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
608                                hal::wform(hal::app().res_wstr(HAL_TRACKER_ALERT))
609                                        % get(a.handle)->name()
610                                        % hal::from_utf8_safe(a.message())
611                                        % a.times_in_row
612                                        % a.status_code)
613                )       );                             
614        }
615       
616        void operator()(libt::tracker_reply_alert const& a) const
617        {
618                event_log().post(shared_ptr<EventDetail>(
619                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
620                                hal::wform(hal::app().res_wstr(HAL_TRACKER_REPLY_ALERT))
621                                        % get(a.handle)->name()
622                                        % hal::from_utf8_safe(a.message())
623                                        % a.num_peers)
624                )       );                             
625        }
626       
627        void operator()(libt::fastresume_rejected_alert const& a) const
628        {
629                event_log().post(shared_ptr<EventDetail>(
630                        new EventGeneral(lbt_category_to_event(a.category()), a.timestamp(),
631                                hal::wform(hal::app().res_wstr(HAL_FAST_RESUME_ALERT))
632                                        % get(a.handle)->name()
633                                        % hal::from_utf8_safe(a.message()))
634                )       );                             
635        }
636       
637        void operator()(libt::piece_finished_alert const& a) const
638        {
639                event_log().post(shared_ptr<EventDetail>(
640                        new EventGeneral(event_logger::debug, a.timestamp(),
641                                hal::wform(hal::app().res_wstr(HAL_PIECE_FINISHED_ALERT))
642                                        % get(a.handle)->name()
643                                        % a.piece_index)
644                )       );                             
645        }
646       
647        void operator()(libt::block_finished_alert const& a) const
648        {
649                event_log().post(shared_ptr<EventDetail>(
650                        new EventGeneral(event_logger::debug, a.timestamp(),
651                                hal::wform(hal::app().res_wstr(HAL_BLOCK_FINISHED_ALERT))
652                                        % get(a.handle)->name()
653                                        % a.block_index
654                                        % a.piece_index)
655                )       );                             
656        }
657       
658        void operator()(libt::block_downloading_alert const& a) const
659        {
660                event_log().post(shared_ptr<EventDetail>(
661                        new EventGeneral(event_logger::debug, a.timestamp(),
662                                hal::wform(hal::app().res_wstr(HAL_BLOCK_DOWNLOADING_ALERT))
663                                        % get(a.handle)->name()
664                                        % a.block_index
665                                        % a.piece_index)
666                )       );                             
667        }
668       
669        void operator()(libt::listen_failed_alert const& a) const
670        {
671                if (a.endpoint.address().is_v6())
672                {       
673                        event_log().post(shared_ptr<EventDetail>(
674                                new EventGeneral(event_logger::info, a.timestamp(),
675                                        hal::app().res_wstr(HAL_LISTEN_V6_FAILED_ALERT))
676                        )       );             
677                }
678                else
679                {
680                        event_log().post(shared_ptr<EventDetail>(
681                                new EventGeneral(event_logger::info, a.timestamp(),
682                                        hal::wform(hal::app().res_wstr(HAL_LISTEN_FAILED_ALERT))
683                                                % hal::from_utf8_safe(a.message()))
684                        )       );
685                }
686        }
687       
688        void operator()(libt::listen_succeeded_alert const& a) const
689        {
690                event_log().post(shared_ptr<EventDetail>(
691                        new EventGeneral(event_logger::info, a.timestamp(),
692                                hal::wform(hal::app().res_wstr(HAL_LISTEN_SUCCEEDED_ALERT))
693                                        % hal::from_utf8_safe(a.message()))
694                )       );     
695
696                //bit_impl_.signals.successful_listen();
697        }
698       
699        void operator()(libt::peer_blocked_alert const& a) const
700        {
701                event_log().post(shared_ptr<EventDetail>(
702                        new EventGeneral(event_logger::debug, a.timestamp(),
703                                hal::wform(hal::app().res_wstr(HAL_IPFILTER_ALERT))
704                                        % hal::from_utf8_safe(a.ip.to_string())
705                                        % hal::from_utf8_safe(a.message()))
706                )       );                             
707        }
708       
709/*      void operator()(libt::alert const& a) const
710        {
711                event_log().post(shared_ptr<EventDetail>(
712                                new EventLibtorrent(lbtAlertToHalEvent(a.severity()),
713                                        a.timestamp(), event_logger::unclassified, hal::from_utf8_safe(a.message()))));         
714        }*/
715       
716        private:
717                bit_impl& bit_impl_;
718               
719                torrent_internal_ptr get(libt::torrent_handle h) const 
720                { 
721                        torrent_internal_ptr p = bit_impl_.the_torrents_.get(from_utf8_safe(h.get_torrent_info().name())); 
722
723                        if (p)
724                                return p;
725                        else
726                                throw bit::null_torrent();
727                }
728       
729        } handler(*this);
730       
731        while (p_alert.get())
732        {       
733                try
734                {
735                mutex_t::scoped_lock l(mutex_);
736               
737                libt::handle_alert<
738                        libt::save_resume_data_alert,
739                        libt::save_resume_data_failed_alert,
740                        libt::external_ip_alert,
741                        libt::portmap_error_alert,
742                        libt::portmap_alert,
743                        libt::file_error_alert,
744                        libt::torrent_finished_alert,
745                        libt::torrent_paused_alert,
746                        libt::torrent_resumed_alert,
747                        libt::peer_error_alert,
748                        libt::peer_ban_alert,
749                        libt::hash_failed_alert,
750                        libt::url_seed_alert,
751                        libt::dht_reply_alert,
752                        libt::tracker_error_alert,
753                        libt::tracker_warning_alert,
754                        libt::tracker_announce_alert,
755                        libt::tracker_reply_alert,
756                        libt::fastresume_rejected_alert,
757                        libt::piece_finished_alert,
758                        libt::block_finished_alert,
759                        libt::block_downloading_alert,
760                        libt::listen_failed_alert,
761                        libt::listen_succeeded_alert,
762                        libt::peer_blocked_alert
763                >::handle_alert(p_alert, handler);                     
764               
765                }
766                catch(const libt::unhandled_alert&)
767                {
768//                      handler(*p_alert);
769                }
770                catch(const bit::null_torrent&)
771                {
772                        // These are logged as debug because they are rarely important to act on!
773                        event_log().post(shared_ptr<EventDetail>(\
774                                new EventMsg(L"null_torrent exception", event_logger::info)));
775                }
776                catch(const std::exception& e)
777                {
778                        // These are logged as debug because they are rarely important to act on!
779                        event_log().post(shared_ptr<EventDetail>(\
780                                new EventStdException(event_logger::debug, e, L"bit_impl::alert_handler()")));
781                }
782               
783                p_alert = session_->pop_alert();
784
785                boost::this_thread::interruption_point();
786        }       
787               
788        boost::this_thread::sleep(pt::milliseconds(100));
789       
790        }
791       
792        boost::this_thread::interruption_point();
793
794        } 
795        catch(boost::thread_interrupted&)
796        {
797                // Not an error!
798
799                event_log().post(shared_ptr<EventDetail>(
800                        new EventMsg(L"thread_interrupted exception", event_logger::info)));
801
802                return;
803        }
804        HAL_GENERIC_FN_EXCEPTION_CATCH(L"bit_impl::alert_handler()")
805}
806
807}
Note: See TracBrowser for help on using the repository browser.