Coverage Report

Created: 2025-08-25 06:28

/src/libtorrent/src/alert.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
3
Copyright (c) 2015, Thomas
4
Copyright (c) 2003, Daniel Wallin
5
Copyright (c) 2004, Magnus Jonsson
6
Copyright (c) 2009-2022, Arvid Norberg
7
Copyright (c) 2014-2018, Steven Siloti
8
Copyright (c) 2015-2018, Alden Torres
9
Copyright (c) 2015, Thomas Yuan
10
Copyright (c) 2016, Pavel Pimenov
11
Copyright (c) 2017, Andrei Kurushin
12
Copyright (c) 2017, Antoine Dahan
13
Copyright (c) 2019, Amir Abrams
14
Copyright (c) 2020, Fonic
15
Copyright (c) 2020, Viktor Elofsson
16
All rights reserved.
17
18
Redistribution and use in source and binary forms, with or without
19
modification, are permitted provided that the following conditions
20
are met:
21
22
    * Redistributions of source code must retain the above copyright
23
      notice, this list of conditions and the following disclaimer.
24
    * Redistributions in binary form must reproduce the above copyright
25
      notice, this list of conditions and the following disclaimer in
26
      the documentation and/or other materials provided with the distribution.
27
    * Neither the name of the author nor the names of its
28
      contributors may be used to endorse or promote products derived
29
      from this software without specific prior written permission.
30
31
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41
POSSIBILITY OF SUCH DAMAGE.
42
43
*/
44
45
#include <string>
46
#include <cstdio> // for snprintf
47
#include <cinttypes> // for PRId64 et.al.
48
49
#include "libtorrent/config.hpp"
50
#include "libtorrent/alert.hpp"
51
#include "libtorrent/alert_types.hpp"
52
#include "libtorrent/socket_io.hpp"
53
#include "libtorrent/error_code.hpp"
54
#include "libtorrent/torrent.hpp"
55
#include "libtorrent/performance_counters.hpp"
56
#include "libtorrent/stack_allocator.hpp"
57
#include "libtorrent/piece_block.hpp"
58
#include "libtorrent/hex.hpp" // to_hex
59
#include "libtorrent/session_stats.hpp"
60
#include "libtorrent/socket_type.hpp"
61
#include "libtorrent/peer_info.hpp"
62
#include "libtorrent/aux_/ip_helpers.hpp" // for is_v4
63
64
#if TORRENT_ABI_VERSION == 1
65
#include "libtorrent/write_resume_data.hpp"
66
#endif
67
68
#include "libtorrent/aux_/escape_string.hpp" // for convert_from_native
69
70
namespace libtorrent {
71
72
  constexpr alert_category_t alert::error_notification;
73
  constexpr alert_category_t alert::peer_notification;
74
  constexpr alert_category_t alert::port_mapping_notification;
75
  constexpr alert_category_t alert::storage_notification;
76
  constexpr alert_category_t alert::tracker_notification;
77
  constexpr alert_category_t alert::connect_notification;
78
  constexpr alert_category_t alert::status_notification;
79
#if TORRENT_ABI_VERSION == 1
80
  constexpr alert_category_t alert::debug_notification;
81
  constexpr alert_category_t alert::progress_notification;
82
#endif
83
  constexpr alert_category_t alert::ip_block_notification;
84
  constexpr alert_category_t alert::performance_warning;
85
  constexpr alert_category_t alert::dht_notification;
86
#if TORRENT_ABI_VERSION <= 2
87
  constexpr alert_category_t alert::stats_notification;
88
#endif
89
  constexpr alert_category_t alert::session_log_notification;
90
  constexpr alert_category_t alert::torrent_log_notification;
91
  constexpr alert_category_t alert::peer_log_notification;
92
  constexpr alert_category_t alert::incoming_request_notification;
93
  constexpr alert_category_t alert::dht_log_notification;
94
  constexpr alert_category_t alert::dht_operation_notification;
95
  constexpr alert_category_t alert::port_mapping_log_notification;
96
  constexpr alert_category_t alert::picker_log_notification;
97
  constexpr alert_category_t alert::file_progress_notification;
98
  constexpr alert_category_t alert::piece_progress_notification;
99
  constexpr alert_category_t alert::upload_notification;
100
  constexpr alert_category_t alert::block_progress_notification;
101
102
  constexpr alert_category_t alert::all_categories;
103
104
0
  alert::alert() : m_timestamp(clock_type::now()) {}
105
0
  alert::~alert() = default;
106
0
  time_point alert::timestamp() const { return m_timestamp; }
107
108
  torrent_alert::torrent_alert(aux::stack_allocator& alloc
109
    , torrent_handle const& h)
110
0
    : handle(h)
111
0
    , m_alloc(alloc)
112
0
  {
113
0
    std::shared_ptr<torrent> t = h.native_handle();
114
0
    if (t)
115
0
      m_name_idx = t->name_idx(alloc);
116
117
0
#if TORRENT_ABI_VERSION == 1
118
0
    name = m_alloc.get().ptr(m_name_idx);
119
0
#endif
120
0
  }
121
122
  char const* torrent_alert::torrent_name() const
123
0
  {
124
0
    return m_alloc.get().ptr(m_name_idx);
125
0
  }
126
127
  std::string torrent_alert::message() const
128
0
  {
129
#ifdef TORRENT_DISABLE_ALERT_MSG
130
    return {};
131
#else
132
0
    if (!handle.is_valid()) return " - ";
133
0
    return torrent_name();
134
0
#endif
135
0
  }
136
137
  peer_alert::peer_alert(aux::stack_allocator& alloc
138
    , torrent_handle const& h
139
    , tcp::endpoint const& i
140
    , peer_id const& pi)
141
0
    : torrent_alert(alloc, h)
142
0
    , endpoint(i)
143
0
    , pid(pi)
144
#if TORRENT_ABI_VERSION == 1
145
0
    , ip(i)
146
#endif
147
0
  {}
148
149
  std::string peer_alert::message() const
150
0
  {
151
#ifdef TORRENT_DISABLE_ALERT_MSG
152
    return {};
153
#else
154
0
    return torrent_alert::message() + " peer [ " + print_endpoint(endpoint)
155
0
      + " client: " + aux::identify_client_impl(pid) + " ]";
156
0
#endif
157
0
  }
158
159
  tracker_alert::tracker_alert(aux::stack_allocator& alloc
160
    , torrent_handle const& h, tcp::endpoint const& ep, string_view u)
161
0
    : torrent_alert(alloc, h)
162
0
    , local_endpoint(ep)
163
0
    , m_url_idx(alloc.copy_string(u))
164
#if TORRENT_ABI_VERSION == 1
165
0
    , url(u)
166
#endif
167
0
  {}
168
169
  char const* tracker_alert::tracker_url() const
170
0
  {
171
0
    return m_alloc.get().ptr(m_url_idx);
172
0
  }
173
174
  std::string tracker_alert::message() const
175
0
  {
176
#ifdef TORRENT_DISABLE_ALERT_MSG
177
    return {};
178
#else
179
0
    return torrent_alert::message() + " (" + tracker_url() + ")"
180
0
      + "[" + print_endpoint(local_endpoint) + "]";
181
0
#endif
182
0
  }
183
184
  read_piece_alert::read_piece_alert(aux::stack_allocator& alloc
185
    , torrent_handle const& h
186
    , piece_index_t p, boost::shared_array<char> d, int s)
187
0
    : torrent_alert(alloc, h)
188
0
    , buffer(std::move(d))
189
0
    , piece(p)
190
0
    , size(s)
191
0
  {}
192
193
  read_piece_alert::read_piece_alert(aux::stack_allocator& alloc
194
    , torrent_handle h, piece_index_t p, error_code e)
195
0
    : torrent_alert(alloc, h)
196
0
    , error(e)
197
0
    , piece(p)
198
0
    , size(0)
199
#if TORRENT_ABI_VERSION == 1
200
0
    , ec(e)
201
#endif
202
0
  {}
203
204
  std::string read_piece_alert::message() const
205
0
  {
206
#ifdef TORRENT_DISABLE_ALERT_MSG
207
    return {};
208
#else
209
0
    char msg[200];
210
0
    if (error)
211
0
    {
212
0
      std::snprintf(msg, sizeof(msg), "%s: read_piece %d failed: %s"
213
0
        , torrent_alert::message().c_str() , static_cast<int>(piece)
214
0
        , convert_from_native(error.message()).c_str());
215
0
    }
216
0
    else
217
0
    {
218
0
      std::snprintf(msg, sizeof(msg), "%s: read_piece %d successful"
219
0
        , torrent_alert::message().c_str() , static_cast<int>(piece));
220
0
    }
221
0
    return msg;
222
0
#endif
223
0
  }
224
225
  file_completed_alert::file_completed_alert(aux::stack_allocator& alloc
226
    , torrent_handle const& h
227
    , file_index_t idx)
228
0
    : torrent_alert(alloc, h)
229
0
    , index(idx)
230
0
  {}
231
232
  std::string file_completed_alert::message() const
233
0
  {
234
#ifdef TORRENT_DISABLE_ALERT_MSG
235
    return {};
236
#else
237
0
    std::string ret { torrent_alert::message() };
238
0
    char msg[200];
239
0
    std::snprintf(msg, sizeof(msg), ": file %d finished downloading"
240
0
      , static_cast<int>(index));
241
0
    ret.append(msg);
242
0
    return ret;
243
0
#endif
244
0
  }
245
246
  file_renamed_alert::file_renamed_alert(aux::stack_allocator& alloc
247
    , torrent_handle const& h, string_view n, string_view old, file_index_t const idx)
248
0
    : torrent_alert(alloc, h)
249
0
    , index(idx)
250
0
    , m_name_idx(alloc.copy_string(n))
251
0
    , m_old_name_idx(alloc.copy_string(old))
252
#if TORRENT_ABI_VERSION == 1
253
0
    , name(n)
254
#endif
255
0
  {}
256
257
  char const* file_renamed_alert::new_name() const
258
0
  {
259
0
    return m_alloc.get().ptr(m_name_idx);
260
0
  }
261
262
  char const* file_renamed_alert::old_name() const
263
0
  {
264
0
    return m_alloc.get().ptr(m_old_name_idx);
265
0
  }
266
267
  std::string file_renamed_alert::message() const
268
0
  {
269
#ifdef TORRENT_DISABLE_ALERT_MSG
270
    return {};
271
#else
272
0
    std::string ret { torrent_alert::message() };
273
0
    char msg[200];
274
0
    std::snprintf(msg, sizeof(msg), ": file %d renamed from \""
275
0
      , static_cast<int>(index));
276
0
    ret.append(msg);
277
0
    ret.append(old_name());
278
0
    ret.append("\" to \"");
279
0
    ret.append(new_name());
280
0
    ret.append("\"");
281
0
    return ret;
282
0
#endif
283
0
  }
284
285
  file_rename_failed_alert::file_rename_failed_alert(aux::stack_allocator& alloc
286
    , torrent_handle const& h
287
    , file_index_t const idx
288
    , error_code ec)
289
0
    : torrent_alert(alloc, h)
290
0
    , index(idx)
291
0
    , error(ec)
292
0
  {}
293
294
  std::string file_rename_failed_alert::message() const
295
0
  {
296
#ifdef TORRENT_DISABLE_ALERT_MSG
297
    return {};
298
#else
299
0
    std::string ret { torrent_alert::message() };
300
0
    char msg[200];
301
0
    std::snprintf(msg, sizeof(msg), ": failed to rename file %d: "
302
0
      , static_cast<int>(index));
303
0
    ret.append(msg);
304
0
    ret.append(convert_from_native(error.message()));
305
0
    return ret;
306
0
#endif
307
0
  }
308
309
  performance_alert::performance_alert(aux::stack_allocator& alloc
310
    , torrent_handle const& h
311
    , performance_warning_t w)
312
0
    : torrent_alert(alloc, h)
313
0
    , warning_code(w)
314
0
  {}
315
316
  char const* performance_warning_str(performance_alert::performance_warning_t i)
317
0
  {
318
#ifdef TORRENT_DISABLE_ALERT_MSG
319
    TORRENT_UNUSED(i);
320
    return "";
321
#else
322
0
    static char const* const warning_str[] =
323
0
    {
324
0
      "max outstanding disk writes reached",
325
0
      "max outstanding piece requests reached",
326
0
      "upload limit too low (download rate will suffer)",
327
0
      "download limit too low (upload rate will suffer)",
328
0
      "send buffer watermark too low (upload rate will suffer)",
329
0
      "too many optimistic unchoke slots",
330
0
      "the disk queue limit is too high compared to the cache size. The disk queue eats into the cache size",
331
0
      "outstanding AIO operations limit reached",
332
0
      "",
333
0
      "too few ports allowed for outgoing connections",
334
0
      "too few file descriptors are allowed for this process. connection limit lowered"
335
0
    };
336
337
0
    TORRENT_ASSERT(i >= 0);
338
0
    TORRENT_ASSERT(i < std::end(warning_str) - std::begin(warning_str));
339
0
    return warning_str[i];
340
0
#endif
341
0
  }
342
343
  std::string performance_alert::message() const
344
0
  {
345
0
    return torrent_alert::message() + ": performance warning: "
346
0
      + performance_warning_str(warning_code);
347
0
  }
348
349
  state_changed_alert::state_changed_alert(aux::stack_allocator& alloc
350
    , torrent_handle const& h
351
    , torrent_status::state_t st
352
    , torrent_status::state_t prev_st)
353
0
    : torrent_alert(alloc, h)
354
0
    , state(st)
355
0
    , prev_state(prev_st)
356
0
  {}
357
358
  std::string state_changed_alert::message() const
359
0
  {
360
#ifdef TORRENT_DISABLE_ALERT_MSG
361
    return {};
362
#else
363
0
    static char const* const state_str[] =
364
0
      {"checking (q)", "checking", "dl metadata"
365
0
      , "downloading", "finished", "seeding", "allocating"
366
0
      , "checking (r)"};
367
368
0
    return torrent_alert::message() + ": state changed to: "
369
0
      + state_str[state];
370
0
#endif
371
0
  }
372
373
  tracker_error_alert::tracker_error_alert(aux::stack_allocator& alloc
374
    , torrent_handle const& h, tcp::endpoint const& ep, int times
375
    , protocol_version v, string_view u, operation_t const operation
376
    , error_code const& e
377
    , string_view m)
378
0
    : tracker_alert(alloc, h, ep, u)
379
0
    , times_in_row(times)
380
0
    , error(e)
381
0
    , op(operation)
382
0
    , m_msg_idx(alloc.copy_string(m))
383
#if TORRENT_ABI_VERSION == 1
384
0
    , status_code(e && e.category() == http_category() ? e.value() : -1)
385
0
    , msg(m)
386
#endif
387
    // TODO: move this field into tracker_alert
388
0
    , version(v)
389
0
  {
390
0
    TORRENT_ASSERT(!u.empty());
391
0
  }
392
393
  char const* tracker_error_alert::failure_reason() const
394
0
  {
395
0
    return m_alloc.get().ptr(m_msg_idx);
396
0
  }
397
398
  std::string tracker_error_alert::message() const
399
0
  {
400
#ifdef TORRENT_DISABLE_ALERT_MSG
401
    return {};
402
#else
403
0
    char ret[400];
404
0
    std::snprintf(ret, sizeof(ret), "%s %s %s \"%s\" (%d)"
405
0
      , tracker_alert::message().c_str()
406
0
      , version == protocol_version::V1 ? "v1" : "v2"
407
0
      , convert_from_native(error.message()).c_str(), error_message()
408
0
      , times_in_row);
409
0
    return ret;
410
0
#endif
411
0
  }
412
413
  tracker_warning_alert::tracker_warning_alert(aux::stack_allocator& alloc
414
    , torrent_handle const& h, tcp::endpoint const& ep
415
    , string_view u, protocol_version v, string_view m)
416
0
    : tracker_alert(alloc, h, ep, u)
417
0
    , m_msg_idx(alloc.copy_string(m))
418
#if TORRENT_ABI_VERSION == 1
419
0
    , msg(m)
420
#endif
421
    // TODO: move this into tracker_alert
422
0
    , version(v)
423
0
  {
424
0
    TORRENT_ASSERT(!u.empty());
425
0
  }
426
427
  char const* tracker_warning_alert::warning_message() const
428
0
  {
429
0
    return m_alloc.get().ptr(m_msg_idx);
430
0
  }
431
432
  std::string tracker_warning_alert::message() const
433
0
  {
434
#ifdef TORRENT_DISABLE_ALERT_MSG
435
    return {};
436
#else
437
0
    return tracker_alert::message() + (version == protocol_version::V1 ? " v1" : " v2") + " warning: " + warning_message();
438
0
#endif
439
0
  }
440
441
  scrape_reply_alert::scrape_reply_alert(aux::stack_allocator& alloc
442
    , torrent_handle const& h, tcp::endpoint const& ep
443
    , int incomp, int comp, string_view u, protocol_version const v)
444
0
    : tracker_alert(alloc, h, ep, u)
445
0
    , incomplete(incomp)
446
0
    , complete(comp)
447
    // TODO: move this into tracker_alert
448
0
    , version(v)
449
0
  {
450
0
    TORRENT_ASSERT(!u.empty());
451
0
  }
452
453
  std::string scrape_reply_alert::message() const
454
0
  {
455
#ifdef TORRENT_DISABLE_ALERT_MSG
456
    return {};
457
#else
458
0
    char ret[400];
459
0
    std::snprintf(ret, sizeof(ret), "%s %s scrape reply: %d %d"
460
0
      , tracker_alert::message().c_str()
461
0
      , version == protocol_version::V1 ? "v1" : "v2"
462
0
      , incomplete, complete);
463
0
    return ret;
464
0
#endif
465
0
  }
466
467
  scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc
468
    , torrent_handle const& h, tcp::endpoint const& ep
469
    , string_view u, protocol_version const v, error_code const& e)
