1 /*
2 
3 Copyright (c) 2015-2018, Arvid Norberg, Steven Siloti
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9 
10     * Redistributions of source code must retain the above copyright
11       notice, this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright
13       notice, this list of conditions and the following disclaimer in
14       the documentation and/or other materials provided with the distribution.
15     * Neither the name of the author nor the names of its
16       contributors may be used to endorse or promote products derived
17       from this software without specific prior written permission.
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
30 
31 */
32 
33 #include "libtorrent/peer_connection_handle.hpp"
34 #include "libtorrent/bt_peer_connection.hpp"
35 
36 #ifndef TORRENT_DISABLE_LOGGING
37 #include <cstdarg> // for va_start, va_end
38 #endif
39 
40 namespace libtorrent {
41 
type() const42 connection_type peer_connection_handle::type() const
43 {
44 	std::shared_ptr<peer_connection> pc = native_handle();
45 	TORRENT_ASSERT(pc);
46 	return pc->type();
47 }
48 
add_extension(std::shared_ptr<peer_plugin> ext)49 void peer_connection_handle::add_extension(std::shared_ptr<peer_plugin> ext)
50 {
51 #ifndef TORRENT_DISABLE_EXTENSIONS
52 	std::shared_ptr<peer_connection> pc = native_handle();
53 	TORRENT_ASSERT(pc);
54 	pc->add_extension(std::move(ext));
55 #else
56 	TORRENT_UNUSED(ext);
57 #endif
58 }
59 
find_plugin(string_view type) const60 peer_plugin const* peer_connection_handle::find_plugin(string_view type) const
61 {
62 #ifndef TORRENT_DISABLE_EXTENSIONS
63 	std::shared_ptr<peer_connection> pc = native_handle();
64 	TORRENT_ASSERT(pc);
65 	return pc->find_plugin(type);
66 #else
67 	TORRENT_UNUSED(type);
68 	return nullptr;
69 #endif
70 }
71 
is_seed() const72 bool peer_connection_handle::is_seed() const
73 {
74 	std::shared_ptr<peer_connection> pc = native_handle();
75 	TORRENT_ASSERT(pc);
76 	return pc->is_seed();
77 }
78 
upload_only() const79 bool peer_connection_handle::upload_only() const
80 {
81 	std::shared_ptr<peer_connection> pc = native_handle();
82 	TORRENT_ASSERT(pc);
83 	return pc->upload_only();
84 }
85 
pid() const86 peer_id const& peer_connection_handle::pid() const
87 {
88 	std::shared_ptr<peer_connection> pc = native_handle();
89 	TORRENT_ASSERT(pc);
90 	return pc->pid();
91 }
92 
has_piece(piece_index_t i) const93 bool peer_connection_handle::has_piece(piece_index_t i) const
94 {
95 	std::shared_ptr<peer_connection> pc = native_handle();
96 	TORRENT_ASSERT(pc);
97 	return pc->has_piece(i);
98 }
99 
is_interesting() const100 bool peer_connection_handle::is_interesting() const
101 {
102 	std::shared_ptr<peer_connection> pc = native_handle();
103 	TORRENT_ASSERT(pc);
104 	return pc->is_interesting();
105 }
106 
is_choked() const107 bool peer_connection_handle::is_choked() const
108 {
109 	std::shared_ptr<peer_connection> pc = native_handle();
110 	TORRENT_ASSERT(pc);
111 	return pc->is_choked();
112 }
113 
is_peer_interested() const114 bool peer_connection_handle::is_peer_interested() const
115 {
116 	std::shared_ptr<peer_connection> pc = native_handle();
117 	TORRENT_ASSERT(pc);
118 	return pc->is_peer_interested();
119 }
120 
has_peer_choked() const121 bool peer_connection_handle::has_peer_choked() const
122 {
123 	std::shared_ptr<peer_connection> pc = native_handle();
124 	TORRENT_ASSERT(pc);
125 	return pc->has_peer_choked();
126 }
127 
choke_this_peer()128 void peer_connection_handle::choke_this_peer()
129 {
130 	std::shared_ptr<peer_connection> pc = native_handle();
131 	TORRENT_ASSERT(pc);
132 	pc->choke_this_peer();
133 }
134 
maybe_unchoke_this_peer()135 void peer_connection_handle::maybe_unchoke_this_peer()
136 {
137 	std::shared_ptr<peer_connection> pc = native_handle();
138 	TORRENT_ASSERT(pc);
139 	pc->maybe_unchoke_this_peer();
140 }
141 
get_peer_info(peer_info & p) const142 void peer_connection_handle::get_peer_info(peer_info& p) const
143 {
144 	std::shared_ptr<peer_connection> pc = native_handle();
145 	TORRENT_ASSERT(pc);
146 	pc->get_peer_info(p);
147 }
148 
associated_torrent() const149 torrent_handle peer_connection_handle::associated_torrent() const
150 {
151 	std::shared_ptr<peer_connection> pc = native_handle();
152 	if (!pc) return torrent_handle();
153 	std::shared_ptr<torrent> t = pc->associated_torrent().lock();
154 	if (!t) return torrent_handle();
155 	return t->get_handle();
156 }
157 
remote() const158 tcp::endpoint const& peer_connection_handle::remote() const
159 {
160 	std::shared_ptr<peer_connection> pc = native_handle();
161 	TORRENT_ASSERT(pc);
162 	return pc->remote();
163 }
164 
local_endpoint() const165 tcp::endpoint peer_connection_handle::local_endpoint() const
166 {
167 	std::shared_ptr<peer_connection> pc = native_handle();
168 	TORRENT_ASSERT(pc);
169 	return pc->local_endpoint();
170 }
171 
disconnect(error_code const & ec,operation_t const op,disconnect_severity_t const error)172 void peer_connection_handle::disconnect(error_code const& ec, operation_t const op
173 	, disconnect_severity_t const error)
174 {
175 	std::shared_ptr<peer_connection> pc = native_handle();
176 	TORRENT_ASSERT(pc);
177 	pc->disconnect(ec, op, error);
178 }
179 
is_disconnecting() const180 bool peer_connection_handle::is_disconnecting() const
181 {
182 	std::shared_ptr<peer_connection> pc = native_handle();
183 	TORRENT_ASSERT(pc);
184 	return pc->is_disconnecting();
185 }
186 
is_connecting() const187 bool peer_connection_handle::is_connecting() const
188 {
189 	std::shared_ptr<peer_connection> pc = native_handle();
190 	TORRENT_ASSERT(pc);
191 	return pc->is_connecting();
192 }
193 
is_outgoing() const194 bool peer_connection_handle::is_outgoing() const
195 {
196 	std::shared_ptr<peer_connection> pc = native_handle();
197 	TORRENT_ASSERT(pc);
198 	return pc->is_outgoing();
199 }
200 
on_local_network() const201 bool peer_connection_handle::on_local_network() const
202 {
203 	std::shared_ptr<peer_connection> pc = native_handle();
204 	TORRENT_ASSERT(pc);
205 	return pc->on_local_network();
206 }
207 
ignore_unchoke_slots() const208 bool peer_connection_handle::ignore_unchoke_slots() const
209 {
210 	std::shared_ptr<peer_connection> pc = native_handle();
211 	TORRENT_ASSERT(pc);
212 	return pc->ignore_unchoke_slots();
213 }
214 
failed() const215 bool peer_connection_handle::failed() const
216 {
217 	std::shared_ptr<peer_connection> pc = native_handle();
218 	TORRENT_ASSERT(pc);
219 	return pc->failed();
220 }
221 
should_log(peer_log_alert::direction_t direction) const222 bool peer_connection_handle::should_log(peer_log_alert::direction_t direction) const
223 {
224 #ifndef TORRENT_DISABLE_LOGGING
225 	std::shared_ptr<peer_connection> pc = native_handle();
226 	TORRENT_ASSERT(pc);
227 	return pc->should_log(direction);
228 #else
229 	TORRENT_UNUSED(direction);
230 	return false;
231 #endif
232 }
233 
234 TORRENT_FORMAT(4,5)
peer_log(peer_log_alert::direction_t direction,char const * event,char const * fmt,...) const235 void peer_connection_handle::peer_log(peer_log_alert::direction_t direction
236 	, char const* event, char const* fmt, ...) const
237 {
238 #ifndef TORRENT_DISABLE_LOGGING
239 	std::shared_ptr<peer_connection> pc = native_handle();
240 	TORRENT_ASSERT(pc);
241 	va_list v;
242 	va_start(v, fmt);
243 #ifdef __clang__
244 #pragma clang diagnostic push
245 #pragma clang diagnostic ignored "-Wformat-nonliteral"
246 #pragma clang diagnostic ignored "-Wclass-varargs"
247 #endif
248 	pc->peer_log(direction, event, fmt, v);
249 #ifdef __clang__
250 #pragma clang diagnostic pop
251 #endif
252 	va_end(v);
253 #else // TORRENT_DISABLE_LOGGING
254 	TORRENT_UNUSED(direction);
255 	TORRENT_UNUSED(event);
256 	TORRENT_UNUSED(fmt);
257 #endif
258 }
259 
can_disconnect(error_code const & ec) const260 bool peer_connection_handle::can_disconnect(error_code const& ec) const
261 {
262 	std::shared_ptr<peer_connection> pc = native_handle();
263 	TORRENT_ASSERT(pc);
264 	return pc->can_disconnect(ec);
265 }
266 
has_metadata() const267 bool peer_connection_handle::has_metadata() const
268 {
269 	std::shared_ptr<peer_connection> pc = native_handle();
270 	TORRENT_ASSERT(pc);
271 	return pc->has_metadata();
272 }
273 
in_handshake() const274 bool peer_connection_handle::in_handshake() const
275 {
276 	std::shared_ptr<peer_connection> pc = native_handle();
277 	TORRENT_ASSERT(pc);
278 	return pc->in_handshake();
279 }
280 
send_buffer(char const * begin,int size)281 void peer_connection_handle::send_buffer(char const* begin, int size)
282 {
283 	std::shared_ptr<peer_connection> pc = native_handle();
284 	TORRENT_ASSERT(pc);
285 	pc->send_buffer({begin, size});
286 }
287 
last_seen_complete() const288 std::time_t peer_connection_handle::last_seen_complete() const
289 {
290 	std::shared_ptr<peer_connection> pc = native_handle();
291 	TORRENT_ASSERT(pc);
292 	return pc->last_seen_complete();
293 }
294 
time_of_last_unchoke() const295 time_point peer_connection_handle::time_of_last_unchoke() const
296 {
297 	std::shared_ptr<peer_connection> pc = native_handle();
298 	TORRENT_ASSERT(pc);
299 	return pc->time_of_last_unchoke();
300 }
301 
packet_finished() const302 bool bt_peer_connection_handle::packet_finished() const
303 {
304 	std::shared_ptr<bt_peer_connection> pc = native_handle();
305 	TORRENT_ASSERT(pc);
306 	return pc->packet_finished();
307 }
308 
support_extensions() const309 bool bt_peer_connection_handle::support_extensions() const
310 {
311 	std::shared_ptr<bt_peer_connection> pc = native_handle();
312 	TORRENT_ASSERT(pc);
313 	return pc->support_extensions();
314 }
315 
supports_encryption() const316 bool bt_peer_connection_handle::supports_encryption() const
317 {
318 #if !defined TORRENT_DISABLE_ENCRYPTION
319 	std::shared_ptr<bt_peer_connection> pc = native_handle();
320 	TORRENT_ASSERT(pc);
321 	return pc->supports_encryption();
322 #else
323 	return false;
324 #endif
325 }
326 
switch_send_crypto(std::shared_ptr<crypto_plugin> crypto)327 void bt_peer_connection_handle::switch_send_crypto(std::shared_ptr<crypto_plugin> crypto)
328 {
329 #if !defined TORRENT_DISABLE_ENCRYPTION
330 	std::shared_ptr<bt_peer_connection> pc = native_handle();
331 	TORRENT_ASSERT(pc);
332 	pc->switch_send_crypto(std::move(crypto));
333 #else
334 	TORRENT_UNUSED(crypto);
335 #endif
336 }
337 
switch_recv_crypto(std::shared_ptr<crypto_plugin> crypto)338 void bt_peer_connection_handle::switch_recv_crypto(std::shared_ptr<crypto_plugin> crypto)
339 {
340 #if !defined TORRENT_DISABLE_ENCRYPTION
341 	std::shared_ptr<bt_peer_connection> pc = native_handle();
342 	TORRENT_ASSERT(pc);
343 	pc->switch_recv_crypto(std::move(crypto));
344 #else
345 	TORRENT_UNUSED(crypto);
346 #endif
347 }
348 
native_handle() const349 std::shared_ptr<bt_peer_connection> bt_peer_connection_handle::native_handle() const
350 {
351 	return std::static_pointer_cast<bt_peer_connection>(
352 		peer_connection_handle::native_handle());
353 }
354 
355 } // namespace libtorrent
356