This file is indexed.

/usr/include/libtorrent/receive_buffer.hpp is in libtorrent-rasterbar-dev 1.1.1-1+b1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
/*

Copyright (c) 2014-2016, Arvid Norberg, 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_RECEIVE_BUFFER_HPP_INCLUDED
#define TORRENT_RECEIVE_BUFFER_HPP_INCLUDED

#include <libtorrent/buffer.hpp>
#include <libtorrent/disk_buffer_holder.hpp>
#include <boost/asio/buffer.hpp>
#include <vector>

namespace libtorrent {

struct TORRENT_EXTRA_EXPORT receive_buffer
{
	friend struct crypto_receive_buffer;

	receive_buffer(buffer_allocator_interface& allocator)
		: m_recv_start(0)
		, m_recv_end(0)
		, m_recv_pos(0)
		, m_packet_size(0)
		, m_soft_packet_size(0)
		, m_disk_recv_buffer_size(0)
		, m_disk_recv_buffer(allocator, 0)
	{}

	int packet_size() const { return m_packet_size; }
	int packet_bytes_remaining() const
	{
		TORRENT_ASSERT(m_recv_start == 0);
		TORRENT_ASSERT(m_packet_size > 0);
		return m_packet_size - m_recv_pos;
	}

	int max_receive();

	bool packet_finished() const { return m_packet_size <= m_recv_pos; }
	int pos() const { return m_recv_pos; }
	int capacity() const { return m_recv_buffer.capacity() + m_disk_recv_buffer_size; }

	int regular_buffer_size() const
	{
		TORRENT_ASSERT(m_packet_size > 0);
		return m_packet_size - m_disk_recv_buffer_size;
	}

	// regular buffer only
	boost::asio::mutable_buffer reserve(int size);
	// with possible disk buffer usage
	int reserve(boost::array<boost::asio::mutable_buffer, 2>& vec, int size);

	// tell the buffer we just receved more bytes at the end of it. This will
	// advance the end cursor
	void received(int bytes_transferred)
	{
		TORRENT_ASSERT(m_packet_size > 0);
		m_recv_end += bytes_transferred;
		TORRENT_ASSERT(m_recv_pos <= int(m_recv_buffer.size()
			+ m_disk_recv_buffer_size));
	}

	// tell the buffer we consumed some bytes of it. This will advance the read
	// cursor
	int advance_pos(int bytes);

	// has the read cursor reached the end cursor?
	bool pos_at_end() { return m_recv_pos == m_recv_end; }

	// make the buffer size dividible by 8 bytes (RC4 block size)
	void clamp_size();

	void set_soft_packet_size(int size) { m_soft_packet_size = size; }

	// size = the packet size to remove from the receive buffer
	// packet_size = the next packet size to receive in the buffer
	// offset = the offset into the receive buffer where to remove `size` bytes
	void cut(int size, int packet_size, int offset = 0);

	// return the interval between the start of the buffer to the read cursor.
	// This is the "current" packet.
	buffer::const_interval get() const;

#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
	// returns the entire regular buffer
	// should only be used during the handshake
	buffer::interval mutable_buffer();
	// returns the last 'bytes' from the receive buffer
	void mutable_buffers(std::vector<boost::asio::mutable_buffer>& vec, int bytes);
#endif

	void free_disk_buffer()
	{
		m_disk_recv_buffer.reset();
		m_disk_recv_buffer_size = 0;
	}

	bool has_disk_buffer() const { return m_disk_recv_buffer; }
	void assert_no_disk_buffer() const
	{
		TORRENT_ASSERT(!m_disk_recv_buffer);
		TORRENT_ASSERT(m_disk_recv_buffer_size == 0);
	}

	void assign_disk_buffer(char* buffer, int size);
	char* release_disk_buffer();

	// the purpose of this function is to free up and cut off all messages
	// in the receive buffer that have been parsed and processed.
	void normalize();
	bool normalized() const { return m_recv_start == 0; }

	void reset(int packet_size);

	bool can_recv_contiguous(int /*size*/) const { return true; }

#if TORRENT_USE_INVARIANT_CHECKS
	void check_invariant() const
	{
		TORRENT_ASSERT(m_recv_end >= m_recv_start);
		TORRENT_ASSERT(bool(m_disk_recv_buffer) == (m_disk_recv_buffer_size > 0));
	}
#endif