470
0
    : tracker_alert(alloc, h, ep, u)
471
0
    , error(e)
472
0
    , m_msg_idx()
473
#if TORRENT_ABI_VERSION == 1
474
0
    , msg(convert_from_native(e.message()))
475
#endif
476
    // TODO: move this into tracker_alert
477
0
    , version(v)
478
0
  {
479
0
    TORRENT_ASSERT(!u.empty());
480
0
  }
481
482
  scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc
483
    , torrent_handle const& h, tcp::endpoint const& ep
484
    , string_view u, string_view m)
485
0
    : tracker_alert(alloc, h, ep, u)
486
0
    , error(errors::tracker_failure)
487
0
    , m_msg_idx(alloc.copy_string(m))
488
#if TORRENT_ABI_VERSION == 1
489
0
    , msg(m)
490
#endif
491
0
  {
492
0
    TORRENT_ASSERT(!u.empty());
493
0
  }
494
495
  char const* scrape_failed_alert::error_message() const
496
0
  {
497
0
    if (m_msg_idx == aux::allocation_slot()) return "";
498
0
    else return m_alloc.get().ptr(m_msg_idx);
499
0
  }
500
501
  std::string scrape_failed_alert::message() const
502
0
  {
503
#ifdef TORRENT_DISABLE_ALERT_MSG
504
    return {};
505
#else
506
0
    return tracker_alert::message() + " scrape failed: " + error_message();
507
0
#endif
508
0
  }
509
510
  tracker_reply_alert::tracker_reply_alert(aux::stack_allocator& alloc
511
    , torrent_handle const& h, tcp::endpoint const& ep
512
    , int np, protocol_version v, string_view u)
513
0
    : tracker_alert(alloc, h, ep, u)
514
0
    , num_peers(np)
515
    // TODO: move this field into tracker_alert
516
0
    , version(v)
517
0
  {
518
0
    TORRENT_ASSERT(!u.empty());
519
0
  }
520
521
  std::string tracker_reply_alert::message() const
522
0
  {
523
#ifdef TORRENT_DISABLE_ALERT_MSG
524
    return {};
525
#else
526
0
    char ret[400];
527
0
    std::snprintf(ret, sizeof(ret), "%s %s received peers: %d"
528
0
      , tracker_alert::message().c_str()
529
0
      , version == protocol_version::V1 ? "v1" : "v2"
530
0
      , num_peers);
531
0
    return ret;
532
0
#endif
533
0
  }
534
535
  dht_reply_alert::dht_reply_alert(aux::stack_allocator& alloc
536
    , torrent_handle const& h
537
    , int np)
538
0
    : tracker_alert(alloc, h, {}, "")
539
0
    , num_peers(np)
540
0
  {}
541
542
  std::string dht_reply_alert::message() const
543
0
  {
544
#ifdef TORRENT_DISABLE_ALERT_MSG
545
    return {};
546
#else
547
0
    char ret[400];
548
0
    std::snprintf(ret, sizeof(ret), "%s received DHT peers: %d"
549
0
      , tracker_alert::message().c_str(), num_peers);
550
0
    return ret;
551
0
#endif
552
0
  }
553
554
  tracker_announce_alert::tracker_announce_alert(aux::stack_allocator& alloc
555
    , torrent_handle const& h, tcp::endpoint const& ep, string_view u
556
    , protocol_version const v, event_t const e)
557
0
    : tracker_alert(alloc, h, ep, u)
558
0
    , event(e)
559
    // TODO: move this to tracker_alert
560
0
    , version(v)
561
0
  {
562
0
    TORRENT_ASSERT(!u.empty());
563
0
  }
564
565
  std::string tracker_announce_alert::message() const
566
0
  {
567
#ifdef TORRENT_DISABLE_ALERT_MSG
568
    return {};
569
#else
570
0
    static const char* const event_str[] = {"none", "completed", "started", "stopped", "paused"};
571
0
    return tracker_alert::message()
572
0
      + (version == protocol_version::V1 ? " v1" : " v2")
573
0
      + " sending announce (" + event_str[static_cast<int>(event)] + ")";
574
0
#endif
575
0
  }
576
577
  hash_failed_alert::hash_failed_alert(
578
    aux::stack_allocator& alloc
579
    , torrent_handle const& h
580
    , piece_index_t index)
581
0
    : torrent_alert(alloc, h)
582
0
    , piece_index(index)
583
0
  {
584
0
    TORRENT_ASSERT(index >= piece_index_t(0));
585
0
  }
586
587
  std::string hash_failed_alert::message() const
588
0
  {
589
#ifdef TORRENT_DISABLE_ALERT_MSG
590
    return {};
591
#else
592
0
    char ret[400];
593
0
    std::snprintf(ret, sizeof(ret), "%s hash for piece %d failed"
594
0
      , torrent_alert::message().c_str(), static_cast<int>(piece_index));
595
0
    return ret;
596
0
#endif
597
0
  }
598
599
  peer_ban_alert::peer_ban_alert(aux::stack_allocator& alloc
600
    , torrent_handle h, tcp::endpoint const& ep
601
    , peer_id const& peer_id)
602
0
    : peer_alert(alloc, h, ep, peer_id)
603
0
  {}
604
605
  std::string peer_ban_alert::message() const
606
0
  {
607
#ifdef TORRENT_DISABLE_ALERT_MSG
608
    return {};
609
#else
610
0
    return peer_alert::message() + " banned peer";
611
0
#endif
612
0
  }
613
614
  peer_unsnubbed_alert::peer_unsnubbed_alert(aux::stack_allocator& alloc
615
    , torrent_handle h, tcp::endpoint const& ep
616
    , peer_id const& peer_id)
617
0
    : peer_alert(alloc, h, ep, peer_id)
618
0
  {}
619
620
  std::string peer_unsnubbed_alert::message() const
621
0
  {
622
#ifdef TORRENT_DISABLE_ALERT_MSG
623
    return {};
624
#else
625
0
    return peer_alert::message() + " peer unsnubbed";
626
0
#endif
627
0
  }
628
629
  peer_snubbed_alert::peer_snubbed_alert(aux::stack_allocator& alloc
630
    , torrent_handle h, tcp::endpoint const& ep
631
    , peer_id const& peer_id)
632
0
    : peer_alert(alloc, h, ep, peer_id)
633
0
  {}
634
635
  std::string peer_snubbed_alert::message() const
636
0
  {
637
#ifdef TORRENT_DISABLE_ALERT_MSG
638
    return {};
639
#else
640
0
    return peer_alert::message() + " peer snubbed";
641
0
#endif
642
0
  }
643
644
  invalid_request_alert::invalid_request_alert(aux::stack_allocator& alloc
645
    , torrent_handle const& h, tcp::endpoint const& ep
646
    , peer_id const& peer_id, peer_request const& r
647
    , bool _have, bool _peer_interested, bool _withheld)
648
0
    : peer_alert(alloc, h, ep, peer_id)
649
0
    , request(r)
650
0
    , we_have(_have)
651
0
    , peer_interested(_peer_interested)
652
0
    , withheld(_withheld)
653
0
  {}
654
655
  std::string invalid_request_alert::message() const
656
0
  {
657
#ifdef TORRENT_DISABLE_ALERT_MSG
658
    return {};
659
#else
660
0
    char ret[400];
661
0
    std::snprintf(ret, sizeof(ret), "%s peer sent an invalid piece request "
662
0
      "(piece: %d start: %d len: %d)%s"
663
0
      , peer_alert::message().c_str()
664
0
      , static_cast<int>(request.piece)
665
0
      , request.start
666
0
      , request.length
667
0
      , withheld ? ": super seeding withheld piece"
668
0
      : !we_have ? ": we don't have piece"
669
0
      : !peer_interested ? ": peer is not interested"
670
0
      : "");
671
0
    return ret;
672
0
#endif
673
0
  }
674
675
  torrent_finished_alert::torrent_finished_alert(aux::stack_allocator& alloc
676
    , torrent_handle h)
677
0
    : torrent_alert(alloc, h)
678
0
  {}
679
680
  std::string torrent_finished_alert::message() const
681
0
  {
682
#ifdef TORRENT_DISABLE_ALERT_MSG
683
    return {};
684
#else
685
0
    return torrent_alert::message() + " torrent finished downloading";
686
0
#endif
687
0
  }
688
689
  piece_finished_alert::piece_finished_alert(aux::stack_allocator& alloc
690
    , torrent_handle const& h, piece_index_t piece_num)
691
0
    : torrent_alert(alloc, h)
692
0
    , piece_index(piece_num)
693
0
  {}
694
695
  std::string piece_finished_alert::message() const
696
0
  {
697
#ifdef TORRENT_DISABLE_ALERT_MSG
698
    return {};
699
#else
700
0
    char ret[200];
701
0
    std::snprintf(ret, sizeof(ret), "%s piece: %d finished downloading"
702
0
      , torrent_alert::message().c_str(), static_cast<int>(piece_index));
703
0
    return ret;
704
0
#endif
705
0
  }
706
707
  request_dropped_alert::request_dropped_alert(aux::stack_allocator& alloc, torrent_handle h
708
    , tcp::endpoint const& ep, peer_id const& peer_id, int block_num
709
    , piece_index_t piece_num)
710
0
    : peer_alert(alloc, h, ep, peer_id)
711
0
    , block_index(block_num)
712
0
    , piece_index(piece_num)
713
0
  {
714
0
    TORRENT_ASSERT(block_index >= 0 && piece_index >= piece_index_t(0));
715
0
  }
716
717
  std::string request_dropped_alert::message() const
718
0
  {
719
#ifdef TORRENT_DISABLE_ALERT_MSG
720
    return {};
721
#else
722
0
    char ret[200];
723
0
    std::snprintf(ret, sizeof(ret), "%s peer dropped block ( piece: %d block: %d)"
724
0
      , peer_alert::message().c_str(), static_cast<int>(piece_index), block_index);
725
0
    return ret;
726
0
#endif
727
0
  }
728
729
  block_timeout_alert::block_timeout_alert(aux::stack_allocator& alloc, torrent_handle h
730
    , tcp::endpoint const& ep, peer_id const& peer_id, int block_num
731
    , piece_index_t piece_num)
732
0
    : peer_alert(alloc, h, ep, peer_id)
733
0
    , block_index(block_num)
734
0
    , piece_index(piece_num)
735
0
  {
736
0
    TORRENT_ASSERT(block_index >= 0 && piece_index >= piece_index_t(0));
737
0
  }
738
739
  std::string block_timeout_alert::message() const
740
0
  {
741
#ifdef TORRENT_DISABLE_ALERT_MSG
742
    return {};
743
#else
744
0
    char ret[200];
745
0
    std::snprintf(ret, sizeof(ret), "%s peer timed out request ( piece: %d block: %d)"
746
0
      , peer_alert::message().c_str(), static_cast<int>(piece_index), block_index);
747
0
    return ret;
748
0
#endif
749
0
  }
750
751
  block_finished_alert::block_finished_alert(aux::stack_allocator& alloc, torrent_handle h
752
    , tcp::endpoint const& ep, peer_id const& peer_id, int block_num
753
    , piece_index_t piece_num)
754
0
    : peer_alert(alloc, h, ep, peer_id)
755
0
    , block_index(block_num)
756
0
    , piece_index(piece_num)
757
0
  {
758
0
    TORRENT_ASSERT(block_index >= 0 && piece_index >= piece_index_t(0));
759
0
  }
760
761
  std::string block_finished_alert::message() const
762
0
  {
763
#ifdef TORRENT_DISABLE_ALERT_MSG
764
    return {};
765
#else
766
0
    char ret[200];
767
0
    std::snprintf(ret, sizeof(ret), "%s block finished downloading (piece: %d block: %d)"
768
0
      , peer_alert::message().c_str(), static_cast<int>(piece_index), block_index);
769
0
    return ret;
770
0
#endif
771
0
  }
772
773
  block_downloading_alert::block_downloading_alert(aux::stack_allocator& alloc, torrent_handle h
774
    , tcp::endpoint const& ep
775
    , peer_id const& peer_id, int block_num, piece_index_t piece_num)
776
0
    : peer_alert(alloc, h, ep, peer_id)
777
0
    , block_index(block_num)
778
0
    , piece_index(piece_num)
779
#if TORRENT_ABI_VERSION == 1
780
0
    , peer_speedmsg("")
781
#endif
782
0
  {
783
0
    TORRENT_ASSERT(block_index >= 0 && piece_index >= piece_index_t(0));
784
0
  }
785
786
  std::string block_downloading_alert::message() const
787
0
  {
788
#ifdef TORRENT_DISABLE_ALERT_MSG
789
    return {};
790
#else
791
0
    char ret[200];
792
0
    std::snprintf(ret, sizeof(ret), "%s requested block (piece: %d block: %d)"
793
0
      , peer_alert::message().c_str(), static_cast<int>(piece_index), block_index);
794
0
    return ret;
795
0
#endif
796
0
  }
797
798
  unwanted_block_alert::unwanted_block_alert(aux::stack_allocator& alloc, torrent_handle h
799
    , tcp::endpoint const& ep
800
    , peer_id const& peer_id, int block_num, piece_index_t piece_num)
801
0
    : peer_alert(alloc, h, ep, peer_id)
802
0
    , block_index(block_num)
803
0
    , piece_index(piece_num)
804
0
  {
805
0
    TORRENT_ASSERT(block_index >= 0 && piece_index >= piece_index_t(0));
806
0
  }
807
808
  std::string unwanted_block_alert::message() const
809
0
  {
810
#ifdef TORRENT_DISABLE_ALERT_MSG
811
    return {};
812
#else
813
0
    char ret[200];
814
0
    std::snprintf(ret, sizeof(ret), "%s received block not in download queue (piece: %d block: %d)"
815
0
      , peer_alert::message().c_str(), static_cast<int>(piece_index), block_index);
816
0
    return ret;
817
0
#endif
818
0
  }
819
820
  storage_moved_alert::storage_moved_alert(aux::stack_allocator& alloc
821
    , torrent_handle const& h, string_view p, string_view old)
822
0
    : torrent_alert(alloc, h)
823
0
    , m_path_idx(alloc.copy_string(p))
824
0
    , m_old_path_idx(alloc.copy_string(old))
825
#if TORRENT_ABI_VERSION == 1
826
0
    , path(p)
827
#endif
828
0
  {}
829
830
  std::string storage_moved_alert::message() const
831
0
  {
832
#ifdef TORRENT_DISABLE_ALERT_MSG
833
    return {};
834
#else
835
0
    return torrent_alert::message() + " moved storage from \""
836
0
      + old_path() + "\" to: \"" + storage_path() + "\"";
837
0
#endif
838
0
  }
839
840
  char const* storage_moved_alert::storage_path() const
841
0
  {
842
0
    return m_alloc.get().ptr(m_path_idx);
843
0
  }
844
845
  char const* storage_moved_alert::old_path() const
846
0
  {
847
0
    return m_alloc.get().ptr(m_old_path_idx);
848
0
  }
849
850
  storage_moved_failed_alert::storage_moved_failed_alert(
851
    aux::stack_allocator& alloc, torrent_handle const& h, error_code const& e
852
    , string_view f, operation_t const op_)
853
0
    : torrent_alert(alloc, h)
854
0
    , error(e)
855
0
    , op(op_)
856
0
    , m_file_idx(alloc.copy_string(f))
857
#if TORRENT_ABI_VERSION == 1
858
0
    , operation(operation_name(op_))
859
0
    , file(f)
860
#endif
861
0
  {}
862
863
  char const* storage_moved_failed_alert::file_path() const
864
0
  {
865
0
    return m_alloc.get().ptr(m_file_idx);
866
0
  }
867
868
  std::string storage_moved_failed_alert::message() const
869
0
  {
870
#ifdef TORRENT_DISABLE_ALERT_MSG
871
    return {};
872
#else
873
0
    return torrent_alert::message() + " storage move failed. "
874
0
      + operation_name(op) + " (" + file_path() + "): "
875
0
      + convert_from_native(error.message());
876
0
#endif
877
0
  }
