Merge pull request #1123 from aldenml/system-port-and-logs-1.2

* accept port 0 in listen_interfaces
* more session log and source code refactor
This commit is contained in:
Arvid Norberg 2016-09-20 23:50:49 -07:00 committed by GitHub
commit 752ff24357
5 changed files with 60 additions and 47 deletions

View File

@ -76,8 +76,8 @@ namespace libtorrent
// this parses the string that's used as the listen_interfaces setting. // this parses the string that's used as the listen_interfaces setting.
// it is a comma-separated list of IP or device names with ports. For // it is a comma-separated list of IP or device names with ports. For
// example: "eth0:6881,eth1:6881" or "127.0.0.1:6881" // example: "eth0:6881,eth1:6881" or "127.0.0.1:6881"
TORRENT_EXTRA_EXPORT void parse_listen_interfaces( TORRENT_EXTRA_EXPORT std::vector<listen_interface_t> parse_listen_interfaces(
std::string const& in, std::vector<listen_interface_t>& out); std::string const& in);
TORRENT_EXTRA_EXPORT std::string print_listen_interfaces( TORRENT_EXTRA_EXPORT std::string print_listen_interfaces(
std::vector<listen_interface_t> const& in); std::vector<listen_interface_t> const& in);

View File

@ -474,9 +474,9 @@ namespace libtorrent
if (iface_from_ifaddrs(ifa, iface)) if (iface_from_ifaddrs(ifa, iface))
{ {
ifreq req; ifreq req;
memset(&req, 0, sizeof(req)); std::memset(&req, 0, sizeof(req));
// -1 to leave a 0-terminator // -1 to leave a 0-terminator
strncpy(req.ifr_name, iface.name, IF_NAMESIZE - 1); std::strncpy(req.ifr_name, iface.name, IF_NAMESIZE - 1);
// ignore errors here. This is best-effort // ignore errors here. This is best-effort
ioctl(s, siocgifmtu, &req); ioctl(s, siocgifmtu, &req);

View File

@ -1441,11 +1441,19 @@ namespace aux {
&& pack.get_str(settings_pack::listen_interfaces) && pack.get_str(settings_pack::listen_interfaces)
!= m_settings.get_str(settings_pack::listen_interfaces)); != m_settings.get_str(settings_pack::listen_interfaces));
#ifndef TORRENT_DISABLE_LOGGING
session_log("applying settings pack, init=%s, reopen_listen_port=%s"
, init ? "true" : "false", reopen_listen_port ? "true" : "false");
#endif
apply_pack(&pack, m_settings, this); apply_pack(&pack, m_settings, this);
m_disk_thread.set_settings(&pack, m_alerts); m_disk_thread.set_settings(&pack, m_alerts);
if (init) if (init && !reopen_listen_port)
{ // no need to call this if reopen_listen_port is true
// since the apply_pack will do it
update_listen_interfaces(); update_listen_interfaces();
}
if (init || reopen_listen_port) if (init || reopen_listen_port)
{ {
@ -1634,7 +1642,8 @@ namespace aux {
} }
if (ec == error_code(error::address_in_use) if (ec == error_code(error::address_in_use)
&& !(flags & listen_no_system_port)) && !(flags & listen_no_system_port)
&& bind_ep.port() != 0)
{ {
// instead of giving up, try let the OS pick a port // instead of giving up, try let the OS pick a port
bind_ep.port(0); bind_ep.port(0);
@ -1789,7 +1798,7 @@ namespace aux {
void session_impl::reopen_listen_sockets() void session_impl::reopen_listen_sockets()
{ {
#ifndef TORRENT_DISABLE_LOGGING #ifndef TORRENT_DISABLE_LOGGING
session_log("open listen port"); session_log("reopen listen sockets");
#endif #endif
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
@ -1802,7 +1811,10 @@ namespace aux {
// close the open listen sockets // close the open listen sockets
// close the listen sockets // close the listen sockets
#ifndef TORRENT_DISABLE_LOGGING #ifndef TORRENT_DISABLE_LOGGING
session_log("closing all listen sockets"); if (m_listen_sockets.empty())
session_log("no currently open sockets to close");
else
session_log("closing all listen sockets (%d)", int(m_listen_sockets.size()));
#endif #endif
for (auto const& s : m_listen_sockets) for (auto const& s : m_listen_sockets)
{ {
@ -1864,7 +1876,7 @@ namespace aux {
// enumerate all IPs associated with this device // enumerate all IPs associated with this device
// TODO: 3 only run this once, not every turn through the loop // TODO: 3 only run this once, not every turn through the loop
std::vector<ip_interface> ifs = enum_net_interfaces(m_io_service, ec); std::vector<ip_interface> const ifs = enum_net_interfaces(m_io_service, ec);
if (ec) if (ec)
{ {
#ifndef TORRENT_DISABLE_LOGGING #ifndef TORRENT_DISABLE_LOGGING
@ -1914,17 +1926,16 @@ namespace aux {
// listening on // listening on
if (m_alerts.should_post<listen_succeeded_alert>()) if (m_alerts.should_post<listen_succeeded_alert>())
{ {
for (std::list<listen_socket_t>::iterator i = m_listen_sockets.begin() for (auto const& l : m_listen_sockets)
, end(m_listen_sockets.end()); i != end; ++i)
{ {
error_code err; error_code err;
if (i->sock) if (l.sock)
{ {
tcp::endpoint const tcp_ep = i->sock->local_endpoint(err); tcp::endpoint const tcp_ep = l.sock->local_endpoint(err);
if (!err) if (!err)
{ {
listen_succeeded_alert::socket_type_t const socket_type listen_succeeded_alert::socket_type_t const socket_type
= i->ssl = l.ssl
? listen_succeeded_alert::tcp_ssl ? listen_succeeded_alert::tcp_ssl
: listen_succeeded_alert::tcp; : listen_succeeded_alert::tcp;
@ -1933,13 +1944,13 @@ namespace aux {
} }
} }
if (i->udp_sock) if (l.udp_sock)
{ {
udp::endpoint const udp_ep = i->udp_sock->local_endpoint(err); udp::endpoint const udp_ep = l.udp_sock->local_endpoint(err);
if (!err && i->udp_sock->is_open()) if (!err && l.udp_sock->is_open())
{ {
listen_succeeded_alert::socket_type_t const socket_type listen_succeeded_alert::socket_type_t const socket_type
= i->ssl = l.ssl
? listen_succeeded_alert::utp_ssl ? listen_succeeded_alert::utp_ssl
: listen_succeeded_alert::udp; : listen_succeeded_alert::udp;
@ -4469,7 +4480,7 @@ namespace aux {
std::weak_ptr<torrent> session_impl::find_disconnect_candidate_torrent() const std::weak_ptr<torrent> session_impl::find_disconnect_candidate_torrent() const
{ {
auto i = std::min_element(m_torrents.begin(), m_torrents.end() auto const i = std::min_element(m_torrents.begin(), m_torrents.end()
, &compare_disconnect_torrent); , &compare_disconnect_torrent);
TORRENT_ASSERT(i != m_torrents.end()); TORRENT_ASSERT(i != m_torrents.end());
@ -5139,9 +5150,8 @@ namespace aux {
// this function maps the previous functionality of just setting the ssl // this function maps the previous functionality of just setting the ssl
// listen port in order to enable the ssl listen sockets, to the new // listen port in order to enable the ssl listen sockets, to the new
// mechanism where SSL sockets are specified in listen_interfaces. // mechanism where SSL sockets are specified in listen_interfaces.
std::vector<listen_interface_t> current_ifaces; auto current_ifaces = parse_listen_interfaces(
parse_listen_interfaces(m_settings.get_str(settings_pack::listen_interfaces) m_settings.get_str(settings_pack::listen_interfaces));
, current_ifaces);
// these are the current interfaces we have, first remove all the SSL // these are the current interfaces we have, first remove all the SSL
// interfaces // interfaces
current_ifaces.erase(std::remove_if(current_ifaces.begin(), current_ifaces.end() current_ifaces.erase(std::remove_if(current_ifaces.begin(), current_ifaces.end()
@ -5173,17 +5183,18 @@ namespace aux {
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
std::string net_interfaces = m_settings.get_str(settings_pack::listen_interfaces); std::string const net_interfaces = m_settings.get_str(settings_pack::listen_interfaces);
std::vector<listen_interface_t> new_listen_interfaces; m_listen_interfaces = parse_listen_interfaces(net_interfaces);
// declared in string_util.hpp
parse_listen_interfaces(net_interfaces, new_listen_interfaces);
#ifndef TORRENT_DISABLE_LOGGING #ifndef TORRENT_DISABLE_LOGGING
if (should_log())
{
session_log("update listen interfaces: %s", net_interfaces.c_str()); session_log("update listen interfaces: %s", net_interfaces.c_str());
session_log("parsed listen interfaces count: %d, ifaces: %s"
, int(m_listen_interfaces.size())
, print_listen_interfaces(m_listen_interfaces).c_str());
}
#endif #endif
m_listen_interfaces = new_listen_interfaces;
} }
void session_impl::update_privileged_ports() void session_impl::update_privileged_ports()
@ -5194,9 +5205,8 @@ namespace aux {
// Close connections whose endpoint is filtered // Close connections whose endpoint is filtered
// by the new ip-filter // by the new ip-filter
for (torrent_map::iterator i = m_torrents.begin() for (auto const& t : m_torrents)
, end(m_torrents.end()); i != end; ++i) t.second->port_filter_updated();
i->second->port_filter_updated();
} }
else else
{ {
@ -6352,10 +6362,9 @@ namespace aux {
extra = extra % num_above; extra = extra % num_above;
} }
for (torrent_map::iterator i = m_torrents.begin() for (auto const& t : m_torrents)
, end(m_torrents.end()); i != end; ++i)
{ {
int num = i->second->num_peers(); int const num = t.second->num_peers();
if (num <= average) continue; if (num <= average) continue;
// distribute the remainder // distribute the remainder
@ -6366,9 +6375,9 @@ namespace aux {
--extra; --extra;
} }
int disconnect = (std::min)(to_disconnect, num - my_average); int const disconnect = std::min(to_disconnect, num - my_average);
to_disconnect -= disconnect; to_disconnect -= disconnect;
i->second->disconnect_peers(disconnect t.second->disconnect_peers(disconnect
, error_code(errors::too_many_connections, get_libtorrent_category())); , error_code(errors::too_many_connections, get_libtorrent_category()));
} }
} }

View File

@ -214,10 +214,9 @@ namespace libtorrent
// this parses the string that's used as the listen_interfaces setting. // this parses the string that's used as the listen_interfaces setting.
// it is a comma-separated list of IP or device names with ports. For // it is a comma-separated list of IP or device names with ports. For
// example: "eth0:6881,eth1:6881" or "127.0.0.1:6881" // example: "eth0:6881,eth1:6881" or "127.0.0.1:6881"
void parse_listen_interfaces(std::string const& in std::vector<listen_interface_t> parse_listen_interfaces(std::string const& in)
, std::vector<listen_interface_t>& out)
{ {
out.clear(); std::vector<listen_interface_t> out;
std::string::size_type start = 0; std::string::size_type start = 0;
@ -227,7 +226,7 @@ namespace libtorrent
while (start < in.size() && is_space(in[start])) while (start < in.size() && is_space(in[start]))
++start; ++start;
if (start == in.size()) return; if (start == in.size()) return out;
listen_interface_t iface; listen_interface_t iface;
iface.ssl = false; iface.ssl = false;
@ -260,7 +259,7 @@ namespace libtorrent
while (start < in.size() && is_space(in[start])) while (start < in.size() && is_space(in[start]))
++start; ++start;
if (start == in.size() || in[start] != ':') return; if (start == in.size() || in[start] != ':') return out;
++start; // skip colon ++start; // skip colon
// skip spaces // skip spaces
@ -279,7 +278,7 @@ namespace libtorrent
else else
{ {
iface.port = std::atoi(port.c_str()); iface.port = std::atoi(port.c_str());
if (iface.port <= 0 || iface.port > 65535) iface.port = -1; if (iface.port < 0 || iface.port > 65535) iface.port = -1;
} }
// skip spaces // skip spaces
@ -311,6 +310,8 @@ namespace libtorrent
++start; ++start;
} }
return out;
} }
// this parses the string that's used as the listen_interfaces setting. // this parses the string that's used as the listen_interfaces setting.

View File

@ -279,8 +279,7 @@ void test_parse_interface(char const* input
, std::string output) , std::string output)
{ {
std::fprintf(stderr, "parse interface: %s\n", input); std::fprintf(stderr, "parse interface: %s\n", input);
std::vector<listen_interface_t> list; auto const list = parse_listen_interfaces(input);
parse_listen_interfaces(input, list);
TEST_EQUAL(list.size(), expected.size()); TEST_EQUAL(list.size(), expected.size());
if (list.size() == expected.size()) if (list.size() == expected.size())
{ {
@ -342,6 +341,10 @@ TORRENT_TEST(parse_list)
test_parse_interface("nic :", {}, ""); test_parse_interface("nic :", {}, "");
test_parse_interface("nic ", {}, ""); test_parse_interface("nic ", {}, "");
test_parse_interface("nic s", {}, ""); test_parse_interface("nic s", {}, "");
// parse interface with port 0
test_parse_interface("127.0.0.1:0"
, {{"127.0.0.1", 0, false}}, "127.0.0.1:0");
} }
TORRENT_TEST(tokenize) TORRENT_TEST(tokenize)