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 uTP edge case where udp socket buffer fills up
* fix nagle implementation in uTP * 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 * fix mingw build for linux crosscompiler
0.16.3 release 0.16.3 release

View File

@ -255,8 +255,13 @@ The extensions field is a bitmask. The following
bits are assigned: bits are assigned:
* 1 = authentication_. * 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 authentication
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -281,9 +286,35 @@ appended to it. It has the following format:
| | | from the 20 bytes hash calculated. | | | | 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 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 #endif
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/tuple/tuple.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
@ -599,7 +600,7 @@ namespace libtorrent
if (m_abort) return; 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; char* out = buf;
tracker_request const& req = tracker_req(); tracker_request const& req = tracker_req();
@ -636,9 +637,23 @@ namespace libtorrent
detail::write_int32(req.key, out); // key detail::write_int32(req.key, out); // key
detail::write_int32(req.num_want, out); // num_want detail::write_int32(req.num_want, out); // num_want
detail::write_uint16(req.listen_port, out); // port 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 #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
boost::shared_ptr<request_callback> cb = requester(); boost::shared_ptr<request_callback> cb = requester();
@ -652,17 +667,16 @@ namespace libtorrent
} }
#endif #endif
error_code ec;
if (!m_hostname.empty()) 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 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; m_state = action_announce;
sent_bytes(sizeof(buf) + 28); // assuming UDP/IP header sent_bytes(out - buf + 28); // assuming UDP/IP header
++m_attempts; ++m_attempts;
if (ec) if (ec)
{ {