878
879
  torrent_deleted_alert::torrent_deleted_alert(aux::stack_allocator& alloc
880
    , torrent_handle const& h, info_hash_t const& ih)
881
0
    : torrent_alert(alloc, h)
882
0
    , info_hashes(ih)
883
0
  {
884
0
#if TORRENT_ABI_VERSION < 3
885
0
    info_hash = info_hashes.get_best();
886
0
#endif
887
0
  }
888
889
  std::string torrent_deleted_alert::message() const
890
0
  {
891
#ifdef TORRENT_DISABLE_ALERT_MSG
892
    return {};
893
#else
894
0
    return torrent_alert::message() + " deleted";
895
0
#endif
896
0
  }
897
898
  torrent_delete_failed_alert::torrent_delete_failed_alert(aux::stack_allocator& alloc
899
    , torrent_handle const& h, error_code const& e, info_hash_t const& ih)
900
0
    : torrent_alert(alloc, h)
901
0
    , error(e)
902
0
    , info_hashes(ih)
903
#if TORRENT_ABI_VERSION == 1
904
0
    , msg(convert_from_native(error.message()))
905
#endif
906
0
  {
907
0
#if TORRENT_ABI_VERSION < 3
908
0
    info_hash = info_hashes.get_best();
909
0
#endif
910
0
  }
911
912
  std::string torrent_delete_failed_alert::message() const
913
0
  {
914
#ifdef TORRENT_DISABLE_ALERT_MSG
915
    return {};
916
#else
917
0
    return torrent_alert::message() + " torrent deletion failed: "
918
0
      + convert_from_native(error.message());
919
0
#endif
920
0
  }
921
922
  save_resume_data_alert::save_resume_data_alert(aux::stack_allocator& alloc
923
    , add_torrent_params&& p
924
    , torrent_handle const& h)
925
0
    : torrent_alert(alloc, h)
926
0
    , params(std::move(p))
927
#if TORRENT_ABI_VERSION == 1
928
0
    , resume_data(std::make_shared<entry>(write_resume_data(params)))
929
#endif
930
0
  {
931
0
#if TORRENT_ABI_VERSION < 3
932
0
    params.info_hash = params.info_hashes.get_best();
933
0
#endif
934
0
  }
935
936
  std::string save_resume_data_alert::message() const
937
0
  {
938
#ifdef TORRENT_DISABLE_ALERT_MSG
939
    return {};
940
#else
941
0
    return torrent_alert::message() + " resume data generated";
942
0
#endif
943
0
  }
944
945
  save_resume_data_failed_alert::save_resume_data_failed_alert(aux::stack_allocator& alloc
946
    , torrent_handle const& h, error_code const& e)
947
0
    : torrent_alert(alloc, h)
948
0
    , error(e)
949
#if TORRENT_ABI_VERSION == 1
950
0
    , msg(convert_from_native(error.message()))
951
#endif
952
0
  {
953
0
  }
954
955
  std::string save_resume_data_failed_alert::message() const
956
0
  {
957
#ifdef TORRENT_DISABLE_ALERT_MSG
958
    return {};
959
#else
960
0
    return torrent_alert::message() + " resume data was not generated: "
961
0
      + convert_from_native(error.message());
962
0
#endif
963
0
  }
964
965
  torrent_paused_alert::torrent_paused_alert(aux::stack_allocator& alloc
966
    , torrent_handle const& h)
967
0
    : torrent_alert(alloc, h)
968
0
  {}
969
970
  std::string torrent_paused_alert::message() const
971
0
  {
972
#ifdef TORRENT_DISABLE_ALERT_MSG
973
    return {};
974
#else
975
0
    return torrent_alert::message() + " paused";
976
0
#endif
977
0
  }
978
979
  torrent_resumed_alert::torrent_resumed_alert(aux::stack_allocator& alloc
980
    , torrent_handle const& h)
981
0
    : torrent_alert(alloc, h)
982
0
  {}
983
984
  std::string torrent_resumed_alert::message() const
985
0
  {
986
#ifdef TORRENT_DISABLE_ALERT_MSG
987
    return {};
988
#else
989
0
    return torrent_alert::message() + " resumed";
990
0
#endif
991
0
  }
992
993
  torrent_checked_alert::torrent_checked_alert(aux::stack_allocator& alloc
994
    , torrent_handle const& h)
995
0
    : torrent_alert(alloc, h)
996
0
  {}
997
998
  std::string torrent_checked_alert::message() const
999
0
  {
1000
#ifdef TORRENT_DISABLE_ALERT_MSG
1001
    return {};
1002
#else
1003
0
    return torrent_alert::message() + " checked";
1004
0
#endif
1005
0
  }
1006
1007
namespace {
1008
1009
#ifndef TORRENT_DISABLE_ALERT_MSG
1010
  char const* const nat_type_str[] = {"NAT-PMP", "UPnP"};
1011
1012
  char const* const protocol_str[] = {"none", "TCP", "UDP"};
1013
#endif
1014
1015
#if TORRENT_ABI_VERSION == 1
1016
  int sock_type_idx(socket_type_t type)
1017
0
  {
1018
    // these numbers are the deprecated enum values in
1019
    // listen_succeeded_alert and listen_failed_alert
1020
0
    static aux::array<int, 9, socket_type_t> const mapping{{
1021
0
      0, // tcp
1022
0
      4, // socks5,
1023
0
      0, // http,
1024
0
      2, // utp,
1025
0
      3, // i2p,
1026
0
      1, // tcp_ssl
1027
0
      4, // socks5_ssl,
1028
0
      1, // http_ssl,
1029
0
      5  // utp_ssl,
1030
0
    }};
1031
0
    return mapping[type];
1032
0
  }
1033
1034
  int to_op_t(operation_t op)
1035
0
  {
1036
0
    using o = operation_t;
1037
0
    using lfo = listen_failed_alert::op_t;
1038
1039
    // we have to use deprecated enum values here. suppress the warnings
1040
0
#include "libtorrent/aux_/disable_deprecation_warnings_push.hpp"
1041
0
    switch (op)
1042
0
    {
1043
0
      case o::bittorrent: return -1;
1044
0
      case o::iocontrol: return -1;
1045
0
      case o::getpeername: return -1;
1046
0
      case o::getname: return lfo::get_socket_name;
1047
0
      case o::alloc_recvbuf: return -1;
1048
0
      case o::alloc_sndbuf: return -1;
1049
0
      case o::file_write: return -1;
1050
0
      case o::file_read: return -1;
1051
0
      case o::file: return -1;
1052
0
      case o::sock_write: return -1;
1053
0
      case o::sock_read: return -1;
1054
0
      case o::sock_open: return lfo::open;
1055
0
      case o::sock_bind: return lfo::bind;
1056
0
      case o::available: return -1;
1057
0
      case o::encryption: return -1;
1058
0
      case o::connect: return -1;
1059
0
      case o::ssl_handshake: return -1;
1060
0
      case o::get_interface: return -1;
1061
0
      case o::unknown: return -1;
1062
0
      case o::sock_listen: return lfo::listen;
1063
0
      case o::sock_bind_to_device: return lfo::bind_to_device;
1064
0
      case o::sock_accept: return lfo::accept;
1065
0
      case o::parse_address: return lfo::parse_addr;
1066
0
      case o::enum_if: return lfo::enum_if;
1067
0
      case o::file_stat: return -1;
1068
0
      case o::file_copy: return -1;
1069
0
      case o::file_fallocate: return -1;
1070
0
      case o::file_hard_link: return -1;
1071
0
      case o::file_remove: return -1;
1072
0
      case o::file_rename: return -1;
1073
0
      case o::file_open: return -1;
1074
0
      case o::mkdir: return -1;
1075
0
      case o::check_resume: return -1;
1076
0
      case o::exception: return -1;
1077
0
      case o::alloc_cache_piece: return -1;
1078
0
      case o::partfile_move: return -1;
1079
0
      case o::partfile_read: return -1;
1080
0
      case o::partfile_write: return -1;
1081
0
      case o::hostname_lookup: return -1;
1082
0
      case o::symlink: return -1;
1083
0
      case o::handshake: return -1;
1084
0
      case o::sock_option: return -1;
1085
0
      case o::enum_route: return -1;
1086
0
      case o::file_seek: return -1;
1087
0
      case o::timer: return -1;
1088
0
      case o::file_mmap: return -1;
1089
0
      case o::file_truncate: return -1;
1090
0
    }
1091
0
    return -1;
1092
0
  }
1093
#include "libtorrent/aux_/disable_warnings_pop.hpp"
1094
1095
#endif // TORRENT_ABI_VERSION
1096
1097
} // anonymous namespace
1098
1099
  listen_failed_alert::listen_failed_alert(
1100
    aux::stack_allocator& alloc
1101
    , string_view iface
1102
    , libtorrent::address const& listen_addr
1103
    , int listen_port
1104
    , operation_t const op_
1105
    , error_code const& ec
1106
    , libtorrent::socket_type_t t)
1107
0
    : error(ec)
1108
0
    , op(op_)
1109
0
    , socket_type(t)
1110
0
    , address(listen_addr)
1111
0
    , port(listen_port)
1112
0
    , m_alloc(alloc)
1113
0
    , m_interface_idx(alloc.copy_string(iface))
1114
#if TORRENT_ABI_VERSION == 1
1115
0
    , operation(to_op_t(op_))
1116
0
    , endpoint(listen_addr, std::uint16_t(listen_port))
1117
0
    , sock_type(static_cast<socket_type_t>(sock_type_idx(t)))
1118
#endif
1119
0
  {}
1120
1121
  listen_failed_alert::listen_failed_alert(
1122
    aux::stack_allocator& alloc
1123
    , string_view iface
1124
    , tcp::endpoint const& ep
1125
    , operation_t const op_
1126
    , error_code const& ec
1127
    , libtorrent::socket_type_t t)
1128
0
    : listen_failed_alert(alloc
1129
0
      , iface
1130
0
      , ep.address()
1131
0
      , ep.port()
1132
0
      , op_
1133
0
      , ec
1134
0
      , t)
1135
0
  {}
1136
1137
  listen_failed_alert::listen_failed_alert(
1138
    aux::stack_allocator& alloc
1139
    , string_view iface
1140
    , udp::endpoint const& ep
1141
    , operation_t const op_
1142
    , error_code const& ec
1143
    , libtorrent::socket_type_t t)
1144
0
    : listen_failed_alert(alloc
1145
0
      , iface
1146
0
      , ep.address()
1147
0
      , ep.port()
1148
0
      , op_
1149
0
      , ec
1150
0
      , t)
1151
0
  {}
1152
1153
  listen_failed_alert::listen_failed_alert(
1154
    aux::stack_allocator& alloc
1155
    , string_view iface
1156
    , operation_t const op_
1157
    , error_code const& ec
1158
    , libtorrent::socket_type_t t)
1159
0
    : listen_failed_alert(alloc
1160
0
      , iface
1161
0
      , libtorrent::address()
1162
0
      , 0
1163
0
      , op_
1164
0
      , ec
1165
0
      , t)
1166
0
  {}
1167
1168
  char const* listen_failed_alert::listen_interface() const
1169
0
  {
1170
0
    return m_alloc.get().ptr(m_interface_idx);
1171
0
  }
1172
1173
  std::string listen_failed_alert::message() const
1174
0
  {
1175
#ifdef TORRENT_DISABLE_ALERT_MSG
1176
    return {};
1177
#else
1178
0
    char ret[300];
1179
0
    std::snprintf(ret, sizeof(ret), "listening on %s (device: %s) failed: [%s] [%s] %s"
1180
0
      , print_endpoint(address, port).c_str()
1181
0
      , listen_interface()
1182
0
      , operation_name(op)
1183
0
      , socket_type_name(socket_type)
1184
0
      , convert_from_native(error.message()).c_str());
1185
0
    return ret;
1186
0
#endif
1187
0
  }
1188
1189
  metadata_failed_alert::metadata_failed_alert(aux::stack_allocator& alloc
1190
    , const torrent_handle& h, error_code const& e)
1191
0
    : torrent_alert(alloc, h)
1192
0
    , error(e)
1193
0
  {}
1194
1195
  std::string metadata_failed_alert::message() const
1196
0
  {
1197
#ifdef TORRENT_DISABLE_ALERT_MSG
1198
    return {};
1199
#else
1200
0
    return torrent_alert::message() + " invalid metadata received";
1201
0
#endif
1202
0
  }
1203
1204
  metadata_received_alert::metadata_received_alert(aux::stack_allocator& alloc
1205
    , const torrent_handle& h)
1206
0
    : torrent_alert(alloc, h)
1207
0
  {}
1208
1209
  std::string metadata_received_alert::message() const
1210
0
  {
1211
#ifdef TORRENT_DISABLE_ALERT_MSG
1212
    return {};
1213
#else
1214
0
    return torrent_alert::message() + " metadata successfully received";
1215
0
#endif
1216
0
  }
1217
1218
  udp_error_alert::udp_error_alert(
1219
    aux::stack_allocator&
1220
    , udp::endpoint const& ep
1221
    , operation_t op
1222
    , error_code const& ec)
1223
0
    : endpoint(ep)
1224
0
    , operation(op)
1225
0
    , error(ec)
1226
0
  {}
1227
1228
  std::string udp_error_alert::message() const
1229
0
  {
1230
#ifdef TORRENT_DISABLE_ALERT_MSG
1231
    return {};
1232
#else
1233
0
    return "UDP error: " + convert_from_native(error.message())
1234
0
      + " from: " + endpoint.address().to_string()
1235
0
      + " op: " + operation_name(operation);
1236
0
#endif
1237
0
  }
1238
1239
  external_ip_alert::external_ip_alert(aux::stack_allocator&
1240
    , address const& ip)
1241
0
    : external_address(ip)
1242
0
  {}
1243
1244
  std::string external_ip_alert::message() const
1245
0
  {
1246
#ifdef TORRENT_DISABLE_ALERT_MSG
1247
    return {};
1248
#else
1249
0
    return "external IP received: " + external_address.to_string();
1250
0
#endif
1251
0
  }
1252
1253
  listen_succeeded_alert::listen_succeeded_alert(aux::stack_allocator&
1254
    , libtorrent::address const& listen_addr
1255
    , int listen_port
1256
    , libtorrent::socket_type_t t)
1257
0
    : address(listen_addr)
1258
0
    , port(listen_port)
1259
0
    , socket_type(t)
1260
#if TORRENT_ABI_VERSION == 1
1261
0
    , endpoint(listen_addr, std::uint16_t(listen_port))
1262
0
    , sock_type(static_cast<socket_type_t>(sock_type_idx(t)))
1263
#endif
1264
0
  {}
1265
1266
  listen_succeeded_alert::listen_succeeded_alert(aux::stack_allocator& alloc
1267
    , tcp::endpoint const& ep
1268
    , libtorrent::socket_type_t t)
1269
0
    : listen_succeeded_alert(alloc
1270
0
      , ep.address()
1271
0
      , ep.port()
1272
0
      , t)
1273
0
  {}
1274
1275
  listen_succeeded_alert::listen_succeeded_alert(aux::stack_allocator& alloc
1276
    , udp::endpoint const& ep
1277
    , libtorrent::socket_type_t t)
1278
0
    : listen_succeeded_alert(alloc
1279
0
      , ep.address()
1280
0
      , ep.port()
1281
0
      , t)
1282
0
  {}
1283
1284
  std::string listen_succeeded_alert::message() const
1285
0
  {
1286
#ifdef TORRENT_DISABLE_ALERT_MSG
1287
    return {};
1288
#else
1289
0
    char ret[200];
1290
0
    std::snprintf(ret, sizeof(ret), "successfully listening on [%s] %s"
1291
0
      , socket_type_name(socket_type), print_endpoint(address, port).c_str());
1292
0
    return ret;
1293
0
#endif
1294
0
  }
1295
1296
  portmap_error_alert::portmap_error_alert(aux::stack_allocator&
1297
    , port_mapping_t const i, portmap_transport const t, error_code const& e
1298
    , address const& local)
1299
0
    : mapping(i)
1300
0
    , map_transport(t)
1301
0
    , local_address(local)
1302
0
    , error(e)
1303
#if TORRENT_ABI_VERSION == 1
1304
0
    , map_type(static_cast<int>(t))
1305
0
    , msg(convert_from_native(error.message()))
1306
#endif
1307
0
  {}
1308
1309
  std::string portmap_error_alert::message() const
1310
0
  {
1311
#ifdef TORRENT_DISABLE_ALERT_MSG
1312
    return {};
1313
#else
1314
0
    return std::string("could not map port using ")
1315
0
      + nat_type_str[static_cast<int>(map_transport)]
1316
0
      + "[" + local_address.to_string() + "]: "
1317
0
      + convert_from_native(error.message());
1318
0
#endif
1319
0
  }
