1 /** @file 2 * 3 * A brief file description 4 * 5 * @section license License 6 * 7 * Licensed to the Apache Software Foundation (ASF) under one 8 * or more contributor license agreements. See the NOTICE file 9 * distributed with this work for additional information 10 * regarding copyright ownership. The ASF licenses this file 11 * to you under the Apache License, Version 2.0 (the 12 * "License"); you may not use this file except in compliance 13 * with the License. You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23 24 #pragma once 25 26 #include <string> 27 #include <yaml-cpp/yaml.h> 28 29 #include "QUICTypes.h" 30 #include "QLogEvent.h" 31 #include "QLogFrame.h" 32 33 namespace QLog 34 { 35 class QLogEvent 36 { 37 public: ~QLogEvent()38 virtual ~QLogEvent() {} 39 40 virtual std::string category() const = 0; 41 virtual std::string event() const = 0; 42 virtual void encode(YAML::Node &) = 0; 43 44 virtual ink_hrtime get_time()45 get_time() const 46 { 47 return this->_time; 48 }; 49 50 protected: 51 ink_hrtime _time = Thread::get_hrtime(); 52 }; 53 54 using QLogEventUPtr = std::unique_ptr<QLogEvent>; 55 56 #define SET(field, type) \ 57 void set_##field(type v) { this->_node[#field] = v; } 58 59 // enum class PacketType : uint8_t { initial, handshake, zerortt, onertt, retry, version_negotiation, unknown }; 60 using PacketType = std::string; 61 62 struct PacketHeader { 63 std::string packet_number; 64 uint64_t packet_size; 65 uint64_t payload_length; 66 67 // only if present in the header 68 // if correctly using NEW_CONNECTION_ID events, 69 // dcid can be skipped for 1RTT packets 70 std::string version; 71 std::string scil; 72 std::string dcil; 73 std::string scid; 74 std::string dcid; 75 76 // Note: short vs long header is implicit through PacketType 77 void encodePacketHeader78 encode(YAML::Node &node) const 79 { 80 node["packet_number"] = packet_number; 81 node["packet_size"] = packet_size; 82 node["payload_length"] = payload_length; 83 node["version"] = version; 84 node["scil"] = scil; 85 node["dcil"] = dcil; 86 node["scid"] = scid; 87 node["dcid"] = dcid; 88 } 89 }; 90 91 #define SET_FUNC(cla, field, type) \ 92 public: \ 93 cla &set_##field(const type &v) \ 94 { \ 95 this->_##field = v; \ 96 return *this; \ 97 } \ 98 \ 99 private: \ 100 type _##field; 101 102 #define APPEND_FUNC(cla, field, type) \ 103 public: \ 104 cla &append_##field(type v) \ 105 { \ 106 this->_##field.push_back(v); \ 107 return *this; \ 108 } \ 109 \ 110 private: \ 111 std::vector<type> _##field; 112 113 #define APPEND_FRAME_FUNC(cla) \ 114 public: \ 115 cla &append_frames(QLogFrameUPtr v) \ 116 { \ 117 this->_frames.push_back(std::move(v)); \ 118 return *this; \ 119 } \ 120 \ 121 private: \ 122 std::vector<QLogFrameUPtr> _frames; 123 124 // 125 // connectivity 126 // 127 namespace Connectivity 128 { 129 class ConnectivityEvent : public QLogEvent 130 { 131 public: 132 std::string category()133 category() const override 134 { 135 return "connectivity"; 136 } 137 }; 138 139 class ServerListening : public ConnectivityEvent 140 { 141 public: 142 ServerListening(int port, bool v6 = false) 143 { 144 if (v6) { 145 set_port_v6(port); 146 } else { 147 set_port_v4(port); 148 } 149 } 150 151 #define _SET(a, b) SET_FUNC(ServerListening, a, b) 152 #define _APPEND(a, b) APPEND_FUNC(ServerListening, a, b) 153 _SET(port_v4, int) 154 _SET(port_v6, int) 155 _SET(ip_v4, std::string) 156 _SET(ip_v6, std::string) 157 _SET(stateless_reset_required, bool) 158 _APPEND(quic_version, std::string) 159 _APPEND(alpn_values, std::string) 160 161 #undef _SET 162 #undef _APPEND 163 164 void encode(YAML::Node &) override; 165 166 std::string event()167 event() const override 168 { 169 return "server_listening"; 170 } 171 }; 172 173 class ConnectionStarted : public ConnectivityEvent 174 { 175 public: 176 ConnectionStarted(const std::string &version, const std::string &sip, const std::string &dip, int sport, int dport, 177 const std::string &protocol = "QUIC") 178 { 179 set_ip_version(version); 180 set_protocol(protocol); 181 set_src_ip(sip); 182 set_dst_ip(dip); 183 set_src_port(sport); 184 set_dst_port(dport); 185 } 186 187 #define _SET(a, b) SET_FUNC(ConnectionStarted, a, b) 188 #define _APPEND(a, b) APPEND_FUNC(ConnectionStarted, a, b) 189 _SET(quic_version, std::string); 190 _SET(src_cid, std::string); 191 _SET(dst_cid, std::string); 192 _SET(protocol, std::string); 193 _SET(ip_version, std::string) 194 _SET(src_ip, std::string) 195 _SET(dst_ip, std::string) 196 _SET(src_port, int) 197 _SET(dst_port, int) 198 _APPEND(alpn_values, std::string) 199 200 #undef _SET 201 #undef _APPEND 202 203 void encode(YAML::Node &) override; 204 205 std::string event()206 event() const override 207 { 208 return "connection_started"; 209 } 210 }; 211 212 class ConnectionIdUpdated : public ConnectivityEvent 213 { 214 public: 215 ConnectionIdUpdated(const std::string &old, const std::string &n, bool peer = false) 216 { 217 if (peer) { 218 set_dst_old(old); 219 set_dst_new(n); 220 } else { 221 set_src_old(old); 222 set_src_new(n); 223 } 224 } 225 226 #define _SET(a, b) SET_FUNC(ConnectionIdUpdated, a, b) 227 #define _APPEND(a, b) APPEND_FUNC(ConnectionIdUpdated, a, b) 228 229 _SET(src_old, std::string); 230 _SET(src_new, std::string); 231 _SET(dst_old, std::string); 232 _SET(dst_new, std::string); 233 234 #undef _SET 235 #undef _APPEND 236 237 void encode(YAML::Node &) override; 238 239 std::string event()240 event() const override 241 { 242 return "connection_id_updated"; 243 } 244 }; 245 246 class SpinBitUpdated : public ConnectivityEvent 247 { 248 public: SpinBitUpdated(bool state)249 SpinBitUpdated(bool state) { set_state(state); } 250 251 #define _SET(a, b) SET_FUNC(SpinBitUpdated, a, b) 252 _SET(state, bool); 253 #undef _SET 254 255 void encode(YAML::Node &) override; 256 257 std::string event()258 event() const override 259 { 260 return "spin_bit_updated"; 261 } 262 }; 263 264 class ConnectionStateUpdated : public ConnectivityEvent 265 { 266 public: 267 enum class ConnectionState : uint8_t { 268 attempted, // client initial sent 269 reset, // stateless reset sent 270 handshake, // handshake in progress 271 active, // handshake successful, data exchange 272 keepalive, // no data for a longer period 273 draining, // CONNECTION_CLOSE sent 274 closed // connection actually fully closed, memory freed 275 }; 276 277 enum class Triggered : uint8_t { 278 unknown, 279 error, // when closing because of an unexpected event 280 clean, // when closing normally 281 application // e.g., HTTP/3's GOAWAY frame 282 }; 283 284 ConnectionStateUpdated(ConnectionState n, Triggered tr = Triggered::unknown) 285 { 286 set_new(n); 287 set_trigger(tr); 288 } 289 290 #define _SET(a, b) SET_FUNC(ConnectionStateUpdated, a, b) 291 _SET(new, ConnectionState); 292 _SET(old, ConnectionState); 293 _SET(trigger, Triggered) 294 295 #undef _SET 296 297 void encode(YAML::Node &) override; 298 299 static const char * trigger_name(Triggered trigger)300 trigger_name(Triggered trigger) 301 { 302 switch (trigger) { 303 case Triggered::error: 304 return "error"; 305 case Triggered::clean: 306 return "clean"; 307 case Triggered::application: 308 return "application"; 309 default: 310 return nullptr; 311 } 312 } 313 314 std::string event()315 event() const override 316 { 317 return "connection_state_updated"; 318 } 319 }; 320 321 } // namespace Connectivity 322 323 namespace Security 324 { 325 class KeyEvent : public QLogEvent 326 { 327 public: 328 enum class KeyType : uint8_t { 329 server_initial_secret, 330 client_initial_secret, 331 332 server_handshake_secret, 333 client_handshake_secret, 334 335 server_0rtt_secret, 336 client_0rtt_secret, 337 338 server_1rtt_secret, 339 client_1rtt_secret 340 }; 341 342 enum class Triggered : uint8_t { 343 unknown, 344 remote_update, 345 local_update, 346 tls, 347 }; 348 349 KeyEvent(KeyType ty, const std::string &n, int generation, Triggered triggered = Triggered::unknown) 350 { 351 set_key_type(ty); 352 set_new(n); 353 set_generation(generation); 354 set_trigger(triggered); 355 } 356 357 #define _SET(a, b) SET_FUNC(KeyEvent, a, b) 358 _SET(key_type, KeyType); 359 _SET(new, std::string) 360 _SET(old, std::string); 361 _SET(generation, int) 362 _SET(trigger, Triggered) 363 #undef _SET 364 365 void encode(YAML::Node &) override; 366 367 const char * trigger_name(Triggered triggered)368 trigger_name(Triggered triggered) 369 { 370 switch (triggered) { 371 case Triggered::remote_update: 372 return "remote_update"; 373 case Triggered::local_update: 374 return "local_update"; 375 case Triggered::tls: 376 return "tls"; 377 default: 378 return nullptr; 379 } 380 } 381 382 std::string category()383 category() const override 384 { 385 return "security"; 386 } 387 }; 388 389 class KeyUpdated : public KeyEvent 390 { 391 public: 392 KeyUpdated(KeyType ty, const std::string &n, int generation, Triggered triggered = KeyEvent::Triggered::unknown) KeyEvent(ty,n,generation,triggered)393 : KeyEvent(ty, n, generation, triggered) 394 { 395 } 396 397 std::string event()398 event() const override 399 { 400 return "key_updated"; 401 } 402 }; 403 404 class KeyRetired : public KeyEvent 405 { 406 public: 407 KeyRetired(KeyType ty, const std::string &n, int generation, Triggered triggered = KeyEvent::Triggered::unknown) KeyEvent(ty,n,generation,triggered)408 : KeyEvent(ty, n, generation, triggered) 409 { 410 } 411 412 std::string event()413 event() const override 414 { 415 return "key_retired"; 416 } 417 }; 418 419 } // namespace Security 420 421 // 422 // transport event 423 // 424 namespace Transport 425 { 426 class TransportEvent : public QLogEvent 427 { 428 public: 429 std::string category()430 category() const override 431 { 432 return "transport"; 433 } 434 }; 435 436 class ParametersSet : public TransportEvent 437 { 438 public: 439 struct PreferredAddress { 440 std::string ip; 441 int port; 442 std::string connection_id; 443 std::string stateless_reset_token; 444 bool ipv4 = true; 445 }; 446 ParametersSet(bool owner)447 ParametersSet(bool owner) : _owner(owner) {} 448 449 std::string event()450 event() const override 451 { 452 return "parameters_set"; 453 } 454 455 #define _SET(a, b) SET_FUNC(ParametersSet, a, b) 456 _SET(resumption_allowed, bool); // early data extension was enabled on the TLS layer 457 _SET(early_data_enabled, bool); // early data extension was enabled on the TLS layer 458 _SET(alpn, std::string); 459 _SET(version, std::string); // hex (e.g. 0x); 460 _SET(tls_cipher, std::string); // (e.g. AES_128_GCM_SHA256); 461 _SET(original_connection_id, std::string); // hex 462 _SET(stateless_reset_token, std::string); // hex 463 _SET(disable_active_migration, bool); 464 _SET(idle_timeout, int); 465 _SET(max_packet_size, int); 466 _SET(ack_delay_exponent, int); 467 _SET(max_ack_delay, int); 468 _SET(active_connection_id_limit, int); 469 _SET(initial_max_data, std::string); 470 _SET(initial_max_stream_data_bidi_local, std::string); 471 _SET(initial_max_stream_data_bidi_remote, std::string); 472 _SET(initial_max_stream_data_uni, std::string); 473 _SET(initial_max_streams_bidi, std::string); 474 _SET(initial_max_streams_uni, std::string); 475 _SET(max_idle_timeout, int64_t) 476 _SET(max_udp_payload_size, size_t) 477 _SET(preferred_address, PreferredAddress) 478 #undef _SET 479 480 void encode(YAML::Node &) override; 481 482 private: 483 bool _owner = false; 484 }; 485 486 class PacketEvent : public TransportEvent 487 { 488 public: 489 enum class Triggered : uint8_t { 490 unknown, 491 keys_available, // if packet was buffered because it couldn't be decrypted before 492 retransmit_reordered, // draft-23 5.1.1 493 retransmit_timeout, // draft-23 5.1.2 494 pto_probe, // draft-23 5.3.1 495 retransmit_crypto, // draft-19 6.2 496 cc_bandwidth_probe, // needed for some CCs to figure out bandwidth allocations when there are no normal sends 497 }; 498 499 PacketEvent(const PacketType &type, PacketHeader h, Triggered tr = Triggered::unknown) 500 { 501 set_packet_type(type).set_header(h).set_trigger(tr); 502 } 503 504 #define _SET(a, b) SET_FUNC(PacketEvent, a, b) 505 #define _APPEND(a, b) APPEND_FUNC(PacketEvent, a, b) 506 _SET(packet_type, PacketType) 507 _SET(header, PacketHeader) 508 _SET(is_coalesced, bool); 509 _SET(raw_encrypted, std::string); 510 _SET(raw_decrypted, std::string); 511 _SET(stateless_reset_token, std::string); 512 _SET(trigger, Triggered); 513 _APPEND(supported_version, std::string); 514 515 #undef _SET 516 #undef _APPEND 517 APPEND_FRAME_FUNC(PacketEvent) 518 519 void encode(YAML::Node &) override; 520 521 static const char * trigger_name(Triggered triggered)522 trigger_name(Triggered triggered) 523 { 524 switch (triggered) { 525 case Triggered::retransmit_reordered: 526 return "retransmit_reordered"; 527 case Triggered::retransmit_timeout: 528 return "retransmit_timeout"; 529 case Triggered::pto_probe: 530 return "pto_probe"; 531 case Triggered::retransmit_crypto: 532 return "retransmit_crypto"; 533 case Triggered::cc_bandwidth_probe: 534 return "cc_bandwidth_probe"; 535 break; 536 case Triggered::keys_available: 537 return "keys_available"; 538 default: 539 return nullptr; 540 } 541 } 542 }; 543 544 class PacketSent : public PacketEvent 545 { 546 public: PacketEvent(type,h,tr)547 PacketSent(const PacketType &type, const PacketHeader &h, Triggered tr = Triggered::unknown) : PacketEvent(type, h, tr) {} 548 std::string event()549 event() const override 550 { 551 return "packet_sent"; 552 } 553 }; 554 555 class PacketReceived : public PacketEvent 556 { 557 public: PacketEvent(type,h,tr)558 PacketReceived(const PacketType &type, const PacketHeader &h, Triggered tr = Triggered::unknown) : PacketEvent(type, h, tr) {} 559 std::string event()560 event() const override 561 { 562 return "packet_received"; 563 } 564 }; 565 566 class PacketDropped : public TransportEvent 567 { 568 public: 569 enum class Triggered : uint8_t { 570 unknown, 571 key_unavailable, 572 unknown_connection_id, 573 header_decrypt_error, 574 payload_decrypt_error, 575 protocol_violation, 576 dos_prevention, 577 unsupported_version, 578 unexpected_packet, 579 unexpected_source_connection_id, 580 unexpected_version, 581 }; 582 583 PacketDropped(Triggered tr = Triggered::unknown) { set_trigger(tr); } 584 585 #define _SET(a, b) SET_FUNC(PacketDropped, a, b) 586 _SET(packet_size, int); 587 _SET(raw, std::string); 588 _SET(trigger, Triggered); 589 _SET(packet_type, PacketType) 590 #undef _SET 591 592 void encode(YAML::Node &) override; 593 594 std::string event()595 event() const override 596 { 597 return "packet_dropped"; 598 } 599 600 static const char * trigger_name(Triggered tr)601 trigger_name(Triggered tr) 602 { 603 switch (tr) { 604 case Triggered::key_unavailable: 605 return "key_unavailable"; 606 case Triggered::unknown_connection_id: 607 return "unknown_connection_id"; 608 case Triggered::header_decrypt_error: 609 return "header_decrypt_error"; 610 case Triggered::payload_decrypt_error: 611 return "payload_decrypt_error"; 612 case Triggered::protocol_violation: 613 return "protocol_violation"; 614 case Triggered::dos_prevention: 615 return "dos_prevention"; 616 case Triggered::unsupported_version: 617 return "unsupported_version"; 618 case Triggered::unexpected_packet: 619 return "unexpected_packet"; 620 case Triggered::unexpected_source_connection_id: 621 return "unexpected_source_connection_id"; 622 case Triggered::unexpected_version: 623 return "unexpected_version"; 624 default: 625 return nullptr; 626 } 627 } 628 }; 629 630 class PacketBuffered : public TransportEvent 631 { 632 public: 633 enum class Triggered : uint8_t { 634 unknown, 635 backpressure, 636 keys_unavailable, 637 }; 638 639 PacketBuffered(Triggered tr = Triggered::unknown) { set_trigger(tr); } 640 641 #define _SET(a, b) SET_FUNC(PacketBuffered, a, b) 642 _SET(trigger, Triggered); 643 _SET(packet_type, PacketType) 644 _SET(packet_number, std::string) 645 #undef _SET 646 647 void encode(YAML::Node &) override; 648 649 std::string event()650 event() const override 651 { 652 return "packet_buffered"; 653 } 654 655 static const char * trigger_name(Triggered tr)656 trigger_name(Triggered tr) 657 { 658 switch (tr) { 659 case Triggered::backpressure: 660 return "backpressure"; 661 case Triggered::keys_unavailable: 662 return "keys_unavailable"; 663 default: 664 return nullptr; 665 } 666 } 667 }; 668 669 class DatagramsEvent : public TransportEvent 670 { 671 public: 672 #define _SET(a, b) SET_FUNC(DatagramsEvent, a, b) 673 _SET(count, int); 674 _SET(byte_length, int); 675 #undef _SET 676 void encode(YAML::Node &) override; 677 }; 678 679 class DatagramsSent : public DatagramsEvent 680 { 681 public: 682 std::string event()683 event() const override 684 { 685 return "datagrams_sent"; 686 } 687 }; 688 class DatagramReceived : public DatagramsEvent 689 { 690 public: 691 std::string event()692 event() const override 693 { 694 return "datagrams_received"; 695 } 696 }; 697 698 class DatagramsDropped : public TransportEvent 699 { 700 public: 701 #define _SET(a, b) SET_FUNC(DatagramsDropped, a, b) 702 _SET(byte_length, int); 703 #undef _SET 704 705 void encode(YAML::Node &) override; 706 707 std::string event()708 event() const override 709 { 710 return "datagrams_dropped"; 711 } 712 }; 713 714 class StreamStateUpdated : public TransportEvent 715 { 716 enum class StreamState { 717 // bidirectional stream states, draft-23 3.4. 718 idle, 719 open, 720 half_closed_local, 721 half_closed_remote, 722 closed, 723 724 // sending-side stream states, draft-23 3.1. 725 ready, 726 send, 727 data_sent, 728 reset_sent, 729 reset_received, 730 731 // receive-side stream states, draft-23 3.2. 732 receive, 733 size_known, 734 data_read, 735 reset_read, 736 737 // both-side states 738 data_received, 739 740 // qlog-defined 741 destroyed // memory actually freed 742 }; 743 StreamStateUpdated(std::string stream_id,StreamState n)744 StreamStateUpdated(std::string stream_id, StreamState n) { set_new(n).set_stream_id(stream_id); } 745 746 void encode(YAML::Node &) override; 747 748 #define _SET(a, b) SET_FUNC(StreamStateUpdated, a, b) 749 _SET(new, StreamState); 750 _SET(old, StreamState); 751 _SET(stream_id, std::string); 752 _SET(bidi, bool); 753 #undef _SET 754 755 std::string event()756 event() const override 757 { 758 return "stream_state_updated"; 759 } 760 }; 761 762 class FrameProcessed : public TransportEvent 763 { 764 public: 765 APPEND_FRAME_FUNC(FrameProcessed) 766 767 void encode(YAML::Node &) override; 768 769 std::string event()770 event() const override 771 { 772 return "frame_processed"; 773 } 774 }; 775 776 } // namespace Transport 777 778 namespace Recovery 779 { 780 class RecoveryEvent : public QLogEvent 781 { 782 public: 783 std::string category()784 category() const override 785 { 786 return "recovery"; 787 } 788 }; 789 790 class ParametersSet : public RecoveryEvent 791 { 792 public: 793 #define _SET(a, b) SET_FUNC(ParametersSet, a, b) 794 _SET(reordering_threshold, int); 795 _SET(time_threshold, int); 796 _SET(timer_granularity, int); 797 _SET(initial_rtt, int); 798 _SET(max_datagram_size, int); 799 _SET(initial_congestion_window, int); 800 _SET(minimum_congestion_window, int); 801 _SET(loss_reduction_factor, int); 802 _SET(persistent_congestion_threshold, int); 803 #undef _SET 804 void encode(YAML::Node &) override; 805 806 std::string event()807 event() const override 808 { 809 return "parameters_set"; 810 } 811 }; 812 813 class MetricsUpdated : public RecoveryEvent 814 { 815 public: 816 #define _SET(a, b) SET_FUNC(MetricsUpdated, a, b) 817 _SET(min_rtt, int); 818 _SET(smoothed_rtt, int); 819 _SET(latest_rtt, int); 820 _SET(rtt_variance, int); 821 _SET(max_ack_delay, int); 822 _SET(pto_count, int); 823 _SET(congestion_window, int); 824 _SET(bytes_in_flight, int); 825 _SET(ssthresh, int); 826 _SET(packets_in_flight, int); 827 _SET(in_recovery, int); 828 _SET(pacing_rate, int); 829 #undef _SET 830 void encode(YAML::Node &) override; 831 832 std::string event()833 event() const override 834 { 835 return "metrics_updated"; 836 } 837 }; 838 839 class CongestionStateUpdated : public RecoveryEvent 840 { 841 public: 842 enum class State : uint8_t { 843 slow_start, 844 congestion_avoidance, 845 application_limited, 846 recovery, 847 }; 848 849 enum class Triggered : uint8_t { 850 unknown, 851 persistent_congestion, 852 ECN, 853 }; 854 855 CongestionStateUpdated(State n, Triggered tr = Triggered::unknown) { set_trigger(tr).set_new(n); } 856 857 #define _SET(a, b) SET_FUNC(CongestionStateUpdated, a, b) 858 _SET(trigger, Triggered) 859 _SET(new, State) 860 _SET(old, State) 861 #undef _SET 862 863 void encode(YAML::Node &) override; 864 865 std::string event()866 event() const override 867 { 868 return "congestion_state_updated"; 869 } 870 871 static const char * trigger_name(Triggered tr)872 trigger_name(Triggered tr) 873 { 874 switch (tr) { 875 case Triggered::persistent_congestion: 876 return "persistent_congestion"; 877 case Triggered::ECN: 878 return "ECN"; 879 default: 880 return nullptr; 881 } 882 } 883 884 static const char * state_to_string(State s)885 state_to_string(State s) 886 { 887 switch (s) { 888 case State::slow_start: 889 return "slow_start"; 890 case State::congestion_avoidance: 891 return "congestion_avoidance"; 892 case State::application_limited: 893 return "application_limited"; 894 case State::recovery: 895 return "recovery"; 896 default: 897 break; 898 } 899 900 return nullptr; 901 } 902 }; 903 904 class LossTimerUpdated : public RecoveryEvent 905 { 906 public: 907 enum class EventType : uint8_t { 908 set, 909 expired, 910 cancelled, 911 }; 912 913 void set_timer_type(bool ack)914 set_timer_type(bool ack) 915 { 916 this->_timer_type_ack = ack; 917 } 918 919 void encode(YAML::Node &) override; 920 921 #define _SET(a, b) SET_FUNC(LossTimerUpdated, a, b) 922 _SET(event_type, EventType) 923 _SET(packet_number_space, int); 924 _SET(delta, int); 925 #undef _SET 926 927 std::string event()928 event() const override 929 { 930 return "loss_timer_updated"; 931 } 932 933 static const char * event_type_name(EventType et)934 event_type_name(EventType et) 935 { 936 switch (et) { 937 case EventType::set: 938 return "set"; 939 case EventType::expired: 940 return "expired"; 941 case EventType::cancelled: 942 return "cancelled"; 943 default: 944 break; 945 } 946 return nullptr; 947 } 948 949 private: 950 bool _timer_type_ack = false; 951 }; 952 953 class PacketLost : public RecoveryEvent 954 { 955 public: 956 enum class Triggered : uint8_t { 957 unknown, 958 reordering_threshold, 959 time_threshold, 960 pto_expired, 961 }; 962 963 PacketLost(PacketType pt, uint64_t pn, Triggered tr = Triggered::unknown) 964 { 965 set_trigger(tr).set_packet_type(pt).set_packet_number(pn); 966 } 967 968 #define _SET(a, b) SET_FUNC(PacketLost, a, b) 969 _SET(header, PacketHeader) 970 _SET(packet_number, uint64_t); 971 _SET(packet_type, PacketType); 972 _SET(trigger, Triggered) 973 APPEND_FRAME_FUNC(PacketLost) 974 #undef _SET 975 976 void encode(YAML::Node &) override; 977 978 std::string event()979 event() const override 980 { 981 return "packet_lost"; 982 } 983 984 static const char * trigger_name(Triggered tr)985 trigger_name(Triggered tr) 986 { 987 switch (tr) { 988 case Triggered::pto_expired: 989 return "pto_expired"; 990 case Triggered::reordering_threshold: 991 return "reordering_threshold"; 992 case Triggered::time_threshold: 993 return "time_threshold"; 994 default: 995 return nullptr; 996 } 997 } 998 }; 999 1000 class MarkedForRetransmit : public RecoveryEvent 1001 { 1002 public: 1003 APPEND_FRAME_FUNC(MarkedForRetransmit) 1004 void encode(YAML::Node &) override; 1005 std::string event()1006 event() const override 1007 { 1008 return "marked_for_retransmit"; 1009 } 1010 }; 1011 1012 } // namespace Recovery 1013 1014 } // namespace QLog 1015