3 Copyright (c) 2006, Arvid Norberg, Magnus Jonsson
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #include "libtorrent/pch.hpp"
46 #pragma warning(push, 1)
49 #include <boost/lexical_cast.hpp>
50 #include <boost/filesystem/convenience.hpp>
51 #include <boost/filesystem/exception.hpp>
52 #include <boost/limits.hpp>
53 #include <boost/bind.hpp>
59 #include "libtorrent/peer_id.hpp"
60 #include "libtorrent/torrent_info.hpp"
61 #include "libtorrent/tracker_manager.hpp"
62 #include "libtorrent/bencode.hpp"
63 #include "libtorrent/hasher.hpp"
64 #include "libtorrent/entry.hpp"
65 #include "libtorrent/session.hpp"
66 #include "libtorrent/fingerprint.hpp"
67 #include "libtorrent/entry.hpp"
68 #include "libtorrent/alert_types.hpp"
69 #include "libtorrent/invariant_check.hpp"
70 #include "libtorrent/file.hpp"
71 #include "libtorrent/bt_peer_connection.hpp"
72 #include "libtorrent/ip_filter.hpp"
73 #include "libtorrent/socket.hpp"
74 #include "libtorrent/aux_/session_impl.hpp"
75 #include "libtorrent/kademlia/dht_tracker.hpp"
77 using boost::shared_ptr
;
78 using boost::weak_ptr
;
81 using libtorrent::aux::session_impl
;
83 #ifdef TORRENT_MEMDEBUG
84 void start_malloc_debug();
85 void stop_malloc_debug();
91 std::string
log_time()
93 static const ptime start
= time_now();
95 std::sprintf(ret
, "%d", total_milliseconds(time_now() - start
));
101 filesystem_init::filesystem_init()
103 #if BOOST_VERSION < 103400
104 using namespace boost::filesystem
;
105 if (path::default_name_check_writable())
106 path::default_name_check(no_check
);
112 fingerprint
const& id
113 , std::pair
<int, int> listen_port_range
114 , char const* listen_interface
115 #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
119 : m_impl(new session_impl(listen_port_range
, id
, listen_interface
120 #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
125 #ifdef TORRENT_MEMDEBUG
126 start_malloc_debug();
128 // turn off the filename checking in boost.filesystem
129 TORRENT_ASSERT(listen_port_range
.first
> 0);
130 TORRENT_ASSERT(listen_port_range
.first
< listen_port_range
.second
);
132 // this test was added after it came to my attention
133 // that devstudios managed c++ failed to generate
134 // correct code for boost.function
135 boost::function0
<void> test
= boost::ref(*m_impl
);
136 TORRENT_ASSERT(!test
.empty());
140 session::session(fingerprint
const& id
141 #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
145 #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
146 : m_impl(new session_impl(std::make_pair(0, 0), id
, "0.0.0.0", logpath
))
148 : m_impl(new session_impl(std::make_pair(0, 0), id
, "0.0.0.0"))
151 #ifdef TORRENT_MEMDEBUG
152 start_malloc_debug();
155 boost::function0
<void> test
= boost::ref(*m_impl
);
156 TORRENT_ASSERT(!test
.empty());
162 #ifdef TORRENT_MEMDEBUG
165 TORRENT_ASSERT(m_impl
);
166 // if there is at least one destruction-proxy
167 // abort the session and let the destructor
168 // of the proxy to syncronize
169 if (!m_impl
.unique())
173 void session::add_extension(boost::function
<boost::shared_ptr
<torrent_plugin
>(torrent
*, void*)> ext
)
175 m_impl
->add_extension(ext
);
178 #ifndef TORRENT_DISABLE_GEO_IP
179 bool session::load_asnum_db(char const* file
)
181 return m_impl
->load_asnum_db(file
);
184 bool session::load_country_db(char const* file
)
186 return m_impl
->load_country_db(file
);
189 int session::as_for_ip(address
const& addr
)
191 aux::session_impl::mutex_t::scoped_lock
l(m_impl
->m_mutex
);
192 return m_impl
->as_for_ip(addr
);
197 void session::load_state(entry
const& ses_state
)
199 m_impl
->load_state(ses_state
);
202 entry
session::state() const
204 return m_impl
->state();
207 void session::set_ip_filter(ip_filter
const& f
)
209 m_impl
->set_ip_filter(f
);
212 void session::set_port_filter(port_filter
const& f
)
214 m_impl
->set_port_filter(f
);
217 void session::set_peer_id(peer_id
const& id
)
219 m_impl
->set_peer_id(id
);
222 peer_id
session::id() const
224 return m_impl
->get_peer_id();
227 void session::set_key(int key
)
229 m_impl
->set_key(key
);
232 std::vector
<torrent_handle
> session::get_torrents() const
234 return m_impl
->get_torrents();
237 torrent_handle
session::find_torrent(sha1_hash
const& info_hash
) const
239 return m_impl
->find_torrent_handle(info_hash
);
242 torrent_handle
session::add_torrent(add_torrent_params
const& params
)
244 return m_impl
->add_torrent(params
);
247 #ifndef TORRENT_NO_DEPRECATE
248 // if the torrent already exists, this will throw duplicate_torrent
249 torrent_handle
session::add_torrent(
250 torrent_info
const& ti
251 , fs::path
const& save_path
252 , entry
const& resume_data
253 , storage_mode_t storage_mode
255 , storage_constructor_type sc
)
257 boost::intrusive_ptr
<torrent_info
> tip(new torrent_info(ti
));
258 add_torrent_params
p(sc
);
260 p
.save_path
= save_path
;
261 std::vector
<char> buf
;
262 if (resume_data
.type() != entry::undefined_t
)
264 bencode(std::back_inserter(buf
), resume_data
);
265 p
.resume_data
= &buf
;
267 p
.storage_mode
= storage_mode
;
269 return m_impl
->add_torrent(p
);
272 torrent_handle
session::add_torrent(
273 boost::intrusive_ptr
<torrent_info
> ti
274 , fs::path
const& save_path
275 , entry
const& resume_data
276 , storage_mode_t storage_mode
278 , storage_constructor_type sc
281 add_torrent_params
p(sc
);
283 p
.save_path
= save_path
;
284 std::vector
<char> buf
;
285 if (resume_data
.type() != entry::undefined_t
)
287 bencode(std::back_inserter(buf
), resume_data
);
288 p
.resume_data
= &buf
;
290 p
.storage_mode
= storage_mode
;
292 p
.userdata
= userdata
;
293 return m_impl
->add_torrent(p
);
296 torrent_handle
session::add_torrent(
297 char const* tracker_url
298 , sha1_hash
const& info_hash
300 , fs::path
const& save_path
302 , storage_mode_t storage_mode
304 , storage_constructor_type sc
307 add_torrent_params
p(sc
);
308 p
.tracker_url
= tracker_url
;
309 p
.info_hash
= info_hash
;
310 p
.save_path
= save_path
;
312 p
.userdata
= userdata
;
313 return m_impl
->add_torrent(p
);
317 void session::remove_torrent(const torrent_handle
& h
, int options
)
319 m_impl
->remove_torrent(h
, options
);
322 bool session::listen_on(
323 std::pair
<int, int> const& port_range
324 , const char* net_interface
)
326 return m_impl
->listen_on(port_range
, net_interface
);
329 unsigned short session::listen_port() const
331 return m_impl
->listen_port();
334 session_status
session::status() const
336 return m_impl
->status();
339 void session::pause() { m_impl
->pause(); }
340 void session::resume() { m_impl
->resume(); }
341 bool session::is_paused() const { return m_impl
->is_paused(); }
343 void session::get_cache_info(sha1_hash
const& ih
344 , std::vector
<cached_piece_info
>& ret
) const
346 m_impl
->m_disk_thread
.get_cache_info(ih
, ret
);
349 cache_status
session::get_cache_status() const
351 return m_impl
->m_disk_thread
.status();
354 #ifndef TORRENT_DISABLE_DHT
356 void session::start_dht(entry
const& startup_state
)
358 m_impl
->start_dht(startup_state
);
361 void session::stop_dht()
366 void session::set_dht_settings(dht_settings
const& settings
)
368 m_impl
->set_dht_settings(settings
);
371 entry
session::dht_state() const
373 return m_impl
->dht_state();
376 void session::add_dht_node(std::pair
<std::string
, int> const& node
)
378 m_impl
->add_dht_node(node
);
381 void session::add_dht_router(std::pair
<std::string
, int> const& node
)
383 m_impl
->add_dht_router(node
);
388 #ifndef TORRENT_DISABLE_ENCRYPTION
389 void session::set_pe_settings(pe_settings
const& settings
)
391 m_impl
->set_pe_settings(settings
);
394 pe_settings
const& session::get_pe_settings() const
396 return m_impl
->get_pe_settings();
400 bool session::is_listening() const
402 return m_impl
->is_listening();
405 void session::set_settings(session_settings
const& s
)
407 m_impl
->set_settings(s
);
410 session_settings
const& session::settings()
412 return m_impl
->settings();
415 void session::set_peer_proxy(proxy_settings
const& s
)
417 m_impl
->set_peer_proxy(s
);
420 void session::set_web_seed_proxy(proxy_settings
const& s
)
422 m_impl
->set_web_seed_proxy(s
);
425 void session::set_tracker_proxy(proxy_settings
const& s
)
427 m_impl
->set_tracker_proxy(s
);
430 proxy_settings
const& session::peer_proxy() const
432 return m_impl
->peer_proxy();
435 proxy_settings
const& session::web_seed_proxy() const
437 return m_impl
->web_seed_proxy();
440 proxy_settings
const& session::tracker_proxy() const
442 return m_impl
->tracker_proxy();
446 #ifndef TORRENT_DISABLE_DHT
447 void session::set_dht_proxy(proxy_settings
const& s
)
449 m_impl
->set_dht_proxy(s
);
452 proxy_settings
const& session::dht_proxy() const
454 return m_impl
->dht_proxy();
458 void session::set_max_uploads(int limit
)
460 m_impl
->set_max_uploads(limit
);
463 void session::set_max_connections(int limit
)
465 m_impl
->set_max_connections(limit
);
468 int session::max_half_open_connections() const
470 return m_impl
->max_half_open_connections();
473 void session::set_max_half_open_connections(int limit
)
475 m_impl
->set_max_half_open_connections(limit
);
478 int session::upload_rate_limit() const
480 return m_impl
->upload_rate_limit();
483 int session::download_rate_limit() const
485 return m_impl
->download_rate_limit();
488 void session::set_upload_rate_limit(int bytes_per_second
)
490 m_impl
->set_upload_rate_limit(bytes_per_second
);
493 void session::set_download_rate_limit(int bytes_per_second
)
495 m_impl
->set_download_rate_limit(bytes_per_second
);
498 int session::num_uploads() const
500 return m_impl
->num_uploads();
503 int session::num_connections() const
505 return m_impl
->num_connections();
508 std::auto_ptr
<alert
> session::pop_alert()
510 return m_impl
->pop_alert();
513 alert
const* session::wait_for_alert(time_duration max_wait
)
515 return m_impl
->wait_for_alert(max_wait
);
518 void session::set_alert_mask(int m
)
520 m_impl
->set_alert_mask(m
);
523 #ifndef TORRENT_NO_DEPRECATE
524 void session::set_severity_level(alert::severity_t s
)
529 case alert::debug
: m
= alert::all_categories
; break;
530 case alert::info
: m
= alert::all_categories
& ~(alert::debug_notification
531 | alert::progress_notification
); break;
532 case alert::warning
: m
= alert::all_categories
& ~(alert::debug_notification
533 | alert::status_notification
| alert::progress_notification
); break;
534 case alert::critical
: m
= alert::error_notification
| alert::storage_notification
; break;
535 case alert::fatal
: m
= alert::error_notification
; break;
539 m_impl
->set_alert_mask(m
);
543 void session::start_lsd()
548 natpmp
* session::start_natpmp()
550 return m_impl
->start_natpmp();
553 upnp
* session::start_upnp()
555 return m_impl
->start_upnp();
558 void session::stop_lsd()
563 void session::stop_natpmp()
565 m_impl
->stop_natpmp();
568 void session::stop_upnp()
573 connection_queue
& session::get_connection_queue()
575 return m_impl
->m_half_open
;