1320
1321
  portmap_alert::portmap_alert(aux::stack_allocator&, port_mapping_t const i
1322
    , int const port, portmap_transport const t, portmap_protocol const proto
1323
    , address const& local)
1324
0
    : mapping(i)
1325
0
    , external_port(port)
1326
0
    , map_protocol(proto)
1327
0
    , map_transport(t)
1328
0
    , local_address(local)
1329
#if TORRENT_ABI_VERSION == 1
1330
0
    , protocol(static_cast<int>(proto))
1331
0
    , map_type(static_cast<int>(t))
1332
#endif
1333
0
  {}
1334
1335
  std::string portmap_alert::message() const
1336
0
  {
1337
#ifdef TORRENT_DISABLE_ALERT_MSG
1338
    return {};
1339
#else
1340
0
    char ret[200];
1341
0
    std::snprintf(ret, sizeof(ret), "successfully mapped port using %s. local: %s external port: %s/%d"
1342
0
      , nat_type_str[static_cast<int>(map_transport)]
1343
0
      , local_address.to_string().c_str()
1344
0
      , protocol_str[static_cast<int>(map_protocol)], external_port);
1345
0
    return ret;
1346
0
#endif
1347
0
  }
1348
1349
  portmap_log_alert::portmap_log_alert(aux::stack_allocator& alloc
1350
    , portmap_transport const t, const char* m, address const& local)
1351
0
    : map_transport(t)
1352
0
    , local_address(local)
1353
0
    , m_alloc(alloc)
1354
0
    , m_log_idx(alloc.copy_string(m))
1355
#if TORRENT_ABI_VERSION == 1
1356
0
    , map_type(static_cast<int>(t))
1357
0
    , msg(m)
1358
#endif
1359
0
  {}
1360
1361
  char const* portmap_log_alert::log_message() const
1362
0
  {
1363
0
    return m_alloc.get().ptr(m_log_idx);
1364
0
  }
1365
1366
  std::string portmap_log_alert::message() const
1367
0
  {
1368
#ifdef TORRENT_DISABLE_ALERT_MSG
1369
    return {};
1370
#else
1371
0
    char ret[1024];
1372
0
    std::snprintf(ret, sizeof(ret), "%s [%s]: %s"
1373
0
      , nat_type_str[static_cast<int>(map_transport)]
1374
0
      , local_address.to_string().c_str()
1375
0
      , log_message());
1376
0
    return ret;
1377
0
#endif
1378
0
  }
1379
1380
  fastresume_rejected_alert::fastresume_rejected_alert(
1381
    aux::stack_allocator& alloc
1382
    , torrent_handle const& h
1383
    , error_code const& ec
1384
    , string_view f
1385
    , operation_t const op_)
1386
0
    : torrent_alert(alloc, h)
1387
0
    , error(ec)
1388
0
    , op(op_)
1389
0
    , m_path_idx(alloc.copy_string(f))
1390
#if TORRENT_ABI_VERSION == 1
1391
0
    , operation(operation_name(op_))
1392
0
    , file(f)
1393
0
    , msg(convert_from_native(error.message()))
1394
#endif
1395
0
  {
1396
0
  }
1397
1398
  std::string fastresume_rejected_alert::message() const
1399
0
  {
1400
#ifdef TORRENT_DISABLE_ALERT_MSG
1401
    return {};
1402
#else
1403
0
    return torrent_alert::message() + " fast resume rejected. "
1404
0
      + operation_name(op) + "(" + file_path() + "): "
1405
0
      + convert_from_native(error.message());
1406
0
#endif
1407
0
  }
1408
1409
  char const* fastresume_rejected_alert::file_path() const
1410
0
  {
1411
0
    return m_alloc.get().ptr(m_path_idx);
1412
0
  }
1413
1414
  peer_blocked_alert::peer_blocked_alert(aux::stack_allocator& alloc
1415
    , torrent_handle const& h, tcp::endpoint const& ep, int r)
1416
0
    : peer_alert(alloc, h, ep, peer_id(nullptr))
1417
0
    , reason(r)
1418
0
  {}
1419
1420
  std::string peer_blocked_alert::message() const
1421
0
  {
1422
#ifdef TORRENT_DISABLE_ALERT_MSG
1423
    return {};
1424
#else
1425
0
    char ret[600];
1426
0
    static char const* const reason_str[] =
1427
0
    {
1428
0
      "ip_filter",
1429
0
      "port_filter",
1430
0
      "i2p_mixed",
1431
0
      "privileged_ports",
1432
0
      "utp_disabled",
1433
0
      "tcp_disabled",
1434
0
      "invalid_local_interface",
1435
0
      "ssrf_mitigation"
1436
0
    };
1437
1438
0
    std::snprintf(ret, sizeof(ret), "%s: blocked peer [%s]"
1439
0
      , peer_alert::message().c_str(), reason_str[reason]);
1440
0
    return ret;
1441
0
#endif
1442
0
  }
1443
1444
  dht_announce_alert::dht_announce_alert(aux::stack_allocator&
1445
    , address const& i, int p
1446
    , sha1_hash const& ih)
1447
0
    : ip(i)
1448
0
    , port(p)
1449
0
    , info_hash(ih)
1450
0
  {}
1451
1452
  std::string dht_announce_alert::message() const
1453
0
  {
1454
#ifdef TORRENT_DISABLE_ALERT_MSG
1455
    return {};
1456
#else
1457
0
    char msg[200];
1458
0
    std::snprintf(msg, sizeof(msg), "incoming dht announce: %s:%d (%s)"
1459
0
      , ip.to_string().c_str(), port, aux::to_hex(info_hash).c_str());
1460
0
    return msg;
1461
0
#endif
1462
0
  }
1463
1464
  dht_get_peers_alert::dht_get_peers_alert(aux::stack_allocator&
1465
    , sha1_hash const& ih)
1466
0
    : info_hash(ih)
1467
0
  {}
1468
1469
  std::string dht_get_peers_alert::message() const
1470
0
  {
1471
#ifdef TORRENT_DISABLE_ALERT_MSG
1472
    return {};
1473
#else
1474
0
    char msg[200];
1475
0
    std::snprintf(msg, sizeof(msg), "incoming dht get_peers: %s", aux::to_hex(info_hash).c_str());
1476
0
    return msg;
1477
0
#endif
1478
0
  }
1479
1480
#if TORRENT_ABI_VERSION <= 2
1481
namespace {
1482
1483
    std::array<int, stats_alert::num_channels> stat_to_array(stat const& s)
1484
0
    {
1485
0
      std::array<int, stats_alert::num_channels> arr;
1486
1487
0
      arr[stats_alert::upload_payload] = s[stat::upload_payload].counter();
1488
0
      arr[stats_alert::upload_protocol] = s[stat::upload_protocol].counter();
1489
0
      arr[stats_alert::download_payload] = s[stat::download_payload].counter();
1490
0
      arr[stats_alert::download_protocol] = s[stat::download_protocol].counter();
1491
0
      arr[stats_alert::upload_ip_protocol] = s[stat::upload_ip_protocol].counter();
1492
0
      arr[stats_alert::download_ip_protocol] = s[stat::download_ip_protocol].counter();
1493
1494
0
#if TORRENT_ABI_VERSION == 1
1495
0
      arr[stats_alert::upload_dht_protocol] = 0;
1496
0
      arr[stats_alert::upload_tracker_protocol] = 0;
1497
0
      arr[stats_alert::download_dht_protocol] = 0;
1498
0
      arr[stats_alert::download_tracker_protocol] = 0;
1499
#else
1500
      arr[stats_alert::deprecated1] = 0;
1501
      arr[stats_alert::deprecated2] = 0;
1502
      arr[stats_alert::deprecated3] = 0;
1503
      arr[stats_alert::deprecated4] = 0;
1504
#endif
1505
0
      return arr;
1506
0
    }
1507
  }
1508
1509
  stats_alert::stats_alert(aux::stack_allocator& alloc
1510
    , torrent_handle const& h, int in, stat const& s)
1511
0
    : torrent_alert(alloc, h)
1512
0
    , transferred(stat_to_array(s))
1513
0
    , interval(in)
1514
0
  {}
1515
1516
  std::string stats_alert::message() const
1517
0
  {
1518
#ifdef TORRENT_DISABLE_ALERT_MSG
1519
    return {};
1520
#else
1521
0
    char msg[200];
1522
0
    std::snprintf(msg, sizeof(msg), "%s: [%d] %d %d %d %d %d %d"
1523
0
#if TORRENT_ABI_VERSION == 1
1524
0
      " %d %d %d %d"
1525
0
#endif
1526
0
      , torrent_alert::message().c_str()
1527
0
      , interval
1528
0
      , transferred[0]
1529
0
      , transferred[1]
1530
0
      , transferred[2]
1531
0
      , transferred[3]
1532
0
      , transferred[4]
1533
0
      , transferred[5]
1534
0
#if TORRENT_ABI_VERSION == 1
1535
0
      , transferred[6]
1536
0
      , transferred[7]
1537
0
      , transferred[8]
1538
0
      , transferred[9]
1539
0
#endif
1540
0
      );
1541
0
    return msg;
1542
0
#endif
1543
0
  }
1544
#endif // TORRENT_ABI_VERSION
1545
1546
  cache_flushed_alert::cache_flushed_alert(aux::stack_allocator& alloc
1547
    , torrent_handle const& h)
1548
0
    : torrent_alert(alloc, h) {}
1549
1550
#if TORRENT_ABI_VERSION == 1
1551
  anonymous_mode_alert::anonymous_mode_alert(aux::stack_allocator& alloc
1552
    , torrent_handle const& h, int k, string_view s)
1553
0
    : torrent_alert(alloc, h)
1554
0
    , kind(k)
1555
0
    , str(s)
1556
0
  {}
1557
1558
  std::string anonymous_mode_alert::message() const
1559
0
  {
1560
#ifdef TORRENT_DISABLE_ALERT_MSG
1561
    return {};
1562
#else
1563
0
    char msg[200];
1564
0
    static char const* const msgs[] = {
1565
0
      "tracker is not anonymous, set a proxy"
1566
0
    };
1567
0
    std::snprintf(msg, sizeof(msg), "%s: %s: %s"
1568
0
      , torrent_alert::message().c_str()
1569
0
      , msgs[kind], str.c_str());
1570
0
    return msg;
1571
0
#endif
1572
0
  }
1573
#endif // TORRENT_ABI_VERSION
1574
1575
  lsd_peer_alert::lsd_peer_alert(aux::stack_allocator& alloc, torrent_handle const& h
1576
    , tcp::endpoint const& i)
1577
0
    : peer_alert(alloc, h, i, peer_id(nullptr))
1578
0
  {}
1579
1580
  std::string lsd_peer_alert::message() const
1581
0
  {
1582
#ifdef TORRENT_DISABLE_ALERT_MSG
1583
    return {};
1584
#else
1585
0
    char msg[200];
1586
0
    std::snprintf(msg, sizeof(msg), "%s: received peer from local service discovery"
1587
0
      , peer_alert::message().c_str());
1588
0
    return msg;
1589
0
#endif
1590
0
  }
1591
1592
  trackerid_alert::trackerid_alert(
1593
    aux::stack_allocator& alloc
1594
    , torrent_handle const& h
1595
    , tcp::endpoint const& ep
1596
    , string_view u
1597
    , const std::string& id)
1598
0
    : tracker_alert(alloc, h,  ep, u)
1599
0
    , m_tracker_idx(alloc.copy_string(id))
1600
#if TORRENT_ABI_VERSION == 1
1601
0
    , trackerid(id)
1602
#endif
1603
0
  {}
1604
1605
  char const* trackerid_alert::tracker_id() const
1606
0
  {
1607
0
    return m_alloc.get().ptr(m_tracker_idx);
1608
0
  }
1609
1610
  std::string trackerid_alert::message() const
1611
0
  {
1612
#ifdef TORRENT_DISABLE_ALERT_MSG
1613
    return {};
1614
#else
1615
0
    return std::string("trackerid received: ") + tracker_id();
1616
0
#endif
1617
0
  }
1618
1619
  dht_bootstrap_alert::dht_bootstrap_alert(aux::stack_allocator&)
1620
0
  {}
1621
1622
  std::string dht_bootstrap_alert::message() const
1623
0
  {
1624
#ifdef TORRENT_DISABLE_ALERT_MSG
1625
    return {};
1626
#else
1627
0
    return "DHT bootstrap complete";
1628
0
#endif
1629
0
  }
1630
1631
  torrent_error_alert::torrent_error_alert(
1632
    aux::stack_allocator& alloc
1633
    , torrent_handle const& h
1634
    , error_code const& e, string_view f)
1635
0
    : torrent_alert(alloc, h)
1636
0
    , error(e)
1637
0
    , m_file_idx(alloc.copy_string(f))
1638
#if TORRENT_ABI_VERSION == 1
1639
0
    , error_file(f)
1640
#endif
1641
0
  {}
1642
1643
  std::string torrent_error_alert::message() const
1644
0
  {
1645
#ifdef TORRENT_DISABLE_ALERT_MSG
1646
    return {};
1647
#else
1648
0
    char msg[400];
1649
0
    if (error)
1650
0
    {
1651
0
      std::snprintf(msg, sizeof(msg), " ERROR: (%d %s) %s"
1652
0
        , error.value(), convert_from_native(error.message()).c_str()
1653
0
        , filename());
1654
0
    }
1655
0
    else
1656
0
    {
1657
0
      std::snprintf(msg, sizeof(msg), " ERROR: %s", filename());
1658
0
    }
1659
0
    return torrent_alert::message() + msg;
1660
0
#endif
1661
0
  }
1662
1663
  char const* torrent_error_alert::filename() const
1664
0
  {
1665
0
    return m_alloc.get().ptr(m_file_idx);
1666
0
  }
1667
1668
#if TORRENT_ABI_VERSION == 1
1669
  torrent_added_alert::torrent_added_alert(aux::stack_allocator& alloc
1670
    , torrent_handle const& h)
1671
0
    : torrent_alert(alloc, h)
1672
0
  {}
1673
1674
  std::string torrent_added_alert::message() const
1675
0
  {
1676
#ifdef TORRENT_DISABLE_ALERT_MSG
1677
    return {};
1678
#else
1679
0
    return torrent_alert::message() + " added";
1680
0
#endif
1681
0
  }
1682
#endif
1683
1684
  torrent_removed_alert::torrent_removed_alert(aux::stack_allocator& alloc
1685
    , torrent_handle const& h, info_hash_t const& ih, client_data_t u)
1686
0
    : torrent_alert(alloc, h)
1687
0
    , info_hashes(ih)
1688
0
    , userdata(u)
1689
0
  {
1690
0
#if TORRENT_ABI_VERSION < 3
1691
0
    info_hash = info_hashes.get_best();
1692
0
#endif
1693
0
  }
1694
1695
  std::string torrent_removed_alert::message() const
1696
0
  {
1697
#ifdef TORRENT_DISABLE_ALERT_MSG
1698
    return {};
1699
#else
1700
0
    return torrent_alert::message() + " removed";
1701
0
#endif
1702
0
  }
1703
1704
  torrent_need_cert_alert::torrent_need_cert_alert(aux::stack_allocator& alloc
1705
    , torrent_handle const& h)
1706
0
    : torrent_alert(alloc, h)
1707
0
  {}
1708
1709
  std::string torrent_need_cert_alert::message() const
1710
0
  {
1711
#ifdef TORRENT_DISABLE_ALERT_MSG
1712
    return {};
1713
#else
1714
0
    return torrent_alert::message() + " needs SSL certificate";
1715
0
#endif
1716
0
  }
1717
1718
  incoming_connection_alert::incoming_connection_alert(aux::stack_allocator&
1719
    , socket_type_t t, tcp::endpoint const& i)
1720
0
    : socket_type(t)
1721
0
    , endpoint(i)
1722
#if TORRENT_ABI_VERSION == 1
1723
0
    , ip(i)
1724
#endif
1725
0
  {}
1726
1727
  std::string incoming_connection_alert::message() const
1728
0
  {
1729
#ifdef TORRENT_DISABLE_ALERT_MSG
1730
    return {};
1731
#else
1732
0
    char msg[600];
1733
0
    std::snprintf(msg, sizeof(msg), "incoming connection from %s (%s)"
1734
0
      , print_endpoint(endpoint).c_str(), socket_type_name(socket_type));
1735
0
    return msg;
1736
0
#endif
1737
0
  }
1738
1739
  peer_connect_alert::peer_connect_alert(aux::stack_allocator& alloc, torrent_handle h
1740
    , tcp::endpoint const& ep, peer_id const& peer_id, socket_type_t const type, direction_t const dir)
1741
0
    : peer_alert(alloc, h, ep, peer_id)
1742
0
    , direction(dir)
1743
0
    , socket_type(type)
1744
0
  {}
1745
1746
  std::string peer_connect_alert::message() const
