merged RC_1_1
This commit is contained in:
commit
0b173c6651
|
@ -91,6 +91,9 @@ script:
|
|||
|
||||
- cd ../examples
|
||||
- bjam --hash -j3 warnings-as-errors=on variant=$variant $toolset link=shared
|
||||
- if [[ lang == "cpp11" ]]; then
|
||||
bjam --hash -j3 warnings-as-errors=on variant=$variant $toolset link=shared bt-get bt-get2;
|
||||
fi
|
||||
- cd ..
|
||||
|
||||
# build libtorrent separately and install it in a temporary (well known) dir
|
||||
|
|
|
@ -118,6 +118,9 @@ build_script:
|
|||
- if not defined x64 (
|
||||
cd %ROOT_DIRECTORY%\examples
|
||||
& b2.exe --hash -j2 %compiler% variant=%variant% linkflags=%linkflags% include=%include% link=shared
|
||||
& if %compiler% == msvc-14.0 ( b2.exe --hash -j2 %compiler% variant=%variant% linkflags=%linkflags% include=%include% link=shared bt-get bt-get2 )
|
||||
& cd %ROOT_DIRECTORY%\examples
|
||||
& b2.exe --hash -j2 %compiler% variant=%variant% linkflags=%linkflags% include=%include% link=shared
|
||||
& cd %ROOT_DIRECTORY%\bindings\python
|
||||
& b2.exe --hash -j2 %compiler% stage_module install-dependencies=on variant=%variant% libtorrent-link=shared linkflags=%linkflags% include=%include%
|
||||
& python test.py
|
||||
|
|
|
@ -149,6 +149,7 @@ def is_visible(desc):
|
|||
return True
|
||||
|
||||
def highlight_signature(s):
|
||||
s = s.replace('TORRENT_OVERRIDE', 'override').replace('TORRENT_FINAL', 'final')
|
||||
name = s.split('(', 1)
|
||||
name2 = name[0].split(' ')
|
||||
if len(name2[-1]) == 0: return s
|
||||
|
@ -273,7 +274,8 @@ def parse_class(lno, lines, filename):
|
|||
state = 'private'
|
||||
class_type = 'class'
|
||||
|
||||
name = decl.split(':')[0].replace('class ', '').replace('struct ', '').replace('TORRENT_FINAL', '').strip()
|
||||
decl = decl.replace('TORRENT_FINAL', 'final')
|
||||
name = decl.split(':')[0].replace('class ', '').replace('struct ', '').replace('final', '').strip()
|
||||
|
||||
|
||||
while lno < len(lines):
|
||||
|
|
|
@ -70,46 +70,165 @@ completes downloading, we can poll the session for alerts periodically and print
|
|||
them out, as well as listening for the torrent_finished_alert_, which is posted
|
||||
when a torrent completes.
|
||||
|
||||
.. include:: ../examples/bt-get.cpp
|
||||
:code: c++
|
||||
:tab-width: 2
|
||||
:start-after: */
|
||||
|
||||
alert masks
|
||||
-----------
|
||||
|
||||
The output from this program will be quite verbose, which is probably a good
|
||||
starting point to get some understanding of what's going on. Alerts are
|
||||
categorized into alert categories. Each category can be enabled and disabled
|
||||
independently via the *alert mask*.
|
||||
|
||||
The alert mask is a configuration option offered by libtorrent. There are many
|
||||
configuration options, see settings_pack_. The alert_mask_ setting is an integer
|
||||
of the `category flags`_ ORed together.
|
||||
|
||||
For instance, to only see the most pertinent alerts, the session can be
|
||||
constructed like this:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
#include <iostream>
|
||||
lt::settings_pack pack;
|
||||
pack.set_int(lt::settings_pack::alert_mask
|
||||
, lt::alert::error_notification
|
||||
| lt::alert::storage_notification
|
||||
| lt::alert::status_notification);
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/add_torrent_params.hpp>
|
||||
#include <libtorrent/torrent_handle.hpp>
|
||||
#include <libtorrent/alert_types.hpp>
|
||||
lt::session ses(pack);
|
||||
|
||||
namespace lt = libtorrent;
|
||||
int main(int argc, char const* argv[])
|
||||
Configuration options can be updated after the session is started by calling
|
||||
`apply_settings()`_. Some settings are best set before starting the session
|
||||
though, like listen_interfaces_, to avoid race conditions. If you start the
|
||||
session with the default settings and then immediately change them, there will
|
||||
still be a window where the default settings apply.
|
||||
|
||||
Changing the settings may trigger listen sockets to close and re-open and
|
||||
NAT-PMP, UPnP updates to be sent. For this reason, it's typically a good idea
|
||||
to batch settings updates into a single call.
|
||||
|
||||
session destruction
|
||||
-------------------
|
||||
|
||||
The session destructor is blocking by default. When shutting down, trackers
|
||||
will need to be contacted to stop torrents and other outstanding operations
|
||||
need to be cancelled. Shutting down can sometimes take several seconds,
|
||||
primarily because of trackers that are unresponsive (and time out) and also
|
||||
DNS servers that are unresponsive. DNS lookups are especially difficult to
|
||||
abort when stalled.
|
||||
|
||||
In order to be able to start destruction an wait for it asynchronously, one
|
||||
can call `session::abort()`_.
|
||||
|
||||
This call returns a session_proxy_ object, which is a handle keeping the session
|
||||
state alive while destructing it. It deliberately does not provide any of the
|
||||
session operations, since it's shutting down.
|
||||
|
||||
After having a session_proxy_ object, the session destructor does not block.
|
||||
However, the session_proxy_ destructor *will*.
|
||||
|
||||
This can be used to shut down multiple sessions or other parts of the
|
||||
application in parallel.
|
||||
|
||||
asynchronous operations
|
||||
-----------------------
|
||||
|
||||
Essentially any call to a member function of session_ or torrent_handle_ that
|
||||
returns a value is a blocking synchronous call. Meaning it will post a message
|
||||
to the main libtorrent thread and wait for a response. Such calls may be
|
||||
expensive, and in applications where stalls should be avoided (such as user
|
||||
interface threads), blocking calls should be avoided.
|
||||
|
||||
In the example above, session::add_torrent() returns a torrent_handle_ and is
|
||||
thus blocking. For higher efficiency, `async_add_torrent()`_ will post a message
|
||||
to the main thread to add a torrent, and post the resulting torrent_handle_ back
|
||||
in an alert (add_torrent_alert_). This is especially useful when adding a lot
|
||||
of torrents in quick succession, as there's no stall in between calls.
|
||||
|
||||
In the example above, we don't actually use the torrent_handle_ for anything, so
|
||||
converting it to use `async_add_torrent()`_ is just a matter of replacing the
|
||||
`add_torrent()`_ call with `async_add_torrent()`_.
|
||||
|
||||
torrent_status_updates
|
||||
----------------------
|
||||
|
||||
To get updates to the status of torrents, call `post_torrent_updates()`_ on the
|
||||
session object. This will cause libtorrent to post a state_update_alert_
|
||||
containing torrent_status_ objects for all torrents whose status has *changed*
|
||||
since the last call to `post_torrent_updates()`_.
|
||||
|
||||
The state_update_alert_ looks something like this:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
struct state_update_alert : alert
|
||||
{
|
||||
if (argc != 2) {
|
||||
std::cerr << "usage: " << argv[0] << " <magnet-url>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
lt::session ses;
|
||||
virtual std::string message() const;
|
||||
std::vector<torrent_status> status;
|
||||
};
|
||||
|
||||
lt::add_torrent_params atp;
|
||||
atp.url = argv[1];
|
||||
atp.save_path = "."; // save in current dir
|
||||
lt::torrent_handle h = ses.add_torrent(atp);
|
||||
The ``status`` field only contains the torrent_status_ for torrents with
|
||||
updates since the last call. It may be empty if no torrent has updated its
|
||||
state. This feature is critical for scalability_.
|
||||
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
std::vector<lt::alert*> alerts;
|
||||
ses.pop_alerts(&alerts);
|
||||
See the torrent_status_ object for more information on what is in there.
|
||||
Perhaps the most interesting fields are ``total_payload_download``,
|
||||
``total_payload_upload``, ``num_peers`` and ``state``.
|
||||
|
||||
for (lt::alert const* a : alerts) {
|
||||
std::cout << a->message() << std::endl;
|
||||
if (lt::alert_cast<lt::torrent_finished_alert>(a)) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resuming torrents
|
||||
-----------------
|
||||
|
||||
*TODO* cover async_add_torrent()
|
||||
*TODO* cover post_torrent_updates()
|
||||
*TODO* cover save_resume_data()
|
||||
Since bittorrent downloads pieces of files in random order, it's not trivial to
|
||||
resume a partial download. When resuming a download, the bittorrent engine must
|
||||
restore the state of the downloading torrent, specifically, which parts of the
|
||||
file(s) are downloaded. There are two approaches to doing this:
|
||||
|
||||
1. read every piece of the downloaded files from disk and compare it against the
|
||||
expected hash.
|
||||
2. save to disk the state of which pieces (and partial pieces) are downloaded,
|
||||
and load it back in again when resuming.
|
||||
|
||||
If no resume data is provided with a torrent that's added, libtorrent will
|
||||
employ (1) by default.
|
||||
|
||||
To save resume data, call `save_resume_data()`_ on the torrent_handle_ object.
|
||||
This will ask libtorrent to generate the resume data and post it back in
|
||||
a save_resume_data_alert_. If generating the resume data fails for any reason,
|
||||
a save_resume_data_failed_alert_ is posted instead. Exactly one of those alerts
|
||||
will be posted for every call to `save_resume_data()`_.
|
||||
|
||||
The save_resume_data_alert_ looks something like this:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
struct save_resume_data_alert : torrent_alert
|
||||
{
|
||||
virtual std::string message() const;
|
||||
|
||||
// points to the resume data.
|
||||
boost::shared_ptr<entry> resume_data;
|
||||
};
|
||||
|
||||
``resume_data`` points to an entry_ object. This represents a node or a tree
|
||||
of nodes in a bencoded_ structure, which is the native encoding scheme in
|
||||
bittorrent. It can be encoded into a byte buffer or file using `bencode()`_.
|
||||
|
||||
example
|
||||
-------
|
||||
|
||||
Here's an updated version of the above example with the following updates:
|
||||
|
||||
1. not using blocking calls
|
||||
2. printing torrent status updates rather than the raw log
|
||||
3. saving and loading resume files
|
||||
|
||||
.. include:: ../examples/bt-get2.cpp
|
||||
:code: c++
|
||||
:tab-width: 2
|
||||
:start-after: */
|
||||
|
||||
.. _session: reference-Core.html#session
|
||||
.. _session_handle: reference-Core.html#session_handle
|
||||
|
@ -121,5 +240,22 @@ when a torrent completes.
|
|||
.. _`alert`: reference-Alerts.html#alert
|
||||
.. _`alert_cast<>`: reference-Alerts.html#alert_cast()
|
||||
.. _torrent_finished_alert: reference-Alerts.html#torrent-finished-alert
|
||||
|
||||
.. _listen_interfaces: reference-Settings.html#listen_interfaces
|
||||
.. _`add_torrent_alert`: reference-Alerts.html#add-torrent-alert
|
||||
.. _settings_pack: reference-Settings.html#settings_pack
|
||||
.. _alert_mask: reference-Settings.html#alert_mask
|
||||
.. _`category flags`: reference-Alerts.html#category_t
|
||||
.. _`apply_settings()`: reference-Core.html#apply_settings()
|
||||
.. _`session::abort()`: reference-Core.html#abort()
|
||||
.. _session_proxy: reference-Core.html#session_proxy
|
||||
.. _`post_torrent_updates()`: reference-Core.html#post_torrent_updates()
|
||||
.. _torrent_status: reference-Core.html#torrent_status
|
||||
.. _state_update_alert: reference-Alerts.html#state_update_alert
|
||||
.. _scalability: http://blog.libtorrent.org/2011/11/scalable-interfaces/
|
||||
.. _`save_resume_data()`: reference-Core.html#save_resume_data()
|
||||
.. _save_resume_data_alert: reference-Alerts.html#save_resume_data_alert
|
||||
.. _save_resume_data_failed_alert: reference-Alerts.html#save_resume_data_failed_alert
|
||||
.. _bencoded: https://en.wikipedia.org/wiki/Bencode
|
||||
.. _entry: reference-Bencoding.html#entry
|
||||
.. _`bencode()`: reference-Bencoding.html#bencode()
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ project client_test
|
|||
exe client_test : client_test.cpp print.cpp torrent_view.cpp session_view.cpp ;
|
||||
|
||||
exe simple_client : simple_client.cpp ;
|
||||
exe bt-get : bt-get.cpp ;
|
||||
exe bt-get2 : bt-get2.cpp ;
|
||||
exe stats_counters : stats_counters.cpp ;
|
||||
exe dump_torrent : dump_torrent.cpp ;
|
||||
exe make_torrent : make_torrent.cpp ;
|
||||
|
@ -28,6 +30,8 @@ exe upnp_test : upnp_test.cpp ;
|
|||
|
||||
explicit stage_client_test ;
|
||||
explicit stage_connection_tester ;
|
||||
explicit bt-get ;
|
||||
explicit bt-get2 ;
|
||||
|
||||
install stage_client_test : client_test : <location>. ;
|
||||
install stage_connection_tester : connection_tester : <location>. ;
|
||||
|
|
|
@ -5,6 +5,8 @@ example_programs = \
|
|||
make_torrent \
|
||||
simple_client \
|
||||
upnp_test \
|
||||
bt_get \
|
||||
bt_get2 \
|
||||
connection_tester
|
||||
|
||||
if ENABLE_EXAMPLES
|
||||
|
@ -15,25 +17,14 @@ EXTRA_PROGRAMS = $(example_programs)
|
|||
EXTRA_DIST = Jamfile CMakeLists.txt run_cmake.sh.in cmake/FindLibtorrentRasterbar.cmake
|
||||
|
||||
client_test_SOURCES = client_test.cpp print.cpp session_view.cpp torrent_view.cpp
|
||||
#client_test_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
||||
stats_counters_SOURCES = stats_counters.cpp
|
||||
#stats_counters_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
||||
bt_get_SOURCES = bt-get.cpp
|
||||
bt_get2_SOURCES = bt-get2.cpp
|
||||
dump_torrent_SOURCES = dump_torrent.cpp
|
||||
#dump_torrent_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
||||
make_torrent_SOURCES = make_torrent.cpp
|
||||
#make_torrent_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
||||
simple_client_SOURCES = simple_client.cpp
|
||||
#simple_client_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
||||
connection_tester_SOURCES = connection_tester.cpp
|
||||
#connection_tester_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
||||
upnp_test_SOURCES = upnp_test.cpp
|
||||
#upnp_test_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
||||
LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2016, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/add_torrent_params.hpp>
|
||||
#include <libtorrent/torrent_handle.hpp>
|
||||
#include <libtorrent/alert_types.hpp>
|
||||
|
||||
namespace lt = libtorrent;
|
||||
int main(int argc, char const* argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
std::cerr << "usage: " << argv[0] << " <magnet-url>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
lt::session ses;
|
||||
|
||||
lt::add_torrent_params atp;
|
||||
atp.url = argv[1];
|
||||
atp.save_path = "."; // save in current dir
|
||||
lt::torrent_handle h = ses.add_torrent(atp);
|
||||
|
||||
for (;;) {
|
||||
std::vector<lt::alert*> alerts;
|
||||
ses.pop_alerts(&alerts);
|
||||
|
||||
for (lt::alert const* a : alerts) {
|
||||
std::cout << a->message() << std::endl;
|
||||
// if we receive the finished alert or an error, we're done
|
||||
if (lt::alert_cast<lt::torrent_finished_alert>(a)) {
|
||||
goto done;
|
||||
}
|
||||
if (lt::alert_cast<lt::torrent_error_alert>(a)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
}
|
||||
done:
|
||||
std::cout << "done, shutting down" << std::endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2016, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
|
||||
#include <libtorrent/session.hpp>
|
||||
#include <libtorrent/add_torrent_params.hpp>
|
||||
#include <libtorrent/torrent_handle.hpp>
|
||||
#include <libtorrent/alert_types.hpp>
|
||||
#include <libtorrent/bencode.hpp>
|
||||
#include <libtorrent/torrent_status.hpp>
|
||||
|
||||
namespace lt = libtorrent;
|
||||
|
||||
// return the name of a torrent status enum
|
||||
char const* state(lt::torrent_status::state_t s)
|
||||
{
|
||||
switch(s)
|
||||
{
|
||||
case lt::torrent_status::checking_files: return "checking";
|
||||
case lt::torrent_status::downloading_metadata: return "dl metadata";
|
||||
case lt::torrent_status::downloading: return "downloading";
|
||||
case lt::torrent_status::finished: return "finished";
|
||||
case lt::torrent_status::seeding: return "seeding";
|
||||
case lt::torrent_status::allocating: return "allocating";
|
||||
case lt::torrent_status::checking_resume_data: return "checking resume";
|
||||
default: return "<>";
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char const* argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
std::cerr << "usage: " << argv[0] << " <magnet-url>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
lt::settings_pack pack;
|
||||
pack.set_int(lt::settings_pack::alert_mask
|
||||
, lt::alert::error_notification
|
||||
| lt::alert::storage_notification
|
||||
| lt::alert::status_notification);
|
||||
|
||||
lt::session ses(pack);
|
||||
|
||||
lt::add_torrent_params atp;
|
||||
|
||||
// load resume data from disk and pass it in as we add the magnet link
|
||||
std::ifstream ifs(".resume_file", std::ios_base::binary);
|
||||
ifs.unsetf(std::ios_base::skipws);
|
||||
atp.resume_data.assign(std::istream_iterator<char>(ifs)
|
||||
, std::istream_iterator<char>());
|
||||
atp.url = argv[1];
|
||||
atp.save_path = "."; // save in current dir
|
||||
ses.async_add_torrent(atp);
|
||||
|
||||
// this is the handle we'll set once we get the notification of it being
|
||||
// added
|
||||
lt::torrent_handle h;
|
||||
for (;;) {
|
||||
std::vector<lt::alert*> alerts;
|
||||
ses.pop_alerts(&alerts);
|
||||
|
||||
for (lt::alert const* a : alerts) {
|
||||
if (auto at = lt::alert_cast<lt::add_torrent_alert>(a)) {
|
||||
h = at->handle;
|
||||
}
|
||||
// if we receive the finished alert or an error, we're done
|
||||
if (lt::alert_cast<lt::torrent_finished_alert>(a)) {
|
||||
h.save_resume_data();
|
||||
goto done;
|
||||
}
|
||||
if (lt::alert_cast<lt::torrent_error_alert>(a)) {
|
||||
std::cout << a->message() << std::endl;
|
||||
goto done;
|
||||
}
|
||||
|
||||
// when resume data is ready, save it
|
||||
if (auto rd = lt::alert_cast<lt::save_resume_data_alert>(a)) {
|
||||
std::ofstream of(".resume_file", std::ios_base::binary);
|
||||
of.unsetf(std::ios_base::skipws);
|
||||
lt::bencode(std::ostream_iterator<char>(of)
|
||||
, *rd->resume_data);
|
||||
}
|
||||
|
||||
if (auto st = lt::alert_cast<lt::state_update_alert>(a)) {
|
||||
if (st->status.empty()) continue;
|
||||
|
||||
// we only have a single torrent, so we know which one
|
||||
// the status is for
|
||||
lt::torrent_status const& s = st->status[0];
|
||||
std::cout << "\r" << state(s.state) << " "
|
||||
<< (s.download_payload_rate / 1000) << " kB/s "
|
||||
<< (s.total_done / 1000) << " kB ("
|
||||
<< (s.progress_ppm / 10000) << "%) downloaded\x1b[K";
|
||||
std::cout.flush();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
|
||||
// ask the session to post a state_update_alert, to update our
|
||||
// state output for the torrent
|
||||
ses.post_torrent_updates();
|
||||
|
||||
// TODO: 3 call save_resume_data() once every 30 seconds or so
|
||||
}
|
||||
done:
|
||||
std::cout << "\ndone, shutting down" << std::endl;
|
||||
}
|
||||
|
|
@ -1366,7 +1366,7 @@ namespace libtorrent
|
|||
struct TORRENT_EXPORT portmap_alert TORRENT_FINAL : alert
|
||||
{
|
||||
// internal
|
||||
portmap_alert(aux::stack_allocator& alloc, int i, int port, int t);
|
||||
portmap_alert(aux::stack_allocator& alloc, int i, int port, int t, int protocol);
|
||||
|
||||
TORRENT_DEFINE_ALERT(portmap_alert, 51)
|
||||
|
||||
|
@ -1382,6 +1382,15 @@ namespace libtorrent
|
|||
|
||||
// 0 for NAT-PMP and 1 for UPnP.
|
||||
int map_type;
|
||||
|
||||
enum protocol_t
|
||||
{
|
||||
tcp,
|
||||
udp
|
||||
};
|
||||
|
||||
// the protocol this mapping was for. one of protocol_t enums
|
||||
int protocol;
|
||||
};
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
|
@ -1942,8 +1951,7 @@ namespace libtorrent
|
|||
|
||||
TORRENT_DEFINE_ALERT(dht_error_alert, 73)
|
||||
|
||||
static const int static_category = alert::error_notification
|
||||
| alert::dht_notification;
|
||||
static const int static_category = alert::error_notification | alert::dht_notification;
|
||||
virtual std::string message() const TORRENT_OVERRIDE;
|
||||
|
||||
// the error code
|
||||
|
|
|
@ -353,7 +353,7 @@ namespace libtorrent
|
|||
, std::vector<address> const& addresses, int port);
|
||||
#endif
|
||||
|
||||
void maybe_update_udp_mapping(int nat, int local_port, int external_port);
|
||||
void maybe_update_udp_mapping(int nat, bool ssl, int local_port, int external_port);
|
||||
|
||||
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
||||
torrent const* find_encrypted_torrent(
|
||||
|
@ -372,7 +372,7 @@ namespace libtorrent
|
|||
// called when a port mapping is successful, or a router returns
|
||||
// a failure to map a port
|
||||
void on_port_mapping(int mapping, address const& ip, int port
|
||||
, error_code const& ec, int nat_transport);
|
||||
, int protocol, error_code const& ec, int nat_transport);
|
||||
|
||||
bool is_aborted() const TORRENT_OVERRIDE { return m_abort; }
|
||||
bool is_paused() const TORRENT_OVERRIDE { return m_paused; }
|
||||
|
|
|
@ -43,7 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||
|
||||
#include <boost/function/function1.hpp>
|
||||
#include <boost/function/function4.hpp>
|
||||
#include <boost/function/function5.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
||||
|
@ -54,7 +54,7 @@ namespace libtorrent
|
|||
// int: port mapping index
|
||||
// int: external port
|
||||
// std::string: error message
|
||||
typedef boost::function<void(int, address, int, error_code const&)> portmap_callback_t;
|
||||
typedef boost::function<void(int, address, int, int, error_code const&)> portmap_callback_t;
|
||||
typedef boost::function<void(char const*)> log_callback_t;
|
||||
|
||||
class natpmp : public boost::enable_shared_from_this<natpmp>
|
||||
|
|
|
@ -662,9 +662,8 @@ namespace libtorrent
|
|||
only_if_modified = 4
|
||||
};
|
||||
|
||||
// ``save_resume_data()`` generates fast-resume data and returns it as an
|
||||
// entry. This entry is suitable for being bencoded. For more information
|
||||
// about how fast-resume works, see fast-resume_.
|
||||
// ``save_resume_data()`` asks libtorrent to generate fast-resume data for
|
||||
// this torrent.
|
||||
//
|
||||
// The ``flags`` argument is a bitmask of flags ORed together. see
|
||||
// save_resume_flags_t
|
||||
|
@ -676,9 +675,7 @@ namespace libtorrent
|
|||
// The fast resume data will be empty in the following cases:
|
||||
//
|
||||
// 1. The torrent handle is invalid.
|
||||
// 2. The torrent is checking (or is queued for checking) its storage, it
|
||||
// will obviously not be ready to write resume data.
|
||||
// 3. The torrent hasn't received valid metadata and was started without
|
||||
// 2. The torrent hasn't received valid metadata and was started without
|
||||
// metadata (see libtorrent's metadata-from-peers_ extension)
|
||||
//
|
||||
// Note that by the time you receive the fast resume data, it may already
|
||||
|
|
|
@ -78,14 +78,7 @@ namespace libtorrent
|
|||
, dont_queue = 4
|
||||
};
|
||||
|
||||
bool is_open() const
|
||||
{
|
||||
return m_ipv4_sock.is_open()
|
||||
#if TORRENT_USE_IPV6
|
||||
|| m_ipv6_sock.is_open()
|
||||
#endif
|
||||
;
|
||||
}
|
||||
bool is_open() const { return m_abort == false; }
|
||||
io_service& get_io_service() { return m_ipv4_sock.get_io_service(); }
|
||||
|
||||
void subscribe(udp_socket_observer* o);
|
||||
|
@ -143,7 +136,7 @@ namespace libtorrent
|
|||
|
||||
udp::endpoint proxy_addr() const { return m_proxy_addr; }
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
struct queued_packet
|
||||
{
|
||||
|
@ -169,12 +162,12 @@ namespace libtorrent
|
|||
;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// non-copyable
|
||||
udp_socket(udp_socket const&);
|
||||
udp_socket& operator=(udp_socket const&);
|
||||
|
||||
void close_impl();
|
||||
|
||||
// observers on this udp socket
|
||||
std::vector<udp_socket_observer*> m_observers;
|
||||
std::vector<udp_socket_observer*> m_added_observers;
|
||||
|
|
|
@ -43,7 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/resolver.hpp"
|
||||
|
||||
#include <boost/function/function1.hpp>
|
||||
#include <boost/function/function4.hpp>
|
||||
#include <boost/function/function5.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
@ -100,9 +100,7 @@ namespace libtorrent
|
|||
// int: external port
|
||||
// std::string: error message
|
||||
// an empty string as error means success
|
||||
// a port-mapping index of -1 means it's
|
||||
// an informational log message
|
||||
typedef boost::function<void(int, address, int, error_code const&)> portmap_callback_t;
|
||||
typedef boost::function<void(int, address, int, int, error_code const&)> portmap_callback_t;
|
||||
typedef boost::function<void(char const*)> log_callback_t;
|
||||
|
||||
struct parse_state
|
||||
|
|
|
@ -774,6 +774,8 @@ namespace libtorrent {
|
|||
|
||||
static char const* const nat_type_str[] = {"NAT-PMP", "UPnP"};
|
||||
|
||||
static char const* const protocol_str[] = {"TCP", "UDP"};
|
||||
|
||||
static char const* const socket_type_str[] = {
|
||||
"null",
|
||||
"TCP",
|
||||
|
@ -907,15 +909,16 @@ namespace libtorrent {
|
|||
+ ": " + convert_from_native(error.message());
|
||||
}
|
||||
|
||||
portmap_alert::portmap_alert(aux::stack_allocator&, int i, int port, int t)
|
||||
: mapping(i), external_port(port), map_type(t)
|
||||
portmap_alert::portmap_alert(aux::stack_allocator&, int i, int port, int t
|
||||
, int proto)
|
||||
: mapping(i), external_port(port), map_type(t), protocol(proto)
|
||||
{}
|
||||
|
||||
std::string portmap_alert::message() const
|
||||
{
|
||||
char ret[200];
|
||||
snprintf(ret, sizeof(ret), "successfully mapped port using %s. external port: %u"
|
||||
, nat_type_str[map_type], external_port);
|
||||
snprintf(ret, sizeof(ret), "successfully mapped port using %s. external port: %s/%u"
|
||||
, nat_type_str[map_type], protocol_str[protocol], external_port);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -185,10 +185,11 @@ void natpmp::disable(error_code const& ec, mutex::scoped_lock& l)
|
|||
, end(m_mappings.end()); i != end; ++i)
|
||||
{
|
||||
if (i->protocol == none) continue;
|
||||
int const proto = i->protocol;
|
||||
i->protocol = none;
|
||||
int index = i - m_mappings.begin();
|
||||
l.unlock();
|
||||
m_callback(index, address(), 0, ec);
|
||||
m_callback(index, address(), 0, proto, ec);
|
||||
l.lock();
|
||||
}
|
||||
close_impl(l);
|
||||
|
@ -563,15 +564,18 @@ void natpmp::on_reply(error_code const& e
|
|||
if (result >= 1 && result <= 5) ev = errors[result - 1];
|
||||
|
||||
m->expires = aux::time_now() + hours(2);
|
||||
int const proto = m->protocol;
|
||||
l.unlock();
|
||||
m_callback(index, address(), 0, error_code(ev, get_libtorrent_category()));
|
||||
m_callback(index, address(), 0, proto
|
||||
, error_code(ev, get_libtorrent_category()));
|
||||
l.lock();
|
||||
}
|
||||
else if (m->action == mapping_t::action_add)
|
||||
{
|
||||
int const proto = m->protocol;
|
||||
l.unlock();
|
||||
m_callback(index, m_external_ip, m->external_port,
|
||||
error_code(errors::no_error, get_libtorrent_category()));
|
||||
m_callback(index, m_external_ip, m->external_port, proto
|
||||
, error_code(errors::no_error, get_libtorrent_category()));
|
||||
l.lock();
|
||||
}
|
||||
|
||||
|
|
|
@ -2000,7 +2000,8 @@ namespace aux {
|
|||
else
|
||||
{
|
||||
created_ssl_udp_socket = true;
|
||||
// TODO: 3 port map SSL udp socket here
|
||||
maybe_update_udp_mapping(0, true, bind_ep.port(), bind_ep.port());
|
||||
maybe_update_udp_mapping(1, true, bind_ep.port(), bind_ep.port());
|
||||
}
|
||||
} while (ec == error_code(error::address_in_use) && retries > 0);
|
||||
}
|
||||
|
@ -2035,8 +2036,8 @@ namespace aux {
|
|||
{
|
||||
created_udp_socket = true;
|
||||
m_external_udp_port = m_udp_socket.local_port();
|
||||
maybe_update_udp_mapping(0, bind_ep.port(), bind_ep.port());
|
||||
maybe_update_udp_mapping(1, bind_ep.port(), bind_ep.port());
|
||||
maybe_update_udp_mapping(0, false, bind_ep.port(), bind_ep.port());
|
||||
maybe_update_udp_mapping(1, false, bind_ep.port(), bind_ep.port());
|
||||
}
|
||||
} while (ec == error_code(error::address_in_use) && retries > 0);
|
||||
}
|
||||
|
@ -2046,11 +2047,39 @@ namespace aux {
|
|||
// previous one
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
if (!created_ssl_udp_socket)
|
||||
{
|
||||
m_ssl_udp_socket.close();
|
||||
|
||||
// if there are mappings for the SSL socket, delete them now
|
||||
if (m_ssl_udp_mapping[0] != -1 && m_natpmp)
|
||||
{
|
||||
m_natpmp->delete_mapping(m_ssl_udp_mapping[0]);
|
||||
m_ssl_udp_mapping[0] = -1;
|
||||
}
|
||||
if (m_ssl_udp_mapping[1] != -1 && m_upnp)
|
||||
{
|
||||
m_upnp->delete_mapping(m_ssl_udp_mapping[1]);
|
||||
m_ssl_udp_mapping[1] = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!created_udp_socket)
|
||||
{
|
||||
m_udp_socket.close();
|
||||
|
||||
// if there are mappings for the socket, delete them now
|
||||
if (m_udp_mapping[0] != -1 && m_natpmp)
|
||||
{
|
||||
m_natpmp->delete_mapping(m_udp_mapping[0]);
|
||||
m_udp_mapping[0] = -1;
|
||||
}
|
||||
if (m_udp_mapping[1] != -1 && m_upnp)
|
||||
{
|
||||
m_upnp->delete_mapping(m_udp_mapping[1]);
|
||||
m_udp_mapping[1] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// we made it! now post all the listen_succeeded_alerts
|
||||
|
||||
for (std::list<listen_socket_t>::iterator i = m_listen_sockets.begin()
|
||||
|
@ -5241,6 +5270,11 @@ namespace aux {
|
|||
boost::uint16_t session_impl::ssl_listen_port() const
|
||||
{
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
|
||||
// honor the SSL listen port being disabled
|
||||
if (m_settings.get_int(settings_pack::ssl_listen) == 0)
|
||||
return 0;
|
||||
|
||||
// if peer connections are set up to be received over a socks
|
||||
// proxy, and it's the same one as we're using for the tracker
|
||||
// just tell the tracker the socks5 port we're listening on
|
||||
|
@ -5317,7 +5351,7 @@ namespace aux {
|
|||
|
||||
// transport is 0 for NAT-PMP and 1 for UPnP
|
||||
void session_impl::on_port_mapping(int mapping, address const& ip, int port
|
||||
, error_code const& ec, int map_transport)
|
||||
, int const protocol, error_code const& ec, int map_transport)
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
|
@ -5334,7 +5368,8 @@ namespace aux {
|
|||
m_external_udp_port = port;
|
||||
if (m_alerts.should_post<portmap_alert>())
|
||||
m_alerts.emplace_alert<portmap_alert>(mapping, port
|
||||
, map_transport);
|
||||
, map_transport, protocol == natpmp::udp
|
||||
? portmap_alert::udp : portmap_alert::tcp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5361,7 +5396,8 @@ namespace aux {
|
|||
if (!ec && m_alerts.should_post<portmap_alert>())
|
||||
{
|
||||
m_alerts.emplace_alert<portmap_alert>(mapping, port
|
||||
, map_transport);
|
||||
, map_transport, protocol == natpmp::udp
|
||||
? portmap_alert::udp : portmap_alert::tcp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5759,38 +5795,45 @@ namespace aux {
|
|||
|
||||
#endif
|
||||
|
||||
void session_impl::maybe_update_udp_mapping(int nat, int local_port, int external_port)
|
||||
void session_impl::maybe_update_udp_mapping(int const nat, bool const ssl
|
||||
, int const local_port, int const external_port)
|
||||
{
|
||||
int local, external, protocol;
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
int* mapping = ssl ? m_ssl_udp_mapping : m_udp_mapping;
|
||||
#else
|
||||
TORRENT_UNUSED(ssl);
|
||||
int* mapping = m_udp_mapping;
|
||||
#endif
|
||||
if (nat == 0 && m_natpmp)
|
||||
{
|
||||
if (m_udp_mapping[nat] != -1)
|
||||
if (mapping[nat] != -1)
|
||||
{
|
||||
if (m_natpmp->get_mapping(m_udp_mapping[nat], local, external, protocol))
|
||||
if (m_natpmp->get_mapping(mapping[nat], local, external, protocol))
|
||||
{
|
||||
// we already have a mapping. If it's the same, don't do anything
|
||||
if (local == local_port && external == external_port && protocol == natpmp::udp)
|
||||
return;
|
||||
}
|
||||
m_natpmp->delete_mapping(m_udp_mapping[nat]);
|
||||
m_natpmp->delete_mapping(mapping[nat]);
|
||||
}
|
||||
m_udp_mapping[nat] = m_natpmp->add_mapping(natpmp::udp
|
||||
mapping[nat] = m_natpmp->add_mapping(natpmp::udp
|
||||
, local_port, external_port);
|
||||
return;
|
||||
}
|
||||
else if (nat == 1 && m_upnp)
|
||||
{
|
||||
if (m_udp_mapping[nat] != -1)
|
||||
if (mapping[nat] != -1)
|
||||
{
|
||||
if (m_upnp->get_mapping(m_udp_mapping[nat], local, external, protocol))
|
||||
if (m_upnp->get_mapping(mapping[nat], local, external, protocol))
|
||||
{
|
||||
// we already have a mapping. If it's the same, don't do anything
|
||||
if (local == local_port && external == external_port && protocol == natpmp::udp)
|
||||
return;
|
||||
}
|
||||
m_upnp->delete_mapping(m_udp_mapping[nat]);
|
||||
m_upnp->delete_mapping(mapping[nat]);
|
||||
}
|
||||
m_udp_mapping[nat] = m_upnp->add_mapping(upnp::udp
|
||||
mapping[nat] = m_upnp->add_mapping(upnp::udp
|
||||
, local_port, external_port);
|
||||
return;
|
||||
}
|
||||
|
@ -6489,7 +6532,7 @@ namespace aux {
|
|||
// into the session_impl.
|
||||
m_natpmp = boost::make_shared<natpmp>(boost::ref(m_io_service)
|
||||
, boost::bind(&session_impl::on_port_mapping
|
||||
, this, _1, _2, _3, _4, 0)
|
||||
, this, _1, _2, _3, _4, _5, 0)
|
||||
, boost::bind(&session_impl::on_port_map_log
|
||||
, this, _1, 0));
|
||||
m_natpmp->start();
|
||||
|
@ -6537,7 +6580,7 @@ namespace aux {
|
|||
m_upnp = boost::make_shared<upnp>(boost::ref(m_io_service)
|
||||
, m_settings.get_str(settings_pack::user_agent)
|
||||
, boost::bind(&session_impl::on_port_mapping
|
||||
, this, _1, _2, _3, _4, 1)
|
||||
, this, _1, _2, _3, _4, _5, 1)
|
||||
, boost::bind(&session_impl::on_port_map_log
|
||||
, this, _1, 1)
|
||||
, m_settings.get_bool(settings_pack::upnp_ignore_nonrouters));
|
||||
|
|
|
@ -78,7 +78,7 @@ udp_socket::udp_socket(io_service& ios)
|
|||
, m_queue_packets(false)
|
||||
, m_tunnel_packets(false)
|
||||
, m_force_proxy(false)
|
||||
, m_abort(false)
|
||||
, m_abort(true)
|
||||
, m_outstanding_ops(0)
|
||||
#if TORRENT_USE_IPV6
|
||||
, m_v6_write_subscribed(false)
|
||||
|
@ -307,7 +307,11 @@ void udp_socket::on_read(error_code const& ec, udp::socket* s)
|
|||
}
|
||||
return;
|
||||
}
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
|
||||
|
@ -493,7 +497,11 @@ void udp_socket::on_read_impl(udp::endpoint const& ep
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -516,7 +524,11 @@ void udp_socket::on_read_impl(udp::endpoint const& ep
|
|||
|
||||
void udp_socket::setup_read(udp::socket* s)
|
||||
{
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
if (s == &m_ipv6_sock)
|
||||
|
@ -774,17 +786,13 @@ void udp_socket::bind(udp::endpoint const& ep, error_code& ec)
|
|||
CHECK_MAGIC;
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
TORRENT_ASSERT(m_abort == false);
|
||||
if (m_abort)
|
||||
{
|
||||
ec = boost::asio::error::operation_aborted;
|
||||
return;
|
||||
}
|
||||
m_abort = false;
|
||||
|
||||
if (m_ipv4_sock.is_open()) m_ipv4_sock.close(ec);
|
||||
#if TORRENT_USE_IPV6
|
||||
if (m_ipv6_sock.is_open()) m_ipv6_sock.close(ec);
|
||||
#endif
|
||||
ec.clear();
|
||||
|
||||
if (ep.address().is_v4())
|
||||
{
|
||||
|
@ -858,7 +866,11 @@ void udp_socket::set_proxy_settings(aux::proxy_settings const& ps)
|
|||
|
||||
m_proxy_settings = ps;
|
||||
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ps.type == settings_pack::socks5
|
||||
|| ps.type == settings_pack::socks5_pw)
|
||||
|
@ -880,6 +892,19 @@ void udp_socket::set_proxy_settings(aux::proxy_settings const& ps)
|
|||
}
|
||||
}
|
||||
|
||||
void udp_socket::close_impl()
|
||||
{
|
||||
if (m_outstanding_ops == 0)
|
||||
{
|
||||
error_code ec;
|
||||
m_ipv4_sock.close(ec);
|
||||
#if TORRENT_USE_IPV6
|
||||
m_ipv6_sock.close(ec);
|
||||
#endif
|
||||
m_socks5_sock.close(ec);
|
||||
}
|
||||
}
|
||||
|
||||
void udp_socket::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
|
||||
{
|
||||
#if defined TORRENT_ASIO_DEBUGGING
|
||||
|
@ -897,7 +922,12 @@ void udp_socket::on_name_lookup(error_code const& e, tcp::resolver::iterator i)
|
|||
+ m_outstanding_resolve
|
||||
+ m_outstanding_socks);
|
||||
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
|
||||
if (e == boost::asio::error::operation_aborted) return;
|
||||
|
@ -976,7 +1006,11 @@ void udp_socket::on_connect_timeout(error_code const& ec)
|
|||
|
||||
m_queue_packets = false;
|
||||
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_MAGIC;
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
@ -1009,7 +1043,11 @@ void udp_socket::on_connected(error_code const& e)
|
|||
|
||||
if (e == boost::asio::error::operation_aborted) return;
|
||||
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e)
|
||||
{
|
||||
|
@ -1068,7 +1106,11 @@ void udp_socket::handshake1(error_code const& e)
|
|||
+ m_outstanding_timeout
|
||||
+ m_outstanding_resolve
|
||||
+ m_outstanding_socks);
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
CHECK_MAGIC;
|
||||
if (e)
|
||||
{
|
||||
|
@ -1104,7 +1146,11 @@ void udp_socket::handshake2(error_code const& e)
|
|||
+ m_outstanding_timeout
|
||||
+ m_outstanding_resolve
|
||||
+ m_outstanding_socks);
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
CHECK_MAGIC;
|
||||
|
||||
if (e)
|
||||
|
@ -1185,7 +1231,11 @@ void udp_socket::handshake3(error_code const& e)
|
|||
+ m_outstanding_timeout
|
||||
+ m_outstanding_resolve
|
||||
+ m_outstanding_socks);
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
CHECK_MAGIC;
|
||||
if (e)
|
||||
{
|
||||
|
@ -1221,7 +1271,11 @@ void udp_socket::handshake4(error_code const& e)
|
|||
+ m_outstanding_timeout
|
||||
+ m_outstanding_resolve
|
||||
+ m_outstanding_socks);
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
CHECK_MAGIC;
|
||||
if (e)
|
||||
{
|
||||
|
@ -1287,7 +1341,11 @@ void udp_socket::connect1(error_code const& e)
|
|||
+ m_outstanding_timeout
|
||||
+ m_outstanding_resolve
|
||||
+ m_outstanding_socks);
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
CHECK_MAGIC;
|
||||
if (e)
|
||||
{
|
||||
|
@ -1394,7 +1452,11 @@ void udp_socket::hung_up(error_code const& e)
|
|||
+ m_outstanding_timeout
|
||||
+ m_outstanding_resolve
|
||||
+ m_outstanding_socks);
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
close_impl();
|
||||
return;
|
||||
}
|
||||
CHECK_MAGIC;
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
|
|
12
src/upnp.cpp
12
src/upnp.cpp
|
@ -1041,9 +1041,10 @@ void upnp::disable(error_code const& ec, mutex::scoped_lock& l)
|
|||
, end(m_mappings.end()); i != end; ++i)
|
||||
{
|
||||
if (i->protocol == none) continue;
|
||||
int const proto = i->protocol;
|
||||
i->protocol = none;
|
||||
l.unlock();
|
||||
m_callback(i - m_mappings.begin(), address(), 0, ec);
|
||||
m_callback(i - m_mappings.begin(), address(), 0, proto, ec);
|
||||
l.lock();
|
||||
}
|
||||
|
||||
|
@ -1372,7 +1373,7 @@ void upnp::on_upnp_map_response(error_code const& e
|
|||
if (s.error_code == -1)
|
||||
{
|
||||
l.unlock();
|
||||
m_callback(mapping, d.external_ip, m.external_port, error_code());
|
||||
m_callback(mapping, d.external_ip, m.external_port, m.protocol, error_code());
|
||||
l.lock();
|
||||
if (d.lease_duration > 0)
|
||||
{
|
||||
|
@ -1414,8 +1415,9 @@ void upnp::return_error(int mapping, int code, mutex::scoped_lock& l)
|
|||
error_string += ": ";
|
||||
error_string += e->msg;
|
||||
}
|
||||
const int proto = m_mappings[mapping].protocol;
|
||||
l.unlock();
|
||||
m_callback(mapping, address(), 0, error_code(code, get_upnp_category()));
|
||||
m_callback(mapping, address(), 0, proto, error_code(code, get_upnp_category()));
|
||||
l.lock();
|
||||
}
|
||||
|
||||
|
@ -1468,8 +1470,10 @@ void upnp::on_upnp_unmap_response(error_code const& e
|
|||
, boost::bind(&find_error_code, _1, _2, boost::ref(s)));
|
||||
}
|
||||
|
||||
int const proto = m_mappings[mapping].protocol;
|
||||
|
||||
l.unlock();
|
||||
m_callback(mapping, address(), 0, p.status_code() != 200
|
||||
m_callback(mapping, address(), 0, proto, p.status_code() != 200
|
||||
? error_code(p.status_code(), get_http_category())
|
||||
: error_code(s.error_code, get_upnp_category()));
|
||||
l.lock();
|
||||
|
|
Loading…
Reference in New Issue