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 <inttypes.h> 27 #include <queue> 28 29 #include "QUICFrameGenerator.h" 30 #include "QUICTypes.h" 31 #include "QUICConnection.h" 32 33 class QUICConnectionTable; 34 class QUICResetTokenTable; 35 36 class QUICAltConnectionManager : public QUICFrameHandler, public QUICFrameGenerator 37 { 38 public: 39 QUICAltConnectionManager(QUICConnection *qc, QUICConnectionTable &ctable, QUICResetTokenTable &rtable, 40 const QUICConnectionId &peer_initial_cid, uint32_t instance_id, uint8_t active_cid_limit, 41 const IpEndpoint *preferred_endpoint_ipv4 = nullptr, 42 const IpEndpoint *preferred_endpoint_ipv6 = nullptr); 43 ~QUICAltConnectionManager(); 44 45 /** 46 * Check if AltConnectionManager has at least one CID advertised by the peer. 47 */ 48 bool is_ready_to_migrate() const; 49 50 /** 51 * Prepare for new CID for the peer, and return one of CIDs advertised by the peer. 52 * New CID for the peer will be sent on next call for generate_frame() 53 */ 54 QUICConnectionId migrate_to_alt_cid(); 55 56 /** 57 * Migrate to new CID 58 * 59 * cid need to match with one of alt CID that AltConnectionManager prepared. 60 */ 61 bool migrate_to(const QUICConnectionId &cid, QUICStatelessResetToken &new_reset_token); 62 63 void drop_cid(const QUICConnectionId &cid); 64 65 void set_remote_preferred_address(const QUICPreferredAddress &preferred_address); 66 void set_remote_active_cid_limit(uint8_t active_cid_limit); 67 68 /** 69 * Invalidate all CIDs prepared 70 */ 71 void invalidate_alt_connections(); 72 73 /** 74 * Returns server preferred address if available 75 */ 76 const QUICPreferredAddress *preferred_address() const; 77 78 // QUICFrameHandler 79 virtual std::vector<QUICFrameType> interests() override; 80 virtual QUICConnectionErrorUPtr handle_frame(QUICEncryptionLevel level, const QUICFrame &frame) override; 81 82 // QUICFrameGenerator 83 bool will_generate_frame(QUICEncryptionLevel level, size_t current_packet_size, bool ack_eliciting, uint32_t seq_num) override; 84 QUICFrame *generate_frame(uint8_t *buf, QUICEncryptionLevel level, uint64_t connection_credit, uint16_t maximum_frame_size, 85 size_t current_packet_size, uint32_t seq_num) override; 86 87 private: 88 struct AltConnectionInfo { 89 uint64_t seq_num; 90 QUICConnectionId id; 91 QUICStatelessResetToken token; 92 union { 93 bool advertised; // For local info 94 bool used; // For remote info 95 }; 96 }; 97 98 QUICConnection *_qc = nullptr; 99 QUICConnectionTable &_ctable; 100 QUICResetTokenTable &_rtable; 101 AltConnectionInfo _alt_quic_connection_ids_local[8]; // 8 is perhaps enough 102 std::vector<AltConnectionInfo> _alt_quic_connection_ids_remote; 103 std::queue<uint64_t> _retired_seq_nums; 104 uint32_t _instance_id = 0; 105 uint8_t _local_active_cid_limit = 0; 106 uint8_t _remote_active_cid_limit = 0; 107 uint64_t _alt_quic_connection_id_seq_num = 0; 108 bool _need_advertise = false; 109 QUICPreferredAddress *_local_preferred_address = nullptr; 110 111 AltConnectionInfo _generate_next_alt_con_info(); 112 void _init_alt_connection_ids(); 113 void _update_alt_connection_id(uint64_t chosen_seq_num); 114 115 void _records_new_connection_id_frame(QUICEncryptionLevel level, const QUICNewConnectionIdFrame &frame); 116 void _records_retire_connection_id_frame(QUICEncryptionLevel, const QUICRetireConnectionIdFrame &frame); 117 118 void _on_frame_lost(QUICFrameInformationUPtr &info) override; 119 120 QUICConnectionErrorUPtr _register_remote_connection_id(const QUICNewConnectionIdFrame &frame); 121 QUICConnectionErrorUPtr _retire_remote_connection_id(const QUICRetireConnectionIdFrame &frame); 122 }; 123