1747
0
  {
1748
#ifdef TORRENT_DISABLE_ALERT_MSG
1749
    return {};
1750
#else
1751
0
    char msg[600];
1752
0
    char const* direction_str = direction == direction_t::in ? "incoming" : "outgoing";
1753
0
    std::snprintf(msg, sizeof(msg), "%s %s connection to peer (%s)"
1754
0
      , peer_alert::message().c_str(), direction_str, socket_type_name(socket_type));
1755
0
    return msg;
1756
0
#endif
1757
0
  }
1758
1759
  add_torrent_alert::add_torrent_alert(aux::stack_allocator& alloc, torrent_handle const& h
1760
    , add_torrent_params p, error_code const& ec)
1761
0
    : torrent_alert(alloc, h)
1762
0
    , params(std::move(p))
1763
0
    , error(ec)
1764
0
  {
1765
0
#if TORRENT_ABI_VERSION < 3
1766
0
    params.info_hash = params.info_hashes.get_best();
1767
0
#endif
1768
0
  }
1769
1770
  std::string add_torrent_alert::message() const
1771
0
  {
1772
#ifdef TORRENT_DISABLE_ALERT_MSG
1773
    return {};
1774
#else
1775
0
    char msg[600];
1776
0
    char info_hash[41];
1777
0
    char const* torrent_name = info_hash;
1778
0
    if (params.ti) torrent_name = params.ti->name().c_str();
1779
0
    else if (!params.name.empty()) torrent_name = params.name.c_str();
1780
0
#if TORRENT_ABI_VERSION == 1
1781
0
    else if (!params.url.empty()) torrent_name = params.url.c_str();
1782
0
#endif
1783
0
    else aux::to_hex(params.info_hashes.get_best(), info_hash);
1784
1785
0
    if (error)
1786
0
    {
1787
0
      std::snprintf(msg, sizeof(msg), "failed to add torrent \"%s\": [%s] %s"
1788
0
        , torrent_name, error.category().name()
1789
0
        , convert_from_native(error.message()).c_str());
1790
0
    }
1791
0
    else
1792
0
    {
1793
0
      std::snprintf(msg, sizeof(msg), "added torrent: %s", torrent_name);
1794
0
    }
1795
0
    return msg;
1796
0
#endif
1797
0
  }
1798
1799
  state_update_alert::state_update_alert(aux::stack_allocator&
1800
    , std::vector<torrent_status> st)
1801
0
    : status(std::move(st))
1802
0
  {}
1803
1804
  std::string state_update_alert::message() const
1805
0
  {
1806
#ifdef TORRENT_DISABLE_ALERT_MSG
1807
    return {};
1808
#else
1809
0
    char msg[600];
1810
0
    std::snprintf(msg, sizeof(msg), "state updates for %d torrents", int(status.size()));
1811
0
    return msg;
1812
0
#endif
1813
0
  }
1814
1815
#if TORRENT_ABI_VERSION == 1
1816
  mmap_cache_alert::mmap_cache_alert(aux::stack_allocator&
1817
0
    , error_code const& ec): error(ec)
1818
0
  {}
1819
1820
  std::string mmap_cache_alert::message() const
1821
0
  {
1822
#ifdef TORRENT_DISABLE_ALERT_MSG
1823
    return {};
1824
#else
1825
0
    char msg[600];
1826
0
    std::snprintf(msg, sizeof(msg), "mmap cache failed: (%d) %s", error.value()
1827
0
      , convert_from_native(error.message()).c_str());
1828
0
    return msg;
1829
0
#endif
1830
0
  }
1831
#endif
1832
1833
  char const* operation_name(operation_t const op)
1834
0
  {
1835
#ifdef TORRENT_DISABLE_ALERT_MSG
1836
    TORRENT_UNUSED(op);
1837
    return "";
1838
#else
1839
0
    static char const* const names[] = {
1840
0
      "unknown",
1841
0
      "bittorrent",
1842
0
      "iocontrol",
1843
0
      "getpeername",
1844
0
      "getname",
1845
0
      "alloc_recvbuf",
1846
0
      "alloc_sndbuf",
1847
0
      "file_write",
1848
0
      "file_read",
1849
0
      "file",
1850
0
      "sock_write",
1851
0
      "sock_read",
1852
0
      "sock_open",
1853
0
      "sock_bind",
1854
0
      "available",
1855
0
      "encryption",
1856
0
      "connect",
1857
0
      "ssl_handshake",
1858
0
      "get_interface",
1859
0
      "sock_listen",
1860
0
      "sock_bind_to_device",
1861
0
      "sock_accept",
1862
0
      "parse_address",
1863
0
      "enum_if",
1864
0
      "file_stat",
1865
0
      "file_copy",
1866
0
      "file_fallocate",
1867
0
      "file_hard_link",
1868
0
      "file_remove",
1869
0
      "file_rename",
1870
0
      "file_open",
1871
0
      "mkdir",
1872
0
      "check_resume",
1873
0
      "exception",
1874
0
      "alloc_cache_piece",
1875
0
      "partfile_move",
1876
0
      "partfile_read",
1877
0
      "partfile_write",
1878
0
      "hostname_lookup",
1879
0
      "symlink",
1880
0
      "handshake",
1881
0
      "sock_option",
1882
0
      "enum_route",
1883
0
      "file_seek",
1884
0
      "timer",
1885
0
      "file_mmap",
1886
0
      "file_truncate",
1887
0
    };
1888
1889
0
    int const idx = static_cast<int>(op);
1890
0
    if (idx < 0 || idx >= int(sizeof(names) / sizeof(names[0])))
1891
0
      return "unknown operation";
1892
1893
0
    return names[idx];
1894
0
#endif
1895
0
  }
1896
1897
#if TORRENT_ABI_VERSION == 1
1898
  char const* operation_name(int const op)
1899
0
  {
1900
0
    return operation_name(static_cast<operation_t>(op));
1901
0
  }
1902
#endif
1903
1904
  peer_error_alert::peer_error_alert(aux::stack_allocator& alloc, torrent_handle const& h
1905
    , tcp::endpoint const& ep, peer_id const& peer_id, operation_t const op_
1906
    , error_code const& e)
1907
0
    : peer_alert(alloc, h, ep, peer_id)
1908
0
    , op(op_)
1909
0
    , error(e)
1910
#if TORRENT_ABI_VERSION == 1
1911
0
    , operation(static_cast<int>(op_))
1912
0
    , msg(convert_from_native(error.message()))
1913
#endif
1914
0
  {}
1915
1916
  std::string peer_error_alert::message() const
1917
0
  {
1918
#ifdef TORRENT_DISABLE_ALERT_MSG
1919
    return {};
1920
#else
1921
0
    char buf[200];
1922
0
    std::snprintf(buf, sizeof(buf), "%s peer error [%s] [%s]: %s"
1923
0
      , peer_alert::message().c_str()
1924
0
      , operation_name(op), error.category().name()
1925
0
      , convert_from_native(error.message()).c_str());
1926
0
    return buf;
1927
0
#endif
1928
0
  }
1929
1930
  peer_disconnected_alert::peer_disconnected_alert(aux::stack_allocator& alloc
1931
    , torrent_handle const& h, tcp::endpoint const& ep
1932
    , peer_id const& peer_id, operation_t op_, socket_type_t const type, error_code const& e
1933
    , close_reason_t r)
1934
0
    : peer_alert(alloc, h, ep, peer_id)
1935
0
    , socket_type(type)
1936
0
    , op(op_)
1937
0
    , error(e)
1938
0
    , reason(r)
1939
#if TORRENT_ABI_VERSION == 1
1940
0
    , operation(static_cast<int>(op))
1941
0
    , msg(convert_from_native(error.message()))
1942
#endif
1943
0
  {}
1944
1945
  std::string peer_disconnected_alert::message() const
1946
0
  {
1947
#ifdef TORRENT_DISABLE_ALERT_MSG
1948
    return {};
1949
#else
1950
0
    char buf[600];
1951
0
    std::snprintf(buf, sizeof(buf), "%s disconnecting (%s) [%s] [%s]: %s (reason: %d)"
1952
0
      , peer_alert::message().c_str()
1953
0
      , socket_type_name(socket_type)
1954
0
      , operation_name(op), error.category().name()
1955
0
      , convert_from_native(error.message()).c_str()
1956
0
      , int(reason));
1957
0
    return buf;
1958
0
#endif
1959
0
  }
1960
1961
  dht_error_alert::dht_error_alert(aux::stack_allocator&
1962
    , operation_t const op_
1963
    , error_code const& ec)
1964
0
    : error(ec)
1965
0
    , op(op_)
1966
#if TORRENT_ABI_VERSION == 1
1967
0
    , operation(op_ == operation_t::hostname_lookup
1968
0
      ? op_t::hostname_lookup : op_t::unknown)
1969
#endif
1970
0
  {}
1971
1972
  std::string dht_error_alert::message() const
1973
0
  {
1974
#ifdef TORRENT_DISABLE_ALERT_MSG
1975
    return {};
1976
#else
1977
0
    char msg[600];
1978
0
    std::snprintf(msg, sizeof(msg), "DHT error [%s] (%d) %s"
1979
0
      , operation_name(op)
1980
0
      , error.value()
1981
0
      , convert_from_native(error.message()).c_str());
1982
0
    return msg;
1983
0
#endif
1984
0
  }
1985
1986
  dht_immutable_item_alert::dht_immutable_item_alert(aux::stack_allocator&
1987
    , sha1_hash const& t, entry i)
1988
0
    : target(t), item(std::move(i))
1989
0
  {}
1990
1991
  std::string dht_immutable_item_alert::message() const
1992
0
  {
1993
#ifdef TORRENT_DISABLE_ALERT_MSG
1994
    return {};
1995
#else
1996
0
    char msg[1050];
1997
0
    std::snprintf(msg, sizeof(msg), "DHT immutable item %s [ %s ]"
1998
0
      , aux::to_hex(target).c_str()
1999
0
      , item.to_string().c_str());
2000
0
    return msg;
2001
0
#endif
2002
0
  }
2003
2004
  // TODO: 2 the salt here is allocated on the heap. It would be nice to
2005
  // allocate in the stack_allocator
2006
  dht_mutable_item_alert::dht_mutable_item_alert(aux::stack_allocator&
2007
    , std::array<char, 32> const& k
2008
    , std::array<char, 64> const& sig
2009
    , std::int64_t sequence
2010
    , string_view s
2011
    , entry i
2012
    , bool a)
2013
0
    : key(k), signature(sig), seq(sequence), salt(s), item(std::move(i)), authoritative(a)
2014
0
  {}
2015
2016
  std::string dht_mutable_item_alert::message() const
2017
0
  {
2018
#ifdef TORRENT_DISABLE_ALERT_MSG
2019
    return {};
2020
#else
2021
0
    char msg[1050];
2022
0
    std::snprintf(msg, sizeof(msg), "DHT mutable item (key=%s salt=%s seq=%" PRId64 " %s) [ %s ]"
2023
0
      , aux::to_hex(key).c_str()
2024
0
      , salt.c_str()
2025
0
      , seq
2026
0
      , authoritative ? "auth" : "non-auth"
2027
0
      , item.to_string().c_str());
2028
0
    return msg;
2029
0
#endif
2030
0
  }
2031
2032
  dht_put_alert::dht_put_alert(aux::stack_allocator&, sha1_hash const& t, int n)
2033
0
    : target(t)
2034
0
    , public_key()
2035
0
    , signature()
2036
0
    , salt()
2037
0
    , seq(0)
2038
0
    , num_success(n)
2039
0
  {}
2040
2041
  dht_put_alert::dht_put_alert(aux::stack_allocator&
2042
    , std::array<char, 32> const& key
2043
    , std::array<char, 64> const& sig
2044
    , std::string s
2045
    , std::int64_t sequence_number
2046
    , int n)
2047
0
    : target(nullptr)
2048
0
    , public_key(key)
2049
0
    , signature(sig)
2050
0
    , salt(std::move(s))
2051
0
    , seq(sequence_number)
2052
0
    , num_success(n)
2053
0
  {}
2054
2055
  std::string dht_put_alert::message() const
2056
0
  {
2057
#ifdef TORRENT_DISABLE_ALERT_MSG
2058
    return {};
2059
#else
2060
0
    char msg[1050];
2061
0
    if (target.is_all_zeros())
2062
0
    {
2063
0
      std::snprintf(msg, sizeof(msg), "DHT put complete (success=%d key=%s sig=%s salt=%s seq=%" PRId64 ")"
2064
0
        , num_success
2065
0
        , aux::to_hex(public_key).c_str()
2066
0
        , aux::to_hex(signature).c_str()
2067
0
        , salt.c_str()
2068
0
        , seq);
2069
0
      return msg;
2070
0
    }
2071
2072
0
    std::snprintf(msg, sizeof(msg), "DHT put complete (success=%d hash=%s)"
2073
0
      , num_success
2074
0
      , aux::to_hex(target).c_str());
2075
0
    return msg;
2076
0
#endif
2077
0
  }
2078
2079
  i2p_alert::i2p_alert(aux::stack_allocator&, error_code const& ec)
2080
0
    : error(ec)
2081
0
  {}
2082
2083
  std::string i2p_alert::message() const
2084
0
  {
2085
#ifdef TORRENT_DISABLE_ALERT_MSG
2086
    return {};
2087
#else
2088
0
    char msg[600];
2089
0
    std::snprintf(msg, sizeof(msg), "i2p_error: [%s] %s"
2090
0
      , error.category().name(), convert_from_native(error.message()).c_str());
2091
0
    return msg;
2092
0
#endif
2093
0
  }
2094
2095
  dht_outgoing_get_peers_alert::dht_outgoing_get_peers_alert(aux::stack_allocator&
2096
    , sha1_hash const& ih, sha1_hash const& obfih
2097
    , udp::endpoint ep)
2098
0
    : info_hash(ih)
2099
0
    , obfuscated_info_hash(obfih)
2100
0
    , endpoint(std::move(ep))
2101
#if TORRENT_ABI_VERSION == 1
2102
0
    , ip(endpoint)
2103
#endif
2104
0
  {}
2105
2106
  std::string dht_outgoing_get_peers_alert::message() const
2107
0
  {
2108
#ifdef TORRENT_DISABLE_ALERT_MSG
2109
    return {};
2110
#else
2111
0
    char msg[600];
2112
0
    char obf[70];
2113
0
    obf[0] = '\0';
2114
0
    if (obfuscated_info_hash != info_hash)
2115
0
    {
2116
0
      std::snprintf(obf, sizeof(obf), " [obfuscated: %s]"
2117
0
      , aux::to_hex(obfuscated_info_hash).c_str());
2118
0
    }
2119
0
    std::snprintf(msg, sizeof(msg), "outgoing dht get_peers : %s%s -> %s"
2120
0
      , aux::to_hex(info_hash).c_str()
2121
0
      , obf
2122
0
      , print_endpoint(endpoint).c_str());
2123
0
    return msg;
2124
0
#endif
2125
0
  }
2126
2127
  log_alert::log_alert(aux::stack_allocator& alloc, char const* log)
2128
0
    : m_alloc(alloc)
2129
0
    , m_str_idx(alloc.copy_string(log))
2130
0
  {}
2131
  log_alert::log_alert(aux::stack_allocator& alloc, char const* fmt, va_list v)
2132
0
    : m_alloc(alloc)
2133
0
    , m_str_idx(alloc.format_string(fmt, v))
2134
0
  {}
2135
2136
  char const* log_alert::log_message() const
2137
0
  {
2138
0
    return m_alloc.get().ptr(m_str_idx);
2139
0
  }
2140
2141
#if TORRENT_ABI_VERSION == 1
2142
  char const* log_alert::msg() const
2143
0
  {
2144
0
    return log_message();
2145
0
  }
2146
#endif
2147
2148
  std::string log_alert::message() const
2149
0
  {
2150
#ifdef TORRENT_DISABLE_ALERT_MSG
2151
    return {};
2152
#else
2153
0
    return log_message();
2154
0
#endif
2155
0
  }
2156
2157
  torrent_log_alert::torrent_log_alert(aux::stack_allocator& alloc, torrent_handle const& h
2158
    , char const* fmt, va_list v)
2159
0
    : torrent_alert(alloc, h)
2160
0
    , m_str_idx(alloc.format_string(fmt, v))
2161
0
  {}
2162
2163
  char const* torrent_log_alert::log_message() const
2164
0
  {
2165
0
    return m_alloc.get().ptr(m_str_idx);
2166
0
  }
2167
2168
#if TORRENT_ABI_VERSION == 1
2169
  char const* torrent_log_alert::msg() const
2170
0
  {
2171
0
    return log_message();
2172
0
  }
2173
#endif
2174
2175
  std::string torrent_log_alert::message() const
2176
0
  {
2177
#ifdef TORRENT_DISABLE_ALERT_MSG
2178
    return {};
2179
#else
2180
0
    return torrent_alert::message() + ": " + log_message();
2181
0
#endif
2182
0
  }
