diff --git a/docs/manual.html b/docs/manual.html index c9ddc1f79..a98eb675a 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -2612,6 +2612,7 @@ struct session_settings int cache_size; int cache_expiry; std::pair<int, int> outgoing_ports; + char peer_tos; };

user_agent this is the client identification to the tracker. @@ -2768,6 +2769,10 @@ used to bind outgoing sockets to. This may be useful for users whose router allows them to assign QoS classes to traffic based on its local port. It is a range instead of a single port because of the problems with failing to reconnect to peers if a previous socket to that peer and port is in TIME_WAIT state.

+

peer_tos determines the TOS byte set in the IP header of every packet +sent to peers (including web seeds). The default value for this is 0x0 +(no marking). One potentially useful TOS mark is 0x20, this represents +the QBone scavenger service. For more details, see QBSS.

pe_settings

diff --git a/docs/manual.rst b/docs/manual.rst index d35581622..6f11f54ff 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -2605,6 +2605,7 @@ that will be sent to the tracker. The user-agent is a good way to identify your int cache_size; int cache_expiry; std::pair outgoing_ports; + char peer_tos; }; ``user_agent`` this is the client identification to the tracker. @@ -2800,6 +2801,13 @@ allows them to assign QoS classes to traffic based on its local port. It is a range instead of a single port because of the problems with failing to reconnect to peers if a previous socket to that peer and port is in ``TIME_WAIT`` state. +``peer_tos`` determines the TOS byte set in the IP header of every packet +sent to peers (including web seeds). The default value for this is ``0x0`` +(no marking). One potentially useful TOS mark is ``0x20``, this represents +the *QBone scavenger service*. For more details, see QBSS_. + +.. _`QBSS`: http://qbone.internet2.edu/qbss/ + pe_settings =========== diff --git a/include/libtorrent/proxy_base.hpp b/include/libtorrent/proxy_base.hpp index c7a10d9a1..cdf5ff216 100644 --- a/include/libtorrent/proxy_base.hpp +++ b/include/libtorrent/proxy_base.hpp @@ -101,6 +101,20 @@ public: m_sock.async_write_some(buffers, handler); } +#ifndef BOOST_NO_EXCEPTIONS + template + void set_option(SettableSocketOption const& opt) + { + m_sock.set_option(opt); + } +#endif + + template + asio::error_code set_option(SettableSocketOption const& opt, asio::error_code& ec) + { + return m_sock.set_option(opt, ec); + } + #ifndef BOOST_NO_EXCEPTIONS void bind(endpoint_type const& endpoint) { diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 5087a0f25..eb6fa35ca 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -127,6 +127,7 @@ namespace libtorrent , cache_size(512) , cache_expiry(60) , outgoing_ports(0,0) + , peer_tos(0) {} // this is the user agent that will be sent to the tracker @@ -339,6 +340,13 @@ namespace libtorrent // is useful for users that have routers that // allow QoS settings based on local port. std::pair outgoing_ports; + + // the TOS byte of all peer traffic (including + // web seeds) is set to this value. The default + // is the QBSS scavenger service + // http://qbone.internet2.edu/qbss/ + // For unmarked packets, set to 0 + char peer_tos; }; #ifndef TORRENT_DISABLE_DHT diff --git a/include/libtorrent/socket.hpp b/include/libtorrent/socket.hpp index 2d829043e..704f7f171 100755 --- a/include/libtorrent/socket.hpp +++ b/include/libtorrent/socket.hpp @@ -185,6 +185,19 @@ namespace libtorrent int m_value; }; + struct type_of_service + { + type_of_service(char val): m_value(val) {} + template + int level(Protocol const&) const { return IPPROTO_IP; } + template + int name(Protocol const&) const { return IP_TOS; } + template + char const* data(Protocol const&) const { return &m_value; } + template + size_t size(Protocol const&) const { return sizeof(m_value); } + char m_value; + }; } #endif // TORRENT_SOCKET_HPP_INCLUDED diff --git a/include/libtorrent/variant_stream.hpp b/include/libtorrent/variant_stream.hpp index ff2f8f700..2daadbaa8 100644 --- a/include/libtorrent/variant_stream.hpp +++ b/include/libtorrent/variant_stream.hpp @@ -256,6 +256,45 @@ namespace aux { return EndpointType(); } }; +// -------------- set_option ----------- + + template + struct set_option_visitor + : boost::static_visitor<> + { + set_option_visitor(SettableSocketOption const& opt) + : opt_(opt) + {} + + template + void operator()(T* p) const + { p->set_option(opt_); } + + std::size_t operator()(boost::blank) const {} + + SettableSocketOption const& opt_; + }; + + template + struct set_option_visitor_ec + : boost::static_visitor + { + set_option_visitor_ec(SettableSocketOption const& opt, asio::error_code& ec) + : opt_(opt) + , ec_(ec) + {} + + template + asio::error_code operator()(T* p) const + { return p->set_option(opt_, ec_); } + + asio::error_code operator()(boost::blank) const + { return ec_; } + + SettableSocketOption const& opt_; + asio::error_code& ec_; + }; + // -------------- local_endpoint ----------- template @@ -657,6 +696,22 @@ public: ); } + template + void set_option(SettableSocketOption const& opt) + { + TORRENT_ASSERT(instantiated()); + boost::apply_visitor(aux::set_option_visitor(opt) + , m_variant); + } + + template + asio::error_code set_option(SettableSocketOption const& opt, asio::error_code& ec) + { + TORRENT_ASSERT(instantiated()); + return boost::apply_visitor(aux::set_option_visitor_ec(opt, ec) + , m_variant); + } + endpoint_type local_endpoint() const { TORRENT_ASSERT(instantiated()); diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 652776386..884998fc2 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -235,6 +235,9 @@ namespace libtorrent (*m_logger) << "*** INCOMING CONNECTION\n"; #endif + if (m_remote.address().is_v4()) + m_socket->set_option(type_of_service(ses.settings().peer_tos), ec); + #ifndef NDEBUG piece_failed = false; #endif @@ -3011,6 +3014,12 @@ namespace libtorrent << " rtt = " << m_rtt << "\n"; #endif + if (m_remote.address().is_v4()) + { + asio::error_code ec; + m_socket->set_option(type_of_service(m_ses.settings().peer_tos), ec); + } + on_connected(); setup_send(); setup_receive();