Coverage Report

Created: 2025-07-01 06:55

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