2183
2184
  peer_log_alert::peer_log_alert(aux::stack_allocator& alloc
2185
    , torrent_handle const& h
2186
    , tcp::endpoint const& i, peer_id const& pi
2187
    , peer_log_alert::direction_t dir
2188
    , char const* event, char const* fmt, va_list v)
2189
0
    : peer_alert(alloc, h, i, pi)
2190
0
    , event_type(event)
2191
0
    , direction(dir)
2192
0
    , m_str_idx(alloc.format_string(fmt, v))
2193
0
  {}
2194
2195
  char const* peer_log_alert::log_message() const
2196
0
  {
2197
0
    return m_alloc.get().ptr(m_str_idx);
2198
0
  }
2199
2200
#if TORRENT_ABI_VERSION == 1
2201
  char const* peer_log_alert::msg() const
2202
0
  {
2203
0
    return log_message();
2204
0
  }
2205
#endif
2206
2207
  std::string peer_log_alert::message() const
2208
0
  {
2209
#ifdef TORRENT_DISABLE_ALERT_MSG
2210
    return {};
2211
#else
2212
0
    static char const* const mode[] =
2213
0
    { "<==", "==>", "<<<", ">>>", "***" };
2214
0
    return peer_alert::message() + " [" + print_endpoint(endpoint) + "] "
2215
0
      + mode[direction] + " " + event_type + " [ " + log_message() + " ]";
2216
0
#endif
2217
0
  }
2218
2219
  lsd_error_alert::lsd_error_alert(aux::stack_allocator&, error_code const& ec
2220
    , address const& local)
2221
0
    : alert()
2222
0
    , local_address(local)
2223
0
    , error(ec)
2224
0
  {}
2225
2226
  std::string lsd_error_alert::message() const
2227
0
  {
2228
#ifdef TORRENT_DISABLE_ALERT_MSG
2229
    return {};
2230
#else
2231
0
    return "Local Service Discovery startup error [" + local_address.to_string() + "]: "
2232
0
      + convert_from_native(error.message());
2233
0
#endif
2234
0
  }
2235
2236
#if TORRENT_ABI_VERSION == 1
2237
namespace {
2238
2239
  aux::array<std::int64_t, counters::num_counters> counters_to_array(counters const& cnt)
2240
0
  {
2241
0
    aux::array<std::int64_t, counters::num_counters> arr;
2242
2243
0
    for (int i = 0; i < counters::num_counters; ++i)
2244
0
      arr[i] = cnt[i];
2245
2246
0
    return arr;
2247
0
  }
2248
}
2249
#else
2250
namespace {
2251
  template <typename T, typename U>
2252
  T* align_pointer(U* ptr)
2253
  {
2254
    return reinterpret_cast<T*>((reinterpret_cast<std::uintptr_t>(ptr) + alignof(T) - 1)
2255
      & ~(alignof(T) - 1));
2256
  }
2257
}
2258
#endif
2259
2260
#if TORRENT_ABI_VERSION == 1
2261
  session_stats_alert::session_stats_alert(aux::stack_allocator&, struct counters const& cnt)
2262
0
    : values(counters_to_array(cnt))
2263
0
  {}
2264
#else
2265
  session_stats_alert::session_stats_alert(aux::stack_allocator& alloc, struct counters const& cnt)
2266
    : m_alloc(alloc)
2267
    , m_counters_idx(alloc.allocate(sizeof(std::int64_t)
2268
      * counters::num_counters + sizeof(std::int64_t) - 1))
2269
  {
2270
    if (!m_counters_idx.is_valid()) return;
2271
    std::int64_t* ptr = align_pointer<std::int64_t>(alloc.ptr(m_counters_idx));
2272
    for (int i = 0; i < counters::num_counters; ++i, ++ptr)
2273
      *ptr = cnt[i];
2274
  }
2275
#endif
2276
2277
  std::string session_stats_alert::message() const
2278
0
  {
2279
#ifdef TORRENT_DISABLE_ALERT_MSG
2280
    return {};
2281
#else
2282
0
    char msg[50];
2283
0
    auto cnt = counters();
2284
0
    std::snprintf(msg, sizeof(msg), "session stats (%d values): " , int(cnt.size()));
2285
0
    std::string ret = msg;
2286
0
    bool first = true;
2287
0
    for (auto v : cnt)
2288
0
    {
2289
0
      std::snprintf(msg, sizeof(msg), first ? "%" PRId64 : ", %" PRId64, v);
2290
0
      first = false;
2291
0
      ret += msg;
2292
0
    }
2293
0
    return ret;
2294
0
#endif
2295
0
  }
2296
2297
  span<std::int64_t const> session_stats_alert::counters() const
2298
0
  {
2299
0
#if TORRENT_ABI_VERSION == 1
2300
0
    return values;
2301
#else
2302
    return { align_pointer<std::int64_t const>(m_alloc.get().ptr(m_counters_idx))
2303
      , counters::num_counters };
2304
#endif
2305
0
  }
2306
2307
  dht_stats_alert::dht_stats_alert(aux::stack_allocator&
2308
    , std::vector<dht_routing_bucket> table
2309
    , std::vector<dht_lookup> requests
2310
      , sha1_hash id, udp::endpoint ep)
2311
0
    : alert()
2312
0
    , active_requests(std::move(requests))
2313
0
    , routing_table(std::move(table))
2314
0
    , nid(id)
2315
0
    , local_endpoint(ep)
2316
0
  {}
2317
2318
  std::string dht_stats_alert::message() const
2319
0
  {
2320
#ifdef TORRENT_DISABLE_ALERT_MSG
2321
    return {};
2322
#else
2323
0
    char buf[2048];
2324
0
    std::snprintf(buf, sizeof(buf), "DHT stats: (%s) reqs: %d buckets: %d"
2325
0
      , aux::to_hex(nid).c_str()
2326
0
      , int(active_requests.size())
2327
0
      , int(routing_table.size()));
2328
0
    return buf;
2329
0
#endif
2330
0
  }
2331
2332
  url_seed_alert::url_seed_alert(aux::stack_allocator& alloc, torrent_handle const& h
2333
    , string_view u, error_code const& e)
2334
0
    : torrent_alert(alloc, h)
2335
0
    , error(e)
2336
0
    , m_url_idx(alloc.copy_string(u))
2337
0
    , m_msg_idx()
2338
#if TORRENT_ABI_VERSION == 1
2339
0
    , url(u)
2340
0
    , msg(convert_from_native(e.message()))
2341
#endif
2342
0
  {}
2343
2344
  url_seed_alert::url_seed_alert(aux::stack_allocator& alloc, torrent_handle const& h
2345
    , string_view u, string_view m)
2346
0
    : torrent_alert(alloc, h)
2347
0
    , m_url_idx(alloc.copy_string(u))
2348
0
    , m_msg_idx(alloc.copy_string(m))
2349
#if TORRENT_ABI_VERSION == 1
2350
0
    , url(u)
2351
0
    , msg(m)
2352
#endif
2353
0
  {}
2354
2355
  std::string url_seed_alert::message() const
2356
0
  {
2357
#ifdef TORRENT_DISABLE_ALERT_MSG
2358
    return {};
2359
#else
2360
0
    return torrent_alert::message() + " url seed ("
2361
0
      + server_url() + ") failed: " + convert_from_native(error.message());
2362
0
#endif
2363
0
  }
2364
2365
  char const* url_seed_alert::server_url() const
2366
0
  {
2367
0
    return m_alloc.get().ptr(m_url_idx);
2368
0
  }
2369
2370
  char const* url_seed_alert::error_message() const
2371
0
  {
2372
0
    if (m_msg_idx == aux::allocation_slot()) return "";
2373
0
    return m_alloc.get().ptr(m_msg_idx);
2374
0
  }
2375
2376
  file_error_alert::file_error_alert(aux::stack_allocator& alloc
2377
    , error_code const& ec, string_view f, operation_t const op_
2378
    , torrent_handle const& h)
2379
0
    : torrent_alert(alloc, h)
2380
0
    , error(ec)
2381
0
    , op(op_)
2382
0
    , m_file_idx(alloc.copy_string(f))
2383
#if TORRENT_ABI_VERSION == 1
2384
0
    , operation(operation_name(op_))
2385
0
    , file(f)
2386
0
    , msg(convert_from_native(error.message()))
2387
#endif
2388
0
  {}
2389
2390
  char const* file_error_alert::filename() const
2391
0
  {
2392
0
    return m_alloc.get().ptr(m_file_idx);
2393
0
  }
2394
2395
  std::string file_error_alert::message() const
2396
0
  {
2397
#ifdef TORRENT_DISABLE_ALERT_MSG
2398
    return {};
2399
#else
2400
0
    return torrent_alert::message() + " "
2401
0
      + operation_name(op) + " (" + filename()
2402
0
      + ") error: " + convert_from_native(error.message());
2403
0
#endif
2404
0
  }
2405
2406
  incoming_request_alert::incoming_request_alert(aux::stack_allocator& alloc
2407
    , peer_request r, torrent_handle h
2408
    , tcp::endpoint const& ep, peer_id const& peer_id)
2409
0
    : peer_alert(alloc, h, ep, peer_id)
2410
0
    , req(r)
2411
0
  {}
2412
2413
  std::string incoming_request_alert::message() const
2414
0
  {
2415
#ifdef TORRENT_DISABLE_ALERT_MSG
2416
    return {};
2417
#else
2418
0
    char msg[1024];
2419
0
    std::snprintf(msg, sizeof(msg), "%s: incoming request [ piece: %d start: %d length: %d ]"
2420
0
      , peer_alert::message().c_str(), static_cast<int>(req.piece)
2421
0
      , req.start, req.length);
2422
0
    return msg;
2423
0
#endif
2424
0
  }
2425
2426
  dht_log_alert::dht_log_alert(aux::stack_allocator& alloc
2427
    , dht_log_alert::dht_module_t m, const char* fmt, va_list v)
2428
0
    : module(m)
2429
0
    , m_alloc(alloc)
2430
0
    , m_msg_idx(alloc.format_string(fmt, v))
2431
0
  {}
2432
2433
  char const* dht_log_alert::log_message() const
2434
0
  {
2435
0
    return m_alloc.get().ptr(m_msg_idx);
2436
0
  }
2437
2438
  std::string dht_log_alert::message() const
2439
0
  {
2440
#ifdef TORRENT_DISABLE_ALERT_MSG
2441
    return {};
2442
#else
2443
0
    static char const* const dht_modules[] =
2444
0
    {
2445
0
      "tracker",
2446
0
      "node",
2447
0
      "routing_table",
2448
0
      "rpc_manager",
2449
0
      "traversal"
2450
0
    };
2451
2452
0
    char ret[900];
2453
0
    std::snprintf(ret, sizeof(ret), "DHT %s: %s", dht_modules[module]
2454
0
      , log_message());
2455
0
    return ret;
2456
0
#endif
2457
0
  }
2458
2459
  dht_pkt_alert::dht_pkt_alert(aux::stack_allocator& alloc
2460
    , span<char const> buf, dht_pkt_alert::direction_t d
2461
    , udp::endpoint const& ep)
2462
0
    : direction(d)
2463
0
    , node(ep)
2464
0
    , m_alloc(alloc)
2465
0
    , m_msg_idx(alloc.copy_buffer(buf))
2466
0
    , m_size(aux::numeric_cast<int>(buf.size()))
2467
#if TORRENT_ABI_VERSION == 1
2468
0
    , dir(d)
2469
#endif
2470
0
  {}
2471
2472
  span<char const> dht_pkt_alert::pkt_buf() const
2473
0
  {
2474
0
    return {m_alloc.get().ptr(m_msg_idx), m_size};
2475
0
  }
2476
2477
  std::string dht_pkt_alert::message() const
2478
0
  {
2479
#ifdef TORRENT_DISABLE_ALERT_MSG
2480
    return {};
2481
#else
2482
0
    bdecode_node print;
2483
0
    error_code ec;
2484
2485
    // ignore errors here. This is best-effort. It may be a broken encoding
2486
    // but at least we'll print the valid parts
2487
0
    span<char const> pkt = pkt_buf();
2488
0
    bdecode(pkt.data(), pkt.data() + int(pkt.size()), print, ec, nullptr, 100, 100);
2489
2490
0
    std::string msg = print_entry(print, true);
2491
2492
0
    static char const* const prefix[2] = {"<==", "==>"};
2493
0
    char buf[1024];
2494
0
    std::snprintf(buf, sizeof(buf), "%s [%s] %s", prefix[direction]
2495
0
      , print_endpoint(node).c_str(), msg.c_str());
2496
2497
0
    return buf;
2498
0
#endif
2499
0
  }
2500
2501
  dht_get_peers_reply_alert::dht_get_peers_reply_alert(aux::stack_allocator& alloc
2502
    , sha1_hash const& ih
2503
    , std::vector<tcp::endpoint> const& peers)
2504
0
    : info_hash(ih)
2505
0
    , m_alloc(alloc)
2506
0
  {
2507
0
    for (auto const& endp : peers)
2508
0
    {
2509
0
      if (aux::is_v4(endp))
2510
0
        m_v4_num_peers++;
2511
0
      else
2512
0
        m_v6_num_peers++;
2513
0
    }
2514
2515
0
    m_v4_peers_idx = alloc.allocate(m_v4_num_peers * 6);
2516
0
    m_v6_peers_idx = alloc.allocate(m_v6_num_peers * 18);
2517
2518
0
    if ((!m_v4_peers_idx.is_valid() && m_v4_num_peers > 0) || (!m_v6_peers_idx.is_valid() && m_v6_num_peers > 0))
2519
0
    {
2520
0
      m_v4_num_peers = 0;
2521
0
      m_v6_num_peers = 0;
2522
0
      return;
2523
0
    }
2524
2525
0
    char* v4_ptr = alloc.ptr(m_v4_peers_idx);
2526
0
    char* v6_ptr = alloc.ptr(m_v6_peers_idx);
2527
0
    for (auto const& endp : peers)
2528
0
    {
2529
0
      if (aux::is_v4(endp))
2530
0
        aux::write_endpoint(endp, v4_ptr);
2531
0
      else
2532
0
        aux::write_endpoint(endp, v6_ptr);
2533
0
    }
2534
0
  }
2535
2536
  std::string dht_get_peers_reply_alert::message() const
2537
0
  {
2538
#ifdef TORRENT_DISABLE_ALERT_MSG
2539
    return {};
2540
#else
2541
0
    char msg[200];
2542
0
    std::snprintf(msg, sizeof(msg), "incoming dht get_peers reply: %s, peers %d"
2543
0
      , aux::to_hex(info_hash).c_str(), num_peers());
2544
0
    return msg;
2545
0
#endif
2546
0
  }
2547
2548
  int dht_get_peers_reply_alert::num_peers() const
2549
0
  {
2550
0
    return m_v4_num_peers + m_v6_num_peers;
2551
0
  }
2552
2553
#if TORRENT_ABI_VERSION == 1
2554
  void dht_get_peers_reply_alert::peers(std::vector<tcp::endpoint> &v) const
2555
0
  {
2556
0
    std::vector<tcp::endpoint> p(peers());
2557
0
    v.reserve(p.size());
2558
0
    std::copy(p.begin(), p.end(), std::back_inserter(v));
2559
0
  }
2560
#endif
2561
  std::vector<tcp::endpoint> dht_get_peers_reply_alert::peers() const
2562
0
  {
2563
0
    aux::vector<tcp::endpoint> peers;
2564
0
    peers.reserve(num_peers());
2565
2566
0
    char const* v4_ptr = m_alloc.get().ptr(m_v4_peers_idx);
2567
0
    for (int i = 0; i < m_v4_num_peers; i++)
2568
0
      peers.push_back(aux::read_v4_endpoint<tcp::endpoint>(v4_ptr));
2569
0
    char const* v6_ptr = m_alloc.get().ptr(m_v6_peers_idx);
2570
0
    for (int i = 0; i < m_v6_num_peers; i++)
2571
0
      peers.push_back(aux::read_v6_endpoint<tcp::endpoint>(v6_ptr));
2572
2573
0
    return TORRENT_RVO(peers);
2574
0
  }
2575
2576
  dht_direct_response_alert::dht_direct_response_alert(
2577
    aux::stack_allocator& alloc, client_data_t userdata_
2578
    , udp::endpoint const& addr_, bdecode_node const& response)
2579
0
    : userdata(userdata_), endpoint(addr_)
2580
0
    , m_alloc(alloc)
2581
0
    , m_response_idx(alloc.copy_buffer(response.data_section()))
2582
0
    , m_response_size(int(response.data_section().size()))
2583
#if TORRENT_ABI_VERSION == 1
2584
0
    , addr(addr_)
2585
#endif
2586
0
  {}
2587
2588
  dht_direct_response_alert::dht_direct_response_alert(
2589
    aux::stack_allocator& alloc
2590
    , client_data_t userdata_
2591
    , udp::endpoint const& addr_)
2592
0
    : userdata(userdata_), endpoint(addr_)
2593
0
    , m_alloc(alloc)
