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 #include <climits>
24 #include <string>
25 
26 #include "tscore/ink_config.h"
27 #include "records/I_RecHttp.h"
28 #include "tscore/Diags.h"
29 
30 #include "P_QUICNetVConnection.h"
31 #include "P_QUICPacketHandler.h"
32 #include "P_Net.h"
33 #include "InkAPIInternal.h" // Added to include the quic_hook definitions
34 #include "Log.h"
35 
36 #include "P_SSLNextProtocolSet.h"
37 #include "QUICMultiCertConfigLoader.h"
38 #include "QUICTLS.h"
39 
40 #include "QUICNewRenoCongestionController.h"
41 
42 #include "QUICStats.h"
43 #include "QUICGlobals.h"
44 #include "QUICDebugNames.h"
45 #include "QUICEvents.h"
46 #include "QUICHandshake.h"
47 #include "QUICConfig.h"
48 #include "QUICIntUtil.h"
49 
50 using namespace std::literals;
51 static constexpr std::string_view QUIC_DEBUG_TAG = "quic_net"sv;
52 
53 static constexpr uint16_t QUANTUM_TEST_ID         = 3127;
54 static constexpr uint8_t QUANTUM_TEST_VALUE[1200] = {'Q'};
55 
56 #define QUICConDebug(fmt, ...) Debug(QUIC_DEBUG_TAG.data(), "[%s] " fmt, this->cids().data(), ##__VA_ARGS__)
57 
58 #define QUICConVDebug(fmt, ...) Debug("v_quic_net", "[%s] " fmt, this->cids().data(), ##__VA_ARGS__)
59 #define QUICConVVVDebug(fmt, ...) Debug("vvv_quic_net", "[%s] " fmt, this->cids().data(), ##__VA_ARGS__)
60 
61 #define QUICFCDebug(fmt, ...) Debug("quic_flow_ctrl", "[%s] " fmt, this->cids().data(), ##__VA_ARGS__)
62 #define QUICFCVDebug(fmt, ...) Debug("v_quic_flow_ctrl", "[%s] " fmt, this->cids().data(), ##__VA_ARGS__)
63 
64 #define QUICError(fmt, ...)                                           \
65   Debug("quic_net", "[%s] " fmt, this->cids().data(), ##__VA_ARGS__); \
66   Error("quic_net [%s] " fmt, this->cids().data(), ##__VA_ARGS__)
67 
68 static constexpr uint32_t IPV4_HEADER_SIZE            = 20;
69 static constexpr uint32_t IPV6_HEADER_SIZE            = 40;
70 static constexpr uint32_t UDP_HEADER_SIZE             = 8;
71 static constexpr uint32_t MAX_PACKET_OVERHEAD         = 62; ///< Max long header len without length of token field of Initial packet
72 static constexpr uint32_t MINIMUM_INITIAL_PACKET_SIZE = 1200;
73 static constexpr ink_hrtime WRITE_READY_INTERVAL      = HRTIME_MSECONDS(2);
74 static constexpr uint32_t PACKET_PER_EVENT            = 256;
75 static constexpr uint32_t MAX_CONSECUTIVE_STREAMS     = 8; ///< Interrupt sending STREAM frames to send ACK frame
76 // static constexpr uint32_t MIN_PKT_PAYLOAD_LEN         = 3; ///< Minimum payload length for sampling for header protection
77 
78 static constexpr uint32_t STATE_CLOSING_MAX_SEND_PKT_NUM  = 8; ///< Max number of sending packets which contain a closing frame.
79 static constexpr uint32_t STATE_CLOSING_MAX_RECV_PKT_WIND = 1 << STATE_CLOSING_MAX_SEND_PKT_NUM;
80 
81 ClassAllocator<QUICNetVConnection> quicNetVCAllocator("quicNetVCAllocator");
82 
83 class QUICTPConfigQCP : public QUICTPConfig
84 {
85 public:
QUICTPConfigQCP(const QUICConfigParams * params,NetVConnectionContext_t ctx)86   QUICTPConfigQCP(const QUICConfigParams *params, NetVConnectionContext_t ctx) : _params(params), _ctx(ctx) {}
87 
88   uint32_t
no_activity_timeout() const89   no_activity_timeout() const override
90   {
91     if (this->_ctx == NET_VCONNECTION_IN) {
92       return this->_params->no_activity_timeout_in();
93     } else {
94       return this->_params->no_activity_timeout_out();
95     }
96   }
97 
98   const IpEndpoint *
preferred_address_ipv4() const99   preferred_address_ipv4() const override
100   {
101     return this->_params->preferred_address_ipv4();
102   }
103 
104   const IpEndpoint *
preferred_address_ipv6() const105   preferred_address_ipv6() const override
106   {
107     return this->_params->preferred_address_ipv6();
108   }
109 
110   uint32_t
initial_max_data() const111   initial_max_data() const override
112   {
113     if (this->_ctx == NET_VCONNECTION_IN) {
114       return this->_params->initial_max_data_in();
115     } else {
116       return this->_params->initial_max_data_out();
117     }
118   }
119 
120   uint32_t
initial_max_stream_data_bidi_local() const121   initial_max_stream_data_bidi_local() const override
122   {
123     if (this->_ctx == NET_VCONNECTION_IN) {
124       return this->_params->initial_max_stream_data_bidi_local_in();
125     } else {
126       return this->_params->initial_max_stream_data_bidi_local_out();
127     }
128   }
129 
130   uint32_t
initial_max_stream_data_bidi_remote() const131   initial_max_stream_data_bidi_remote() const override
132   {
133     if (this->_ctx == NET_VCONNECTION_IN) {
134       return this->_params->initial_max_stream_data_bidi_remote_in();
135     } else {
136       return this->_params->initial_max_stream_data_bidi_remote_out();
137     }
138   }
139 
140   uint32_t
initial_max_stream_data_uni() const141   initial_max_stream_data_uni() const override
142   {
143     if (this->_ctx == NET_VCONNECTION_IN) {
144       return this->_params->initial_max_stream_data_uni_in();
145     } else {
146       return this->_params->initial_max_stream_data_uni_out();
147     }
148   }
149 
150   uint64_t
initial_max_streams_bidi() const151   initial_max_streams_bidi() const override
152   {
153     if (this->_ctx == NET_VCONNECTION_IN) {
154       return this->_params->initial_max_streams_bidi_in();
155     } else {
156       return this->_params->initial_max_streams_bidi_out();
157     }
158   }
159 
160   uint64_t
initial_max_streams_uni() const161   initial_max_streams_uni() const override
162   {
163     if (this->_ctx == NET_VCONNECTION_IN) {
164       return this->_params->initial_max_streams_uni_in();
165     } else {
166       return this->_params->initial_max_streams_uni_out();
167     }
168   }
169 
170   uint8_t
ack_delay_exponent() const171   ack_delay_exponent() const override
172   {
173     if (this->_ctx == NET_VCONNECTION_IN) {
174       return this->_params->ack_delay_exponent_in();
175     } else {
176       return this->_params->ack_delay_exponent_out();
177     }
178   }
179 
180   uint8_t
max_ack_delay() const181   max_ack_delay() const override
182   {
183     if (this->_ctx == NET_VCONNECTION_IN) {
184       return this->_params->max_ack_delay_in();
185     } else {
186       return this->_params->max_ack_delay_out();
187     }
188   }
189 
190   uint8_t
active_cid_limit() const191   active_cid_limit() const override
192   {
193     if (this->_ctx == NET_VCONNECTION_IN) {
194       return this->_params->active_cid_limit_in();
195     } else {
196       return this->_params->active_cid_limit_out();
197     }
198   }
199 
200   bool
disable_active_migration() const201   disable_active_migration() const override
202   {
203     if (this->_ctx == NET_VCONNECTION_IN) {
204       return this->_params->disable_active_migration();
205     } else {
206       return false;
207     }
208   }
209 
210   const std::unordered_map<uint16_t, std::pair<const uint8_t *, uint16_t>> &
additional_tp() const211   additional_tp() const override
212   {
213     return this->_additional_tp;
214   }
215 
216   void
add_tp(uint16_t id,const uint8_t * value,uint16_t length)217   add_tp(uint16_t id, const uint8_t *value, uint16_t length)
218   {
219     this->_additional_tp.emplace(std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(value, length));
220   }
221 
222 private:
223   const QUICConfigParams *_params;
224   NetVConnectionContext_t _ctx;
225 
226   std::unordered_map<uint16_t, std::pair<const uint8_t *, uint16_t>> _additional_tp;
227 };
228 
QUICNetVConnection()229 QUICNetVConnection::QUICNetVConnection() : _packet_factory(this->_pp_key_info), _ph_protector(this->_pp_key_info) {}
230 
~QUICNetVConnection()231 QUICNetVConnection::~QUICNetVConnection()
232 {
233   this->_unschedule_ack_manager_periodic();
234   this->_unschedule_packet_write_ready();
235   this->_unschedule_closing_timeout();
236   this->_unschedule_closed_event();
237 }
238 
239 // XXX This might be called on ET_UDP thread
240 // Initialize QUICNetVC for out going connection (NET_VCONNECTION_OUT)
241 void
init(QUICVersion version,QUICConnectionId peer_cid,QUICConnectionId original_cid,UDPConnection * udp_con,QUICPacketHandler * packet_handler,QUICResetTokenTable * rtable)242 QUICNetVConnection::init(QUICVersion version, QUICConnectionId peer_cid, QUICConnectionId original_cid, UDPConnection *udp_con,
243                          QUICPacketHandler *packet_handler, QUICResetTokenTable *rtable)
244 {
245   SET_HANDLER((NetVConnHandler)&QUICNetVConnection::startEvent);
246   this->_initial_version             = version;
247   this->_udp_con                     = udp_con;
248   this->_packet_handler              = packet_handler;
249   this->_peer_quic_connection_id     = peer_cid;
250   this->_original_quic_connection_id = original_cid;
251   this->_rtable                      = rtable;
252   this->_quic_connection_id.randomize();
253   this->_initial_source_connection_id = this->_quic_connection_id;
254 
255   this->_update_cids();
256 
257   if (is_debug_tag_set(QUIC_DEBUG_TAG.data())) {
258     QUICConDebug("dcid=%s scid=%s", this->_peer_quic_connection_id.hex().c_str(), this->_quic_connection_id.hex().c_str());
259   }
260 
261   this->_init_submodules();
262 }
263 
264 // Initialize QUICNetVC for in coming connection (NET_VCONNECTION_IN)
265 void
init(QUICVersion version,QUICConnectionId peer_cid,QUICConnectionId original_cid,QUICConnectionId first_cid,QUICConnectionId retry_cid,UDPConnection * udp_con,QUICPacketHandler * packet_handler,QUICResetTokenTable * rtable,QUICConnectionTable * ctable)266 QUICNetVConnection::init(QUICVersion version, QUICConnectionId peer_cid, QUICConnectionId original_cid, QUICConnectionId first_cid,
267                          QUICConnectionId retry_cid, UDPConnection *udp_con, QUICPacketHandler *packet_handler,
268                          QUICResetTokenTable *rtable, QUICConnectionTable *ctable)
269 {
270   SET_HANDLER((NetVConnHandler)&QUICNetVConnection::acceptEvent);
271   this->_initial_version             = version;
272   this->_udp_con                     = udp_con;
273   this->_packet_handler              = packet_handler;
274   this->_peer_quic_connection_id     = peer_cid;
275   this->_original_quic_connection_id = original_cid;
276   this->_first_quic_connection_id    = first_cid;
277   this->_retry_source_connection_id  = retry_cid;
278   this->_quic_connection_id.randomize();
279   this->_initial_source_connection_id = this->_quic_connection_id;
280 
281   if (ctable) {
282     this->_ctable = ctable;
283     this->_ctable->insert(this->_quic_connection_id, this);
284     this->_ctable->insert(this->_original_quic_connection_id, this);
285   }
286   this->_rtable = rtable;
287 
288   this->_update_cids();
289 
290   if (is_debug_tag_set(QUIC_DEBUG_TAG.data())) {
291     QUICConDebug("dcid=%s scid=%s", this->_peer_quic_connection_id.hex().c_str(), this->_quic_connection_id.hex().c_str());
292   }
293 
294   this->_init_submodules();
295 }
296 
297 void
_init_submodules()298 QUICNetVConnection::_init_submodules()
299 {
300   this->_pinger                = new QUICPinger();
301   this->_padder                = new QUICPadder(this->netvc_context);
302   this->_path_validator        = new QUICPathValidator(*this, [this](bool succeeded) {
303     if (succeeded) {
304       this->_alt_con_manager->drop_cid(this->_peer_old_quic_connection_id);
305       // FIXME This is a kind of workaround for connection migration.
306       // This PING make peer to send an ACK frame so that ATS can detect packet loss.
307       // It would be better if QUICLossDetector could detect the loss in another way.
308       this->ping();
309     }
310   });
311   this->_path_manager          = new QUICPathManagerImpl(*this, *this->_path_validator);
312   this->_context               = std::make_unique<QUICContext>(&this->_rtt_measure, this, &this->_pp_key_info, this->_path_manager);
313   this->_congestion_controller = new QUICNewRenoCongestionController(*_context);
314   this->_rtt_measure.init(this->_context->ld_config());
315   this->_loss_detector =
316     new QUICLossDetector(*_context, this->_congestion_controller, &this->_rtt_measure, this->_pinger, this->_padder);
317 }
318 
319 bool
shouldDestroy()320 QUICNetVConnection::shouldDestroy()
321 {
322   return this->refcount() == 0;
323 }
324 
325 VIO *
do_io_read(Continuation * c,int64_t nbytes,MIOBuffer * buf)326 QUICNetVConnection::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf)
327 {
328   ink_assert(false);
329   return nullptr;
330 }
331 
332 VIO *
do_io_write(Continuation * c,int64_t nbytes,IOBufferReader * buf,bool owner)333 QUICNetVConnection::do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *buf, bool owner)
334 {
335   ink_assert(false);
336   return nullptr;
337 }
338 
339 int
acceptEvent(int event,Event * e)340 QUICNetVConnection::acceptEvent(int event, Event *e)
341 {
342   EThread *t    = (e == nullptr) ? this_ethread() : e->ethread;
343   NetHandler *h = get_NetHandler(t);
344 
345   MUTEX_TRY_LOCK(lock, h->mutex, t);
346   if (!lock.is_locked()) {
347     if (event == EVENT_NONE) {
348       t->schedule_in(this, HRTIME_MSECONDS(net_retry_delay));
349       return EVENT_DONE;
350     } else {
351       e->schedule_in(HRTIME_MSECONDS(net_retry_delay));
352       return EVENT_CONT;
353     }
354   }
355 
356   // this->thread is already assigned by QUICPacketHandlerIn::_recv_packet
357   ink_assert(this->thread == this_ethread());
358 
359   // Send this NetVC to NetHandler and start to polling read & write event.
360   if (h->startIO(this) < 0) {
361     free(t);
362     return EVENT_DONE;
363   }
364 
365   // FIXME: complete do_io_xxxx instead
366   this->read.enabled = 1;
367 
368   // Handshake callback handler.
369   SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_pre_handshake);
370 
371   // Send this netvc to InactivityCop.
372   nh->startCop(this);
373 
374   if (inactivity_timeout_in) {
375     set_inactivity_timeout(inactivity_timeout_in);
376   } else {
377     set_inactivity_timeout(0);
378   }
379 
380   if (active_timeout_in) {
381     set_active_timeout(active_timeout_in);
382   }
383 
384   this->start();
385 
386   action_.continuation->handleEvent(NET_EVENT_ACCEPT, this);
387   this->_schedule_packet_write_ready();
388 
389   return EVENT_DONE;
390 }
391 
392 int
startEvent(int event,Event * e)393 QUICNetVConnection::startEvent(int event, Event *e)
394 {
395   ink_assert(event == EVENT_IMMEDIATE);
396   MUTEX_TRY_LOCK(lock, get_NetHandler(e->ethread)->mutex, e->ethread);
397   if (!lock.is_locked()) {
398     e->schedule_in(HRTIME_MSECONDS(net_retry_delay));
399     return EVENT_CONT;
400   }
401 
402   if (!action_.cancelled) {
403     this->connectUp(e->ethread, NO_FD);
404   } else {
405     this->free(e->ethread);
406   }
407 
408   return EVENT_DONE;
409 }
410 
411 // XXX This might be called on ET_UDP thread
412 void
start()413 QUICNetVConnection::start()
414 {
415   ink_release_assert(this->thread != nullptr);
416   this->_five_tuple.update(this->local_addr, this->remote_addr, SOCK_DGRAM);
417   QUICPath trusted_path = {{}, {}};
418   // Version 0x00000001 uses stream 0 for cryptographic handshake with TLS 1.3, but newer version may not
419   if (this->direction() == NET_VCONNECTION_IN) {
420     QUICCertConfig::scoped_config server_cert;
421 
422     this->_pp_key_info.set_context(QUICPacketProtectionKeyInfo::Context::SERVER);
423     this->_ack_frame_manager.set_ack_delay_exponent(this->_quic_config->ack_delay_exponent_in());
424     this->_reset_token       = QUICStatelessResetToken(this->_quic_connection_id, this->_quic_config->instance_id());
425     this->_hs_protocol       = this->_setup_handshake_protocol(server_cert->ssl_default);
426     this->_handshake_handler = new QUICHandshake(this->_initial_version, this, this->_hs_protocol, this->_reset_token,
427                                                  this->_quic_config->stateless_retry());
428     this->_ack_frame_manager.set_max_ack_delay(this->_quic_config->max_ack_delay_in());
429     this->_schedule_ack_manager_periodic(this->_quic_config->max_ack_delay_in());
430   } else {
431     trusted_path = {this->local_addr, this->remote_addr};
432     QUICTPConfigQCP tp_config(this->_quic_config, NET_VCONNECTION_OUT);
433     if (this->_quic_config->quantum_readiness_test_enabled_out()) {
434       tp_config.add_tp(QUANTUM_TEST_ID, QUANTUM_TEST_VALUE, sizeof(QUANTUM_TEST_VALUE));
435     }
436     this->_pp_key_info.set_context(QUICPacketProtectionKeyInfo::Context::CLIENT);
437     this->_ack_frame_manager.set_ack_delay_exponent(this->_quic_config->ack_delay_exponent_out());
438     this->_hs_protocol       = this->_setup_handshake_protocol(this->_quic_config->client_ssl_ctx());
439     this->_handshake_handler = new QUICHandshake(this->_initial_version, this, this->_hs_protocol);
440     this->_handshake_handler->start(tp_config, &this->_packet_factory, this->_quic_config->vn_exercise_enabled());
441     this->_handshake_handler->do_handshake();
442     this->_ack_frame_manager.set_max_ack_delay(this->_quic_config->max_ack_delay_out());
443     this->_schedule_ack_manager_periodic(this->_quic_config->max_ack_delay_out());
444   }
445   this->_path_manager->set_trusted_path(trusted_path);
446 
447   this->_application_map = new QUICApplicationMap();
448 
449   this->_frame_dispatcher = new QUICFrameDispatcher(this);
450 
451   // Create frame handlers
452   this->_frame_dispatcher->add_handler(this->_loss_detector);
453 
454   this->_remote_flow_controller = new QUICRemoteConnectionFlowController(UINT64_MAX);
455   this->_local_flow_controller  = new QUICLocalConnectionFlowController(&this->_rtt_measure, UINT64_MAX);
456   this->_stream_manager         = new QUICStreamManager(this->_context.get(), this->_application_map);
457   this->_token_creator          = new QUICTokenCreator(this->_context.get());
458 
459   static constexpr int QUIC_STREAM_MANAGER_WEIGHT = QUICFrameGeneratorWeight::AFTER_DATA - 1;
460   static constexpr int QUIC_PINGER_WEIGHT         = QUICFrameGeneratorWeight::LATE + 1;
461   static constexpr int QUIC_PADDER_WEIGHT         = QUICFrameGeneratorWeight::LATE + 2;
462 
463   // Register frame generators
464   this->_frame_generators.add_generator(*this->_handshake_handler, QUICFrameGeneratorWeight::EARLY); // CRYPTO
465   this->_frame_generators.add_generator(*this->_path_validator, QUICFrameGeneratorWeight::EARLY); // PATH_CHALLENGE, PATH_RESPOSNE
466   this->_frame_generators.add_generator(*this->_local_flow_controller, QUICFrameGeneratorWeight::BEFORE_DATA);  // MAX_DATA
467   this->_frame_generators.add_generator(*this->_remote_flow_controller, QUICFrameGeneratorWeight::BEFORE_DATA); // DATA_BLOCKED
468   this->_frame_generators.add_generator(*this->_token_creator, QUICFrameGeneratorWeight::BEFORE_DATA);          // NEW_TOKEN
469   this->_frame_generators.add_generator(*this->_stream_manager,
470                                         QUIC_STREAM_MANAGER_WEIGHT); // STREAM, MAX_STREAM_DATA, STREAM_DATA_BLOCKED
471   this->_frame_generators.add_generator(this->_ack_frame_manager, QUICFrameGeneratorWeight::BEFORE_DATA); // ACK
472 
473   this->_frame_generators.add_generator(*this->_pinger, QUIC_PINGER_WEIGHT); // PING
474   // Warning: padder should be tail of the frame generators
475   this->_frame_generators.add_generator(*this->_padder, QUIC_PADDER_WEIGHT); // PADDING
476 
477   // Register frame handlers
478   this->_frame_dispatcher->add_handler(this);
479   this->_frame_dispatcher->add_handler(this->_stream_manager);
480   this->_frame_dispatcher->add_handler(this->_path_validator);
481   this->_frame_dispatcher->add_handler(this->_handshake_handler);
482 
483   // register qlog
484   if (this->_context->config()->qlog_dir() != nullptr) {
485     this->_qlog = std::make_unique<QLog::QLogListener>(*this->_context, this->_original_quic_connection_id.hex());
486     this->_qlog->last_trace().set_vantage_point(
487       {"ats", QLog::Trace::VantagePointType::server, QLog::Trace::VantagePointType::server});
488     this->_context->regist_callback(this->_qlog);
489   }
490 }
491 
492 void
free(EThread * t)493 QUICNetVConnection::free(EThread *t)
494 {
495   QUICConDebug("Free connection");
496 
497   /* TODO: Uncmment these blocks after refactoring read / write process
498     this->_udp_con        = nullptr;
499     this->_packet_handler = nullptr;
500 
501     _unschedule_packet_write_ready();
502 
503     delete this->_handshake_handler;
504     delete this->_application_map;
505     delete this->_hs_protocol;
506     delete this->_loss_detector;
507     delete this->_frame_dispatcher;
508     delete this->_stream_manager;
509     delete this->_congestion_controller;
510     if (this->_alt_con_manager) {
511       delete this->_alt_con_manager;
512     }
513 
514     super::clear();
515   */
516   this->_context->trigger(QUICContext::CallbackEvent::CONNECTION_CLOSE);
517   ALPNSupport::clear();
518   this->_packet_handler->close_connection(this);
519 }
520 
521 void
free()522 QUICNetVConnection::free()
523 {
524   this->free(this_ethread());
525 }
526 
527 // called by ET_UDP
528 void
remove_connection_ids()529 QUICNetVConnection::remove_connection_ids()
530 {
531   if (this->_ctable) {
532     this->_ctable->erase(this->_original_quic_connection_id, this);
533     this->_ctable->erase(this->_quic_connection_id, this);
534   }
535 
536   if (this->_alt_con_manager) {
537     this->_alt_con_manager->invalidate_alt_connections();
538   }
539 }
540 
541 // called by ET_UDP
542 void
destroy(EThread * t)543 QUICNetVConnection::destroy(EThread *t)
544 {
545   QUICConDebug("Destroy connection");
546   /*  TODO: Uncomment these blocks after refactoring read / write process
547     if (from_accept_thread) {
548       quicNetVCAllocator.free(this);
549     } else {
550       THREAD_FREE(this, quicNetVCAllocator, t);
551     }
552   */
553 }
554 
555 void
set_local_addr()556 QUICNetVConnection::set_local_addr()
557 {
558   int local_sa_size = sizeof(local_addr);
559   ATS_UNUSED_RETURN(safe_getsockname(this->_udp_con->getFd(), &local_addr.sa, &local_sa_size));
560 }
561 
562 void
reenable(VIO * vio)563 QUICNetVConnection::reenable(VIO *vio)
564 {
565   return;
566 }
567 
568 int
connectUp(EThread * t,int fd)569 QUICNetVConnection::connectUp(EThread *t, int fd)
570 {
571   int res        = 0;
572   NetHandler *nh = get_NetHandler(t);
573   this->thread   = this_ethread();
574   ink_assert(nh->mutex->thread_holding == this->thread);
575 
576   SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_pre_handshake);
577 
578   if ((res = nh->startIO(this)) < 0) {
579     // FIXME: startIO only return 0 now! what should we do if it failed ?
580   }
581 
582   nh->startCop(this);
583 
584   // FIXME: complete do_io_xxxx instead
585   this->read.enabled = 1;
586 
587   this->set_local_addr();
588   this->remote_addr = con.addr;
589 
590   this->start();
591 
592   // start QUIC handshake
593   this->_schedule_packet_write_ready();
594 
595   return CONNECT_SUCCESS;
596 }
597 
598 QUICConnectionId
peer_connection_id() const599 QUICNetVConnection::peer_connection_id() const
600 {
601   return this->_peer_quic_connection_id;
602 }
603 
604 QUICConnectionId
original_connection_id() const605 QUICNetVConnection::original_connection_id() const
606 {
607   return this->_original_quic_connection_id;
608 }
609 
610 QUICConnectionId
first_connection_id() const611 QUICNetVConnection::first_connection_id() const
612 {
613   return this->_first_quic_connection_id;
614 }
615 
616 QUICConnectionId
retry_source_connection_id() const617 QUICNetVConnection::retry_source_connection_id() const
618 {
619   return this->_retry_source_connection_id;
620 }
621 
622 QUICConnectionId
initial_source_connection_id() const623 QUICNetVConnection::initial_source_connection_id() const
624 {
625   return this->_initial_source_connection_id;
626 }
627 
628 QUICConnectionId
connection_id() const629 QUICNetVConnection::connection_id() const
630 {
631   return this->_quic_connection_id;
632 }
633 
634 /*
635  Return combination of dst connection id and src connection id for debug log
636  e.g. "aaaaaaaa-bbbbbbbb"
637    - "aaaaaaaa" : high 32 bit of dst connection id
638    - "bbbbbbbb" : high 32 bit of src connection id
639  */
640 std::string_view
cids() const641 QUICNetVConnection::cids() const
642 {
643   return this->_cids;
644 }
645 
646 const QUICFiveTuple
five_tuple() const647 QUICNetVConnection::five_tuple() const
648 {
649   return this->_five_tuple;
650 }
651 
652 uint32_t
pmtu() const653 QUICNetVConnection::pmtu() const
654 {
655   return this->_pmtu;
656 }
657 
658 NetVConnectionContext_t
direction() const659 QUICNetVConnection::direction() const
660 {
661   return this->netvc_context;
662 }
663 
664 uint32_t
_minimum_quic_packet_size()665 QUICNetVConnection::_minimum_quic_packet_size()
666 {
667   if (netvc_context == NET_VCONNECTION_OUT) {
668     // FIXME Only the first packet need to be 1200 bytes at least
669     return MINIMUM_INITIAL_PACKET_SIZE;
670   } else {
671     // FIXME This size should be configurable and should have some randomness
672     // This is just for providing protection against packet analysis for protected packets
673     return 32 + (this->_rnd() & 0x3f); // 32 to 96
674   }
675 }
676 
677 uint32_t
_maximum_quic_packet_size() const678 QUICNetVConnection::_maximum_quic_packet_size() const
679 {
680   if (this->options.ip_family == PF_INET6) {
681     return this->_pmtu - UDP_HEADER_SIZE - IPV6_HEADER_SIZE;
682   } else {
683     return this->_pmtu - UDP_HEADER_SIZE - IPV4_HEADER_SIZE;
684   }
685 }
686 
687 uint64_t
_maximum_stream_frame_data_size()688 QUICNetVConnection::_maximum_stream_frame_data_size()
689 {
690   return this->_maximum_quic_packet_size() - MAX_STREAM_FRAME_OVERHEAD - MAX_PACKET_OVERHEAD;
691 }
692 
693 QUICStreamManager *
stream_manager()694 QUICNetVConnection::stream_manager()
695 {
696   return this->_stream_manager;
697 }
698 
699 void
handle_received_packet(UDPPacket * packet)700 QUICNetVConnection::handle_received_packet(UDPPacket *packet)
701 {
702   this->_packet_recv_queue.enqueue(packet);
703   this->_loss_detector->on_datagram_received();
704 }
705 
706 void
ping()707 QUICNetVConnection::ping()
708 {
709   this->_pinger->request(QUICEncryptionLevel::ONE_RTT);
710 }
711 
712 void
close_quic_connection(QUICConnectionErrorUPtr error)713 QUICNetVConnection::close_quic_connection(QUICConnectionErrorUPtr error)
714 {
715   if (this->handler == reinterpret_cast<ContinuationHandler>(&QUICNetVConnection::state_connection_closed) ||
716       this->handler == reinterpret_cast<ContinuationHandler>(&QUICNetVConnection::state_connection_closing)) {
717     // do nothing
718   } else {
719     this->_switch_to_closing_state(std::move(error));
720   }
721 }
722 
723 void
reset_quic_connection()724 QUICNetVConnection::reset_quic_connection()
725 {
726   this->_switch_to_close_state();
727 
728   QUICStatelessResetToken token(this->connection_id(), this->_quic_config->instance_id());
729   auto packet = QUICPacketFactory::create_stateless_reset_packet(token, 128);
730   if (packet) {
731     Ptr<IOBufferBlock> udp_payload(new_IOBufferBlock());
732     udp_payload->alloc(iobuffer_size_to_index(128, BUFFER_SIZE_INDEX_32K));
733     uint8_t *buf = reinterpret_cast<uint8_t *>(udp_payload->end());
734     size_t len   = 0;
735     packet->store(buf, &len);
736     udp_payload->fill(len);
737     this->_packet_handler->send_packet(this, udp_payload);
738   }
739 }
740 
741 std::vector<QUICFrameType>
interests()742 QUICNetVConnection::interests()
743 {
744   return {QUICFrameType::CONNECTION_CLOSE, QUICFrameType::DATA_BLOCKED, QUICFrameType::MAX_DATA};
745 }
746 
747 QUICConnectionErrorUPtr
handle_frame(QUICEncryptionLevel level,const QUICFrame & frame)748 QUICNetVConnection::handle_frame(QUICEncryptionLevel level, const QUICFrame &frame)
749 {
750   QUICConnectionErrorUPtr error = nullptr;
751 
752   switch (frame.type()) {
753   case QUICFrameType::MAX_DATA:
754     this->_remote_flow_controller->forward_limit(static_cast<const QUICMaxDataFrame &>(frame).maximum_data());
755     QUICFCDebug("[REMOTE] %" PRIu64 "/%" PRIu64, this->_remote_flow_controller->current_offset(),
756                 this->_remote_flow_controller->current_limit());
757     this->_schedule_packet_write_ready();
758     break;
759   case QUICFrameType::DATA_BLOCKED:
760     // DATA_BLOCKED frame is for debugging. Nothing to do here.
761     break;
762   case QUICFrameType::CONNECTION_CLOSE:
763     if (this->handler == reinterpret_cast<NetVConnHandler>(&QUICNetVConnection::state_connection_closed) ||
764         this->handler == reinterpret_cast<NetVConnHandler>(&QUICNetVConnection::state_connection_draining)) {
765       return error;
766     }
767 
768     // 7.9.1. Closing and Draining Connection States
769     // An endpoint MAY transition from the closing period to the draining period if it can confirm that its peer is also closing or
770     // draining. Receiving a closing frame is sufficient confirmation, as is receiving a stateless reset.
771     {
772       uint16_t error_code = static_cast<const QUICConnectionCloseFrame &>(frame).error_code();
773       this->_switch_to_draining_state(
774         QUICConnectionErrorUPtr(std::make_unique<QUICConnectionError>(static_cast<QUICTransErrorCode>(error_code))));
775     }
776     break;
777   default:
778     QUICConDebug("Unexpected frame type: %02x", static_cast<unsigned int>(frame.type()));
779     ink_assert(false);
780     break;
781   }
782 
783   return error;
784 }
785 
786 // XXX Setup QUICNetVConnection on regular EThread.
787 // QUICNetVConnection::init() might be called on ET_UDP EThread.
788 int
state_pre_handshake(int event,Event * data)789 QUICNetVConnection::state_pre_handshake(int event, Event *data)
790 {
791   SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
792 
793   // this->thread should be assigned on any direction
794   ink_assert(this->thread == this_ethread());
795 
796   if (!this->nh) {
797     this->nh = get_NetHandler(this_ethread());
798   }
799 
800   // FIXME: Should be accept_no_activity_timeout?
801   if (this->get_context() == NET_VCONNECTION_IN) {
802     this->set_inactivity_timeout(HRTIME_MSECONDS(this->_quic_config->no_activity_timeout_in()));
803   } else {
804     this->set_inactivity_timeout(HRTIME_MSECONDS(this->_quic_config->no_activity_timeout_out()));
805   }
806 
807   this->add_to_active_queue();
808 
809   this->_switch_to_handshake_state();
810   return this->handleEvent(event, data);
811 }
812 
813 // TODO: Timeout by active_timeout
814 int
state_handshake(int event,Event * data)815 QUICNetVConnection::state_handshake(int event, Event *data)
816 {
817   SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
818 
819   if (this->_handshake_handler && this->_handshake_handler->is_completed()) {
820     this->_switch_to_established_state();
821     return this->handleEvent(event, data);
822   }
823 
824   QUICConnectionErrorUPtr error = nullptr;
825 
826   switch (event) {
827   case QUIC_EVENT_PACKET_READ_READY: {
828     QUICPacketCreationResult result;
829     net_activity(this, this_ethread());
830     do {
831       uint8_t packet_buf[QUICPacket::MAX_INSTANCE_SIZE];
832       QUICPacketUPtr packet = this->_dequeue_recv_packet(packet_buf, result);
833       if (result == QUICPacketCreationResult::NOT_READY) {
834         error = nullptr;
835       } else if (result == QUICPacketCreationResult::FAILED) {
836         // Don't make this error, and discard the packet.
837         // Because:
838         // - Attacker can terminate connections
839         // - It could be just an error on lower layer
840         error = nullptr;
841       } else if (result == QUICPacketCreationResult::SUCCESS || result == QUICPacketCreationResult::UNSUPPORTED) {
842         error = this->_state_handshake_process_packet(*packet);
843       }
844 
845       // if we complete handshake, switch to establish state
846       if (this->_handshake_handler && this->_handshake_handler->is_completed()) {
847         this->_switch_to_established_state();
848         return this->handleEvent(event, data);
849       }
850 
851     } while (error == nullptr && (result == QUICPacketCreationResult::SUCCESS || result == QUICPacketCreationResult::IGNORED));
852     break;
853   }
854   case QUIC_EVENT_STATELESS_RESET:
855     this->_switch_to_draining_state(std::make_unique<QUICConnectionError>(QUICTransErrorCode::NO_ERROR, "Stateless Reset"));
856     break;
857   case QUIC_EVENT_ACK_PERIODIC:
858     this->_handle_periodic_ack_event();
859     break;
860   case QUIC_EVENT_PACKET_WRITE_READY:
861     this->_close_packet_write_ready(data);
862     // TODO: support RETRY packet
863     error = this->_state_common_send_packet();
864     // Reschedule WRITE_READY
865     this->_schedule_packet_write_ready(true);
866     break;
867   case VC_EVENT_INACTIVITY_TIMEOUT:
868     // Start Immediate Close because of Idle Timeout
869     this->_handle_idle_timeout();
870     break;
871   case VC_EVENT_ACTIVE_TIMEOUT:
872     // Start Immediate Close
873     this->_handle_active_timeout();
874     break;
875   default:
876     QUICConDebug("Unexpected event: %s (%d)", QUICDebugNames::quic_event(event), event);
877   }
878 
879   if (error != nullptr) {
880     this->_handle_error(std::move(error));
881   }
882 
883   return EVENT_CONT;
884 }
885 
886 int
state_connection_established(int event,Event * data)887 QUICNetVConnection::state_connection_established(int event, Event *data)
888 {
889   SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
890   QUICConnectionErrorUPtr error = nullptr;
891   switch (event) {
892   case QUIC_EVENT_PACKET_READ_READY:
893     error = this->_state_connection_established_receive_packet();
894     break;
895   case QUIC_EVENT_ACK_PERIODIC:
896     this->_handle_periodic_ack_event();
897     break;
898   case QUIC_EVENT_PACKET_WRITE_READY:
899     this->_close_packet_write_ready(data);
900     error = this->_state_common_send_packet();
901     // Reschedule WRITE_READY
902     this->_schedule_packet_write_ready(true);
903     break;
904   case QUIC_EVENT_STATELESS_RESET:
905     this->_switch_to_draining_state(std::make_unique<QUICConnectionError>(QUICTransErrorCode::NO_ERROR, "Stateless Reset"));
906     break;
907   case VC_EVENT_INACTIVITY_TIMEOUT:
908     // Start Immediate Close because of Idle Timeout
909     this->_handle_idle_timeout();
910     break;
911   case VC_EVENT_ACTIVE_TIMEOUT:
912     // Start Immediate Close
913     this->_handle_active_timeout();
914     break;
915   default:
916     QUICConDebug("Unexpected event: %s (%d)", QUICDebugNames::quic_event(event), event);
917   }
918 
919   if (error != nullptr) {
920     QUICConDebug("QUICError: cls=%u, code=0x%" PRIx16, static_cast<unsigned int>(error->cls), error->code);
921     this->_handle_error(std::move(error));
922   }
923 
924   return EVENT_CONT;
925 }
926 
927 int
state_connection_closing(int event,Event * data)928 QUICNetVConnection::state_connection_closing(int event, Event *data)
929 {
930   SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
931 
932   QUICConnectionErrorUPtr error = nullptr;
933   switch (event) {
934   case QUIC_EVENT_PACKET_READ_READY:
935     error = this->_state_closing_receive_packet();
936     break;
937   case QUIC_EVENT_PACKET_WRITE_READY:
938     this->_close_packet_write_ready(data);
939     this->_state_closing_send_packet();
940     break;
941   case QUIC_EVENT_CLOSING_TIMEOUT:
942     this->_close_closing_timeout(data);
943     this->_switch_to_close_state();
944     break;
945   case QUIC_EVENT_STATELESS_RESET:
946     break;
947   case VC_EVENT_ACTIVE_TIMEOUT:
948     // Do nothing because closing is in progress
949     break;
950   case QUIC_EVENT_ACK_PERIODIC:
951   default:
952     QUICConDebug("Unexpected event: %s (%d)", QUICDebugNames::quic_event(event), event);
953     ink_assert(false);
954   }
955 
956   return EVENT_DONE;
957 }
958 
959 int
state_connection_draining(int event,Event * data)960 QUICNetVConnection::state_connection_draining(int event, Event *data)
961 {
962   SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
963 
964   QUICConnectionErrorUPtr error = nullptr;
965   switch (event) {
966   case QUIC_EVENT_PACKET_READ_READY:
967     error = this->_state_draining_receive_packet();
968     break;
969   case QUIC_EVENT_PACKET_WRITE_READY:
970     // Do not send any packets in this state.
971     // This should be the only difference between this and closing_state.
972     this->_close_packet_write_ready(data);
973     break;
974   case QUIC_EVENT_CLOSING_TIMEOUT:
975     this->_close_closing_timeout(data);
976     this->_switch_to_close_state();
977     break;
978   case QUIC_EVENT_STATELESS_RESET:
979     break;
980   case VC_EVENT_ACTIVE_TIMEOUT:
981     // Do nothing because closing is in progress
982     break;
983   case QUIC_EVENT_ACK_PERIODIC:
984   default:
985     QUICConDebug("Unexpected event: %s (%d)", QUICDebugNames::quic_event(event), event);
986     ink_assert(false);
987   }
988 
989   return EVENT_DONE;
990 }
991 
992 int
state_connection_closed(int event,Event * data)993 QUICNetVConnection::state_connection_closed(int event, Event *data)
994 {
995   SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
996   switch (event) {
997   case QUIC_EVENT_SHUTDOWN: {
998     this->_unschedule_ack_manager_periodic();
999     this->_unschedule_packet_write_ready();
1000     this->_unschedule_closing_timeout();
1001     this->_close_closed_event(data);
1002     this->next_inactivity_timeout_at = 0;
1003     this->next_activity_timeout_at   = 0;
1004 
1005     this->inactivity_timeout_in = 0;
1006     this->active_timeout_in     = 0;
1007 
1008     // TODO: Drop record from Connection-ID - QUICNetVConnection table in QUICPacketHandler
1009     // Shutdown loss detector
1010     SCOPED_MUTEX_LOCK(lock2, this->_loss_detector->mutex, this_ethread());
1011     this->_loss_detector->handleEvent(QUIC_EVENT_LD_SHUTDOWN, nullptr);
1012 
1013     // FIXME I'm not sure whether we can block here, but it's needed to not crash.
1014     SCOPED_MUTEX_LOCK(lock, this->nh->mutex, this_ethread());
1015     if (this->nh) {
1016       this->nh->free_netevent(this);
1017     } else {
1018       this->free(this->mutex->thread_holding);
1019     }
1020     break;
1021   }
1022   case QUIC_EVENT_PACKET_WRITE_READY: {
1023     this->_close_packet_write_ready(data);
1024     break;
1025   }
1026   default:
1027     QUICConDebug("Unexpected event: %s (%d)", QUICDebugNames::quic_event(event), event);
1028   }
1029 
1030   return EVENT_DONE;
1031 }
1032 
1033 UDPConnection *
get_udp_con()1034 QUICNetVConnection::get_udp_con()
1035 {
1036   return this->_udp_con;
1037 }
1038 
1039 void
net_read_io(NetHandler * nh,EThread * lthread)1040 QUICNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
1041 {
1042   SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
1043   this->handleEvent(QUIC_EVENT_PACKET_READ_READY, nullptr);
1044 
1045   return;
1046 }
1047 
1048 int64_t
load_buffer_and_write(int64_t towrite,MIOBufferAccessor & buf,int64_t & total_written,int & needs)1049 QUICNetVConnection::load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs)
1050 {
1051   ink_assert(false);
1052 
1053   return 0;
1054 }
1055 
1056 int
populate_protocol(std::string_view * results,int n) const1057 QUICNetVConnection::populate_protocol(std::string_view *results, int n) const
1058 {
1059   int retval = 0;
1060   if (n > retval) {
1061     results[retval++] = IP_PROTO_TAG_QUIC;
1062     if (n > retval) {
1063       retval += super::populate_protocol(results + retval, n - retval);
1064     }
1065   }
1066   return retval;
1067 }
1068 
1069 const char *
protocol_contains(std::string_view prefix) const1070 QUICNetVConnection::protocol_contains(std::string_view prefix) const
1071 {
1072   const char *retval   = nullptr;
1073   std::string_view tag = IP_PROTO_TAG_QUIC;
1074   if (prefix.size() <= tag.size() && strncmp(tag.data(), prefix.data(), prefix.size()) == 0) {
1075     retval = tag.data();
1076   } else {
1077     retval = super::protocol_contains(prefix);
1078   }
1079   return retval;
1080 }
1081 
1082 // ALPN TLS extension callback. Given the client's set of offered
1083 // protocols, we have to select a protocol to use for this session.
1084 int
select_next_protocol(SSL * ssl,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned inlen) const1085 QUICNetVConnection::select_next_protocol(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in,
1086                                          unsigned inlen) const
1087 {
1088   const unsigned char *npnptr = nullptr;
1089   unsigned int npnsize        = 0;
1090   if (this->getNPN(&npnptr, &npnsize)) {
1091     // SSL_select_next_proto chooses the first server-offered protocol that appears in the clients protocol set, ie. the
1092     // server selects the protocol. This is a n^2 search, so it's preferable to keep the protocol set short.
1093     if (SSL_select_next_proto(const_cast<unsigned char **>(out), outlen, npnptr, npnsize, in, inlen) == OPENSSL_NPN_NEGOTIATED) {
1094       Debug("ssl", "selected ALPN protocol %.*s", (int)(*outlen), *out);
1095       return SSL_TLSEXT_ERR_OK;
1096     }
1097   }
1098 
1099   *out    = nullptr;
1100   *outlen = 0;
1101   return SSL_TLSEXT_ERR_NOACK;
1102 }
1103 
1104 bool
is_closed() const1105 QUICNetVConnection::is_closed() const
1106 {
1107   return this->handler == reinterpret_cast<NetVConnHandler>(&QUICNetVConnection::state_connection_closed);
1108 }
1109 
1110 bool
is_at_anti_amplification_limit() const1111 QUICNetVConnection::is_at_anti_amplification_limit() const
1112 {
1113   return !this->_verified_state.is_verified() || this->_verified_state.windows() == 0;
1114 }
1115 
1116 bool
is_address_validation_completed() const1117 QUICNetVConnection::is_address_validation_completed() const
1118 {
1119   return this->_verified_state.is_verified();
1120 }
1121 
1122 bool
is_handshake_completed() const1123 QUICNetVConnection::is_handshake_completed() const
1124 {
1125   return this->_handshake_completed;
1126 }
1127 
1128 bool
has_keys_for(QUICPacketNumberSpace space) const1129 QUICNetVConnection::has_keys_for(QUICPacketNumberSpace space) const
1130 {
1131   switch (space) {
1132   case QUICPacketNumberSpace::INITIAL:
1133     return this->_pp_key_info.is_decryption_key_available(QUICKeyPhase::INITIAL) &&
1134            this->_pp_key_info.is_encryption_key_available(QUICKeyPhase::INITIAL);
1135   case QUICPacketNumberSpace::HANDSHAKE:
1136     return this->_pp_key_info.is_decryption_key_available(QUICKeyPhase::HANDSHAKE) &&
1137            this->_pp_key_info.is_encryption_key_available(QUICKeyPhase::HANDSHAKE);
1138   case QUICPacketNumberSpace::APPLICATION_DATA:
1139     return (this->_pp_key_info.is_decryption_key_available(QUICKeyPhase::PHASE_0) &&
1140             this->_pp_key_info.is_encryption_key_available(QUICKeyPhase::PHASE_0)) ||
1141            (this->_pp_key_info.is_decryption_key_available(QUICKeyPhase::PHASE_1) &&
1142             this->_pp_key_info.is_encryption_key_available(QUICKeyPhase::PHASE_1));
1143   default:
1144     return false;
1145   }
1146 }
1147 
1148 QUICPacketNumber
_largest_acked_packet_number(QUICEncryptionLevel level) const1149 QUICNetVConnection::_largest_acked_packet_number(QUICEncryptionLevel level) const
1150 {
1151   auto index = QUICTypeUtil::pn_space(level);
1152 
1153   return this->_loss_detector->largest_acked_packet_number(index);
1154 }
1155 
1156 QUICVersion
negotiated_version() const1157 QUICNetVConnection::negotiated_version() const
1158 {
1159   return this->_handshake_handler->negotiated_version();
1160 }
1161 
1162 std::string_view
negotiated_application_name() const1163 QUICNetVConnection::negotiated_application_name() const
1164 {
1165   const uint8_t *name;
1166   unsigned int name_len = 0;
1167 
1168   this->_hs_protocol->negotiated_application_name(&name, &name_len);
1169 
1170   return std::string_view(reinterpret_cast<const char *>(name), name_len);
1171 }
1172 
1173 QUICConnectionErrorUPtr
_state_handshake_process_packet(const QUICPacket & packet)1174 QUICNetVConnection::_state_handshake_process_packet(const QUICPacket &packet)
1175 {
1176   QUICConnectionErrorUPtr error = nullptr;
1177   switch (packet.type()) {
1178   case QUICPacketType::VERSION_NEGOTIATION:
1179     error = this->_state_handshake_process_version_negotiation_packet(static_cast<const QUICVersionNegotiationPacketR &>(packet));
1180     break;
1181   case QUICPacketType::INITIAL:
1182     error = this->_state_handshake_process_initial_packet(static_cast<const QUICInitialPacketR &>(packet));
1183     break;
1184   case QUICPacketType::RETRY:
1185     error = this->_state_handshake_process_retry_packet(static_cast<const QUICRetryPacketR &>(packet));
1186     break;
1187   case QUICPacketType::HANDSHAKE:
1188     error = this->_state_handshake_process_handshake_packet(static_cast<const QUICHandshakePacketR &>(packet));
1189     if (this->_pp_key_info.is_decryption_key_available(QUICKeyPhase::INITIAL) && this->netvc_context == NET_VCONNECTION_IN) {
1190       this->_pp_key_info.drop_keys(QUICKeyPhase::INITIAL);
1191       this->_loss_detector->on_packet_number_space_discarded(QUICPacketNumberSpace::INITIAL);
1192       this->_minimum_encryption_level = QUICEncryptionLevel::HANDSHAKE;
1193     }
1194     break;
1195   case QUICPacketType::ZERO_RTT_PROTECTED:
1196     error = this->_state_handshake_process_zero_rtt_protected_packet(static_cast<const QUICZeroRttPacketR &>(packet));
1197     break;
1198   case QUICPacketType::PROTECTED:
1199     QUICConDebug("Ignore %s(%" PRIu8 ") packet", QUICDebugNames::packet_type(packet.type()), static_cast<uint8_t>(packet.type()));
1200     break;
1201   default:
1202     error = std::make_unique<QUICConnectionError>(QUICTransErrorCode::INTERNAL_ERROR);
1203     break;
1204   }
1205   return error;
1206 }
1207 
1208 QUICConnectionErrorUPtr
_state_handshake_process_version_negotiation_packet(const QUICVersionNegotiationPacketR & packet)1209 QUICNetVConnection::_state_handshake_process_version_negotiation_packet(const QUICVersionNegotiationPacketR &packet)
1210 {
1211   QUICConnectionErrorUPtr error = nullptr;
1212 
1213   if (packet.destination_cid() != this->connection_id()) {
1214     QUICConDebug("Ignore Version Negotiation packet");
1215     return error;
1216   }
1217 
1218   if (this->_handshake_handler->is_version_negotiated()) {
1219     QUICConDebug("ignore VN - already negotiated");
1220   } else {
1221     error = this->_handshake_handler->negotiate_version(packet, &this->_packet_factory);
1222 
1223     // discard all transport state except packet number
1224     this->_loss_detector->reset();
1225 
1226     this->_congestion_controller->reset();
1227 
1228     // start handshake over
1229     this->_handshake_handler->reset();
1230     this->_handshake_handler->do_handshake();
1231     this->_schedule_packet_write_ready();
1232   }
1233 
1234   return error;
1235 }
1236 
1237 QUICConnectionErrorUPtr
_state_handshake_process_initial_packet(const QUICInitialPacketR & packet)1238 QUICNetVConnection::_state_handshake_process_initial_packet(const QUICInitialPacketR &packet)
1239 {
1240   // QUIC packet could be smaller than MINIMUM_INITIAL_PACKET_SIZE when coalescing packets
1241   // if (packet->size() < MINIMUM_INITIAL_PACKET_SIZE) {
1242   //   QUICConDebug("Packet size is smaller than the minimum initial packet size");
1243   //   // Ignore the packet
1244   //   return QUICErrorUPtr(new QUICNoError());
1245   // }
1246 
1247   QUICConnectionErrorUPtr error = nullptr;
1248 
1249   // Start handshake
1250   if (this->netvc_context == NET_VCONNECTION_IN) {
1251     this->local_addr.sa  = packet.to().sa;
1252     this->remote_addr.sa = packet.from().sa;
1253     this->_five_tuple.update(this->local_addr, this->remote_addr, SOCK_DGRAM);
1254 
1255     if (!this->_alt_con_manager) {
1256       this->_alt_con_manager =
1257         new QUICAltConnectionManager(this, *this->_ctable, *this->_rtable, this->_peer_quic_connection_id,
1258                                      this->_quic_config->instance_id(), this->_quic_config->active_cid_limit_in(),
1259                                      this->_quic_config->preferred_address_ipv4(), this->_quic_config->preferred_address_ipv6());
1260       this->_frame_generators.add_generator(*this->_alt_con_manager, QUICFrameGeneratorWeight::EARLY);
1261       this->_frame_dispatcher->add_handler(this->_alt_con_manager);
1262     }
1263     QUICTPConfigQCP tp_config(this->_quic_config, NET_VCONNECTION_IN);
1264     if (this->_quic_config->quantum_readiness_test_enabled_in()) {
1265       tp_config.add_tp(QUANTUM_TEST_ID, QUANTUM_TEST_VALUE, sizeof(QUANTUM_TEST_VALUE));
1266     }
1267     error = this->_handshake_handler->start(tp_config, packet, &this->_packet_factory, this->_alt_con_manager->preferred_address());
1268 
1269     // If version negotiation was failed and VERSION NEGOTIATION packet was sent, nothing to do.
1270     if (this->_handshake_handler->is_version_negotiated()) {
1271       error = this->_recv_and_ack(packet);
1272 
1273       if (error == nullptr && this->_handshake_handler->is_completed() && !this->_handshake_handler->has_remote_tp()) {
1274         error = std::make_unique<QUICConnectionError>(QUICTransErrorCode::TRANSPORT_PARAMETER_ERROR);
1275       }
1276     }
1277   } else {
1278     if (!this->_alt_con_manager) {
1279       this->_alt_con_manager =
1280         new QUICAltConnectionManager(this, *this->_ctable, *this->_rtable, this->_peer_quic_connection_id,
1281                                      this->_quic_config->instance_id(), this->_quic_config->active_cid_limit_out());
1282       this->_frame_generators.add_generator(*this->_alt_con_manager, QUICFrameGeneratorWeight::BEFORE_DATA);
1283       this->_frame_dispatcher->add_handler(this->_alt_con_manager);
1284     }
1285 
1286     this->_handshake_handler->update(packet);
1287 
1288     // on client side, _handshake_handler is already started. Just process packet like _state_handshake_process_handshake_packet()
1289     error = this->_recv_and_ack(packet);
1290   }
1291 
1292   return error;
1293 }
1294 
1295 /**
1296    This doesn't call this->_recv_and_ack(), because RETRY packet doesn't have any frames.
1297  */
1298 QUICConnectionErrorUPtr
_state_handshake_process_retry_packet(const QUICRetryPacketR & packet)1299 QUICNetVConnection::_state_handshake_process_retry_packet(const QUICRetryPacketR &packet)
1300 {
1301   ink_assert(this->netvc_context == NET_VCONNECTION_OUT);
1302 
1303   if (this->_av_token) {
1304     QUICConDebug("Ignore RETRY packet - already processed before");
1305     return nullptr;
1306   }
1307 
1308   // Check Integrity Tag
1309   if (!packet.has_valid_tag(this->_original_quic_connection_id)) {
1310     // Discard the packet
1311     QUICConDebug("Ignore RETRY packet - integrity tag is not valid");
1312     return nullptr;
1313   } else {
1314     QUICConDebug("Integrity tag is valid");
1315   }
1316 
1317   // TODO: move packet->payload to _av_token
1318   this->_av_token_len = packet.token().length();
1319   this->_av_token     = ats_unique_malloc(this->_av_token_len);
1320   memcpy(this->_av_token.get(), packet.token().buf(), this->_av_token_len);
1321 
1322   this->_padder->set_av_token_len(this->_av_token_len);
1323 
1324   // discard all transport state
1325   this->_handshake_handler->reset();
1326   this->_handshake_handler->update(packet);
1327   this->_packet_factory.reset();
1328   this->_loss_detector->reset();
1329 
1330   this->_congestion_controller->reset();
1331   this->_packet_recv_queue.reset();
1332 
1333   // Initialize Key Materials with peer CID. Because peer CID is DCID of (second) INITIAL packet from client which reply to RETRY
1334   // packet from server
1335   this->_hs_protocol->initialize_key_materials(this->_peer_quic_connection_id, packet.version());
1336 
1337   // start handshake over
1338   this->_handshake_handler->do_handshake();
1339   this->_schedule_packet_write_ready();
1340 
1341   return nullptr;
1342 }
1343 
1344 QUICConnectionErrorUPtr
_state_handshake_process_handshake_packet(const QUICHandshakePacketR & packet)1345 QUICNetVConnection::_state_handshake_process_handshake_packet(const QUICHandshakePacketR &packet)
1346 {
1347   // Source address is verified by receiving any message from the client encrypted using the
1348   // Handshake keys.
1349   if (this->netvc_context == NET_VCONNECTION_IN && !this->_verified_state.is_verified()) {
1350     this->_verified_state.set_addr_verifed();
1351   }
1352   return this->_recv_and_ack(packet);
1353 }
1354 
1355 QUICConnectionErrorUPtr
_state_handshake_process_zero_rtt_protected_packet(const QUICZeroRttPacketR & packet)1356 QUICNetVConnection::_state_handshake_process_zero_rtt_protected_packet(const QUICZeroRttPacketR &packet)
1357 {
1358   this->_stream_manager->init_flow_control_params(this->_handshake_handler->local_transport_parameters(),
1359                                                   this->_handshake_handler->remote_transport_parameters());
1360   this->_start_application();
1361   return this->_recv_and_ack(packet);
1362 }
1363 
1364 QUICConnectionErrorUPtr
_state_connection_established_process_protected_packet(const QUICShortHeaderPacketR & packet)1365 QUICNetVConnection::_state_connection_established_process_protected_packet(const QUICShortHeaderPacketR &packet)
1366 {
1367   QUICConnectionErrorUPtr error = nullptr;
1368   bool has_non_probing_frame    = false;
1369 
1370   error = this->_recv_and_ack(packet, &has_non_probing_frame);
1371   if (error != nullptr) {
1372     return error;
1373   }
1374 
1375   // Migrate connection if needed
1376   if (this->_alt_con_manager != nullptr) {
1377     if (has_non_probing_frame &&
1378         (packet.destination_cid() != this->_quic_connection_id || !ats_ip_addr_port_eq(packet.from(), this->remote_addr))) {
1379       error = this->_state_connection_established_migrate_connection(packet);
1380       if (error != nullptr) {
1381         return error;
1382       }
1383     }
1384   }
1385 
1386   // For Connection Migration exercise
1387   if (this->netvc_context == NET_VCONNECTION_OUT && this->_quic_config->cm_exercise_enabled()) {
1388     this->_state_connection_established_initiate_connection_migration();
1389   }
1390 
1391   return error;
1392 }
1393 
1394 QUICConnectionErrorUPtr
_state_connection_established_receive_packet()1395 QUICNetVConnection::_state_connection_established_receive_packet()
1396 {
1397   QUICConnectionErrorUPtr error = nullptr;
1398   QUICPacketCreationResult result;
1399 
1400   // Receive a QUIC packet
1401   net_activity(this, this_ethread());
1402   do {
1403     uint8_t packet_buf[QUICPacket::MAX_INSTANCE_SIZE];
1404     QUICPacketUPtr packet = this->_dequeue_recv_packet(packet_buf, result);
1405     if (result == QUICPacketCreationResult::FAILED) {
1406       // Don't make this error, and discard the packet.
1407       // Because:
1408       // - Attacker can terminate connections
1409       // - It could be just an error on lower layer
1410       continue;
1411     } else if (result == QUICPacketCreationResult::NO_PACKET) {
1412       return error;
1413     } else if (result == QUICPacketCreationResult::NOT_READY) {
1414       return error;
1415     } else if (result == QUICPacketCreationResult::IGNORED) {
1416       continue;
1417     }
1418 
1419     // Process the packet
1420     switch (packet->type()) {
1421     case QUICPacketType::PROTECTED:
1422       error = this->_state_connection_established_process_protected_packet(static_cast<QUICShortHeaderPacketR &>(*packet));
1423       break;
1424     case QUICPacketType::INITIAL:
1425     case QUICPacketType::HANDSHAKE:
1426     case QUICPacketType::ZERO_RTT_PROTECTED:
1427       // Pass packet to _recv_and_ack to send ack to the packet. Stream data will be discarded by offset mismatch.
1428       error = this->_recv_and_ack(static_cast<QUICPacketR &>(*packet));
1429       break;
1430     default:
1431       QUICConDebug("Unknown packet type: %s(%" PRIu8 ")", QUICDebugNames::packet_type(packet->type()),
1432                    static_cast<uint8_t>(packet->type()));
1433 
1434       error = std::make_unique<QUICConnectionError>(QUICTransErrorCode::INTERNAL_ERROR);
1435       break;
1436     }
1437 
1438   } while (error == nullptr && (result == QUICPacketCreationResult::SUCCESS || result == QUICPacketCreationResult::IGNORED));
1439   return error;
1440 }
1441 
1442 QUICConnectionErrorUPtr
_state_closing_receive_packet()1443 QUICNetVConnection::_state_closing_receive_packet()
1444 {
1445   while (this->_packet_recv_queue.size() > 0) {
1446     QUICPacketCreationResult result;
1447     uint8_t packet_buf[QUICPacket::MAX_INSTANCE_SIZE];
1448     QUICPacketUPtr packet = this->_dequeue_recv_packet(packet_buf, result);
1449     if (result == QUICPacketCreationResult::SUCCESS) {
1450       switch (packet->type()) {
1451       case QUICPacketType::VERSION_NEGOTIATION:
1452         // Ignore VN packets on closing state
1453         break;
1454       default:
1455         this->_recv_and_ack(static_cast<QUICPacketR &>(*packet));
1456         break;
1457       }
1458     }
1459     ++this->_state_closing_recv_packet_count;
1460 
1461     if (this->_state_closing_recv_packet_window < STATE_CLOSING_MAX_RECV_PKT_WIND &&
1462         this->_state_closing_recv_packet_count >= this->_state_closing_recv_packet_window) {
1463       this->_state_closing_recv_packet_count = 0;
1464       this->_state_closing_recv_packet_window <<= 1;
1465 
1466       this->_schedule_packet_write_ready(true);
1467       break;
1468     }
1469   }
1470 
1471   return nullptr;
1472 }
1473 
1474 QUICConnectionErrorUPtr
_state_draining_receive_packet()1475 QUICNetVConnection::_state_draining_receive_packet()
1476 {
1477   while (this->_packet_recv_queue.size() > 0) {
1478     QUICPacketCreationResult result;
1479     uint8_t packet_buf[QUICPacket::MAX_INSTANCE_SIZE];
1480     QUICPacketUPtr packet = this->_dequeue_recv_packet(packet_buf, result);
1481     if (result == QUICPacketCreationResult::SUCCESS) {
1482       this->_recv_and_ack(static_cast<QUICPacketR &>(*packet));
1483       // Do NOT schedule WRITE_READY event from this point.
1484       // An endpoint in the draining state MUST NOT send any packets.
1485     }
1486   }
1487 
1488   return nullptr;
1489 }
1490 
1491 /**
1492  * 1. Check congestion window
1493  * 2. Allocate buffer for UDP Payload
1494  * 3. Generate QUIC Packet
1495  * 4. Store data to the payload
1496  * 5. Send UDP Packet
1497  */
1498 QUICConnectionErrorUPtr
_state_common_send_packet()1499 QUICNetVConnection::_state_common_send_packet()
1500 {
1501   uint32_t packet_count = 0;
1502   uint32_t error        = 0;
1503   while (error == 0 && packet_count < PACKET_PER_EVENT) {
1504     uint32_t window = this->_congestion_controller->credit();
1505 
1506     if (window == 0) {
1507       break;
1508     }
1509 
1510     Ptr<IOBufferBlock> udp_payload(new_IOBufferBlock());
1511     uint32_t udp_payload_len = std::min(window, this->_pmtu);
1512     udp_payload->alloc(iobuffer_size_to_index(udp_payload_len, BUFFER_SIZE_INDEX_32K));
1513 
1514     uint32_t written = 0;
1515     for (int i = static_cast<int>(this->_minimum_encryption_level); i <= static_cast<int>(QUICEncryptionLevel::ONE_RTT); ++i) {
1516       uint8_t packet_buf[QUICPacket::MAX_INSTANCE_SIZE];
1517 
1518       auto level = QUIC_ENCRYPTION_LEVELS[i];
1519       if (level == QUICEncryptionLevel::ONE_RTT && !this->_handshake_handler->is_completed()) {
1520         continue;
1521       }
1522 
1523       uint32_t max_packet_size = udp_payload_len - written;
1524       if (this->netvc_context == NET_VCONNECTION_IN && !this->_verified_state.is_verified()) {
1525         max_packet_size = std::min(max_packet_size, this->_verified_state.windows());
1526       }
1527 
1528       QUICSentPacketInfoUPtr packet_info = std::make_unique<QUICSentPacketInfo>();
1529       QUICPacketUPtr packet              = this->_packetize_frames(packet_buf, level, max_packet_size, packet_info->frames);
1530 
1531       if (packet) {
1532         // trigger callback
1533         this->_context->trigger(QUICContext::CallbackEvent::PACKET_SEND, packet.get());
1534 
1535         packet_info->packet_number = packet->packet_number();
1536         packet_info->time_sent     = Thread::get_hrtime();
1537         packet_info->ack_eliciting = packet->is_ack_eliciting();
1538         packet_info->in_flight     = true;
1539         if (packet_info->ack_eliciting) {
1540           packet_info->sent_bytes = packet->size();
1541         } else {
1542           packet_info->sent_bytes = 0;
1543         }
1544         packet_info->type     = packet->type();
1545         packet_info->pn_space = QUICTypeUtil::pn_space(level);
1546 
1547         if (this->netvc_context == NET_VCONNECTION_IN && !this->_verified_state.is_verified()) {
1548           QUICConDebug("send to unverified window: %u", this->_verified_state.windows());
1549           this->_verified_state.consume(packet->size());
1550         }
1551 
1552         // TODO: do not write two QUIC Short Header Packets
1553         uint8_t *buf = reinterpret_cast<uint8_t *>(udp_payload->end());
1554         size_t len   = 0;
1555         packet->store(buf, &len);
1556         udp_payload->fill(len);
1557         written += len;
1558 
1559         int dcil = (this->_peer_quic_connection_id == QUICConnectionId::ZERO()) ? 0 : this->_peer_quic_connection_id.length();
1560         if (!this->_ph_protector.protect(buf, len, dcil)) {
1561           ink_assert(!"failed to protect buffer");
1562         }
1563 
1564         QUICConVDebug("[TX] %s packet #%" PRIu64 " size=%zu", QUICDebugNames::packet_type(packet->type()), packet->packet_number(),
1565                       len);
1566 
1567         if (this->_pp_key_info.is_encryption_key_available(QUICKeyPhase::INITIAL) && packet->type() == QUICPacketType::HANDSHAKE &&
1568             this->netvc_context == NET_VCONNECTION_OUT) {
1569           this->_pp_key_info.drop_keys(QUICKeyPhase::INITIAL);
1570           this->_loss_detector->on_packet_number_space_discarded(QUICPacketNumberSpace::INITIAL);
1571           this->_minimum_encryption_level = QUICEncryptionLevel::HANDSHAKE;
1572         }
1573 
1574         this->_loss_detector->on_packet_sent(std::move(packet_info));
1575         packet_count++;
1576       }
1577     }
1578 
1579     if (written) {
1580       this->_packet_handler->send_packet(this, udp_payload);
1581     } else {
1582       udp_payload->dealloc();
1583       break;
1584     }
1585   }
1586 
1587   if (packet_count) {
1588     this->_context->trigger(QUICContext::CallbackEvent::METRICS_UPDATE, this->_congestion_controller->congestion_window(),
1589                             this->_congestion_controller->bytes_in_flight(), this->_congestion_controller->current_ssthresh());
1590 
1591     QUIC_INCREMENT_DYN_STAT_EX(QUICStats::total_packets_sent_stat, packet_count);
1592     net_activity(this, this_ethread());
1593   }
1594 
1595   return nullptr;
1596 }
1597 
1598 QUICConnectionErrorUPtr
_state_closing_send_packet()1599 QUICNetVConnection::_state_closing_send_packet()
1600 {
1601   this->_packetize_closing_frame();
1602 
1603   // TODO: should credit of congestion controller be checked?
1604 
1605   // During the closing period, an endpoint that sends a
1606   // closing frame SHOULD respond to any packet that it receives with
1607   // another packet containing a closing frame.  To minimize the state
1608   // that an endpoint maintains for a closing connection, endpoints MAY
1609   // send the exact same packet.
1610   if (this->_the_final_packet) {
1611     this->_packet_handler->send_packet(*this->_the_final_packet, this, this->_ph_protector);
1612   }
1613 
1614   return nullptr;
1615 }
1616 
1617 Ptr<IOBufferBlock>
_store_frame(Ptr<IOBufferBlock> parent_block,size_t & size_added,uint64_t & max_frame_size,QUICFrame & frame,std::vector<QUICSentPacketInfo::FrameInfo> & frames)1618 QUICNetVConnection::_store_frame(Ptr<IOBufferBlock> parent_block, size_t &size_added, uint64_t &max_frame_size, QUICFrame &frame,
1619                                  std::vector<QUICSentPacketInfo::FrameInfo> &frames)
1620 {
1621   Ptr<IOBufferBlock> new_block = frame.to_io_buffer_block(max_frame_size);
1622 
1623   size_added = 0;
1624   for (Ptr<IOBufferBlock> tmp = new_block; tmp; tmp = tmp->next) {
1625     size_added += tmp->size();
1626   }
1627 
1628   if (parent_block == nullptr) {
1629     parent_block = new_block;
1630   } else {
1631     parent_block->next = new_block;
1632   }
1633 
1634   // frame should be stored because it's created with max_frame_size
1635   ink_assert(size_added != 0);
1636 
1637   max_frame_size -= size_added;
1638 
1639   if (is_debug_tag_set(QUIC_DEBUG_TAG.data())) {
1640     char msg[1024];
1641     frame.debug_msg(msg, sizeof(msg));
1642     QUICConVDebug("[TX] | %s", msg);
1643   }
1644 
1645   frames.emplace_back(frame.id(), frame.generated_by());
1646 
1647   while (parent_block->next) {
1648     parent_block = parent_block->next;
1649   }
1650   return parent_block;
1651 }
1652 
1653 QUICPacketUPtr
_packetize_frames(uint8_t * packet_buf,QUICEncryptionLevel level,uint64_t max_packet_size,std::vector<QUICSentPacketInfo::FrameInfo> & frames)1654 QUICNetVConnection::_packetize_frames(uint8_t *packet_buf, QUICEncryptionLevel level, uint64_t max_packet_size,
1655                                       std::vector<QUICSentPacketInfo::FrameInfo> &frames)
1656 {
1657   QUICPacketUPtr packet = QUICPacketFactory::create_null_packet();
1658   if (max_packet_size <= MAX_PACKET_OVERHEAD) {
1659     return packet;
1660   }
1661 
1662   // TODO: adjust MAX_PACKET_OVERHEAD for each encryption level
1663   uint64_t max_frame_size = max_packet_size - MAX_PACKET_OVERHEAD;
1664   if (level == QUICEncryptionLevel::INITIAL && this->_av_token) {
1665     max_frame_size = max_frame_size - (QUICVariableInt::size(this->_av_token_len) + this->_av_token_len);
1666   }
1667   max_frame_size = std::min(max_frame_size, this->_maximum_stream_frame_data_size());
1668 
1669   bool probing                   = false;
1670   int frame_count                = 0;
1671   size_t len                     = 0;
1672   Ptr<IOBufferBlock> first_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1673   Ptr<IOBufferBlock> last_block  = first_block;
1674   first_block->alloc(iobuffer_size_to_index(0, BUFFER_SIZE_INDEX_32K));
1675   first_block->fill(0);
1676 
1677   uint32_t seq_num   = this->_seq_num++;
1678   size_t size_added  = 0;
1679   bool ack_eliciting = false;
1680   bool crypto        = false;
1681   uint8_t frame_instance_buffer[QUICFrame::MAX_INSTANCE_SIZE]; // This is for a frame instance but not serialized frame data
1682   QUICFrame *frame = nullptr;
1683   for (auto g : this->_frame_generators.generators()) {
1684     // a non-ack_eliciting packet is ready, but we can not send continuous two ack_eliciting packets.
1685     while (g->will_generate_frame(level, len, ack_eliciting, seq_num)) {
1686       // FIXME will_generate_frame should receive more parameters so we don't need extra checks
1687       if (g == this->_remote_flow_controller && !this->_stream_manager->will_generate_frame(level, len, ack_eliciting, seq_num)) {
1688         break;
1689       }
1690 
1691       // Common block
1692       frame =
1693         g->generate_frame(frame_instance_buffer, level, this->_remote_flow_controller->credit(), max_frame_size, len, seq_num);
1694       if (frame) {
1695         this->_context->trigger(QUICContext::CallbackEvent::FRAME_PACKETIZE, *frame);
1696         // Some frame types must not be sent on Initial and Handshake packets
1697         switch (auto t = frame->type(); level) {
1698         case QUICEncryptionLevel::INITIAL:
1699         case QUICEncryptionLevel::HANDSHAKE:
1700           ink_assert(t == QUICFrameType::CRYPTO || t == QUICFrameType::ACK || t == QUICFrameType::PADDING ||
1701                      t == QUICFrameType::CONNECTION_CLOSE || t == QUICFrameType::PING);
1702           break;
1703         default:
1704           break;
1705         }
1706 
1707         ++frame_count;
1708         probing |= frame->is_probing_frame();
1709         if (frame->is_flow_controlled()) {
1710           int ret = this->_remote_flow_controller->update(this->_stream_manager->total_offset_sent());
1711           QUICFCVDebug("[REMOTE] %" PRIu64 "/%" PRIu64, this->_remote_flow_controller->current_offset(),
1712                        this->_remote_flow_controller->current_limit());
1713           ink_assert(ret == 0);
1714         }
1715         last_block = this->_store_frame(last_block, size_added, max_frame_size, *frame, frames);
1716         len += size_added;
1717 
1718         // FIXME ACK frame should have priority
1719         if (frame->type() == QUICFrameType::STREAM) {
1720           if (++this->_stream_frames_sent % MAX_CONSECUTIVE_STREAMS == 0) {
1721             break;
1722           }
1723         }
1724 
1725         if (!ack_eliciting && frame->ack_eliciting()) {
1726           ack_eliciting = true;
1727         }
1728 
1729         if (frame->type() == QUICFrameType::CRYPTO && frame->ack_eliciting()) {
1730           crypto = true;
1731         }
1732 
1733         frame->~QUICFrame();
1734       } else {
1735         // Move to next generator
1736         break;
1737       }
1738     }
1739   }
1740 
1741   // Schedule a packet
1742   if (len != 0) {
1743     // Packet is retransmittable if it's not ack only packet
1744     packet = this->_build_packet(packet_buf, level, first_block, ack_eliciting, probing, crypto);
1745   }
1746 
1747   return packet;
1748 }
1749 
1750 void
_packetize_closing_frame()1751 QUICNetVConnection::_packetize_closing_frame()
1752 {
1753   if (this->_connection_error == nullptr || this->_the_final_packet) {
1754     return;
1755   }
1756 
1757   QUICFrame *frame = nullptr;
1758 
1759   // CONNECTION_CLOSE
1760   uint8_t frame_buf[QUICFrame::MAX_INSTANCE_SIZE];
1761   frame = QUICFrameFactory::create_connection_close_frame(frame_buf, *this->_connection_error);
1762 
1763   uint32_t max_size = this->_maximum_quic_packet_size();
1764 
1765   size_t size_added       = 0;
1766   uint64_t max_frame_size = static_cast<uint64_t>(max_size);
1767   std::vector<QUICSentPacketInfo::FrameInfo> frames;
1768   Ptr<IOBufferBlock> first_block = make_ptr<IOBufferBlock>(new_IOBufferBlock());
1769   Ptr<IOBufferBlock> last_block  = first_block;
1770   first_block->alloc(iobuffer_size_to_index(0, BUFFER_SIZE_INDEX_32K));
1771   first_block->fill(0);
1772   last_block = this->_store_frame(last_block, size_added, max_frame_size, *frame, frames);
1773 
1774   QUICEncryptionLevel level = this->_hs_protocol->current_encryption_level();
1775   ink_assert(level != QUICEncryptionLevel::ZERO_RTT);
1776   this->_the_final_packet = this->_build_packet(this->_final_packet_buf, level, first_block, true, false, false);
1777 }
1778 
1779 QUICConnectionErrorUPtr
_recv_and_ack(const QUICPacketR & packet,bool * has_non_probing_frame)1780 QUICNetVConnection::_recv_and_ack(const QUICPacketR &packet, bool *has_non_probing_frame)
1781 {
1782   ink_assert(packet.type() != QUICPacketType::RETRY);
1783 
1784   uint16_t size               = packet.payload_length();
1785   ats_unique_buf payload_ubuf = ats_unique_malloc(size);
1786   uint8_t *payload            = payload_ubuf.get();
1787   size_t copied_len           = 0;
1788   for (auto b = packet.payload_block(); b; b = b->next) {
1789     memcpy(payload + copied_len, b->start(), b->size());
1790     copied_len += b->size();
1791   }
1792   QUICPacketNumber packet_num = packet.packet_number();
1793   QUICEncryptionLevel level   = QUICTypeUtil::encryption_level(packet.type());
1794 
1795   bool ack_only;
1796   bool is_flow_controlled;
1797 
1798   QUICConnectionErrorUPtr error = nullptr;
1799   if (has_non_probing_frame) {
1800     *has_non_probing_frame = false;
1801   }
1802 
1803   error = this->_frame_dispatcher->receive_frames(*this->_context, level, payload, size, ack_only, is_flow_controlled,
1804                                                   has_non_probing_frame, static_cast<const QUICPacketR *>(&packet));
1805   this->_context->trigger(QUICContext::CallbackEvent::PACKET_RECV, &packet);
1806 
1807   if (error != nullptr) {
1808     return error;
1809   }
1810 
1811   if (is_flow_controlled) {
1812     int ret = this->_local_flow_controller->update(this->_stream_manager->total_offset_received());
1813     QUICFCVDebug("[LOCAL] %" PRIu64 "/%" PRIu64, this->_local_flow_controller->current_offset(),
1814                  this->_local_flow_controller->current_limit());
1815 
1816     if (ret != 0) {
1817       return std::make_unique<QUICConnectionError>(QUICTransErrorCode::FLOW_CONTROL_ERROR);
1818     }
1819 
1820     this->_local_flow_controller->forward_limit(this->_stream_manager->total_reordered_bytes() + this->_flow_control_buffer_size);
1821     QUICFCVDebug("[LOCAL] %" PRIu64 "/%" PRIu64, this->_local_flow_controller->current_offset(),
1822                  this->_local_flow_controller->current_limit());
1823   }
1824 
1825   this->_ack_frame_manager.update(level, packet_num, size, ack_only);
1826 
1827   return error;
1828 }
1829 
1830 QUICPacketUPtr
_build_packet(uint8_t * packet_buf,QUICEncryptionLevel level,const Ptr<IOBufferBlock> & parent_block,bool ack_eliciting,bool probing,bool crypto)1831 QUICNetVConnection::_build_packet(uint8_t *packet_buf, QUICEncryptionLevel level, const Ptr<IOBufferBlock> &parent_block,
1832                                   bool ack_eliciting, bool probing, bool crypto)
1833 {
1834   QUICPacketType type   = QUICTypeUtil::packet_type(level);
1835   QUICPacketUPtr packet = QUICPacketFactory::create_null_packet();
1836 
1837   size_t len = 0;
1838   for (Ptr<IOBufferBlock> tmp = parent_block; tmp; tmp = tmp->next) {
1839     len += tmp->size();
1840   }
1841 
1842   switch (type) {
1843   case QUICPacketType::INITIAL: {
1844     QUICConnectionId dcid = this->_peer_quic_connection_id;
1845     ats_unique_buf token  = {nullptr};
1846     size_t token_len      = 0;
1847 
1848     if (this->netvc_context == NET_VCONNECTION_OUT) {
1849       // TODO: Add a case of using token which is advertised by NEW_TOKEN frame
1850       if (this->_av_token) {
1851         token     = ats_unique_malloc(this->_av_token_len);
1852         token_len = this->_av_token_len;
1853         memcpy(token.get(), this->_av_token.get(), token_len);
1854       } else {
1855         dcid = this->_original_quic_connection_id;
1856       }
1857     }
1858 
1859     packet = this->_packet_factory.create_initial_packet(
1860       packet_buf, dcid, this->_quic_connection_id, this->_largest_acked_packet_number(QUICEncryptionLevel::INITIAL), parent_block,
1861       len, ack_eliciting, probing, crypto, std::move(token), token_len);
1862     break;
1863   }
1864   case QUICPacketType::HANDSHAKE: {
1865     packet = this->_packet_factory.create_handshake_packet(packet_buf, this->_peer_quic_connection_id, this->_quic_connection_id,
1866                                                            this->_largest_acked_packet_number(QUICEncryptionLevel::HANDSHAKE),
1867                                                            parent_block, len, ack_eliciting, probing, crypto);
1868     break;
1869   }
1870   case QUICPacketType::ZERO_RTT_PROTECTED: {
1871     packet = this->_packet_factory.create_zero_rtt_packet(packet_buf, this->_original_quic_connection_id, this->_quic_connection_id,
1872                                                           this->_largest_acked_packet_number(QUICEncryptionLevel::ZERO_RTT),
1873                                                           parent_block, len, ack_eliciting, probing);
1874     break;
1875   }
1876   case QUICPacketType::PROTECTED: {
1877     packet = this->_packet_factory.create_short_header_packet(packet_buf, this->_peer_quic_connection_id,
1878                                                               this->_largest_acked_packet_number(QUICEncryptionLevel::ONE_RTT),
1879                                                               parent_block, len, ack_eliciting, probing);
1880     break;
1881   }
1882   default:
1883     // should not be here
1884     ink_assert(false);
1885     break;
1886   }
1887 
1888   return packet;
1889 }
1890 
1891 void
_init_flow_control_params(const std::shared_ptr<const QUICTransportParameters> & local_tp,const std::shared_ptr<const QUICTransportParameters> & remote_tp)1892 QUICNetVConnection::_init_flow_control_params(const std::shared_ptr<const QUICTransportParameters> &local_tp,
1893                                               const std::shared_ptr<const QUICTransportParameters> &remote_tp)
1894 {
1895   this->_stream_manager->init_flow_control_params(local_tp, remote_tp);
1896 
1897   uint64_t local_initial_max_data  = 0;
1898   uint64_t remote_initial_max_data = 0;
1899   if (local_tp) {
1900     local_initial_max_data          = local_tp->getAsUInt(QUICTransportParameterId::INITIAL_MAX_DATA);
1901     this->_flow_control_buffer_size = local_initial_max_data;
1902   }
1903   if (remote_tp) {
1904     remote_initial_max_data = remote_tp->getAsUInt(QUICTransportParameterId::INITIAL_MAX_DATA);
1905   }
1906 
1907   this->_local_flow_controller->set_limit(local_initial_max_data);
1908   this->_remote_flow_controller->set_limit(remote_initial_max_data);
1909   QUICFCDebug("[LOCAL] %" PRIu64 "/%" PRIu64, this->_local_flow_controller->current_offset(),
1910               this->_local_flow_controller->current_limit());
1911   QUICFCDebug("[REMOTE] %" PRIu64 "/%" PRIu64, this->_remote_flow_controller->current_offset(),
1912               this->_remote_flow_controller->current_limit());
1913 }
1914 
1915 void
_handle_error(QUICConnectionErrorUPtr error)1916 QUICNetVConnection::_handle_error(QUICConnectionErrorUPtr error)
1917 {
1918   QUICError("QUICError: %s (%u), %s (0x%" PRIx16 ")", QUICDebugNames::error_class(error->cls),
1919             static_cast<unsigned int>(error->cls), QUICDebugNames::error_code(error->code), error->code);
1920 
1921   // Connection Error
1922   this->close_quic_connection(std::move(error));
1923 }
1924 
1925 QUICPacketUPtr
_dequeue_recv_packet(uint8_t * packet_buf,QUICPacketCreationResult & result)1926 QUICNetVConnection::_dequeue_recv_packet(uint8_t *packet_buf, QUICPacketCreationResult &result)
1927 {
1928   QUICPacketUPtr packet = this->_packet_recv_queue.dequeue(packet_buf, result);
1929 
1930   if (result == QUICPacketCreationResult::SUCCESS) {
1931     if (this->direction() == NET_VCONNECTION_OUT) {
1932       // Reset CID if a server sent back a new CID
1933       // FIXME This should happen only once - it should probably be controlled by PathManager
1934       if (packet->type() != QUICPacketType::PROTECTED && (packet->type() != QUICPacketType::RETRY || !this->_av_token)) {
1935         QUICConnectionId src_cid = static_cast<QUICLongHeaderPacketR &>(*packet).source_cid();
1936         // FIXME src connection id could be zero ? if so, check packet header type.
1937         if (src_cid != QUICConnectionId::ZERO()) {
1938           if (this->_peer_quic_connection_id != src_cid) {
1939             this->_update_peer_cid(src_cid);
1940           }
1941         }
1942       }
1943     }
1944 
1945     if (!this->_verified_state.is_verified()) {
1946       this->_verified_state.fill(packet->size());
1947     }
1948   }
1949 
1950   // Debug prints
1951   switch (result) {
1952   case QUICPacketCreationResult::NO_PACKET:
1953     break;
1954   case QUICPacketCreationResult::NOT_READY:
1955     QUICConDebug("Not ready to decrypt the packet");
1956     break;
1957   case QUICPacketCreationResult::IGNORED:
1958     QUICConDebug("Ignored");
1959     break;
1960   case QUICPacketCreationResult::UNSUPPORTED:
1961     QUICConDebug("Unsupported version");
1962     break;
1963   case QUICPacketCreationResult::SUCCESS:
1964     switch (packet->type()) {
1965     case QUICPacketType::VERSION_NEGOTIATION:
1966     case QUICPacketType::RETRY:
1967       QUICConVDebug("[RX] %s packet size=%u", QUICDebugNames::packet_type(packet->type()), packet->size());
1968       break;
1969     default:
1970       QUICConVDebug("[RX] %s packet #%" PRIu64 " size=%u header_len=%u payload_len=%u", QUICDebugNames::packet_type(packet->type()),
1971                     packet->packet_number(), packet->size(), packet->header_size(), packet->payload_length());
1972       break;
1973     }
1974     break;
1975   default:
1976     QUICConDebug("Failed to decrypt the packet");
1977     break;
1978   }
1979 
1980   return packet;
1981 }
1982 
1983 void
_schedule_packet_write_ready(bool delay)1984 QUICNetVConnection::_schedule_packet_write_ready(bool delay)
1985 {
1986   if (!this->_packet_write_ready) {
1987     QUICConVVVDebug("Schedule %s event", QUICDebugNames::quic_event(QUIC_EVENT_PACKET_WRITE_READY));
1988     if (delay) {
1989       this->_packet_write_ready = this->thread->schedule_in(this, WRITE_READY_INTERVAL, QUIC_EVENT_PACKET_WRITE_READY, nullptr);
1990     } else {
1991       this->_packet_write_ready = this->thread->schedule_imm(this, QUIC_EVENT_PACKET_WRITE_READY, nullptr);
1992     }
1993   }
1994 }
1995 
1996 void
_unschedule_packet_write_ready()1997 QUICNetVConnection::_unschedule_packet_write_ready()
1998 {
1999   if (this->_packet_write_ready) {
2000     this->_packet_write_ready->cancel();
2001     this->_packet_write_ready = nullptr;
2002   }
2003 }
2004 
2005 void
_close_packet_write_ready(Event * data)2006 QUICNetVConnection::_close_packet_write_ready(Event *data)
2007 {
2008   ink_assert(this->_packet_write_ready == data);
2009   this->_packet_write_ready = nullptr;
2010 }
2011 
2012 void
_schedule_closing_timeout(ink_hrtime interval)2013 QUICNetVConnection::_schedule_closing_timeout(ink_hrtime interval)
2014 {
2015   if (!this->_closing_timeout) {
2016     QUICConDebug("Schedule %s event in %" PRIu64 "ms", QUICDebugNames::quic_event(QUIC_EVENT_CLOSING_TIMEOUT),
2017                  interval / HRTIME_MSECOND);
2018     this->_closing_timeout = this->thread->schedule_in_local(this, interval, QUIC_EVENT_CLOSING_TIMEOUT);
2019   }
2020 }
2021 
2022 void
_unschedule_closing_timeout()2023 QUICNetVConnection::_unschedule_closing_timeout()
2024 {
2025   if (this->_closing_timeout) {
2026     QUICConDebug("Unschedule %s event", QUICDebugNames::quic_event(QUIC_EVENT_CLOSING_TIMEOUT));
2027     this->_closing_timeout->cancel();
2028     this->_closing_timeout = nullptr;
2029   }
2030 }
2031 
2032 void
_schedule_ack_manager_periodic(ink_hrtime interval)2033 QUICNetVConnection::_schedule_ack_manager_periodic(ink_hrtime interval)
2034 {
2035   this->_ack_manager_periodic = this->thread->schedule_every(this, interval, QUIC_EVENT_ACK_PERIODIC);
2036 }
2037 
2038 void
_unschedule_ack_manager_periodic()2039 QUICNetVConnection::_unschedule_ack_manager_periodic()
2040 {
2041   if (this->_ack_manager_periodic) {
2042     QUICConDebug("Unschedule %s event", QUICDebugNames::quic_event(QUIC_EVENT_ACK_PERIODIC));
2043     this->_ack_manager_periodic->cancel();
2044     this->_ack_manager_periodic = nullptr;
2045   }
2046 }
2047 
2048 void
_close_closing_timeout(Event * data)2049 QUICNetVConnection::_close_closing_timeout(Event *data)
2050 {
2051   ink_assert(this->_closing_timeout == data);
2052   this->_closing_timeout = nullptr;
2053 }
2054 
2055 void
_schedule_closed_event()2056 QUICNetVConnection::_schedule_closed_event()
2057 {
2058   if (!this->_closed_event) {
2059     QUICConDebug("Schedule %s event", QUICDebugNames::quic_event(QUIC_EVENT_SHUTDOWN));
2060     this->_closed_event = this->thread->schedule_imm(this, QUIC_EVENT_SHUTDOWN, nullptr);
2061   }
2062 }
2063 
2064 void
_unschedule_closed_event()2065 QUICNetVConnection::_unschedule_closed_event()
2066 {
2067   if (!this->_closed_event) {
2068     QUICConDebug("Unschedule %s event", QUICDebugNames::quic_event(QUIC_EVENT_SHUTDOWN));
2069     this->_closed_event->cancel();
2070     this->_closed_event = nullptr;
2071   }
2072 }
2073 
2074 void
_close_closed_event(Event * data)2075 QUICNetVConnection::_close_closed_event(Event *data)
2076 {
2077   ink_assert(this->_closed_event == data);
2078   this->_closed_event = nullptr;
2079 }
2080 
2081 int
_complete_handshake_if_possible()2082 QUICNetVConnection::_complete_handshake_if_possible()
2083 {
2084   if (this->handler != reinterpret_cast<NetVConnHandler>(&QUICNetVConnection::state_handshake)) {
2085     return 0;
2086   }
2087 
2088   if (!(this->_handshake_handler && this->_handshake_handler->is_completed())) {
2089     return -1;
2090   }
2091 
2092   if (this->netvc_context == NET_VCONNECTION_OUT && !this->_handshake_handler->has_remote_tp()) {
2093     return -1;
2094   }
2095 
2096   this->_init_flow_control_params(this->_handshake_handler->local_transport_parameters(),
2097                                   this->_handshake_handler->remote_transport_parameters());
2098 
2099   uint64_t ack_delay_exponent =
2100     this->_handshake_handler->remote_transport_parameters()->getAsUInt(QUICTransportParameterId::ACK_DELAY_EXPONENT);
2101   this->_loss_detector->update_ack_delay_exponent(ack_delay_exponent);
2102 
2103   uint64_t max_ack_delay =
2104     this->_handshake_handler->remote_transport_parameters()->getAsUInt(QUICTransportParameterId::MAX_ACK_DELAY);
2105   this->_rtt_measure.set_max_ack_delay(max_ack_delay);
2106 
2107   const uint8_t *reset_token;
2108   uint16_t reset_token_len;
2109   reset_token = this->_handshake_handler->remote_transport_parameters()->getAsBytes(QUICTransportParameterId::STATELESS_RESET_TOKEN,
2110                                                                                     reset_token_len);
2111   if (reset_token) {
2112     this->_rtable->insert({reset_token}, this);
2113   }
2114 
2115   this->_start_application();
2116 
2117   this->_handshake_completed = true;
2118 
2119   return 0;
2120 }
2121 
2122 void
_start_application()2123 QUICNetVConnection::_start_application()
2124 {
2125   if (!this->_application_started) {
2126     this->_application_started = true;
2127 
2128     const uint8_t *app_name;
2129     unsigned int app_name_len = 0;
2130     this->_handshake_handler->negotiated_application_name(&app_name, &app_name_len);
2131     if (app_name == nullptr) {
2132       app_name     = reinterpret_cast<const uint8_t *>(IP_PROTO_TAG_HTTP_QUIC.data());
2133       app_name_len = IP_PROTO_TAG_HTTP_QUIC.size();
2134     }
2135 
2136     this->set_negotiated_protocol_id({reinterpret_cast<const char *>(app_name), static_cast<size_t>(app_name_len)});
2137 
2138     if (netvc_context == NET_VCONNECTION_IN) {
2139       if (!this->setSelectedProtocol(app_name, app_name_len)) {
2140         this->_handle_error(std::make_unique<QUICConnectionError>(QUICTransErrorCode::PROTOCOL_VIOLATION));
2141       } else {
2142         this->endpoint()->handleEvent(NET_EVENT_ACCEPT, this);
2143       }
2144     } else {
2145       this->action_.continuation->handleEvent(NET_EVENT_OPEN, this);
2146     }
2147   }
2148 }
2149 
2150 void
_switch_to_handshake_state()2151 QUICNetVConnection::_switch_to_handshake_state()
2152 {
2153   QUICConDebug("Enter state_handshake");
2154   SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_handshake);
2155 }
2156 
2157 void
_switch_to_established_state()2158 QUICNetVConnection::_switch_to_established_state()
2159 {
2160   if (this->_complete_handshake_if_possible() == 0) {
2161     QUICConDebug("Enter state_connection_established");
2162     QUICConDebug("Negotiated cipher suite: %s", this->_handshake_handler->negotiated_cipher_suite());
2163 
2164     SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_established);
2165 
2166     std::shared_ptr<const QUICTransportParameters> remote_tp = this->_handshake_handler->remote_transport_parameters();
2167     std::shared_ptr<const QUICTransportParameters> local_tp  = this->_handshake_handler->local_transport_parameters();
2168 
2169     uint64_t active_cid_limit = remote_tp->getAsUInt(QUICTransportParameterId::ACTIVE_CONNECTION_ID_LIMIT);
2170     if (active_cid_limit) {
2171       this->_alt_con_manager->set_remote_active_cid_limit(active_cid_limit);
2172     }
2173 
2174     this->set_inactivity_timeout(HRTIME_MSECONDS(std::min(remote_tp->getAsUInt(QUICTransportParameterId::MAX_IDLE_TIMEOUT),
2175                                                           local_tp->getAsUInt(QUICTransportParameterId::MAX_IDLE_TIMEOUT))));
2176 
2177     if (this->direction() == NET_VCONNECTION_OUT) {
2178       uint16_t len;
2179       const uint8_t *pref_addr_buf = remote_tp->getAsBytes(QUICTransportParameterId::PREFERRED_ADDRESS, len);
2180       if (pref_addr_buf) {
2181         this->_alt_con_manager->set_remote_preferred_address({pref_addr_buf, len});
2182       }
2183     } else {
2184       QUICPath trusted_path = {this->local_addr, this->remote_addr};
2185       this->_path_manager->set_trusted_path(trusted_path);
2186     }
2187   } else {
2188     // Illegal state change
2189     ink_assert(!"Handshake has to be completed");
2190   }
2191 }
2192 
2193 void
_switch_to_closing_state(QUICConnectionErrorUPtr error)2194 QUICNetVConnection::_switch_to_closing_state(QUICConnectionErrorUPtr error)
2195 {
2196   if (this->_complete_handshake_if_possible() != 0) {
2197     QUICConDebug("Switching state without handshake completion");
2198   }
2199   if (error->msg) {
2200     QUICConDebug("Reason: %.*s", static_cast<int>(strlen(error->msg)), error->msg);
2201   }
2202 
2203   // Once we are in closing or draining state, the ack_manager is not needed anymore. Because we don't send
2204   // any frame other than close_frame.
2205   this->_unschedule_ack_manager_periodic();
2206 
2207   this->_connection_error = std::move(error);
2208   this->_schedule_packet_write_ready();
2209 
2210   this->remove_from_active_queue();
2211   this->set_inactivity_timeout(0);
2212 
2213   ink_hrtime rto = this->_rtt_measure.current_pto_period();
2214 
2215   QUICConDebug("Enter state_connection_closing");
2216   SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_closing);
2217 
2218   // This states SHOULD persist for three times the
2219   // current Retransmission Timeout (RTO) interval as defined in
2220   // [QUIC-RECOVERY].
2221   this->_schedule_closing_timeout(3 * rto);
2222 }
2223 
2224 void
_switch_to_draining_state(QUICConnectionErrorUPtr error)2225 QUICNetVConnection::_switch_to_draining_state(QUICConnectionErrorUPtr error)
2226 {
2227   if (this->_complete_handshake_if_possible() != 0) {
2228     QUICConDebug("Switching state without handshake completion");
2229   }
2230   if (error->msg) {
2231     QUICConDebug("Reason: %.*s", static_cast<int>(strlen(error->msg)), error->msg);
2232   }
2233 
2234   // Once we are in closing or draining state, the ack_manager is not needed anymore. Because we don't send
2235   // any frame other than close_frame.
2236   this->_unschedule_ack_manager_periodic();
2237 
2238   this->remove_from_active_queue();
2239   this->set_inactivity_timeout(0);
2240 
2241   ink_hrtime rto = this->_rtt_measure.current_pto_period();
2242 
2243   QUICConDebug("Enter state_connection_draining");
2244   SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_draining);
2245 
2246   // This states SHOULD persist for three times the
2247   // current Retransmission Timeout (RTO) interval as defined in
2248   // [QUIC-RECOVERY].
2249 
2250   this->_schedule_closing_timeout(3 * rto);
2251 }
2252 
2253 void
_switch_to_close_state()2254 QUICNetVConnection::_switch_to_close_state()
2255 {
2256   this->_unschedule_closing_timeout();
2257 
2258   if (this->_complete_handshake_if_possible() != 0) {
2259     QUICConDebug("Switching state without handshake completion");
2260   }
2261   QUICConDebug("Enter state_connection_closed");
2262   SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_closed);
2263   this->_schedule_closed_event();
2264 }
2265 
2266 void
_handle_idle_timeout()2267 QUICNetVConnection::_handle_idle_timeout()
2268 {
2269   this->remove_from_active_queue();
2270   this->_switch_to_draining_state(std::make_unique<QUICConnectionError>(QUICTransErrorCode::NO_ERROR, "Idle Timeout"));
2271 
2272   // TODO: signal VC_EVENT_ACTIVE_TIMEOUT/VC_EVENT_INACTIVITY_TIMEOUT to application
2273 }
2274 
2275 void
_handle_active_timeout()2276 QUICNetVConnection::_handle_active_timeout()
2277 {
2278   this->close_quic_connection(std::make_unique<QUICConnectionError>(QUICTransErrorCode::NO_ERROR, "Active Timeout"));
2279 }
2280 
2281 void
_validate_new_path(const QUICPath & path)2282 QUICNetVConnection::_validate_new_path(const QUICPath &path)
2283 {
2284   // Not sure how long we should wait. The spec says just "enough time".
2285   // Use the same time amount as the closing timeout.
2286   ink_hrtime rto = this->_rtt_measure.current_pto_period();
2287   this->_path_manager->open_new_path(path, 3 * rto);
2288 }
2289 
2290 void
_update_cids()2291 QUICNetVConnection::_update_cids()
2292 {
2293   snprintf(this->_cids_data, sizeof(this->_cids_data), "%08" PRIx32 "-%08" PRIx32 "", this->_peer_quic_connection_id.h32(),
2294            this->_quic_connection_id.h32());
2295 
2296   this->_cids = {this->_cids_data, sizeof(this->_cids_data)};
2297 }
2298 
2299 void
_update_peer_cid(const QUICConnectionId & new_cid)2300 QUICNetVConnection::_update_peer_cid(const QUICConnectionId &new_cid)
2301 {
2302   if (is_debug_tag_set(QUIC_DEBUG_TAG.data())) {
2303     QUICConDebug("update peer dcid: %s -> %s", this->_peer_quic_connection_id.hex().c_str(), new_cid.hex().c_str());
2304   }
2305 
2306   this->_peer_old_quic_connection_id = this->_peer_quic_connection_id;
2307   this->_peer_quic_connection_id     = new_cid;
2308   this->_update_cids();
2309 }
2310 
2311 void
_update_local_cid(const QUICConnectionId & new_cid)2312 QUICNetVConnection::_update_local_cid(const QUICConnectionId &new_cid)
2313 {
2314   if (is_debug_tag_set(QUIC_DEBUG_TAG.data())) {
2315     QUICConDebug("update local dcid: %s -> %s", this->_quic_connection_id.hex().c_str(), new_cid.hex().c_str());
2316   }
2317 
2318   this->_quic_connection_id = new_cid;
2319   this->_update_cids();
2320 }
2321 
2322 void
_rerandomize_original_cid()2323 QUICNetVConnection::_rerandomize_original_cid()
2324 {
2325   QUICConnectionId tmp = this->_original_quic_connection_id;
2326   this->_original_quic_connection_id.randomize();
2327 
2328   if (is_debug_tag_set(QUIC_DEBUG_TAG.data())) {
2329     QUICConDebug("original cid: %s -> %s", tmp.hex().c_str(), this->_original_quic_connection_id.hex().c_str());
2330   }
2331 }
2332 
2333 QUICHandshakeProtocol *
_setup_handshake_protocol(const shared_SSL_CTX & ctx)2334 QUICNetVConnection::_setup_handshake_protocol(const shared_SSL_CTX &ctx)
2335 {
2336   // Initialize handshake protocol specific stuff
2337   // For QUICv1 TLS is the only option
2338   QUICTLS *tls = new QUICTLS(this->_pp_key_info, ctx.get(), this->direction(), this->options,
2339                              this->_quic_config->client_session_file(), this->_quic_config->client_keylog_file());
2340   SSL_set_ex_data(tls->ssl_handle(), QUIC::ssl_quic_qc_index, static_cast<QUICConnection *>(this));
2341   TLSSessionResumptionSupport::bind(tls->ssl_handle(), this);
2342 
2343   return tls;
2344 }
2345 
2346 QUICConnectionErrorUPtr
_state_connection_established_migrate_connection(const QUICPacketR & p)2347 QUICNetVConnection::_state_connection_established_migrate_connection(const QUICPacketR &p)
2348 {
2349   ink_assert(this->_handshake_handler->is_completed());
2350 
2351   QUICConnectionErrorUPtr error = nullptr;
2352   QUICConnectionId dcid         = p.destination_cid();
2353 
2354   if (this->netvc_context == NET_VCONNECTION_IN) {
2355     QUICConDebug("Connection migration is initiated by remote");
2356   }
2357 
2358   if (this->connection_id() == dcid) {
2359     QUICConDebug("Maybe NAT rebinding");
2360     // On client side (NET_VCONNECTION_OUT), nothing to do any more
2361     if (this->netvc_context == NET_VCONNECTION_IN) {
2362       Connection con;
2363       con.setRemote(&(p.from().sa));
2364       this->con.move(con);
2365       this->set_remote_addr();
2366       this->_udp_con        = p.udp_con();
2367       this->_packet_handler = static_cast<QUICPacketHandlerIn *>(
2368         static_cast<NetAccept *>(static_cast<UnixUDPConnection *>(this->_udp_con)->continuation));
2369 
2370       QUICPath new_path = {p.to(), p.from()};
2371       this->_validate_new_path(new_path);
2372     }
2373   } else {
2374     QUICConDebug("Different CID");
2375     if (!this->_alt_con_manager->is_ready_to_migrate()) {
2376       QUICConDebug("Ignore connection migration - remote endpoint initiated CM before sending NEW_CONNECTION_ID frames");
2377       return error;
2378     }
2379 
2380     if (this->_alt_con_manager->migrate_to(dcid, this->_reset_token)) {
2381       // DCID of received packet is local cid
2382       this->_update_local_cid(dcid);
2383 
2384       // On client side (NET_VCONNECTION_OUT), nothing to do any more
2385       if (this->netvc_context == NET_VCONNECTION_IN) {
2386         Connection con;
2387         con.setRemote(&(p.from().sa));
2388         this->con.move(con);
2389         this->set_remote_addr();
2390         this->_udp_con        = p.udp_con();
2391         this->_packet_handler = static_cast<QUICPacketHandlerIn *>(
2392           static_cast<NetAccept *>(static_cast<UnixUDPConnection *>(this->_udp_con)->continuation));
2393 
2394         this->_update_peer_cid(this->_alt_con_manager->migrate_to_alt_cid());
2395 
2396         QUICPath new_path = {p.to(), p.from()};
2397         this->_validate_new_path(new_path);
2398       }
2399     } else {
2400       QUICConDebug("Connection migration failed cid=%s", dcid.hex().c_str());
2401     }
2402   }
2403 
2404   return error;
2405 }
2406 
2407 /**
2408  * Connection Migration Exercise from client
2409  */
2410 QUICConnectionErrorUPtr
_state_connection_established_initiate_connection_migration()2411 QUICNetVConnection::_state_connection_established_initiate_connection_migration()
2412 {
2413   ink_assert(this->_handshake_handler->is_completed());
2414   ink_assert(this->netvc_context == NET_VCONNECTION_OUT);
2415 
2416   QUICConnectionErrorUPtr error = nullptr;
2417 
2418   std::shared_ptr<const QUICTransportParameters> remote_tp = this->_handshake_handler->remote_transport_parameters();
2419 
2420   if (this->_connection_migration_initiated || remote_tp->contains(QUICTransportParameterId::DISABLE_ACTIVE_MIGRATION) ||
2421       !this->_alt_con_manager->is_ready_to_migrate() ||
2422       this->_alt_con_manager->will_generate_frame(QUICEncryptionLevel::ONE_RTT, 0, true, this->_seq_num++)) {
2423     return error;
2424   }
2425 
2426   QUICConDebug("Initiated connection migration");
2427   this->_connection_migration_initiated = true;
2428 
2429   this->_update_peer_cid(this->_alt_con_manager->migrate_to_alt_cid());
2430 
2431   auto current_path = this->_path_manager->get_verified_path();
2432   QUICPath new_path = {current_path.local_ep(), current_path.remote_ep()};
2433   this->_validate_new_path(new_path);
2434 
2435   return error;
2436 }
2437 
2438 void
_handle_periodic_ack_event()2439 QUICNetVConnection::_handle_periodic_ack_event()
2440 {
2441   bool need_schedule = false;
2442   for (int i = static_cast<int>(this->_minimum_encryption_level); i <= static_cast<int>(QUICEncryptionLevel::ONE_RTT); ++i) {
2443     if (this->_ack_frame_manager.will_generate_frame(QUIC_ENCRYPTION_LEVELS[i], 0, true, this->_seq_num++)) {
2444       need_schedule = true;
2445       break;
2446     }
2447   }
2448 
2449   if (need_schedule) {
2450     // we have ack to send
2451     // FIXME: should sent depend on socket event.
2452     this->_schedule_packet_write_ready();
2453   }
2454 }
2455 
2456 const IpEndpoint &
_getLocalEndpoint()2457 QUICNetVConnection::_getLocalEndpoint()
2458 {
2459   return local_addr;
2460 }
2461