extend the UDP tracker protocol to include the request string from the tracker URL

This commit is contained in:
Arvid Norberg 2012-08-23 21:02:09 +00:00
parent ad586df9fb
commit 43e9270363
3 changed files with 55 additions and 9 deletions

View File

@ -3,6 +3,7 @@
* fix uTP edge case where udp socket buffer fills up
* fix nagle implementation in uTP
* extend the UDP tracker protocol to include the request string from the tracker URL
* fix mingw build for linux crosscompiler
0.16.3 release

View File

@ -255,8 +255,13 @@ The extensions field is a bitmask. The following
bits are assigned:
* 1 = authentication_.
* 2 = `request string`_.
If multiple bits are present in the extension field, the extension
bodies are appended to the packet in the order of least significant
bit first. For instance, if both bit 1 and 2 are set, the extension
represented by bit 1 comes first, followed by the extension represented
by bit 2.
authentication
~~~~~~~~~~~~~~
@ -281,9 +286,35 @@ appended to it. It has the following format:
| | | from the 20 bytes hash calculated. |
+-------------+---------------------+----------------------------------------+
request string
--------------
The request string extension is meant to allow torrent creators pass along
cookies back to the tracker. This can be useful for authenticating that a
torrent is allowed to be tracked by a tracker for instance. It could also
be used to authenticate users by generating torrents with unique tokens
in the tracker URL for each user. The extension body has the following format:
+-------------+---------------------+----------------------------------------+
| size | name | description |
+=============+=====================+========================================+
| int16_t | request length | The number of bytes in the request |
| | | string. |
+-------------+---------------------+----------------------------------------+
| int8_t[] | request string | The string that comes after the host- |
| | | name and port in the udp tracker URL. |
| | | Typically this starts with "/announce" |
| | | The bittorrent client is not expected |
| | | to append query string arguments for |
| | | stats reporting, like "uploaded" and |
| | | "downloaded" since this is already |
| | | reported in the udp tracker protocol. |
| | | However, the client is free to add |
| | | arguments as extensions. |
+-------------+---------------------+----------------------------------------+
credits
-------
Protocol designed by Olaf van der Spek
Protocol designed by Olaf van der Spek and extended by Arvid Norberg

View File

@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include <boost/bind.hpp>
#include <boost/tuple/tuple.hpp>
#ifdef _MSC_VER
#pragma warning(pop)
@ -599,7 +600,7 @@ namespace libtorrent
if (m_abort) return;
char buf[8 + 4 + 4 + 20 + 20 + 8 + 8 + 8 + 4 + 4 + 4 + 4 + 2 + 2];
char buf[800];
char* out = buf;
tracker_request const& req = tracker_req();
@ -636,9 +637,23 @@ namespace libtorrent
detail::write_int32(req.key, out); // key
detail::write_int32(req.num_want, out); // num_want
detail::write_uint16(req.listen_port, out); // port
detail::write_uint16(0, out); // extensions
TORRENT_ASSERT(out - buf == sizeof(buf));
std::string request_string;
error_code ec;
using boost::tuples::ignore;
boost::tie(ignore, ignore, ignore, ignore, request_string) = parse_url_components(req.url, ec);
if (ec) request_string.clear();
detail::write_uint16(request_string.empty() ? 0: 2, out); // extensions. 2 = request-string
if (!request_string.empty())
{
if (request_string.size() > 512) request_string.resize(512);
detail::write_uint16(request_string.size(), out);
detail::write_string(request_string, out);
}
TORRENT_ASSERT(out - buf <= sizeof(buf));
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
boost::shared_ptr<request_callback> cb = requester();
@ -652,17 +667,16 @@ namespace libtorrent
}
#endif
error_code ec;
if (!m_hostname.empty())
{
m_ses.m_udp_socket.send_hostname(m_hostname.c_str(), m_target.port(), buf, sizeof(buf), ec);
m_ses.m_udp_socket.send_hostname(m_hostname.c_str(), m_target.port(), buf, out - buf, ec);
}
else
{
m_ses.m_udp_socket.send(m_target, buf, sizeof(buf), ec);
m_ses.m_udp_socket.send(m_target, buf, out - buf, ec);
}
m_state = action_announce;
sent_bytes(sizeof(buf) + 28); // assuming UDP/IP header
sent_bytes(out - buf + 28); // assuming UDP/IP header
++m_attempts;
if (ec)
{