2594
0
    , m_response_idx()
2595
0
    , m_response_size(0)
2596
#if TORRENT_ABI_VERSION == 1
2597
0
    , addr(addr_)
2598
#endif
2599
0
  {}
2600
2601
  std::string dht_direct_response_alert::message() const
2602
0
  {
2603
#ifdef TORRENT_DISABLE_ALERT_MSG
2604
    return {};
2605
#else
2606
0
    char msg[1050];
2607
0
    std::snprintf(msg, sizeof(msg), "DHT direct response (address=%s) [ %s ]"
2608
0
      , endpoint.address().to_string().c_str()
2609
0
      , m_response_size ? std::string(m_alloc.get().ptr(m_response_idx)
2610
0
        , aux::numeric_cast<std::size_t>(m_response_size)).c_str() : "");
2611
0
    return msg;
2612
0
#endif
2613
0
  }
2614
2615
  bdecode_node dht_direct_response_alert::response() const
2616
0
  {
2617
0
    if (m_response_size == 0) return bdecode_node();
2618
0
    char const* start = m_alloc.get().ptr(m_response_idx);
2619
0
    char const* end = start + m_response_size;
2620
0
    error_code ec;
2621
0
    bdecode_node ret;
2622
0
    bdecode(start, end, ret, ec);
2623
0
    TORRENT_ASSERT(!ec);
2624
0
    return ret;
2625
0
  }
2626
2627
  picker_log_alert::picker_log_alert(aux::stack_allocator& alloc, torrent_handle const& h
2628
    , tcp::endpoint const& ep, peer_id const& peer_id, picker_flags_t const flags
2629
    , span<piece_block const> blocks)
2630
0
    : peer_alert(alloc, h, ep, peer_id)
2631
0
    , picker_flags(flags)
2632
0
    , m_array_idx(alloc.copy_buffer({reinterpret_cast<char const*>(blocks.data())
2633
0
      , blocks.size() * int(sizeof(piece_block))}))
2634
0
    , m_num_blocks(int(blocks.size()))
2635
0
  {}
2636
2637
  std::vector<piece_block> picker_log_alert::blocks() const
2638
0
  {
2639
    // we need to copy this array to make sure the structures are properly
2640
    // aligned, not just to have a nice API
2641
0
    auto const num_blocks = aux::numeric_cast<std::size_t>(m_num_blocks);
2642
0
    std::vector<piece_block> ret(num_blocks);
2643
2644
0
    char const* start = m_alloc.get().ptr(m_array_idx);
2645
0
    std::memcpy(ret.data(), start, num_blocks * sizeof(piece_block));
2646
2647
0
    return ret;
2648
0
  }
2649
2650
  constexpr picker_flags_t picker_log_alert::partial_ratio;
2651
  constexpr picker_flags_t picker_log_alert::prioritize_partials;
2652
  constexpr picker_flags_t picker_log_alert::rarest_first_partials;
2653
  constexpr picker_flags_t picker_log_alert::rarest_first;
2654
  constexpr picker_flags_t picker_log_alert::reverse_rarest_first;
2655
  constexpr picker_flags_t picker_log_alert::suggested_pieces;
2656
  constexpr picker_flags_t picker_log_alert::prio_sequential_pieces;
2657
  constexpr picker_flags_t picker_log_alert::sequential_pieces;
2658
  constexpr picker_flags_t picker_log_alert::reverse_pieces;
2659
  constexpr picker_flags_t picker_log_alert::time_critical;
2660
  constexpr picker_flags_t picker_log_alert::random_pieces;
2661
  constexpr picker_flags_t picker_log_alert::prefer_contiguous;
2662
  constexpr picker_flags_t picker_log_alert::reverse_sequential;
2663
  constexpr picker_flags_t picker_log_alert::backup1;
2664
  constexpr picker_flags_t picker_log_alert::backup2;
2665
  constexpr picker_flags_t picker_log_alert::end_game;
2666
  constexpr picker_flags_t picker_log_alert::extent_affinity;
2667
2668
  std::string picker_log_alert::message() const
2669
0
  {
2670
#ifdef TORRENT_DISABLE_ALERT_MSG
2671
    return {};
2672
#else
2673
0
    static char const* const flag_names[] =
2674
0
    {
2675
0
      "partial_ratio ",
2676
0
      "prioritize_partials ",
2677
0
      "rarest_first_partials ",
2678
0
      "rarest_first ",
2679
0
      "reverse_rarest_first ",
2680
0
      "suggested_pieces ",
2681
0
      "prio_sequential_pieces ",
2682
0
      "sequential_pieces ",
2683
0
      "reverse_pieces ",
2684
0
      "time_critical ",
2685
0
      "random_pieces ",
2686
0
      "prefer_contiguous ",
2687
0
      "reverse_sequential ",
2688
0
      "backup1 ",
2689
0
      "backup2 ",
2690
0
      "end_game ",
2691
0
      "extent_affinity ",
2692
0
    };
2693
2694
0
    std::string ret = peer_alert::message();
2695
2696
0
    auto flags = static_cast<std::uint32_t>(picker_flags);
2697
0
    int idx = 0;
2698
0
    ret += " picker_log [ ";
2699
0
    for (; flags != 0; flags >>= 1, ++idx)
2700
0
    {
2701
0
      if ((flags & 1) == 0) continue;
2702
0
      ret += flag_names[idx];
2703
0
    }
2704
0
    ret += "] ";
2705
2706
0
    std::vector<piece_block> b = blocks();
2707
2708
0
    for (auto const& p : b)
2709
0
    {
2710
0
      char buf[50];
2711
0
      std::snprintf(buf, sizeof(buf), "(%d,%d) "
2712
0
        , static_cast<int>(p.piece_index), p.block_index);
2713
0
      ret += buf;
2714
0
    }
2715
0
    return ret;
2716
0
#endif
2717
0
  }
2718
2719
  session_error_alert::session_error_alert(aux::stack_allocator& alloc
2720
    , error_code e, string_view error_str)
2721
0
    : error(e)
2722
0
    , m_alloc(alloc)
2723
0
    , m_msg_idx(alloc.copy_string(error_str))
2724
0
  {}
2725
2726
  std::string session_error_alert::message() const
2727
0
  {
2728
#ifdef TORRENT_DISABLE_ALERT_MSG
2729
    return {};
2730
#else
2731
0
    char buf[400];
2732
0
    if (error)
2733
0
    {
2734
0
      std::snprintf(buf, sizeof(buf), "session error: (%d %s) %s"
2735
0
        , error.value(), convert_from_native(error.message()).c_str()
2736
0
        , m_alloc.get().ptr(m_msg_idx));
2737
0
    }
2738
0
    else
2739
0
    {
2740
0
      std::snprintf(buf, sizeof(buf), "session error: %s"
2741
0
        , m_alloc.get().ptr(m_msg_idx));
2742
0
    }
2743
0
    return buf;
2744
0
#endif
2745
0
  }
2746
2747
namespace {
2748
2749
  using nodes_slot = std::tuple<int, aux::allocation_slot, int, aux::allocation_slot>;
2750
2751
  nodes_slot write_nodes(aux::stack_allocator& alloc
2752
    , std::vector<std::pair<sha1_hash, udp::endpoint>> const& nodes)
2753
0
  {
2754
0
    int v4_num_nodes = 0;
2755
0
    int v6_num_nodes = 0;
2756
2757
0
    for (auto const& n : nodes)
2758
0
    {
2759
0
      if (aux::is_v4(n.second))
2760
0
        v4_num_nodes++;
2761
0
      else
2762
0
        v6_num_nodes++;
2763
0
    }
2764
2765
0
    aux::allocation_slot const v4_nodes_idx = alloc.allocate(v4_num_nodes * (20 + 6));
2766
0
    aux::allocation_slot const v6_nodes_idx = alloc.allocate(v6_num_nodes * (20 + 18));
2767
2768
0
    if ((v4_nodes_idx.is_valid() || v4_num_nodes == 0) && (v6_nodes_idx.is_valid() || v6_num_nodes == 0))
2769
0
    {
2770
0
      char* v4_ptr = alloc.ptr(v4_nodes_idx);
2771
0
      char* v6_ptr = alloc.ptr(v6_nodes_idx);
2772
0
      for (auto const& n : nodes)
2773
0
      {
2774
0
        udp::endpoint const& endp = n.second;
2775
0
        if (aux::is_v4(endp))
2776
0
        {
2777
0
          aux::write_string(n.first.to_string(), v4_ptr);
2778
0
          aux::write_endpoint(endp, v4_ptr);
2779
0
        }
2780
0
        else
2781
0
        {
2782
0
          aux::write_string(n.first.to_string(), v6_ptr);
2783
0
          aux::write_endpoint(endp, v6_ptr);
2784
0
        }
2785
0
      }
2786
0
    }
2787
0
    else
2788
0
    {
2789
0
      v4_num_nodes = 0;
2790
0
      v6_num_nodes = 0;
2791
0
    }
2792
2793
0
    return nodes_slot{v4_num_nodes, v4_nodes_idx, v6_num_nodes, v6_nodes_idx};
2794
0
  }
2795
2796
  std::vector<std::pair<sha1_hash, udp::endpoint>> read_nodes(
2797
    aux::stack_allocator const& alloc
2798
    , int const v4_num_nodes, aux::allocation_slot const v4_nodes_idx
2799
    , int const v6_num_nodes, aux::allocation_slot const v6_nodes_idx)
2800
0
  {
2801
0
    aux::vector<std::pair<sha1_hash, udp::endpoint>> nodes;
2802
0
    nodes.reserve(v4_num_nodes + v6_num_nodes);
2803
2804
0
    char const* v4_ptr = alloc.ptr(v4_nodes_idx);
2805
0
    for (int i = 0; i < v4_num_nodes; i++)
2806
0
    {
2807
0
      sha1_hash ih;
2808
0
      std::memcpy(ih.data(), v4_ptr, 20);
2809
0
      v4_ptr += 20;
2810
0
      nodes.emplace_back(ih, aux::read_v4_endpoint<udp::endpoint>(v4_ptr));
2811
0
    }
2812
0
    char const* v6_ptr = alloc.ptr(v6_nodes_idx);
2813
0
    for (int i = 0; i < v6_num_nodes; i++)
2814
0
    {
2815
0
      sha1_hash ih;
2816
0
      std::memcpy(ih.data(), v6_ptr, 20);
2817
0
      v6_ptr += 20;
2818
0
      nodes.emplace_back(ih, aux::read_v6_endpoint<udp::endpoint>(v6_ptr));
2819
0
    }
2820
2821
0
    return TORRENT_RVO(nodes);
2822
0
  }
2823
  }
2824
2825
  dht_live_nodes_alert::dht_live_nodes_alert(aux::stack_allocator& alloc
2826
    , sha1_hash const& nid
2827
    , std::vector<std::pair<sha1_hash, udp::endpoint>> const& nodes)
2828
0
    : node_id(nid)
2829
0
    , m_alloc(alloc)
2830
0
  {
2831
0
    std::tie(m_v4_num_nodes, m_v4_nodes_idx, m_v6_num_nodes, m_v6_nodes_idx)
2832
0
      = write_nodes(alloc, nodes);
2833
0
  }
2834
2835
  std::string dht_live_nodes_alert::message() const
2836
0
  {
2837
#ifdef TORRENT_DISABLE_ALERT_MSG
2838
    return {};
2839
#else
2840
0
    char msg[200];
2841
0
    std::snprintf(msg, sizeof(msg), "dht live nodes for id: %s, nodes %d"
2842
0
      , aux::to_hex(node_id).c_str(), num_nodes());
2843
0
    return msg;
2844
0
#endif
2845
0
  }
2846
2847
  int dht_live_nodes_alert::num_nodes() const
2848
0
  {
2849
0
    return m_v4_num_nodes + m_v6_num_nodes;
2850
0
  }
2851
2852
  std::vector<std::pair<sha1_hash, udp::endpoint>> dht_live_nodes_alert::nodes() const
2853
0
  {
2854
0
    return read_nodes(m_alloc.get()
2855
0
      , m_v4_num_nodes, m_v4_nodes_idx
2856
0
      , m_v6_num_nodes, m_v6_nodes_idx);
2857
0
  }
2858
2859
  session_stats_header_alert::session_stats_header_alert(aux::stack_allocator&)
2860
0
  {}
2861
2862
  std::string session_stats_header_alert::message() const
2863
0
  {
2864
#ifdef TORRENT_DISABLE_ALERT_MSG
2865
    return {};
2866
#else
2867
0
    std::string stats_header = "session stats header: ";
2868
0
    std::vector<stats_metric> stats = session_stats_metrics();
2869
0
    std::sort(stats.begin(), stats.end()
2870
0
      , [] (stats_metric const& lhs, stats_metric const& rhs)
2871
0
      { return lhs.value_index < rhs.value_index; });
2872
0
    bool first = true;
2873
0
    for (auto const& s : stats)
2874
0
    {
2875
0
      if (!first) stats_header += ", ";
2876
0
      stats_header += s.name;
2877
0
      first = false;
2878
0
    }
2879
2880
0
    return stats_header;
2881
0
#endif
2882
0
  }
2883
2884
  dht_sample_infohashes_alert::dht_sample_infohashes_alert(aux::stack_allocator& alloc
2885
    , sha1_hash const& nid
2886
    , udp::endpoint const& endp
2887
    , time_duration _interval
2888
    , int _num
2889
    , std::vector<sha1_hash> const& samples
2890
    , std::vector<std::pair<sha1_hash, udp::endpoint>> const& nodes)
2891
0
    : node_id(nid)
2892
0
    , endpoint(endp)
2893
0
    , interval(_interval)
2894
0
    , num_infohashes(_num)
2895
0
    , m_alloc(alloc)
2896
0
    , m_num_samples(aux::numeric_cast<int>(samples.size()))
2897
0
  {
2898
0
    m_samples_idx = alloc.allocate(m_num_samples * 20);
2899
2900
0
    if (!m_samples_idx.is_valid())
2901
0
    {
2902
0
      m_num_samples = 0;
2903
0
      return;
2904
0
    }
2905
2906
0
    char *ptr = alloc.ptr(m_samples_idx);
2907
0
    std::memcpy(ptr, samples.data(), samples.size() * 20);
2908
2909
0
    std::tie(m_v4_num_nodes, m_v4_nodes_idx, m_v6_num_nodes, m_v6_nodes_idx)
2910
0
      = write_nodes(alloc, nodes);
2911
0
  }
2912
2913
  std::string dht_sample_infohashes_alert::message() const
2914
0
  {
2915
#ifdef TORRENT_DISABLE_ALERT_MSG
2916
    return {};
2917
#else
2918
0
    char msg[200];
2919
0
    std::snprintf(msg, sizeof(msg)
2920
0
      , "incoming dht sample_infohashes reply from: %s, samples %d"
2921
0
      , print_endpoint(endpoint).c_str(), m_num_samples);
2922
0
    return msg;
2923
0
#endif
2924
0
  }
2925
2926
  int dht_sample_infohashes_alert::num_samples() const
2927
0
  {
2928
0
    return m_num_samples;
2929
0
  }
2930
2931
  std::vector<sha1_hash> dht_sample_infohashes_alert::samples() const
2932
0
  {
2933
0
    aux::vector<sha1_hash> samples;
2934
0
    samples.resize(m_num_samples);
2935
2936
0
    char const* ptr = m_alloc.get().ptr(m_samples_idx);
2937
0
    std::memcpy(samples.data(), ptr, samples.size() * 20);
2938
2939
0
    return TORRENT_RVO(samples);
2940
0
  }
2941
2942
  int dht_sample_infohashes_alert::num_nodes() const
2943
0
  {
2944
0
    return m_v4_num_nodes + m_v6_num_nodes;
2945
0
  }
2946
2947
  std::vector<std::pair<sha1_hash, udp::endpoint>> dht_sample_infohashes_alert::nodes() const
2948
0
  {
2949
0
    return read_nodes(m_alloc.get()
2950
0
      , m_v4_num_nodes, m_v4_nodes_idx
2951
0
      , m_v6_num_nodes, m_v6_nodes_idx);
2952
0
  }
2953
2954
  block_uploaded_alert::block_uploaded_alert(aux::stack_allocator& alloc, torrent_handle h
2955
    , tcp::endpoint const& ep, peer_id const& peer_id, int block_num
2956
    , piece_index_t piece_num)
2957
0
    : peer_alert(alloc, h, ep, peer_id)
2958
0
    , block_index(block_num)
2959
0
    , piece_index(piece_num)
2960
0
  {
2961
0
    TORRENT_ASSERT(block_index >= 0 && piece_index >= piece_index_t{0});
2962
0
  }
2963
2964
  std::string block_uploaded_alert::message() const
