reopen listen sockets when the system's IP changes (#1299)
reopen listen sockets when the system's IP changes. Only Linux and Windows supported for now.
This commit is contained in:
parent
11ca69b9fc
commit
e589e342ef
|
@ -45,6 +45,7 @@ set(sources
|
||||||
i2p_stream
|
i2p_stream
|
||||||
identify_client
|
identify_client
|
||||||
ip_filter
|
ip_filter
|
||||||
|
ip_notifier
|
||||||
ip_voter
|
ip_voter
|
||||||
performance_counters
|
performance_counters
|
||||||
peer_class
|
peer_class
|
||||||
|
|
1
Jamfile
1
Jamfile
|
@ -599,6 +599,7 @@ SOURCES =
|
||||||
http_parser
|
http_parser
|
||||||
identify_client
|
identify_client
|
||||||
ip_filter
|
ip_filter
|
||||||
|
ip_notifier
|
||||||
ip_voter
|
ip_voter
|
||||||
merkle
|
merkle
|
||||||
peer_connection
|
peer_connection
|
||||||
|
|
|
@ -70,6 +70,7 @@ nobase_include_HEADERS = \
|
||||||
io_service.hpp \
|
io_service.hpp \
|
||||||
io_service_fwd.hpp \
|
io_service_fwd.hpp \
|
||||||
ip_filter.hpp \
|
ip_filter.hpp \
|
||||||
|
ip_notifier.hpp \
|
||||||
ip_voter.hpp \
|
ip_voter.hpp \
|
||||||
lazy_entry.hpp \
|
lazy_entry.hpp \
|
||||||
link.hpp \
|
link.hpp \
|
||||||
|
@ -77,6 +78,7 @@ nobase_include_HEADERS = \
|
||||||
lsd.hpp \
|
lsd.hpp \
|
||||||
magnet_uri.hpp \
|
magnet_uri.hpp \
|
||||||
natpmp.hpp \
|
natpmp.hpp \
|
||||||
|
netlink.hpp \
|
||||||
operations.hpp \
|
operations.hpp \
|
||||||
packet_buffer.hpp \
|
packet_buffer.hpp \
|
||||||
parse_url.hpp \
|
parse_url.hpp \
|
||||||
|
|
|
@ -54,6 +54,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/debug.hpp"
|
#include "libtorrent/debug.hpp"
|
||||||
#include "libtorrent/piece_block_progress.hpp"
|
#include "libtorrent/piece_block_progress.hpp"
|
||||||
#include "libtorrent/ip_filter.hpp"
|
#include "libtorrent/ip_filter.hpp"
|
||||||
|
#include "libtorrent/ip_notifier.hpp"
|
||||||
#include "libtorrent/session_status.hpp"
|
#include "libtorrent/session_status.hpp"
|
||||||
#include "libtorrent/add_torrent_params.hpp"
|
#include "libtorrent/add_torrent_params.hpp"
|
||||||
#include "libtorrent/stat.hpp"
|
#include "libtorrent/stat.hpp"
|
||||||
|
@ -251,6 +252,7 @@ namespace libtorrent
|
||||||
void on_exception(std::exception const& e) override;
|
void on_exception(std::exception const& e) override;
|
||||||
void on_error(error_code const& ec) override;
|
void on_error(error_code const& ec) override;
|
||||||
|
|
||||||
|
void on_ip_change(error_code const& ec);
|
||||||
void reopen_listen_sockets();
|
void reopen_listen_sockets();
|
||||||
|
|
||||||
torrent_peer_allocator_interface* get_peer_allocator() override
|
torrent_peer_allocator_interface* get_peer_allocator() override
|
||||||
|
@ -858,6 +860,9 @@ namespace libtorrent
|
||||||
// at startup
|
// at startup
|
||||||
int m_key = 0;
|
int m_key = 0;
|
||||||
|
|
||||||
|
// posts a notification when the set of local IPs changes
|
||||||
|
ip_change_notifier m_ip_notifier;
|
||||||
|
|
||||||
// the addresses or device names of the interfaces we are supposed to
|
// the addresses or device names of the interfaces we are supposed to
|
||||||
// listen on. if empty, it means that we should let the os decide
|
// listen on. if empty, it means that we should let the os decide
|
||||||
// which interface to listen on
|
// which interface to listen on
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2016, Steven Siloti
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TORRENT_IP_NOTIFIER_HPP_INCLUDED
|
||||||
|
#define TORRENT_IP_NOTIFIER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include "libtorrent/error_code.hpp"
|
||||||
|
#include "libtorrent/address.hpp"
|
||||||
|
#include "libtorrent/io_service.hpp"
|
||||||
|
|
||||||
|
#if defined TORRENT_BUILD_SIMULATOR
|
||||||
|
#elif TORRENT_USE_NETLINK
|
||||||
|
#include "libtorrent/netlink.hpp"
|
||||||
|
#elif defined TORRENT_WINDOWS
|
||||||
|
#include <boost/asio/windows/object_handle.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace libtorrent
|
||||||
|
{
|
||||||
|
struct ip_change_notifier : boost::noncopyable
|
||||||
|
{
|
||||||
|
explicit ip_change_notifier(io_service& ios);
|
||||||
|
~ip_change_notifier();
|
||||||
|
|
||||||
|
// cb will be invoked when a change is detected in the
|
||||||
|
// system's IP addresses
|
||||||
|
void async_wait(std::function<void(error_code const&)> cb);
|
||||||
|
void cancel();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void on_notify(error_code const& error
|
||||||
|
, std::size_t bytes_transferred
|
||||||
|
, std::function<void(error_code const&)> cb);
|
||||||
|
|
||||||
|
#if defined TORRENT_BUILD_SIMULATOR
|
||||||
|
// TODO simulator support
|
||||||
|
#elif TORRENT_USE_NETLINK
|
||||||
|
netlink::socket m_socket;
|
||||||
|
std::array<char, 4096> m_buf;
|
||||||
|
#elif defined TORRENT_WINDOWS
|
||||||
|
OVERLAPPED m_ovl = {};
|
||||||
|
boost::asio::windows::object_handle m_hnd;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2016, Steven Siloti
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TORRENT_NETLINK_HPP
|
||||||
|
#define TORRENT_NETLINK_HPP
|
||||||
|
|
||||||
|
#include "libtorrent/config.hpp"
|
||||||
|
|
||||||
|
#if TORRENT_USE_NETLINK
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <boost/asio/basic_raw_socket.hpp>
|
||||||
|
|
||||||
|
namespace libtorrent
|
||||||
|
{
|
||||||
|
template <typename Protocol>
|
||||||
|
class basic_nl_endpoint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using protocol_type = Protocol;
|
||||||
|
using data_type = boost::asio::detail::socket_addr_type;
|
||||||
|
|
||||||
|
basic_nl_endpoint()
|
||||||
|
{
|
||||||
|
std::memset(&sockaddr, 0, sizeof(sockaddr_nl));
|
||||||
|
sockaddr.nl_family = AF_NETLINK;
|
||||||
|
sockaddr.nl_groups = 0;
|
||||||
|
sockaddr.nl_pid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
basic_nl_endpoint(protocol_type netlink_family, std::uint32_t group, ::pid_t pid = 0)
|
||||||
|
: proto(netlink_family)
|
||||||
|
{
|
||||||
|
std::memset(&sockaddr, 0, sizeof(sockaddr_nl));
|
||||||
|
sockaddr.nl_family = AF_NETLINK;
|
||||||
|
sockaddr.nl_groups = group;
|
||||||
|
sockaddr.nl_pid = pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
basic_nl_endpoint(basic_nl_endpoint const& other)
|
||||||
|
{
|
||||||
|
sockaddr = other.sockaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
basic_nl_endpoint& operator=(const basic_nl_endpoint& other)
|
||||||
|
{
|
||||||
|
sockaddr = other.sockaddr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
basic_nl_endpoint& operator=(const basic_nl_endpoint&& other)
|
||||||
|
{
|
||||||
|
sockaddr = other.sockaddr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol_type protocol() const
|
||||||
|
{
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_type* data()
|
||||||
|
{
|
||||||
|
return &sockaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data_type* data() const
|
||||||
|
{
|
||||||
|
return (struct sockaddr*)&sockaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t size() const
|
||||||
|
{
|
||||||
|
return sizeof(sockaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t capacity() const
|
||||||
|
{
|
||||||
|
return sizeof(sockaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const basic_nl_endpoint<Protocol>& l
|
||||||
|
, const basic_nl_endpoint<Protocol>& r)
|
||||||
|
{
|
||||||
|
return l.sockaddr == r.sockaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const basic_nl_endpoint<Protocol>& l
|
||||||
|
, const basic_nl_endpoint<Protocol>& r)
|
||||||
|
{
|
||||||
|
return !(l.sockaddr == r.sockaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<(const basic_nl_endpoint<Protocol>& l
|
||||||
|
, const basic_nl_endpoint<Protocol>& r)
|
||||||
|
{
|
||||||
|
return l.sockaddr < r.sockaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator>(const basic_nl_endpoint<Protocol>& l
|
||||||
|
, const basic_nl_endpoint<Protocol>& r)
|
||||||
|
{
|
||||||
|
return r.sockaddr < l.sockaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator<=(const basic_nl_endpoint<Protocol>& l
|
||||||
|
, const basic_nl_endpoint<Protocol>& r)
|
||||||
|
{
|
||||||
|
return !(r < l);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator>=(const basic_nl_endpoint<Protocol>& l
|
||||||
|
, const basic_nl_endpoint<Protocol>& r)
|
||||||
|
{
|
||||||
|
return !(l < r);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
protocol_type proto;
|
||||||
|
sockaddr_nl sockaddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class netlink
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using endpoint = basic_nl_endpoint<netlink>;
|
||||||
|
using socket = boost::asio::basic_raw_socket<netlink>;
|
||||||
|
|
||||||
|
netlink() : nl_family(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit netlink(int nl_family)
|
||||||
|
: nl_family(nl_family)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int type() const
|
||||||
|
{
|
||||||
|
return SOCK_RAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
int protocol() const
|
||||||
|
{
|
||||||
|
return nl_family;
|
||||||
|
}
|
||||||
|
|
||||||
|
int family() const
|
||||||
|
{
|
||||||
|
return AF_NETLINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const netlink& l, const netlink& r)
|
||||||
|
{
|
||||||
|
return l.nl_family == r.nl_family;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const netlink& l, const netlink& r)
|
||||||
|
{
|
||||||
|
return l.nl_family != r.nl_family;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int nl_family;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -88,6 +88,7 @@ libtorrent_rasterbar_la_SOURCES = \
|
||||||
identify_client.cpp \
|
identify_client.cpp \
|
||||||
instantiate_connection.cpp \
|
instantiate_connection.cpp \
|
||||||
ip_filter.cpp \
|
ip_filter.cpp \
|
||||||
|
ip_notifier.cpp \
|
||||||
ip_voter.cpp \
|
ip_voter.cpp \
|
||||||
lazy_bdecode.cpp \
|
lazy_bdecode.cpp \
|
||||||
lsd.cpp \
|
lsd.cpp \
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2016, Steven Siloti
|
||||||
|
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 "libtorrent/ip_notifier.hpp"
|
||||||
|
|
||||||
|
#if defined TORRENT_WINDOWS && !defined TORRENT_BUILD_SIMULATOR
|
||||||
|
#include <iphlpapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
namespace libtorrent
|
||||||
|
{
|
||||||
|
ip_change_notifier::ip_change_notifier(io_service& ios)
|
||||||
|
#if defined TORRENT_BUILD_SIMULATOR
|
||||||
|
#elif TORRENT_USE_NETLINK
|
||||||
|
: m_socket(ios
|
||||||
|
, netlink::endpoint(netlink(NETLINK_ROUTE), RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR))
|
||||||
|
#elif defined TORRENT_WINDOWS
|
||||||
|
: m_hnd(ios, WSACreateEvent())
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if defined TORRENT_BUILD_SIMULATOR
|
||||||
|
TORRENT_UNUSED(ios);
|
||||||
|
#elif defined TORRENT_WINDOWS
|
||||||
|
if (!m_hnd.is_open())
|
||||||
|
throw system_error(WSAGetLastError(), system_category());
|
||||||
|
m_ovl.hEvent = m_hnd.native_handle();
|
||||||
|
#elif !TORRENT_USE_NETLINK
|
||||||
|
TORRENT_UNUSED(ios);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_change_notifier::~ip_change_notifier()
|
||||||
|
{
|
||||||
|
#if defined TORRENT_WINDOWS && !defined TORRENT_BUILD_SIMULATOR
|
||||||
|
cancel();
|
||||||
|
m_hnd.close();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ip_change_notifier::async_wait(std::function<void(error_code const&)> cb)
|
||||||
|
{
|
||||||
|
#if defined TORRENT_BUILD_SIMULATOR
|
||||||
|
TORRENT_UNUSED(cb);
|
||||||
|
#elif TORRENT_USE_NETLINK
|
||||||
|
m_socket.async_receive(boost::asio::buffer(m_buf)
|
||||||
|
, std::bind(&ip_change_notifier::on_notify, this, _1, _2, cb));
|
||||||
|
#elif defined TORRENT_WINDOWS
|
||||||
|
HANDLE hnd;
|
||||||
|
DWORD err = NotifyAddrChange(&hnd, &m_ovl);
|
||||||
|
if (err == ERROR_IO_PENDING)
|
||||||
|
{
|
||||||
|
m_hnd.async_wait([this,cb](error_code const& ec) { on_notify(ec, 0, cb); });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_hnd.get_io_service().post([this,cb,err]()
|
||||||
|
{ cb(error_code(err, system_category())); });
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
TORRENT_UNUSED(cb);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ip_change_notifier::cancel()
|
||||||
|
{
|
||||||
|
#if defined TORRENT_BUILD_SIMULATOR
|
||||||
|
#elif TORRENT_USE_NETLINK
|
||||||
|
m_socket.cancel();
|
||||||
|
#elif defined TORRENT_WINDOWS
|
||||||
|
CancelIPChangeNotify(&m_ovl);
|
||||||
|
m_hnd.cancel();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ip_change_notifier::on_notify(error_code const& ec
|
||||||
|
, std::size_t bytes_transferred
|
||||||
|
, std::function<void(error_code const&)> cb)
|
||||||
|
{
|
||||||
|
TORRENT_UNUSED(bytes_transferred);
|
||||||
|
|
||||||
|
// on linux we could parse the message to get information about the
|
||||||
|
// change but Windows requires the application to enumerate the
|
||||||
|
// interfaces after a notification so do that for Linux as well to
|
||||||
|
// minimize the difference between platforms
|
||||||
|
|
||||||
|
// Linux can generate ENOBUFS if the socket's buffers are full
|
||||||
|
// don't treat it as an error
|
||||||
|
if (ec.value() == boost::system::errc::no_buffer_space)
|
||||||
|
cb(error_code());
|
||||||
|
else
|
||||||
|
cb(ec);
|
||||||
|
}
|
||||||
|
}
|
|
@ -411,6 +411,7 @@ namespace aux {
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
, m_work(new io_service::work(m_io_service))
|
, m_work(new io_service::work(m_io_service))
|
||||||
|
, m_ip_notifier(m_io_service)
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
, m_i2p_conn(m_io_service)
|
, m_i2p_conn(m_io_service)
|
||||||
#endif
|
#endif
|
||||||
|
@ -605,6 +606,9 @@ namespace aux {
|
||||||
session_log(" done starting session");
|
session_log(" done starting session");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
m_ip_notifier.async_wait([this](error_code const& e)
|
||||||
|
{ this->wrap(&session_impl::on_ip_change, e); });
|
||||||
|
|
||||||
apply_settings_pack_impl(*pack, true);
|
apply_settings_pack_impl(*pack, true);
|
||||||
|
|
||||||
// call update_* after settings set initialized
|
// call update_* after settings set initialized
|
||||||
|
@ -859,6 +863,9 @@ namespace aux {
|
||||||
// abort the main thread
|
// abort the main thread
|
||||||
m_abort = true;
|
m_abort = true;
|
||||||
error_code ec;
|
error_code ec;
|
||||||
|
|
||||||
|
m_ip_notifier.cancel();
|
||||||
|
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
m_i2p_conn.close(ec);
|
m_i2p_conn.close(ec);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1686,6 +1693,14 @@ namespace aux {
|
||||||
this->abort();
|
this->abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void session_impl::on_ip_change(error_code const& ec)
|
||||||
|
{
|
||||||
|
if (ec || m_abort) return;
|
||||||
|
m_ip_notifier.async_wait([this] (error_code const& e)
|
||||||
|
{ this->wrap(&session_impl::on_ip_change, e); });
|
||||||
|
reopen_listen_sockets();
|
||||||
|
}
|
||||||
|
|
||||||
void session_impl::reopen_listen_sockets()
|
void session_impl::reopen_listen_sockets()
|
||||||
{
|
{
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
|
|
Loading…
Reference in New Issue