Changeset 480
- Timestamp:
- 06/05/08 19:27:01 (13 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sln/Halite/Halite.vcproj
r479 r480 548 548 </File> 549 549 <File 550 RelativePath="..\..\src\halSession.cpp" 551 > 552 </File> 553 <File 550 554 RelativePath="..\..\src\halTorrent.cpp" 551 555 > -
trunk/src/halSession.hpp
r479 r480 34 34 #include "halTypes.hpp" 35 35 #include "halEvent.hpp" 36 #include "halTorrentInternal.hpp" 36 37 #include "halSignaler.hpp" 38 39 namespace boost { 40 namespace serialization { 41 42 #define IP_SAVE 3 43 44 template<class Archive, class address_type> 45 void save(Archive& ar, const address_type& ip, const unsigned int version) 46 { 47 #if IP_SAVE == 1 48 typename address_type::bytes_type bytes = ip.to_bytes(); 49 for (typename address_type::bytes_type::iterator i=bytes.begin(); i != bytes.end(); ++i) 50 ar & BOOST_SERIALIZATION_NVP(*i); 51 #elif IP_SAVE == 2 52 string dotted = ip.to_string(); 53 ar & BOOST_SERIALIZATION_NVP(dotted); 54 #elif IP_SAVE == 3 55 unsigned long addr = ip.to_ulong(); 56 ar & BOOST_SERIALIZATION_NVP(addr); 57 #endif 58 } 59 60 template<class Archive, class address_type> 61 void load(Archive& ar, address_type& ip, const unsigned int version) 62 { 63 #if IP_SAVE == 1 64 typename address_type::bytes_type bytes; 65 for (typename address_type::bytes_type::iterator i=bytes.begin(); i != bytes.end(); ++i) 66 ar & BOOST_SERIALIZATION_NVP(*i); 67 ip = address_type(bytes); 68 #elif IP_SAVE == 2 69 string dotted; 70 ar & BOOST_SERIALIZATION_NVP(dotted); 71 ip = address_type::from_string(dotted); 72 #elif IP_SAVE == 3 73 unsigned long addr; 74 ar & BOOST_SERIALIZATION_NVP(addr); 75 ip = address_type(addr); 76 #endif 77 } 78 79 template<class Archive, class String, class Traits> 80 void save(Archive& ar, const boost::filesystem::basic_path<String, Traits>& p, const unsigned int version) 81 { 82 String str = p.string(); 83 ar & BOOST_SERIALIZATION_NVP(str); 84 } 85 86 template<class Archive, class String, class Traits> 87 void load(Archive& ar, boost::filesystem::basic_path<String, Traits>& p, const unsigned int version) 88 { 89 String str; 90 ar & BOOST_SERIALIZATION_NVP(str); 91 92 p = str; 93 } 94 95 template<class Archive, class String, class Traits> 96 inline void serialize( 97 Archive & ar, 98 boost::filesystem::basic_path<String, Traits>& p, 99 const unsigned int file_version 100 ){ 101 split_free(ar, p, file_version); 102 } 103 104 template<class Archive, class address_type> 105 void serialize(Archive& ar, libtorrent::ip_range<address_type>& addr, const unsigned int version) 106 { 107 ar & BOOST_SERIALIZATION_NVP(addr.first); 108 ar & BOOST_SERIALIZATION_NVP(addr.last); 109 addr.flags = libtorrent::ip_filter::blocked; 110 } 111 112 template<class Archive> 113 void serialize(Archive& ar, hal::tracker_detail& tracker, const unsigned int version) 114 { 115 ar & BOOST_SERIALIZATION_NVP(tracker.url); 116 ar & BOOST_SERIALIZATION_NVP(tracker.tier); 117 } 118 119 } // namespace serialization 120 } // namespace boost 121 122 BOOST_SERIALIZATION_SPLIT_FREE(asio::ip::address_v4) 123 BOOST_SERIALIZATION_SPLIT_FREE(asio::ip::address_v6) 124 125 namespace libtorrent 126 { 127 128 template<class Addr> 129 bool operator==(const libtorrent::ip_range<Addr>& lhs, const int flags) 130 { 131 return (lhs.flags == flags); 132 } 133 134 inline 135 std::ostream& operator<<(std::ostream& os, libtorrent::ip_range<asio::ip::address_v4>& ip) 136 { 137 os << ip.first.to_ulong(); 138 os << ip.last.to_ulong(); 139 140 return os; 141 } 142 143 } // namespace libtorrent 37 144 38 145 namespace hal 39 146 { 40 147 148 namespace libt = libtorrent; 149 150 inline 41 151 bool operator!=(const libt::dht_settings& lhs, const libt::dht_settings& rhs) 42 152 { … … 141 251 } 142 252 253 bool listenOn(std::pair<int, int> const& range) 254 { 255 try 256 { 257 258 if (!session_.is_listening()) 259 { 260 return session_.listen_on(range); 261 } 262 else 263 { 264 int port = session_.listen_port(); 265 266 if (port < range.first || port > range.second) 267 return session_.listen_on(range); 268 else 269 { 270 signals.successful_listen(); 271 272 return true; 273 } 274 } 275 276 } 277 catch (const std::exception& e) 278 { 279 event_log.post(shared_ptr<EventDetail>( 280 new EventStdException(event_logger::fatal, e, L"From bit::listenOn."))); 281 282 return false; 283 } 284 catch(...) 285 { 286 return false; 287 } 288 } 289 290 int isListeningOn() 291 { 292 if (!session_.is_listening()) 293 return -1; 294 else 295 return session_.listen_port(); 296 } 297 298 void stopListening() 299 { 300 ensureDhtOff(); 301 session_.listen_on(std::make_pair(0, 0)); 302 } 303 304 bool ensureDhtOn() 305 { 306 if (!dht_on_) 307 { 308 try 309 { 310 session_.start_dht(dht_state_); 311 dht_on_ = true; 312 } 313 catch(...) 314 {} 315 } 316 return dht_on_; 317 } 318 319 void ensureDhtOff() 320 { 321 if (dht_on_) 322 { 323 session_.stop_dht(); 324 dht_on_ = false; 325 } 326 } 327 328 void setDhtSettings(int max_peers_reply, int search_branching, 329 int service_port, int max_fail_count) 330 { 331 libt::dht_settings settings; 332 settings.max_peers_reply = max_peers_reply; 333 settings.search_branching = search_branching; 334 settings.service_port = service_port; 335 settings.max_fail_count = max_fail_count; 336 337 if (dht_settings_ != settings) 338 { 339 dht_settings_ = settings; 340 session_.set_dht_settings(dht_settings_); 341 } 342 } 343 344 void setMapping(int mapping) 345 { 346 if (mapping != bit::mappingNone) 347 { 348 if (mapping == bit::mappingUPnP) 349 { 350 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"Starting UPnP mapping."))); 351 session_.stop_upnp(); 352 session_.stop_natpmp(); 353 354 signals.successful_listen.connect_once(bind(&libt::session::start_upnp, &session_)); 355 } 356 else 357 { 358 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"Starting NAT-PMP mapping."))); 359 session_.stop_upnp(); 360 session_.stop_natpmp(); 361 362 signals.successful_listen.connect_once(bind(&libt::session::start_natpmp, &session_)); 363 } 364 } 365 else 366 { 367 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"No mapping."))); 368 session_.stop_upnp(); 369 session_.stop_natpmp(); 370 } 371 } 372 373 void setTimeouts(int peers, int tracker) 374 { 375 libt::session_settings settings = session_.settings(); 376 settings.peer_connect_timeout = peers; 377 settings.tracker_completion_timeout = tracker; 378 379 session_.set_settings(settings); 380 381 event_log.post(shared_ptr<EventDetail>(new EventMsg( 382 wformat(L"Set Timeouts, peer %1%, tracker %2%") % peers % tracker))); 383 } 384 385 void setSessionLimits(int maxConn, int maxUpload) 386 { 387 session_.set_max_uploads(maxUpload); 388 session_.set_max_connections(maxConn); 389 390 event_log.post(shared_ptr<EventDetail>(new EventMsg( 391 wformat(L"Set connections totals %1% and uploads %2%.") 392 % maxConn % maxUpload))); 393 } 394 395 void setSessionSpeed(float download, float upload) 396 { 397 int down = (download > 0) ? static_cast<int>(download*1024) : -1; 398 session_.set_download_rate_limit(down); 399 int up = (upload > 0) ? static_cast<int>(upload*1024) : -1; 400 session_.set_upload_rate_limit(up); 401 402 event_log.post(shared_ptr<EventDetail>(new EventMsg( 403 wformat(L"Set session rates at download %1% and upload %2%.") 404 % session_.download_rate_limit() % session_.upload_rate_limit()))); 405 } 406 407 bool ensureIpFilterOn(progress_callback fn) 408 { 409 try 410 { 411 412 if (!ip_filter_loaded_) 413 { 414 ip_filter_load(fn); 415 ip_filter_loaded_ = true; 416 } 417 418 if (!ip_filter_on_) 419 { 420 session_.set_ip_filter(ip_filter_); 421 ip_filter_on_ = true; 422 ip_filter_count(); 423 } 424 425 } 426 catch(const std::exception& e) 427 { 428 hal::event_log.post(boost::shared_ptr<hal::EventDetail>( 429 new hal::EventStdException(event_logger::critical, e, L"ensureIpFilterOn"))); 430 431 ensureIpFilterOff(); 432 } 433 434 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"IP filters on."))); 435 436 return false; 437 } 438 439 void ensureIpFilterOff() 440 { 441 session_.set_ip_filter(libt::ip_filter()); 442 ip_filter_on_ = false; 443 444 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"IP filters off."))); 445 } 446 447 #ifndef TORRENT_DISABLE_ENCRYPTION 448 void ensurePeOn(int enc_level, int in_enc_policy, int out_enc_policy, bool prefer_rc4) 449 { 450 libt::pe_settings pe; 451 452 switch (enc_level) 453 { 454 case 0: 455 pe.allowed_enc_level = libt::pe_settings::plaintext; 456 break; 457 case 1: 458 pe.allowed_enc_level = libt::pe_settings::rc4; 459 break; 460 case 2: 461 pe.allowed_enc_level = libt::pe_settings::both; 462 break; 463 default: 464 pe.allowed_enc_level = libt::pe_settings::both; 465 466 hal::event_log.post(shared_ptr<hal::EventDetail>( 467 new hal::EventGeneral(hal::event_logger::warning, hal::event_logger::unclassified, 468 (wformat(hal::app().res_wstr(HAL_INCORRECT_ENCODING_LEVEL)) % enc_level).str()))); 469 } 470 471 switch (in_enc_policy) 472 { 473 case 0: 474 pe.in_enc_policy = libt::pe_settings::forced; 475 break; 476 case 1: 477 pe.in_enc_policy = libt::pe_settings::enabled; 478 break; 479 case 2: 480 pe.in_enc_policy = libt::pe_settings::disabled; 481 break; 482 default: 483 pe.in_enc_policy = libt::pe_settings::enabled; 484 485 hal::event_log.post(shared_ptr<hal::EventDetail>( 486 new hal::EventGeneral(hal::event_logger::warning, hal::event_logger::unclassified, 487 (wformat(hal::app().res_wstr(HAL_INCORRECT_CONNECT_POLICY)) % in_enc_policy).str()))); 488 } 489 490 switch (out_enc_policy) 491 { 492 case 0: 493 pe.out_enc_policy = libt::pe_settings::forced; 494 break; 495 case 1: 496 pe.out_enc_policy = libt::pe_settings::enabled; 497 break; 498 case 2: 499 pe.out_enc_policy = libt::pe_settings::disabled; 500 break; 501 default: 502 pe.out_enc_policy = libt::pe_settings::enabled; 503 504 hal::event_log.post(shared_ptr<hal::EventDetail>( 505 new hal::EventGeneral(hal::event_logger::warning, hal::event_logger::unclassified, 506 (wformat(hal::app().res_wstr(HAL_INCORRECT_CONNECT_POLICY)) % in_enc_policy).str()))); 507 } 508 509 pe.prefer_rc4 = prefer_rc4; 510 511 try 512 { 513 514 session_.set_pe_settings(pe); 515 516 } 517 catch(const std::exception& e) 518 { 519 hal::event_log.post(boost::shared_ptr<hal::EventDetail>( 520 new hal::EventStdException(event_logger::critical, e, L"ensurePeOn"))); 521 522 ensurePeOff(); 523 } 524 525 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"Protocol encryption on."))); 526 } 527 528 void ensurePeOff() 529 { 530 libt::pe_settings pe; 531 pe.out_enc_policy = libt::pe_settings::disabled; 532 pe.in_enc_policy = libt::pe_settings::disabled; 533 534 pe.allowed_enc_level = libt::pe_settings::both; 535 pe.prefer_rc4 = true; 536 537 session_.set_pe_settings(pe); 538 539 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"Protocol encryption off."))); 540 } 541 #endif 542 543 void ip_v4_filter_block(asio::ip::address_v4 first, asio::ip::address_v4 last) 544 { 545 ip_filter_.add_rule(first, last, libt::ip_filter::blocked); 546 ip_filter_count(); 547 ip_filter_changed_ = true; 548 } 549 550 void ip_v6_filter_block(asio::ip::address_v6 first, asio::ip::address_v6 last) 551 { 552 ip_filter_.add_rule(first, last, libt::ip_filter::blocked); 553 ip_filter_count(); 554 ip_filter_changed_ = true; 555 } 556 557 size_t ip_filter_size() 558 { 559 return ip_filter_count_; 560 } 561 562 void clearIpFilter() 563 { 564 ip_filter_ = libt::ip_filter(); 565 session_.set_ip_filter(libt::ip_filter()); 566 ip_filter_changed_ = true; 567 ip_filter_count(); 568 } 569 570 bool ip_filter_import_dat(boost::filesystem::path file, progress_callback fn, bool octalFix); 571 143 572 struct 144 573 { … … 148 577 signals; 149 578 150 void stopAlertHandler() 151 { 152 mutex_t::scoped_lock l(mutex_); 153 154 keepChecking_ = false; 155 } 156 157 void alertHandler() 158 { 159 mutex_t::scoped_lock l(mutex_); 160 161 if (keepChecking_) 162 { 163 164 std::auto_ptr<libt::alert> p_alert = theSession.pop_alert(); 165 166 class AlertHandler 167 { 168 public: 169 AlertHandler(bit_impl& bit_impl) : 170 bit_impl_(bit_impl) 171 {} 172 173 void operator()(libt::torrent_finished_alert const& a) const 174 { 175 event_log.post(shared_ptr<EventDetail>( 176 new EventMsg((wformat(hal::app().res_wstr(LBT_EVENT_TORRENT_FINISHED)) 177 % get(a.handle)->name()), 178 event_logger::info, a.timestamp()))); 179 180 get(a.handle)->finished(); 181 } 182 183 void operator()(libt::torrent_paused_alert const& a) const 184 { 185 event_log.post(shared_ptr<EventDetail>( 186 new EventMsg((wformat(hal::app().res_wstr(LBT_EVENT_TORRENT_PAUSED)) 187 % get(a.handle)->name()), 188 event_logger::info, a.timestamp()))); 189 190 get(a.handle)->signals().torrent_paused(); 191 } 192 193 void operator()(libt::peer_error_alert const& a) const 194 { 195 event_log.post(shared_ptr<EventDetail>( 196 new EventGeneral(lbtAlertToHalEvent(a.severity()), a.timestamp(), 197 wformat(hal::app().res_wstr(HAL_PEER_ALERT)) 198 % hal::from_utf8_safe(a.msg()) 199 % hal::from_utf8_safe(a.ip.address().to_string())) 200 ) ); 201 } 202 203 void operator()(libt::peer_ban_alert const& a) const 204 { 205 event_log.post(shared_ptr<EventDetail>( 206 new EventGeneral(lbtAlertToHalEvent(a.severity()), a.timestamp(), 207 wformat(hal::app().res_wstr(HAL_PEER_BAN_ALERT)) 208 % get(a.handle)->name() 209 % hal::from_utf8_safe(a.ip.address().to_string())) 210 ) ); 211 } 212 213 void operator()(libt::hash_failed_alert const& a) const 214 { 215 event_log.post(shared_ptr<EventDetail>( 216 new EventGeneral(lbtAlertToHalEvent(a.severity()), a.timestamp(), 217 wformat(hal::app().res_wstr(HAL_HASH_FAIL_ALERT)) 218 % get(a.handle)->name() 219 % a.piece_index) 220 ) ); 221 } 222 223 void operator()(libt::url_seed_alert const& a) const 224 { 225 event_log.post(shared_ptr<EventDetail>( 226 new EventGeneral(lbtAlertToHalEvent(a.severity()), a.timestamp(), 227 wformat(hal::app().res_wstr(HAL_URL_SEED_ALERT)) 228 % get(a.handle)->name() 229 % hal::from_utf8_safe(a.url) 230 % hal::from_utf8_safe(a.msg())) 231 ) ); 232 } 233 234 void operator()(libt::tracker_warning_alert const& a) const 235 { 236 event_log.post(shared_ptr<EventDetail>( 237 new EventGeneral(lbtAlertToHalEvent(a.severity()), a.timestamp(), 238 wformat(hal::app().res_wstr(HAL_TRACKER_WARNING_ALERT)) 239 % get(a.handle)->name() 240 % hal::from_utf8_safe(a.msg())) 241 ) ); 242 } 243 244 void operator()(libt::tracker_announce_alert const& a) const 245 { 246 event_log.post(shared_ptr<EventDetail>( 247 new EventMsg((wformat(hal::app().res_wstr(HAL_TRACKER_ANNOUNCE_ALERT)) 248 % get(a.handle)->name()), 249 event_logger::info, a.timestamp()))); 250 } 251 252 void operator()(libt::tracker_alert const& a) const 253 { 254 event_log.post(shared_ptr<EventDetail>( 255 new EventGeneral(lbtAlertToHalEvent(a.severity()), a.timestamp(), 256 wformat(hal::app().res_wstr(HAL_TRACKER_ALERT)) 257 % get(a.handle)->name() 258 % hal::from_utf8_safe(a.msg()) 259 % a.times_in_row 260 % a.status_code) 261 ) ); 262 } 263 264 void operator()(libt::tracker_reply_alert const& a) const 265 { 266 event_log.post(shared_ptr<EventDetail>( 267 new EventGeneral(lbtAlertToHalEvent(a.severity()), a.timestamp(), 268 wformat(hal::app().res_wstr(HAL_TRACKER_REPLY_ALERT)) 269 % get(a.handle)->name() 270 % hal::from_utf8_safe(a.msg()) 271 % a.num_peers) 272 ) ); 273 } 274 275 void operator()(libt::fastresume_rejected_alert const& a) const 276 { 277 event_log.post(shared_ptr<EventDetail>( 278 new EventGeneral(lbtAlertToHalEvent(a.severity()), a.timestamp(), 279 wformat(hal::app().res_wstr(HAL_FAST_RESUME_ALERT)) 280 % get(a.handle)->name() 281 % hal::from_utf8_safe(a.msg())) 282 ) ); 283 } 284 285 void operator()(libt::piece_finished_alert const& a) const 286 { 287 event_log.post(shared_ptr<EventDetail>( 288 new EventGeneral(event_logger::debug, a.timestamp(), 289 wformat(hal::app().res_wstr(HAL_PIECE_FINISHED_ALERT)) 290 % get(a.handle)->name() 291 % a.piece_index) 292 ) ); 293 } 294 295 void operator()(libt::block_finished_alert const& a) const 296 { 297 event_log.post(shared_ptr<EventDetail>( 298 new EventGeneral(event_logger::debug, a.timestamp(), 299 wformat(hal::app().res_wstr(HAL_BLOCK_FINISHED_ALERT)) 300 % get(a.handle)->name() 301 % a.block_index 302 % a.piece_index) 303 ) ); 304 } 305 306 void operator()(libt::block_downloading_alert const& a) const 307 { 308 event_log.post(shared_ptr<EventDetail>( 309 new EventGeneral(event_logger::debug, a.timestamp(), 310 wformat(hal::app().res_wstr(HAL_BLOCK_DOWNLOADING_ALERT)) 311 % get(a.handle)->name() 312 % a.block_index 313 % a.piece_index) 314 ) ); 315 } 316 317 void operator()(libt::listen_failed_alert const& a) const 318 { 319 if (a.endpoint.address().is_v6()) 320 { 321 event_log.post(shared_ptr<EventDetail>( 322 new EventGeneral(event_logger::info, a.timestamp(), 323 hal::app().res_wstr(HAL_LISTEN_V6_FAILED_ALERT)) 324 ) ); 325 } 326 else 327 { 328 event_log.post(shared_ptr<EventDetail>( 329 new EventGeneral(event_logger::info, a.timestamp(), 330 wformat(hal::app().res_wstr(HAL_LISTEN_FAILED_ALERT)) 331 % hal::from_utf8_safe(a.msg())) 332 ) ); 333 } 334 } 335 336 void operator()(libt::listen_succeeded_alert const& a) const 337 { 338 event_log.post(shared_ptr<EventDetail>( 339 new EventGeneral(event_logger::info, a.timestamp(), 340 wformat(hal::app().res_wstr(HAL_LISTEN_SUCCEEDED_ALERT)) 341 % hal::from_utf8_safe(a.msg())) 342 ) ); 343 344 bit_impl_.signals.successful_listen(); 345 } 346 347 void operator()(libt::peer_blocked_alert const& a) const 348 { 349 event_log.post(shared_ptr<EventDetail>( 350 new EventGeneral(event_logger::debug, a.timestamp(), 351 wformat(hal::app().res_wstr(HAL_IPFILTER_ALERT)) 352 % hal::from_utf8_safe(a.ip.to_string()) 353 % hal::from_utf8_safe(a.msg())) 354 ) ); 355 } 356 357 void operator()(libt::alert const& a) const 358 { 359 event_log.post(shared_ptr<EventDetail>( 360 new EventLibtorrent(lbtAlertToHalEvent(a.severity()), 361 a.timestamp(), event_logger::unclassified, hal::from_utf8_safe(a.msg())))); 362 } 363 364 private: 365 bit_impl& bit_impl_; 366 367 torrent_internal_ptr get(libt::torrent_handle h) const 368 { 369 return bit_impl_.theTorrents.get(from_utf8_safe(h.get_torrent_info().name())); 370 } 371 372 } handler(*this); 373 374 while (p_alert.get()) 375 { 376 try 377 { 378 379 libt::handle_alert< 380 libt::torrent_finished_alert, 381 libt::torrent_paused_alert, 382 libt::peer_error_alert, 383 libt::peer_ban_alert, 384 libt::hash_failed_alert, 385 libt::url_seed_alert, 386 libt::tracker_alert, 387 libt::tracker_warning_alert, 388 libt::tracker_announce_alert, 389 libt::tracker_reply_alert, 390 libt::fastresume_rejected_alert, 391 libt::piece_finished_alert, 392 libt::block_finished_alert, 393 libt::block_downloading_alert, 394 libt::listen_failed_alert, 395 libt::listen_succeeded_alert, 396 libt::peer_blocked_alert, 397 libt::alert 398 >::handle_alert(p_alert, handler); 399 400 } 401 catch(libt::unhandled_alert&) 402 { 403 handler(*p_alert); 404 } 405 catch(std::exception& e) 406 { 407 // These are logged as debug because they are rarely important to act on! 408 event_log.post(shared_ptr<EventDetail>(\ 409 new EventStdException(event_logger::debug, e, L"alertHandler"))); 410 } 411 412 p_alert = theSession.pop_alert(); 413 } 414 415 timer_.expires_from_now(boost::posix_time::seconds(2)); 416 timer_.async_wait(bind(&bit_impl::alertHandler, this)); 417 } 418 } 579 void stopAlertHandler(); 580 void alertHandler(); 419 581 420 582 void saveTorrentData() … … 429 591 if (dht_on_) 430 592 { 431 halencode(workingDirectory/L"DHTState.bin", theSession.dht_state());593 halencode(workingDirectory/L"DHTState.bin", session_.dht_state()); 432 594 } 433 595 … … 449 611 private: 450 612 bit_impl() : 451 theSession(libt::fingerprint(HALITE_FINGERPRINT)),613 session_(libt::fingerprint(HALITE_FINGERPRINT)), 452 614 timer_(io_), 453 615 keepChecking_(false), … … 464 626 dht_on_(false) 465 627 { 466 torrent_internal::the_session_ = & theSession;628 torrent_internal::the_session_ = &session_; 467 629 torrent_internal::workingDir_ = workingDir(); 468 630 469 theSession.set_severity_level(libt::alert::debug);470 theSession.add_extension(&libt::create_metadata_plugin);471 theSession.add_extension(&libt::create_ut_pex_plugin);472 theSession.set_max_half_open_connections(10);631 session_.set_severity_level(libt::alert::debug); 632 session_.add_extension(&libt::create_metadata_plugin); 633 session_.add_extension(&libt::create_ut_pex_plugin); 634 session_.set_max_half_open_connections(10); 473 635 474 636 hal::event_log.post(shared_ptr<hal::EventDetail>( … … 522 684 } 523 685 524 { libt::session_settings settings = theSession.settings();686 { libt::session_settings settings = session_.settings(); 525 687 settings.user_agent = string("Halite ") + HALITE_VERSION_STRING; 526 theSession.set_settings(settings);688 session_.set_settings(settings); 527 689 } 528 690 … … 622 784 void removalThread(torrent_internal_ptr pIT, bool wipeFiles); 623 785 624 libt::session theSession;786 libt::session session_; 625 787 mutable mutex_t mutex_; 626 788 -
trunk/src/halTorrent.cpp
r479 r480 6 6 7 7 #include "stdAfx.hpp" 8 9 #define TORRENT_MAX_ALERT_TYPES 2010 8 11 9 #include <libtorrent/file.hpp> … … 34 32 #include "halTorrentInternal.hpp" 35 33 #include "halSession.hpp" 36 37 namespace boost { 38 namespace serialization { 39 40 #define IP_SAVE 3 41 42 template<class Archive, class address_type> 43 void save(Archive& ar, const address_type& ip, const unsigned int version) 44 { 45 #if IP_SAVE == 1 46 typename address_type::bytes_type bytes = ip.to_bytes(); 47 for (typename address_type::bytes_type::iterator i=bytes.begin(); i != bytes.end(); ++i) 48 ar & BOOST_SERIALIZATION_NVP(*i); 49 #elif IP_SAVE == 2 50 string dotted = ip.to_string(); 51 ar & BOOST_SERIALIZATION_NVP(dotted); 52 #elif IP_SAVE == 3 53 unsigned long addr = ip.to_ulong(); 54 ar & BOOST_SERIALIZATION_NVP(addr); 55 #endif 56 } 57 58 template<class Archive, class address_type> 59 void load(Archive& ar, address_type& ip, const unsigned int version) 60 { 61 #if IP_SAVE == 1 62 typename address_type::bytes_type bytes; 63 for (typename address_type::bytes_type::iterator i=bytes.begin(); i != bytes.end(); ++i) 64 ar & BOOST_SERIALIZATION_NVP(*i); 65 ip = address_type(bytes); 66 #elif IP_SAVE == 2 67 string dotted; 68 ar & BOOST_SERIALIZATION_NVP(dotted); 69 ip = address_type::from_string(dotted); 70 #elif IP_SAVE == 3 71 unsigned long addr; 72 ar & BOOST_SERIALIZATION_NVP(addr); 73 ip = address_type(addr); 74 #endif 75 } 76 77 template<class Archive, class String, class Traits> 78 void save(Archive& ar, const boost::filesystem::basic_path<String, Traits>& p, const unsigned int version) 79 { 80 String str = p.string(); 81 ar & BOOST_SERIALIZATION_NVP(str); 82 } 83 84 template<class Archive, class String, class Traits> 85 void load(Archive& ar, boost::filesystem::basic_path<String, Traits>& p, const unsigned int version) 86 { 87 String str; 88 ar & BOOST_SERIALIZATION_NVP(str); 89 90 p = str; 91 } 92 93 template<class Archive, class String, class Traits> 94 inline void serialize( 95 Archive & ar, 96 boost::filesystem::basic_path<String, Traits>& p, 97 const unsigned int file_version 98 ){ 99 split_free(ar, p, file_version); 100 } 101 102 template<class Archive, class address_type> 103 void serialize(Archive& ar, libtorrent::ip_range<address_type>& addr, const unsigned int version) 104 { 105 ar & BOOST_SERIALIZATION_NVP(addr.first); 106 ar & BOOST_SERIALIZATION_NVP(addr.last); 107 addr.flags = libtorrent::ip_filter::blocked; 108 } 109 110 template<class Archive> 111 void serialize(Archive& ar, hal::tracker_detail& tracker, const unsigned int version) 112 { 113 ar & BOOST_SERIALIZATION_NVP(tracker.url); 114 ar & BOOST_SERIALIZATION_NVP(tracker.tier); 115 } 116 117 } // namespace serialization 118 } // namespace boost 119 120 BOOST_SERIALIZATION_SPLIT_FREE(asio::ip::address_v4) 121 BOOST_SERIALIZATION_SPLIT_FREE(asio::ip::address_v6) 122 123 namespace libtorrent 124 { 125 template<class Addr> 126 bool operator==(const libtorrent::ip_range<Addr>& lhs, const int flags) 127 { 128 return (lhs.flags == flags); 129 } 130 131 std::ostream& operator<<(std::ostream& os, libtorrent::ip_range<asio::ip::address_v4>& ip) 132 { 133 os << ip.first.to_ulong(); 134 os << ip.last.to_ulong(); 135 136 return os; 137 } 138 139 } // namespace libtorrent 140 34 //#include "halSessionAlert.hpp" 141 35 142 36 namespace hal … … 267 161 bool bit::listenOn(std::pair<int, int> const& range) 268 162 { 269 try 270 { 271 272 if (!pimpl->theSession.is_listening()) 273 { 274 return pimpl->theSession.listen_on(range); 275 } 276 else 277 { 278 int port = pimpl->theSession.listen_port(); 279 280 if (port < range.first || port > range.second) 281 return pimpl->theSession.listen_on(range); 282 else 283 { 284 pimpl->signals.successful_listen(); 285 286 return true; 287 } 288 } 289 290 } 291 catch (const std::exception& e) 292 { 293 event_log.post(shared_ptr<EventDetail>( 294 new EventStdException(event_logger::fatal, e, L"From bit::listenOn."))); 295 296 return false; 297 } 298 catch(...) 299 { 300 return false; 301 } 163 return pimpl->listenOn(range); 302 164 } 303 165 304 166 int bit::isListeningOn() 305 167 { 306 if (!pimpl->theSession.is_listening()) 307 return -1; 308 else 309 return pimpl->theSession.listen_port(); 168 return pimpl->isListeningOn(); 310 169 } 311 170 312 171 void bit::stopListening() 313 172 { 314 ensureDhtOff(); 315 pimpl->theSession.listen_on(std::make_pair(0, 0)); 173 pimpl->stopListening(); 316 174 } 317 175 318 176 bool bit::ensureDhtOn() 319 177 { 320 if (!pimpl->dht_on_) 321 { 322 try 323 { 324 pimpl->theSession.start_dht(pimpl->dht_state_); 325 pimpl->dht_on_ = true; 326 } 327 catch(...) 328 {} 329 } 330 return pimpl->dht_on_; 178 return pimpl->ensureDhtOn(); 331 179 } 332 180 333 181 void bit::ensureDhtOff() 334 182 { 335 if (pimpl->dht_on_) 336 { 337 pimpl->theSession.stop_dht(); 338 pimpl->dht_on_ = false; 339 } 183 pimpl->ensureDhtOff(); 340 184 } 341 185 … … 343 187 int service_port, int max_fail_count) 344 188 { 345 libt::dht_settings settings; 346 settings.max_peers_reply = max_peers_reply; 347 settings.search_branching = search_branching; 348 settings.service_port = service_port; 349 settings.max_fail_count = max_fail_count; 350 351 if (pimpl->dht_settings_ != settings) 352 { 353 pimpl->dht_settings_ = settings; 354 pimpl->theSession.set_dht_settings(pimpl->dht_settings_); 355 } 189 pimpl->setDhtSettings(max_peers_reply, search_branching, service_port, max_fail_count); 356 190 } 357 191 358 192 void bit::setMapping(int mapping) 359 193 { 360 if (mapping != mappingNone) 361 { 362 if (mapping == mappingUPnP) 363 { 364 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"Starting UPnP mapping."))); 365 pimpl->theSession.stop_upnp(); 366 pimpl->theSession.stop_natpmp(); 367 368 pimpl->signals.successful_listen.connect_once(bind(&libt::session::start_upnp, &pimpl->theSession)); 369 } 370 else 371 { 372 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"Starting NAT-PMP mapping."))); 373 pimpl->theSession.stop_upnp(); 374 pimpl->theSession.stop_natpmp(); 375 376 pimpl->signals.successful_listen.connect_once(bind(&libt::session::start_natpmp, &pimpl->theSession)); 377 } 378 } 379 else 380 { 381 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"No mapping."))); 382 pimpl->theSession.stop_upnp(); 383 pimpl->theSession.stop_natpmp(); 384 } 194 pimpl->setMapping(mapping); 385 195 } 386 196 387 197 void bit::setTimeouts(int peers, int tracker) 388 198 { 389 libt::session_settings settings = pimpl->theSession.settings(); 390 settings.peer_connect_timeout = peers; 391 settings.tracker_completion_timeout = tracker; 392 393 pimpl->theSession.set_settings(settings); 394 395 event_log.post(shared_ptr<EventDetail>(new EventMsg( 396 wformat(L"Set Timeouts, peer %1%, tracker %2%") % peers % tracker))); 199 pimpl->setTimeouts(peers, tracker); 397 200 } 398 201 399 202 void bit::setSessionLimits(int maxConn, int maxUpload) 400 203 { 401 pimpl->theSession.set_max_uploads(maxUpload); 402 pimpl->theSession.set_max_connections(maxConn); 403 404 event_log.post(shared_ptr<EventDetail>(new EventMsg( 405 wformat(L"Set connections totals %1% and uploads %2%.") 406 % maxConn % maxUpload))); 204 pimpl->setSessionLimits(maxConn, maxUpload); 407 205 } 408 206 409 207 void bit::setSessionSpeed(float download, float upload) 410 208 { 411 int down = (download > 0) ? static_cast<int>(download*1024) : -1; 412 pimpl->theSession.set_download_rate_limit(down); 413 int up = (upload > 0) ? static_cast<int>(upload*1024) : -1; 414 pimpl->theSession.set_upload_rate_limit(up); 415 416 event_log.post(shared_ptr<EventDetail>(new EventMsg( 417 wformat(L"Set session rates at download %1% and upload %2%.") 418 % pimpl->theSession.download_rate_limit() % pimpl->theSession.upload_rate_limit()))); 419 } 420 421 void bit_impl::ip_filter_count() 422 { 423 libt::ip_filter::filter_tuple_t vectors = ip_filter_.export_filter(); 424 425 vectors.get<0>().erase(std::remove(vectors.get<0>().begin(), vectors.get<0>().end(), 0), 426 vectors.get<0>().end()); 427 vectors.get<1>().erase(std::remove(vectors.get<1>().begin(), vectors.get<1>().end(), 0), 428 vectors.get<1>().end()); 429 ip_filter_count_ = vectors.get<0>().size() + vectors.get<1>().size(); 430 } 431 432 void bit_impl::ip_filter_load(progress_callback fn) 433 { 434 fs::ifstream ifs(workingDirectory/L"IPFilter.bin", std::ios::binary); 435 if (ifs) 436 { 437 size_t v4_size; 438 ifs >> v4_size; 439 440 size_t total = v4_size/100; 441 size_t previous = 0; 442 443 for(unsigned i=0; i<v4_size; ++i) 444 { 445 if (i-previous > total) 446 { 447 previous = i; 448 449 if (fn) if (fn(size_t(i/total), hal::app().res_wstr(HAL_TORRENT_LOAD_FILTERS))) break; 450 } 451 452 read_range_to_filter<asio::ip::address_v4>(ifs, ip_filter_); 453 } 454 } 455 } 456 457 void bit_impl::ip_filter_import(std::vector<libt::ip_range<asio::ip::address_v4> >& v4, 458 std::vector<libt::ip_range<asio::ip::address_v6> >& v6) 459 { 460 for(std::vector<libt::ip_range<asio::ip::address_v4> >::iterator i=v4.begin(); 461 i != v4.end(); ++i) 462 { 463 ip_filter_.add_rule(i->first, i->last, libt::ip_filter::blocked); 464 } 465 /* for(std::vector<libt::ip_range<asio::ip::address_v6> >::iterator i=v6.begin(); 466 i != v6.end(); ++i) 467 { 468 ip_filter_.add_rule(i->first, i->last, libt::ip_filter::blocked); 469 } 470 */ 471 /* Note here we do not set ip_filter_changed_ */ 209 pimpl->setSessionSpeed(download, upload); 472 210 } 473 211 474 212 bool bit::ensureIpFilterOn(progress_callback fn) 475 213 { 476 try 477 { 478 479 if (!pimpl->ip_filter_loaded_) 480 { 481 pimpl->ip_filter_load(fn); 482 pimpl->ip_filter_loaded_ = true; 483 } 484 485 if (!pimpl->ip_filter_on_) 486 { 487 pimpl->theSession.set_ip_filter(pimpl->ip_filter_); 488 pimpl->ip_filter_on_ = true; 489 pimpl->ip_filter_count(); 490 } 491 492 } 493 catch(const std::exception& e) 494 { 495 hal::event_log.post(boost::shared_ptr<hal::EventDetail>( 496 new hal::EventStdException(event_logger::critical, e, L"ensureIpFilterOn"))); 497 498 ensureIpFilterOff(); 499 } 500 501 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"IP filters on."))); 502 503 return false; 214 return pimpl->ensureIpFilterOn(fn); 504 215 } 505 216 506 217 void bit::ensureIpFilterOff() 507 218 { 508 pimpl->theSession.set_ip_filter(libt::ip_filter()); 509 pimpl->ip_filter_on_ = false; 510 511 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"IP filters off."))); 219 pimpl->ensureIpFilterOff(); 512 220 } 513 221 514 222 #ifndef TORRENT_DISABLE_ENCRYPTION 223 515 224 void bit::ensurePeOn(int enc_level, int in_enc_policy, int out_enc_policy, bool prefer_rc4) 516 225 { 517 libt::pe_settings pe; 518 519 switch (enc_level) 520 { 521 case 0: 522 pe.allowed_enc_level = libt::pe_settings::plaintext; 523 break; 524 case 1: 525 pe.allowed_enc_level = libt::pe_settings::rc4; 526 break; 527 case 2: 528 pe.allowed_enc_level = libt::pe_settings::both; 529 break; 530 default: 531 pe.allowed_enc_level = libt::pe_settings::both; 532 533 hal::event_log.post(shared_ptr<hal::EventDetail>( 534 new hal::EventGeneral(hal::event_logger::warning, hal::event_logger::unclassified, 535 (wformat(hal::app().res_wstr(HAL_INCORRECT_ENCODING_LEVEL)) % enc_level).str()))); 536 } 537 538 switch (in_enc_policy) 539 { 540 case 0: 541 pe.in_enc_policy = libt::pe_settings::forced; 542 break; 543 case 1: 544 pe.in_enc_policy = libt::pe_settings::enabled; 545 break; 546 case 2: 547 pe.in_enc_policy = libt::pe_settings::disabled; 548 break; 549 default: 550 pe.in_enc_policy = libt::pe_settings::enabled; 551 552 hal::event_log.post(shared_ptr<hal::EventDetail>( 553 new hal::EventGeneral(hal::event_logger::warning, hal::event_logger::unclassified, 554 (wformat(hal::app().res_wstr(HAL_INCORRECT_CONNECT_POLICY)) % in_enc_policy).str()))); 555 } 556 557 switch (out_enc_policy) 558 { 559 case 0: 560 pe.out_enc_policy = libt::pe_settings::forced; 561 break; 562 case 1: 563 pe.out_enc_policy = libt::pe_settings::enabled; 564 break; 565 case 2: 566 pe.out_enc_policy = libt::pe_settings::disabled; 567 break; 568 default: 569 pe.out_enc_policy = libt::pe_settings::enabled; 570 571 hal::event_log.post(shared_ptr<hal::EventDetail>( 572 new hal::EventGeneral(hal::event_logger::warning, hal::event_logger::unclassified, 573 (wformat(hal::app().res_wstr(HAL_INCORRECT_CONNECT_POLICY)) % in_enc_policy).str()))); 574 } 575 576 pe.prefer_rc4 = prefer_rc4; 577 578 try 579 { 580 581 pimpl->theSession.set_pe_settings(pe); 582 583 } 584 catch(const std::exception& e) 585 { 586 hal::event_log.post(boost::shared_ptr<hal::EventDetail>( 587 new hal::EventStdException(event_logger::critical, e, L"ensurePeOn"))); 588 589 ensurePeOff(); 590 } 591 592 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"Protocol encryption on."))); 226 pimpl->ensurePeOn(enc_level, in_enc_policy, out_enc_policy, prefer_rc4); 593 227 } 594 228 595 229 void bit::ensurePeOff() 596 230 { 597 libt::pe_settings pe; 598 pe.out_enc_policy = libt::pe_settings::disabled; 599 pe.in_enc_policy = libt::pe_settings::disabled; 600 601 pe.allowed_enc_level = libt::pe_settings::both; 602 pe.prefer_rc4 = true; 603 604 pimpl->theSession.set_pe_settings(pe); 605 606 event_log.post(shared_ptr<EventDetail>(new EventMsg(L"Protocol encryption off."))); 231 pimpl->ensurePeOff(); 607 232 } 608 233 #endif … … 617 242 void bit::ip_v6_filter_block(asio::ip::address_v6 first, asio::ip::address_v6 last) 618 243 { 619 pimpl->ip_filter_.add_rule(first, last, libt::ip_filter::blocked); 620 pimpl->ip_filter_count(); 621 pimpl->ip_filter_changed_ = true; 244 pimpl->ip_v6_filter_block(first, last); 622 245 } 623 246 624 247 size_t bit::ip_filter_size() 625 248 { 626 return pimpl->ip_filter_ count_;249 return pimpl->ip_filter_size(); 627 250 } 628 251 629 252 void bit::clearIpFilter() 630 253 { 631 pimpl->ip_filter_ = libt::ip_filter(); 632 pimpl->theSession.set_ip_filter(libt::ip_filter()); 633 pimpl->ip_filter_changed_ = true; 634 pimpl->ip_filter_count(); 254 pimpl->clearIpFilter(); 635 255 } 636 256 637 257 bool bit::ip_filter_import_dat(boost::filesystem::path file, progress_callback fn, bool octalFix) 638 258 { 639 try 640 { 641 642 fs::ifstream ifs(file); 643 if (ifs) 644 { 645 boost::uintmax_t total = fs::file_size(file)/100; 646 boost::uintmax_t progress = 0; 647 boost::uintmax_t previous = 0; 648 649 boost::regex reg("\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s*-\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s*.*"); 650 boost::regex ip_reg("0*(\\d*)\\.0*(\\d*)\\.0*(\\d*)\\.0*(\\d*)"); 651 boost::smatch m; 652 653 string ip_address_line; 654 while (!std::getline(ifs, ip_address_line).eof()) 655 { 656 progress += (ip_address_line.length() + 2); 657 if (progress-previous > total) 658 { 659 previous = progress; 660 if (fn) 661 { 662 if (fn(size_t(progress/total), hal::app().res_wstr(HAL_TORRENT_IMPORT_FILTERS))) 663 break; 664 } 665 } 666 667 if (boost::regex_match(ip_address_line, m, reg)) 668 { 669 string first = m[1]; 670 string last = m[2]; 671 672 if (octalFix) 673 { 674 if (boost::regex_match(first, m, ip_reg)) 675 { 676 first = ((m.length(1) != 0) ? m[1] : string("0")) + "." + 677 ((m.length(2) != 0) ? m[2] : string("0")) + "." + 678 ((m.length(3) != 0) ? m[3] : string("0")) + "." + 679 ((m.length(4) != 0) ? m[4] : string("0")); 680 } 681 if (boost::regex_match(last, m, ip_reg)) 682 { 683 last = ((m.length(1) != 0) ? m[1] : string("0")) + "." + 684 ((m.length(2) != 0) ? m[2] : string("0")) + "." + 685 ((m.length(3) != 0) ? m[3] : string("0")) + "." + 686 ((m.length(4) != 0) ? m[4] : string("0")); 687 } 688 } 689 690 try 691 { 692 pimpl->ip_filter_.add_rule(asio::ip::address_v4::from_string(first), 693 asio::ip::address_v4::from_string(last), libt::ip_filter::blocked); 694 } 695 catch(...) 696 { 697 hal::event_log.post(shared_ptr<hal::EventDetail>( 698 new hal::EventDebug(hal::event_logger::info, 699 from_utf8((format("Invalid IP range: %1%-%2%.") % first % last).str())))); 700 } 701 } 702 } 703 } 704 705 pimpl->ip_filter_changed_ = true; 706 pimpl->ip_filter_count(); 707 708 } 709 catch(const std::exception& e) 710 { 711 event_log.post(shared_ptr<EventDetail>( 712 new EventStdException(event_logger::critical, e, L"ip_filter_import_dat"))); 713 } 714 715 return false; 259 return pimpl->ip_filter_import_dat(file, fn, octalFix); 716 260 } 717 261 … … 720 264 SessionDetail details; 721 265 722 details.port = pimpl-> theSession.is_listening() ? pimpl->theSession.listen_port() : -1;723 724 libt::session_status status = pimpl-> theSession.status();266 details.port = pimpl->session_.is_listening() ? pimpl->session_.listen_port() : -1; 267 268 libt::session_status status = pimpl->session_.status(); 725 269 726 270 details.speed = std::pair<double, double>(status.download_rate, status.upload_rate); … … 738 282 void bit::setSessionHalfOpenLimit(int halfConn) 739 283 { 740 pimpl-> theSession.set_max_half_open_connections(halfConn);284 pimpl->session_.set_max_half_open_connections(halfConn); 741 285 742 286 event_log.post(shared_ptr<EventDetail>(new EventMsg( 743 wformat(L"Set half-open connections limit to %1%.") % pimpl-> theSession.max_half_open_connections())));287 wformat(L"Set half-open connections limit to %1%.") % pimpl->session_.max_half_open_connections()))); 744 288 } 745 289 … … 1176 720 if (!wipeFiles) 1177 721 { 1178 theSession.remove_torrent(pIT->handle());722 session_.remove_torrent(pIT->handle()); 1179 723 } 1180 724 else … … 1182 726 if (pIT->in_session()) 1183 727 { 1184 theSession.remove_torrent(pIT->handle(), libt::session::delete_files);728 session_.remove_torrent(pIT->handle(), libt::session::delete_files); 1185 729 } 1186 730 else -
trunk/src/halTorrentInternal.hpp
r479 r480 114 114 namespace libt = libtorrent; 115 115 116 inline 116 117 libt::entry haldecode(const wpath &file) 117 118 { … … 125 126 } 126 127 128 inline 127 129 bool halencode(const wpath &file, const libt::entry &e) 128 130 { … … 146 148 } 147 149 150 inline 148 151 std::pair<std::string, std::string> extract_names(const wpath &file) 149 152 { … … 558 561 #undef TORRENT_INTERNALS_DEFAULTS 559 562 560 TorrentDetail_ptr getTorrentDetail_ptr(); 561 void setTransferSpeed(float down, float up); 562 void setConnectionLimit(int maxConn, int maxUpload); 563 std::pair<float, float> getTransferSpeed(); 564 std::pair<int, int> getConnectionLimit(); 563 TorrentDetail_ptr getTorrentDetail_ptr() 564 { 565 mutex_t::scoped_lock l(mutex_); 566 567 try 568 { 569 570 if (in_session()) 571 { 572 statusMemory_ = handle_.status(); 573 progress_ = statusMemory_.progress; 574 } 575 else 576 { 577 // Wipe these cause they don't make sense for a non-active torrent. 578 579 statusMemory_.download_payload_rate = 0; 580 statusMemory_.upload_payload_rate = 0; 581 statusMemory_.next_announce = boost::posix_time::seconds(0); 582 } 583 584 wstring state; 585 586 switch (state_) 587 { 588 case TorrentDetail::torrent_paused: 589 state = app().res_wstr(HAL_TORRENT_PAUSED); 590 break; 591 592 case TorrentDetail::torrent_pausing: 593 state = app().res_wstr(HAL_TORRENT_PAUSING); 594 break; 595 596 case TorrentDetail::torrent_stopped: 597 state = app().res_wstr(HAL_TORRENT_STOPPED); 598 break; 599 600 case TorrentDetail::torrent_stopping: 601 state = app().res_wstr(HAL_TORRENT_STOPPING); 602 break; 603 604 default: 605 switch (statusMemory_.state) 606 { 607 case libt::torrent_status::queued_for_checking: 608 state = app().res_wstr(HAL_TORRENT_QUEUED_CHECKING); 609 break; 610 case libt::torrent_status::checking_files: 611 state = app().res_wstr(HAL_TORRENT_CHECKING_FILES); 612 break; 613 case libt::torrent_status::connecting_to_tracker: 614 state = app().res_wstr(HAL_TORRENT_CONNECTING); 615 break; 616 case libt::torrent_status::downloading_metadata: 617 state = app().res_wstr(HAL_TORRENT_METADATA); 618 break; 619 case libt::torrent_status::downloading: 620 state = app().res_wstr(HAL_TORRENT_DOWNLOADING); 621 break; 622 case libt::torrent_status::finished: 623 state = app().res_wstr(HAL_TORRENT_FINISHED); 624 break; 625 case libt::torrent_status::seeding: 626 state = app().res_wstr(HAL_TORRENT_SEEDING); 627 break; 628 case libt::torrent_status::allocating: 629 state = app().res_wstr(HAL_TORRENT_ALLOCATING); 630 break; 631 } 632 } 633 634 pt::time_duration td(pt::pos_infin); 635 636 if (statusMemory_.download_payload_rate != 0) 637 { 638 td = boost::posix_time::seconds( 639 long(float(statusMemory_.total_wanted-statusMemory_.total_wanted_done) / statusMemory_.download_payload_rate)); 640 } 641 642 totalUploaded_ += (statusMemory_.total_payload_upload - totalBase_); 643 totalBase_ = statusMemory_.total_payload_upload; 644 645 uploaded_.update(statusMemory_.total_upload); 646 payloadUploaded_.update(statusMemory_.total_payload_upload); 647 downloaded_.update(statusMemory_.total_download); 648 payloadDownloaded_.update(statusMemory_.total_payload_download); 649 650 if (is_active()) 651 { 652 activeDuration_.update(); 653 654 if (libt::torrent_status::seeding == statusMemory_.state) 655 seedingDuration_.update(); 656 } 657 658 boost::tuple<size_t, size_t, size_t, size_t> connections = updatePeers(); 659 660 return TorrentDetail_ptr(new TorrentDetail(name_, filename_, saveDirectory().string(), state, hal::from_utf8(statusMemory_.current_tracker), 661 std::pair<float, float>(statusMemory_.download_payload_rate, statusMemory_.upload_payload_rate), 662 progress_, statusMemory_.distributed_copies, statusMemory_.total_wanted_done, statusMemory_.total_wanted, uploaded_, payloadUploaded_, 663 downloaded_, payloadDownloaded_, connections, ratio_, td, statusMemory_.next_announce, activeDuration_, seedingDuration_, startTime_, finishTime_)); 664 665 } 666 catch (const libt::invalid_handle&) 667 { 668 event_log.post(shared_ptr<EventDetail>( 669 new EventInvalidTorrent(event_logger::critical, event_logger::invalidTorrent, to_utf8(name_), "getTorrentDetail_ptr"))); 670 } 671 catch (const std::exception& e) 672 { 673 event_log.post(shared_ptr<EventDetail>( 674 new EventTorrentException(event_logger::critical, event_logger::torrentException, e.what(), to_utf8(name_), "getTorrentDetail_ptr"))); 675 } 676 677 return TorrentDetail_ptr(new TorrentDetail(name_, filename_, saveDirectory().string(), app().res_wstr(HAL_TORRENT_STOPPED), app().res_wstr(HAL_NA))); 678 } 679 680 void setTransferSpeed(float down, float up) 681 { 682 mutex_t::scoped_lock l(mutex_); 683 684 transferLimit_ = std::make_pair(down, up); 685 686 applyTransferSpeed(); 687 } 688 689 void setConnectionLimit(int maxConn, int maxUpload) 690 { 691 mutex_t::scoped_lock l(mutex_); 692 693 connections_ = maxConn; 694 uploads_ = maxUpload; 695 696 applyConnectionLimit(); 697 } 698 699 std::pair<float, float> getTransferSpeed() 700 { 701 return transferLimit_; 702 } 703 704 std::pair<int, int> getConnectionLimit() 705 { 706 return std::make_pair(connections_, uploads_); 707 } 565 708 566 709 const wstring& name() const { return name_; } … … 1537 1680 }; 1538 1681 1539 void torrent_internal::setConnectionLimit(int maxConn, int maxUpload)1540 {1541 mutex_t::scoped_lock l(mutex_);1542 1543 connections_ = maxConn;1544 uploads_ = maxUpload;1545 1546 applyConnectionLimit();1547 }1548 1549 std::pair<int, int> torrent_internal::getConnectionLimit()1550 {1551 return std::make_pair(connections_, uploads_);1552 }1553 1554 void torrent_internal::setTransferSpeed(float download, float upload)1555 {1556 mutex_t::scoped_lock l(mutex_);1557 1558 transferLimit_ = std::make_pair(download, upload);1559 1560 applyTransferSpeed();1561 }1562 1563 std::pair<float, float> torrent_internal::getTransferSpeed()1564 {1565 return transferLimit_;1566 }1567 1568 TorrentDetail_ptr torrent_internal::getTorrentDetail_ptr()1569 {1570 mutex_t::scoped_lock l(mutex_);1571 1572 try1573 {1574 1575 if (in_session())1576 {1577 statusMemory_ = handle_.status();1578 progress_ = statusMemory_.progress;1579 }1580 else1581 {1582 // Wipe these cause they don't make sense for a non-active torrent.1583 1584 statusMemory_.download_payload_rate = 0;1585 statusMemory_.upload_payload_rate = 0;1586 statusMemory_.next_announce = boost::posix_time::seconds(0);1587 }1588 1589 wstring state;1590 1591 switch (state_)1592 {1593 case TorrentDetail::torrent_paused:1594 state = app().res_wstr(HAL_TORRENT_PAUSED);1595 break;1596 1597 case TorrentDetail::torrent_pausing:1598 state = app().res_wstr(HAL_TORRENT_PAUSING);1599 break;1600 1601 case TorrentDetail::torrent_stopped:1602 state = app().res_wstr(HAL_TORRENT_STOPPED);1603 break;1604 1605 case TorrentDetail::torrent_stopping:1606 state = app().res_wstr(HAL_TORRENT_STOPPING);1607 break;1608 1609 default:1610 switch (statusMemory_.state)1611 {1612 case libt::torrent_status::queued_for_checking:1613 state = app().res_wstr(HAL_TORRENT_QUEUED_CHECKING);1614 break;1615 case libt::torrent_status::checking_files:1616 state = app().res_wstr(HAL_TORRENT_CHECKING_FILES);1617 break;1618 case libt::torrent_status::connecting_to_tracker:1619 state = app().res_wstr(HAL_TORRENT_CONNECTING);1620 break;1621 case libt::torrent_status::downloading_metadata:1622 state = app().res_wstr(HAL_TORRENT_METADATA);1623 break;1624 case libt::torrent_status::downloading:1625 state = app().res_wstr(HAL_TORRENT_DOWNLOADING);1626 break;1627 case libt::torrent_status::finished:1628 state = app().res_wstr(HAL_TORRENT_FINISHED);1629 break;1630 case libt::torrent_status::seeding:1631 state = app().res_wstr(HAL_TORRENT_SEEDING);1632 break;1633 case libt::torrent_status::allocating:1634 state = app().res_wstr(HAL_TORRENT_ALLOCATING);1635 break;1636 }1637 }1638 1639 pt::time_duration td(pt::pos_infin);1640 1641 if (statusMemory_.download_payload_rate != 0)1642 {1643 td = boost::posix_time::seconds(1644 long(float(statusMemory_.total_wanted-statusMemory_.total_wanted_done) / statusMemory_.download_payload_rate));1645 }1646 1647 totalUploaded_ += (statusMemory_.total_payload_upload - totalBase_);1648 totalBase_ = statusMemory_.total_payload_upload;1649 1650 uploaded_.update(statusMemory_.total_upload);1651 payloadUploaded_.update(statusMemory_.total_payload_upload);1652 downloaded_.update(statusMemory_.total_download);1653 payloadDownloaded_.update(statusMemory_.total_payload_download);1654 1655 if (is_active())1656 {1657 activeDuration_.update();1658 1659 if (libt::torrent_status::seeding == statusMemory_.state)1660 seedingDuration_.update();1661 }1662 1663 boost::tuple<size_t, size_t, size_t, size_t> connections = updatePeers();1664 1665 return TorrentDetail_ptr(new TorrentDetail(name_, filename_, saveDirectory().string(), state, hal::from_utf8(statusMemory_.current_tracker),1666 std::pair<float, float>(statusMemory_.download_payload_rate, statusMemory_.upload_payload_rate),1667 progress_, statusMemory_.distributed_copies, statusMemory_.total_wanted_done, statusMemory_.total_wanted, uploaded_, payloadUploaded_,1668 downloaded_, payloadDownloaded_, connections, ratio_, td, statusMemory_.next_announce, activeDuration_, seedingDuration_, startTime_, finishTime_));1669 1670 }1671 catch (const libt::invalid_handle&)1672 {1673 event_log.post(shared_ptr<EventDetail>(1674 new EventInvalidTorrent(event_logger::critical, event_logger::invalidTorrent, to_utf8(name_), "getTorrentDetail_ptr")));1675 }1676 catch (const std::exception& e)1677 {1678 event_log.post(shared_ptr<EventDetail>(1679 new EventTorrentException(event_logger::critical, event_logger::torrentException, e.what(), to_utf8(name_), "getTorrentDetail_ptr")));1680 }1681 1682 return TorrentDetail_ptr(new TorrentDetail(name_, filename_, saveDirectory().string(), app().res_wstr(HAL_TORRENT_STOPPED), app().res_wstr(HAL_NA)));1683 }1684 1685 1682 } // namespace hal 1686 1683
Note: See TracChangeset
for help on using the changeset viewer.