2965
0
  {
2966
#ifdef TORRENT_DISABLE_ALERT_MSG
2967
    return {};
2968
#else
2969
0
    char ret[200];
2970
0
    snprintf(ret, sizeof(ret), "%s block uploaded to a peer (piece: %d block: %d)"
2971
0
      , peer_alert::message().c_str(), static_cast<int>(piece_index), block_index);
2972
0
    return ret;
2973
0
#endif
2974
0
  }
2975
2976
  alerts_dropped_alert::alerts_dropped_alert(aux::stack_allocator&
2977
    , std::bitset<abi_alert_count> const& dropped)
2978
0
    : dropped_alerts(dropped)
2979
0
  {}
2980
2981
  char const* alert_name(int const alert_type)
2982
0
  {
2983
0
    static std::array<char const*, num_alert_types> const names = {{
2984
0
#if TORRENT_ABI_VERSION == 1
2985
0
    "torrent", "peer", "tracker", "torrent_added",
2986
#else
2987
    "", "", "", "",
2988
#endif
2989
0
    "torrent_removed", "read_piece", "file_completed",
2990
0
    "file_renamed", "file_rename_failed", "performance",
2991
0
    "state_changed", "tracker_error", "tracker_warning",
2992
0
    "scrape_reply", "scrape_failed", "tracker_reply",
2993
0
    "dht_reply", "tracker_announce", "hash_failed",
2994
0
    "peer_ban", "peer_unsnubbed", "peer_snubbed",
2995
0
    "peer_error", "peer_connect", "peer_disconnected",
2996
0
    "invalid_request", "torrent_finished", "piece_finished",
2997
0
    "request_dropped", "block_timeout", "block_finished",
2998
0
    "block_downloading", "unwanted_block", "storage_moved",
2999
0
    "storage_moved_failed", "torrent_deleted",
3000
0
    "torrent_delete_failed", "save_resume_data",
3001
0
    "save_resume_data_failed", "torrent_paused",
3002
0
    "torrent_resumed", "torrent_checked", "url_seed",
3003
0
    "file_error", "metadata_failed", "metadata_received",
3004
0
    "udp_error", "external_ip", "listen_failed",
3005
0
    "listen_succeeded", "portmap_error", "portmap",
3006
0
    "portmap_log", "fastresume_rejected", "peer_blocked",
3007
0
    "dht_announce", "dht_get_peers", "stats",
3008
0
    "cache_flushed", "anonymous_mode", "lsd_peer",
3009
0
    "trackerid", "dht_bootstrap", "", "torrent_error",
3010
0
    "torrent_need_cert", "incoming_connection",
3011
0
    "add_torrent", "state_update",
3012
0
#if TORRENT_ABI_VERSION == 1
3013
0
    "mmap_cache",
3014
#else
3015
    "",
3016
#endif
3017
0
    "session_stats",
3018
0
#if TORRENT_ABI_VERSION == 1
3019
0
    "torrent_update",
3020
#else
3021
    "",
3022
#endif
3023
0
    "", "dht_error", "dht_immutable_item", "dht_mutable_item",
3024
0
    "dht_put", "i2p", "dht_outgoing_get_peers", "log",
3025
0
    "torrent_log", "peer_log", "lsd_error",
3026
0
    "dht_stats", "incoming_request", "dht_log",
3027
0
    "dht_pkt", "dht_get_peers_reply", "dht_direct_response",
3028
0
    "picker_log", "session_error", "dht_live_nodes",
3029
0
    "session_stats_header", "dht_sample_infohashes",
3030
0
    "block_uploaded", "alerts_dropped", "socks5",
3031
0
    "file_prio", "oversized_file", "torrent_conflict",
3032
0
    "peer_info", "file_progress", "piece_info",
3033
0
    "piece_availability", "tracker_list"
3034
0
    }};
3035
3036
0
    TORRENT_ASSERT(alert_type >= 0);
3037
0
    TORRENT_ASSERT(alert_type < num_alert_types);
3038
0
    return names[std::size_t(alert_type)];
3039
0
  }
3040
3041
  std::string alerts_dropped_alert::message() const
3042
0
  {
3043
#ifdef TORRENT_DISABLE_ALERT_MSG
3044
    return {};
3045
#else
3046
0
    std::string ret = "dropped alerts: ";
3047
3048
0
    TORRENT_ASSERT(int(dropped_alerts.size()) >= num_alert_types);
3049
0
    for (int idx = 0; idx < num_alert_types; ++idx)
3050
0
    {
3051
0
      if (!dropped_alerts.test(std::size_t(idx))) continue;
3052
0
      ret += alert_name(idx);
3053
0
      ret += ' ';
3054
0
    }
3055
3056
0
    return ret;
3057
0
#endif
3058
0
  }
3059
3060
  socks5_alert::socks5_alert(aux::stack_allocator&
3061
    , tcp::endpoint const& ep, operation_t operation, error_code const& ec)
3062
0
    : error(ec)
3063
0
    , op(operation)
3064
0
    , ip(ep)
3065
0
  {}
3066
3067
  std::string socks5_alert::message() const
3068
0
  {
3069
#ifdef TORRENT_DISABLE_ALERT_MSG
3070
    return {};
3071
#else
3072
0
    char buf[512];
3073
0
    std::snprintf(buf, sizeof(buf), "SOCKS5 error. op: %s ec: %s ep: %s"
3074
0
      , operation_name(op), error.message().c_str(), print_endpoint(ip).c_str());
3075
0
    return buf;
3076
0
#endif
3077
0
  }
3078
3079
  file_prio_alert::file_prio_alert(aux::stack_allocator& a, torrent_handle h)
3080
0
    : torrent_alert(a, std::move(h))
3081
0
  {}
3082
3083
  std::string file_prio_alert::message() const
3084
0
  {
3085
#ifdef TORRENT_DISABLE_ALERT_MSG
3086
    return {};
3087
#else
3088
0
    return torrent_alert::message() + " file priorities updated";
3089
0
#endif
3090
0
  }
3091
3092
  oversized_file_alert::oversized_file_alert(aux::stack_allocator& a, torrent_handle h)
3093
0
    : torrent_alert(a, std::move(h))
3094
0
  {}
3095
3096
  std::string oversized_file_alert::message() const
3097
0
  {
3098
#ifdef TORRENT_DISABLE_ALERT_MSG
3099
    return {};
3100
#else
3101
0
    return torrent_alert::message() + " has an oversized file";
3102
0
#endif
3103
0
  }
3104
3105
  torrent_conflict_alert::torrent_conflict_alert(aux::stack_allocator& alloc, torrent_handle h1
3106
    , torrent_handle h2, std::shared_ptr<torrent_info> ti)
3107
0
    : torrent_alert(alloc, h1)
3108
0
    , conflicting_torrent(h2)
3109
0
    , metadata(std::move(ti))
3110
0
  {}
3111
3112
  std::string torrent_conflict_alert::message() const
3113
0
  {
3114
#ifdef TORRENT_DISABLE_ALERT_MSG
3115
    return {};
3116
#else
3117
0
    return torrent_alert::message() + " has a conflict with another torrent";
3118
0
#endif
3119
0
  }
3120
3121
  peer_info_alert::peer_info_alert(aux::stack_allocator& alloc, torrent_handle h
3122
    , std::vector<lt::peer_info> p)
3123
0
    : torrent_alert(alloc, std::move(h))
3124
0
    , peer_info(std::move(p))
3125
0
  {}
3126
3127
  std::string peer_info_alert::message() const
3128
0
  {
3129
#ifdef TORRENT_DISABLE_ALERT_MSG
3130
    return {};
3131
#else
3132
0
    return torrent_alert::message() + " peer_info";
3133
0
#endif
3134
0
  }
3135
3136
  file_progress_alert::file_progress_alert(aux::stack_allocator& alloc, torrent_handle h
3137
    , aux::vector<std::int64_t, file_index_t> fp)
3138
0
    : torrent_alert(alloc, std::move(h))
3139
0
    , files(std::move(fp))
3140
0
  {}
3141
3142
  std::string file_progress_alert::message() const
3143
0
  {
3144
#ifdef TORRENT_DISABLE_ALERT_MSG
3145
    return {};
3146
#else
3147
0
    return torrent_alert::message() + " file_progress";
3148
0
#endif
3149
0
  }
3150
3151
  piece_info_alert::piece_info_alert(aux::stack_allocator& alloc, torrent_handle h
3152
      , std::vector<partial_piece_info> pi, std::vector<block_info>&& bd)
3153
0
    : torrent_alert(alloc, std::move(h))
3154
0
    , piece_info(std::move(pi))
3155
0
    , block_data(std::move(bd))
3156
0
  {}
3157
3158
  std::string piece_info_alert::message() const
3159
0
  {
3160
#ifdef TORRENT_DISABLE_ALERT_MSG
3161
    return {};
3162
#else
3163
0
    return torrent_alert::message() + " piece_info";
3164
0
#endif
3165
0
  }
3166
3167
  piece_availability_alert::piece_availability_alert(aux::stack_allocator& alloc
3168
      , torrent_handle h, std::vector<int> pa)
3169
0
    : torrent_alert(alloc, std::move(h))
3170
0
    , piece_availability(std::move(pa))
3171
0
  {}
3172
3173
  std::string piece_availability_alert::message() const
3174
0
  {
3175
#ifdef TORRENT_DISABLE_ALERT_MSG
3176
    return {};
3177
#else
3178
0
    return torrent_alert::message() + " piece_availability";
3179
0
#endif
3180
0
  }
3181
3182
  tracker_list_alert::tracker_list_alert(aux::stack_allocator& alloc
3183
      , torrent_handle h, std::vector<announce_entry> t)
3184
0
    : torrent_alert(alloc, std::move(h))
3185
0
    , trackers(std::move(t))
3186
0
  {}
3187
3188
  std::string tracker_list_alert::message() const
3189
0
  {
3190
#ifdef TORRENT_DISABLE_ALERT_MSG
3191
    return {};
3192
#else
3193
0
    return torrent_alert::message() + " tracker_list";
3194
0
#endif
3195
0
  }
3196
3197
  // this will no longer be necessary in C++17
3198
  constexpr alert_category_t torrent_removed_alert::static_category;
3199
  constexpr alert_category_t read_piece_alert::static_category;
3200
  constexpr alert_category_t file_completed_alert::static_category;
3201
  constexpr alert_category_t file_renamed_alert::static_category;
3202
  constexpr alert_category_t file_rename_failed_alert::static_category;
3203
  constexpr alert_category_t performance_alert::static_category;
3204
  constexpr alert_category_t state_changed_alert::static_category;
3205
  constexpr alert_category_t tracker_error_alert::static_category;
3206
  constexpr alert_category_t tracker_warning_alert::static_category;
3207
  constexpr alert_category_t scrape_reply_alert::static_category;
3208
  constexpr alert_category_t scrape_failed_alert::static_category;
3209
  constexpr alert_category_t tracker_reply_alert::static_category;
3210
  constexpr alert_category_t dht_reply_alert::static_category;
3211
  constexpr alert_category_t tracker_announce_alert::static_category;
3212
  constexpr alert_category_t hash_failed_alert::static_category;
3213
  constexpr alert_category_t peer_ban_alert::static_category;
3214
  constexpr alert_category_t peer_unsnubbed_alert::static_category;
3215
  constexpr alert_category_t peer_snubbed_alert::static_category;
3216
  constexpr alert_category_t peer_error_alert::static_category;
3217
  constexpr alert_category_t peer_connect_alert::static_category;
3218
  constexpr alert_category_t peer_disconnected_alert::static_category;
3219
  constexpr alert_category_t invalid_request_alert::static_category;
3220
  constexpr alert_category_t torrent_finished_alert::static_category;
3221
  constexpr alert_category_t piece_finished_alert::static_category;
3222
  constexpr alert_category_t request_dropped_alert::static_category;
3223
  constexpr alert_category_t block_timeout_alert::static_category;
3224
  constexpr alert_category_t block_finished_alert::static_category;
3225
  constexpr alert_category_t block_downloading_alert::static_category;
3226
  constexpr alert_category_t unwanted_block_alert::static_category;
3227
  constexpr alert_category_t storage_moved_alert::static_category;
3228
  constexpr alert_category_t storage_moved_failed_alert::static_category;
3229
  constexpr alert_category_t torrent_deleted_alert::static_category;
3230
  constexpr alert_category_t torrent_delete_failed_alert::static_category;
3231
  constexpr alert_category_t save_resume_data_alert::static_category;
3232
  constexpr alert_category_t save_resume_data_failed_alert::static_category;
3233
  constexpr alert_category_t torrent_paused_alert::static_category;
3234
  constexpr alert_category_t torrent_resumed_alert::static_category;
3235
  constexpr alert_category_t torrent_checked_alert::static_category;
3236
  constexpr alert_category_t url_seed_alert::static_category;
3237
  constexpr alert_category_t file_error_alert::static_category;
3238
  constexpr alert_category_t metadata_failed_alert::static_category;
3239
  constexpr alert_category_t metadata_received_alert::static_category;
3240
  constexpr alert_category_t udp_error_alert::static_category;
3241
  constexpr alert_category_t external_ip_alert::static_category;
3242
  constexpr alert_category_t listen_failed_alert::static_category;
3243
  constexpr alert_category_t listen_succeeded_alert::static_category;
3244
  constexpr alert_category_t portmap_error_alert::static_category;
3245
  constexpr alert_category_t portmap_alert::static_category;
3246
  constexpr alert_category_t portmap_log_alert::static_category;
3247
  constexpr alert_category_t fastresume_rejected_alert::static_category;
3248
  constexpr alert_category_t peer_blocked_alert::static_category;
3249
  constexpr alert_category_t dht_announce_alert::static_category;
3250
  constexpr alert_category_t dht_get_peers_alert::static_category;
3251
#if TORRENT_ABI_VERSION <= 2
3252
  constexpr alert_category_t stats_alert::static_category;
3253
#endif
3254
  constexpr alert_category_t cache_flushed_alert::static_category;
3255
  constexpr alert_category_t lsd_peer_alert::static_category;
3256
  constexpr alert_category_t trackerid_alert::static_category;
3257
  constexpr alert_category_t dht_bootstrap_alert::static_category;
3258
  constexpr alert_category_t torrent_error_alert::static_category;
3259
  constexpr alert_category_t torrent_need_cert_alert::static_category;
3260
  constexpr alert_category_t incoming_connection_alert::static_category;
3261
  constexpr alert_category_t add_torrent_alert::static_category;
3262
  constexpr alert_category_t state_update_alert::static_category;
3263
  constexpr alert_category_t session_stats_alert::static_category;
3264
  constexpr alert_category_t dht_error_alert::static_category;
3265
  constexpr alert_category_t dht_immutable_item_alert::static_category;
3266
  constexpr alert_category_t dht_mutable_item_alert::static_category;
3267
  constexpr alert_category_t dht_put_alert::static_category;
3268
  constexpr alert_category_t i2p_alert::static_category;
3269
  constexpr alert_category_t dht_outgoing_get_peers_alert::static_category;
3270
  constexpr alert_category_t log_alert::static_category;
3271
  constexpr alert_category_t torrent_log_alert::static_category;
3272
  constexpr alert_category_t peer_log_alert::static_category;
3273
  constexpr alert_category_t lsd_error_alert::static_category;
3274
  constexpr alert_category_t dht_stats_alert::static_category;
3275
  constexpr alert_category_t incoming_request_alert::static_category;
3276
  constexpr alert_category_t dht_log_alert::static_category;
3277
  constexpr alert_category_t dht_pkt_alert::static_category;
3278
  constexpr alert_category_t dht_get_peers_reply_alert::static_category;
3279
  constexpr alert_category_t dht_direct_response_alert::static_category;
3280
  constexpr alert_category_t picker_log_alert::static_category;
3281
  constexpr alert_category_t session_error_alert::static_category;
3282
  constexpr alert_category_t dht_live_nodes_alert::static_category;
3283
  constexpr alert_category_t session_stats_header_alert::static_category;
3284
  constexpr alert_category_t dht_sample_infohashes_alert::static_category;
3285
  constexpr alert_category_t block_uploaded_alert::static_category;
3286
  constexpr alert_category_t alerts_dropped_alert::static_category;
3287
  constexpr alert_category_t socks5_alert::static_category;
3288
  constexpr alert_category_t file_prio_alert::static_category;
3289
  constexpr alert_category_t oversized_file_alert::static_category;
3290
  constexpr alert_category_t torrent_conflict_alert::static_category;
3291
  constexpr alert_category_t peer_info_alert::static_category;
3292
  constexpr alert_category_t file_progress_alert::static_category;
3293
  constexpr alert_category_t piece_info_alert::static_category;
3294
  constexpr alert_category_t piece_availability_alert::static_category;
3295
  constexpr alert_category_t tracker_list_alert::static_category;
3296
#if TORRENT_ABI_VERSION == 1
3297
  constexpr alert_category_t anonymous_mode_alert::static_category;
3298
  constexpr alert_category_t mmap_cache_alert::static_category;
3299
  constexpr alert_category_t torrent_added_alert::static_category;
3300
#endif
3301
3302
} // namespace libtorrent