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