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 // if the torrent already exists, this will throw duplicate_torrent
248 torrent_handle
session::add_torrent(
249 torrent_info
const& ti
250 , fs::path
const& save_path
251 , entry
const& resume_data
252 , storage_mode_t storage_mode
254 , storage_constructor_type sc
)
256 boost::intrusive_ptr
<torrent_info
> tip(new torrent_info(ti
));
257 add_torrent_params
p(sc
);
259 p
.save_path
= save_path
;
260 std::vector
<char> buf
;
261 if (resume_data
.type() != entry::undefined_t
)
263 bencode(std::back_inserter(buf
), resume_data
);
264 p
.resume_data
= &buf
;
266 p
.storage_mode
= storage_mode
;
268 return m_impl
->add_torrent(p
);
271 torrent_handle
session::add_torrent(
272 boost::intrusive_ptr
<torrent_info
> ti
273 , fs::path
const& save_path
274 , entry
const& resume_data
275 , storage_mode_t storage_mode
277 , storage_constructor_type sc
280 add_torrent_params
p(sc
);
282 p
.save_path
= save_path
;
283 std::vector
<char> buf
;
284 if (resume_data
.type() != entry::undefined_t
)
286 bencode(std::back_inserter(buf
), resume_data
);
287 p
.resume_data
= &buf
;
289 p
.storage_mode
= storage_mode
;
291 p
.userdata
= userdata
;
292 return m_impl
->add_torrent(p
);
295 torrent_handle
session::add_torrent(
296 char const* tracker_url
297 , sha1_hash
const& info_hash
299 , fs::path
const& save_path
301 , storage_mode_t storage_mode
303 , storage_constructor_type sc
306 add_torrent_params
p(sc
);
307 p
.tracker_url
= tracker_url
;
308 p
.info_hash
= info_hash
;
309 p
.save_path
= save_path
;
311 p
.userdata
= userdata
;
312 return m_impl
->add_torrent(p
);
315 void session::remove_torrent(const torrent_handle
& h
, int options
)
317 m_impl
->remove_torrent(h
, options
);
320 bool session::listen_on(
321 std::pair
<int, int> const& port_range
322 , const char* net_interface
)
324 return m_impl
->listen_on(port_range
, net_interface
);
327 unsigned short session::listen_port() const
329 return m_impl
->listen_port();
332 session_status
session::status() const
334 return m_impl
->status();
337 void session::pause() { m_impl
->pause(); }
338 void session::resume() { m_impl
->resume(); }
339 bool session::is_paused() const { return m_impl
->is_paused(); }
341 void session::get_cache_info(sha1_hash
const& ih
342 , std::vector
<cached_piece_info
>& ret
) const
344 m_impl
->m_disk_thread
.get_cache_info(ih
, ret
);
347 cache_status
session::get_cache_status() const
349 return m_impl
->m_disk_thread
.status();
352 #ifndef TORRENT_DISABLE_DHT
354 void session::start_dht(entry
const& startup_state
)
356 m_impl
->start_dht(startup_state
);
359 void session::stop_dht()
364 void session::set_dht_settings(dht_settings
const& settings
)
366 m_impl
->set_dht_settings(settings
);
369 entry
session::dht_state() const
371 return m_impl
->dht_state();
374 void session::add_dht_node(std::pair
<std::string
, int> const& node
)
376 m_impl
->add_dht_node(node
);
379 void session::add_dht_router(std::pair
<std::string
, int> const& node
)
381 m_impl
->add_dht_router(node
);
386 #ifndef TORRENT_DISABLE_ENCRYPTION
387 void session::set_pe_settings(pe_settings
const& settings
)
389 m_impl
->set_pe_settings(settings
);
392 pe_settings
const& session::get_pe_settings() const
394 return m_impl
->get_pe_settings();
398 bool session::is_listening() const
400 return m_impl
->is_listening();
403 void session::set_settings(session_settings
const& s
)
405 m_impl
->set_settings(s
);
408 session_settings
const& session::settings()
410 return m_impl
->settings();
413 void session::set_peer_proxy(proxy_settings
const& s
)
415 m_impl
->set_peer_proxy(s
);
418 void session::set_web_seed_proxy(proxy_settings
const& s
)
420 m_impl
->set_web_seed_proxy(s
);
423 void session::set_tracker_proxy(proxy_settings
const& s
)
425 m_impl
->set_tracker_proxy(s
);
428 proxy_settings
const& session::peer_proxy() const
430 return m_impl
->peer_proxy();
433 proxy_settings
const& session::web_seed_proxy() const
435 return m_impl
->web_seed_proxy();
438 proxy_settings
const& session::tracker_proxy() const
440 return m_impl
->tracker_proxy();
444 #ifndef TORRENT_DISABLE_DHT
445 void session::set_dht_proxy(proxy_settings
const& s
)
447 m_impl
->set_dht_proxy(s
);
450 proxy_settings
const& session::dht_proxy() const
452 return m_impl
->dht_proxy();
456 void session::set_max_uploads(int limit
)
458 m_impl
->set_max_uploads(limit
);
461 void session::set_max_connections(int limit
)
463 m_impl
->set_max_connections(limit
);
466 int session::max_half_open_connections() const
468 return m_impl
->max_half_open_connections();
471 void session::set_max_half_open_connections(int limit
)
473 m_impl
->set_max_half_open_connections(limit
);
476 int session::upload_rate_limit() const
478 return m_impl
->upload_rate_limit();
481 int session::download_rate_limit() const
483 return m_impl
->download_rate_limit();
486 void session::set_upload_rate_limit(int bytes_per_second
)
488 m_impl
->set_upload_rate_limit(bytes_per_second
);
491 void session::set_download_rate_limit(int bytes_per_second
)
493 m_impl
->set_download_rate_limit(bytes_per_second
);
496 int session::num_uploads() const
498 return m_impl
->num_uploads();
501 int session::num_connections() const
503 return m_impl
->num_connections();
506 std::auto_ptr
<alert
> session::pop_alert()
508 return m_impl
->pop_alert();
511 alert
const* session::wait_for_alert(time_duration max_wait
)
513 return m_impl
->wait_for_alert(max_wait
);
516 void session::set_alert_mask(int m
)
518 m_impl
->set_alert_mask(m
);
521 void session::set_severity_level(alert::severity_t s
)
526 case alert::debug
: m
= alert::all_categories
; break;
527 case alert::info
: m
= alert::all_categories
& ~(alert::debug_notification
528 | alert::progress_notification
); break;
529 case alert::warning
: m
= alert::all_categories
& ~(alert::debug_notification
530 | alert::status_notification
| alert::progress_notification
); break;
531 case alert::critical
: m
= alert::error_notification
| alert::storage_notification
; break;
532 case alert::fatal
: m
= alert::error_notification
; break;
536 m_impl
->set_alert_mask(m
);
539 void session::start_lsd()
544 natpmp
* session::start_natpmp()
546 return m_impl
->start_natpmp();
549 upnp
* session::start_upnp()
551 return m_impl
->start_upnp();
554 void session::stop_lsd()
559 void session::stop_natpmp()
561 m_impl
->stop_natpmp();
564 void session::stop_upnp()
569 connection_queue
& session::get_connection_queue()
571 return m_impl
->m_half_open
;