private:
	// explicitly disallow assignment, to silence msvc warning
	receive_buffer& operator=(receive_buffer const&);

	// recv_buf.begin (start of actual receive buffer)
	// |
	// |      m_recv_start (logical start of current
	// |      |  receive buffer, as perceived by upper layers)
	// |      |
	// |      |    m_recv_pos (number of bytes consumed
	// |      |    |  by upper layer, from logical receive buffer)
	// |      |    |
	// |      x---------x
	// |      |         |        recv_buf.end (end of actual receive buffer)
	// |      |         |        |
	// v      v         v        v
	// *------==========---------
	//                     ^
	//                     |
	//                     |
	// ------------------->x  m_recv_end (end of received data,
	//                          beyond this point is garbage)
	// m_recv_buffer

	// when not using contiguous receive buffers, there
	// may be a disk_recv_buffer in the mix as well. Whenever
	// m_disk_recv_buffer_size > 0 (and presumably also
	// m_disk_recv_buffer != NULL) the disk buffer is imagined
	// to be appended to the receive buffer right after m_recv_end.

	// the start of the logical receive buffer
	int m_recv_start;

	// the number of valid, received bytes in m_recv_buffer
	int m_recv_end;

	// the byte offset in m_recv_buffer that we have
	// are passing on to the upper layer. This is
	// always <= m_recv_end
	int m_recv_pos;

	// the size (in bytes) of the bittorrent message
	// we're currently receiving
	int m_packet_size;

	// the number of bytes that the other
	// end has to send us in order to respond
	// to all outstanding piece requests we
	// have sent to it
	int m_soft_packet_size;

	int m_disk_recv_buffer_size;

	buffer m_recv_buffer;

	// if this peer is receiving a piece, this
	// points to a disk buffer that the data is
	// read into. This eliminates a memcopy from
	// the receive buffer into the disk buffer
	disk_buffer_holder m_disk_recv_buffer;
};

#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
// Wraps a receive_buffer to provide the ability to inject
// possibly authenticated crypto beneath the bittorrent protocol.
// When authenticated crypto is in use the wrapped receive_buffer
// holds the receive state of the crpyto layer while this class
// tracks the state of the bittorrent protocol.
struct crypto_receive_buffer
{
	crypto_receive_buffer(receive_buffer& next)
	: m_recv_pos(INT_MAX)
	, m_packet_size(0)
	, m_soft_packet_size(0)
	, m_connection_buffer(next)
	{}

	buffer::interval mutable_buffer() { return m_connection_buffer.mutable_buffer(); }
	char* release_disk_buffer() { return m_connection_buffer.release_disk_buffer(); }
	bool has_disk_buffer() const { return m_connection_buffer.has_disk_buffer(); }
	void assert_no_disk_buffer() const { m_connection_buffer.assert_no_disk_buffer(); }

	bool packet_finished() const;

	bool crypto_packet_finished() const
	{
		return m_recv_pos == INT_MAX || m_connection_buffer.packet_finished();
	}

	int packet_size() const;

	int crypto_packet_size() const
	{
		TORRENT_ASSERT(m_recv_pos != INT_MAX);
		return m_connection_buffer.packet_size() - m_recv_pos;
	}

	int pos() const;

	void cut(int size, int packet_size, int offset = 0);

	void crypto_cut(int size, int packet_size)
	{
		TORRENT_ASSERT(m_recv_pos != INT_MAX);
		m_connection_buffer.cut(size, m_recv_pos + packet_size, m_recv_pos);
	}

	void reset(int packet_size);
	void crypto_reset(int packet_size);

	void set_soft_packet_size(int size);

	int advance_pos(int bytes);

	buffer::const_interval get() const;

	bool can_recv_contiguous(int /*size*/) const
	{
		// TODO: Detect when the start of the next crpyto packet is aligned
		// with the start of piece data and the crpyto packet is at least
		// as large as the piece data. With a little extra work
		// we could receive directly into a disk buffer in that case.
		return m_recv_pos == INT_MAX;
	}

	void mutable_buffers(std::vector<boost::asio::mutable_buffer>& vec
		, std::size_t bytes_transfered);

private:
	// explicitly disallow assignment, to silence msvc warning
	crypto_receive_buffer& operator=(crypto_receive_buffer const&);

	int m_recv_pos;
	int m_packet_size;
	int m_soft_packet_size;
	receive_buffer& m_connection_buffer;
};
#endif // TORRENT_DISABLE_ENCRYPTION

} // namespace libtorrent

#endif // #ifndef TORRENT_RECEIVE_BUFFER_HPP_INCLUDED