This is an automated email from the ASF dual-hosted git repository. masaori pushed a commit to branch quic-latest in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/quic-latest by this push: new f04b6b5 Add APPLICATION_CLOSE frame and change Error Code f04b6b5 is described below commit f04b6b5939cd3f59e0a0de4bbd7302112bdcf8cc Author: Masaori Koshiba <masa...@apache.org> AuthorDate: Wed Nov 15 14:15:40 2017 +0900 Add APPLICATION_CLOSE frame and change Error Code --- iocore/net/QUICNetVConnection.cc | 29 ++-- iocore/net/quic/QUICDebugNames.cc | 54 +++----- iocore/net/quic/QUICDebugNames.h | 2 +- iocore/net/quic/QUICFlowController.cc | 2 +- iocore/net/quic/QUICFrame.cc | 152 +++++++++++++++++---- iocore/net/quic/QUICFrame.h | 66 +++++++-- iocore/net/quic/QUICHandshake.cc | 17 +-- iocore/net/quic/QUICIncomingFrameBuffer.cc | 6 +- iocore/net/quic/QUICStream.cc | 12 +- iocore/net/quic/QUICStreamManager.cc | 8 +- iocore/net/quic/QUICTypes.cc | 28 +++- iocore/net/quic/QUICTypes.h | 67 +++++---- iocore/net/quic/test/test_QUICFlowController.cc | 6 +- iocore/net/quic/test/test_QUICFrame.cc | 134 +++++++++++++----- .../net/quic/test/test_QUICIncomingFrameBuffer.cc | 6 +- iocore/net/quic/test/test_QUICStream.cc | 3 +- iocore/net/quic/test/test_QUICStreamManager.cc | 3 +- iocore/net/quic/test/test_QUICStreamState.cc | 8 +- 18 files changed, 416 insertions(+), 187 deletions(-) diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc index 7a4c457..29833c6 100644 --- a/iocore/net/QUICNetVConnection.cc +++ b/iocore/net/QUICNetVConnection.cc @@ -301,7 +301,11 @@ QUICNetVConnection::close(QUICConnectionErrorUPtr error) } else { DebugQUICCon("Enter state_connection_closing"); SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_closing); - this->transmit_frame(QUICFrameFactory::create_connection_close_frame(std::move(error))); + if (error->cls == QUICErrorClass::APPLICATION) { + this->transmit_frame(QUICFrameFactory::create_application_close_frame(std::move(error))); + } else { + this->transmit_frame(QUICFrameFactory::create_connection_close_frame(std::move(error))); + } } } @@ -403,7 +407,7 @@ QUICNetVConnection::state_handshake(int event, Event *data) this_ethread()->schedule_imm_local(this, event); break; default: - error = QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::INTERNAL_ERROR)); + error = QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::INTERNAL_ERROR)); break; } @@ -450,8 +454,7 @@ QUICNetVConnection::state_handshake(int event, Event *data) Continuation *endpoint = this->_next_protocol_set->findEndpoint(app_name, app_name_len); if (endpoint == nullptr) { - this->_handle_error( - QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::CRYPTOGRAPHIC, QUICErrorCode::VERSION_NEGOTIATION_ERROR))); + this->_handle_error(QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::VERSION_NEGOTIATION_ERROR))); } else { endpoint->handleEvent(NET_EVENT_ACCEPT, this); } @@ -489,7 +492,7 @@ QUICNetVConnection::state_connection_established(int event, Event *data) } if (error->cls != QUICErrorClass::NONE) { - DebugQUICCon("QUICError: cls=%u, code=0x%x", static_cast<unsigned int>(error->cls), static_cast<unsigned int>(error->code)); + DebugQUICCon("QUICError: cls=%u, code=0x%" PRIu16, static_cast<unsigned int>(error->cls), error->code()); this->_handle_error(std::move(error)); } @@ -708,8 +711,8 @@ QUICNetVConnection::_state_connection_established_process_packet(QUICPacketUPtr packet->header_size(), plain_txt_len); return this->_recv_and_ack(plain_txt.get(), plain_txt_len, packet->packet_number()); } else { - DebugQUICCon("CRYPTOGRAPHIC Error"); - return QUICConnectionErrorUPtr(new QUICConnectionError(QUICErrorClass::CRYPTOGRAPHIC, QUICErrorCode::CRYPTOGRAPHIC_ERROR)); + DebugQUICCon("Decrypt Error"); + return QUICConnectionErrorUPtr(new QUICConnectionError(QUICTransErrorCode::TLS_FATAL_ALERT_GENERATED)); } } @@ -732,7 +735,7 @@ QUICNetVConnection::_state_common_receive_packet() // FIXME Just ignore for now but it has to be acked (GitHub#2609) break; default: - error = QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::INTERNAL_ERROR)); + error = QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::INTERNAL_ERROR)); break; } return error; @@ -941,8 +944,14 @@ QUICNetVConnection::_init_flow_control_params(const std::shared_ptr<const QUICTr void QUICNetVConnection::_handle_error(QUICErrorUPtr error) { - DebugQUICCon("QUICError: %s (%u), %s (0x%x)", QUICDebugNames::error_class(error->cls), static_cast<unsigned int>(error->cls), - QUICDebugNames::error_code(error->code), static_cast<unsigned int>(error->code)); + if (error->cls == QUICErrorClass::APPLICATION) { + DebugQUICCon("QUICError: %s (%u), APPLICATION ERROR (0x%" PRIu16 ")", QUICDebugNames::error_class(error->cls), + static_cast<unsigned int>(error->cls), error->code()); + } else { + DebugQUICCon("QUICError: %s (%u), %s (0x%" PRIu16 ")", QUICDebugNames::error_class(error->cls), + static_cast<unsigned int>(error->cls), QUICDebugNames::error_code(error->trans_error_code), error->code()); + } + if (dynamic_cast<QUICStreamError *>(error.get()) != nullptr) { // Stream Error QUICStreamError *serror = static_cast<QUICStreamError *>(error.release()); diff --git a/iocore/net/quic/QUICDebugNames.cc b/iocore/net/quic/QUICDebugNames.cc index 5526d2d..7e4fd44 100644 --- a/iocore/net/quic/QUICDebugNames.cc +++ b/iocore/net/quic/QUICDebugNames.cc @@ -94,58 +94,48 @@ QUICDebugNames::error_class(QUICErrorClass cls) switch (cls) { case QUICErrorClass::NONE: return "NONE"; - case QUICErrorClass::AQPPLICATION_SPECIFIC: - return "AQPPLICATION_SPECIFIC"; - case QUICErrorClass::HOST_LOCAL: - return "HOST_LOCAL"; - case QUICErrorClass::QUIC_TRANSPORT: - return "QUIC_TRANSPORT"; - case QUICErrorClass::CRYPTOGRAPHIC: - return "CRYPTOGRAPHIC"; + case QUICErrorClass::TRANSPORT: + return "TRANSPORT"; + case QUICErrorClass::APPLICATION: + return "APPLICATION"; default: return "UNKNOWN"; } } const char * -QUICDebugNames::error_code(QUICErrorCode code) +QUICDebugNames::error_code(QUICTransErrorCode code) { switch (code) { - case QUICErrorCode::APPLICATION_SPECIFIC_ERROR: - return "APPLICATION_SPECIFIC_ERROR"; - case QUICErrorCode::HOST_LOCAL_ERROR: - return "HOST_LOCAL_ERROR"; - case QUICErrorCode::NO_ERROR: + case QUICTransErrorCode::NO_ERROR: return "NO_ERROR"; - case QUICErrorCode::INTERNAL_ERROR: + case QUICTransErrorCode::INTERNAL_ERROR: return "INTERNAL_ERROR"; - case QUICErrorCode::CANCELLED: - return "CANCELLED"; - case QUICErrorCode::FLOW_CONTROL_ERROR: + case QUICTransErrorCode::FLOW_CONTROL_ERROR: return "FLOW_CONTROL_ERROR"; - case QUICErrorCode::STREAM_ID_ERROR: + case QUICTransErrorCode::STREAM_ID_ERROR: return "STREAM_ID_ERROR"; - case QUICErrorCode::STREAM_STATE_ERROR: + case QUICTransErrorCode::STREAM_STATE_ERROR: return "STREAM_STATE_ERROR"; - case QUICErrorCode::FINAL_OFFSET_ERROR: + case QUICTransErrorCode::FINAL_OFFSET_ERROR: return "FINAL_OFFSET_ERROR"; - case QUICErrorCode::FRAME_FORMAT_ERROR: + case QUICTransErrorCode::FRAME_FORMAT_ERROR: return "FRAME_FORMAT_ERROR"; - case QUICErrorCode::TRANSPORT_PARAMETER_ERROR: + case QUICTransErrorCode::TRANSPORT_PARAMETER_ERROR: return "TRANSPORT_PARAMETER_ERROR"; - case QUICErrorCode::VERSION_NEGOTIATION_ERROR: + case QUICTransErrorCode::VERSION_NEGOTIATION_ERROR: return "VERSION_NEGOTIATION_ERROR"; - case QUICErrorCode::PROTOCOL_VIOLATION: + case QUICTransErrorCode::PROTOCOL_VIOLATION: return "PROTOCOL_VIOLATION"; - case QUICErrorCode::QUIC_RECEIVED_RST: - return "QUIC_RECEIVED_RST"; - case QUICErrorCode::CRYPTOGRAPHIC_ERROR: - return "CRYPTOGRAPHIC_ERROR"; - case QUICErrorCode::TLS_HANDSHAKE_FAILED: + case QUICTransErrorCode::TLS_HANDSHAKE_FAILED: return "TLS_HANDSHAKE_FAILED"; + case QUICTransErrorCode::TLS_FATAL_ALERT_GENERATED: + return "TLS_FATAL_ALERT_GENERATED"; + case QUICTransErrorCode::TLS_FATAL_ALERT_RECEIVED: + return "TLS_FATAL_ALERT_RECEIVED"; default: - if ((static_cast<uint32_t>(code) & 0xFFFFFF00) == static_cast<uint32_t>(QUICErrorCode::FRAME_ERROR)) { - // TODO: Add frame type + if (0x0100 <= static_cast<uint16_t>(code) && static_cast<uint16_t>(code) <= 0x01FF) { + // TODO: Add frame types return "FRAME_ERROR"; } return "UNKNOWN"; diff --git a/iocore/net/quic/QUICDebugNames.h b/iocore/net/quic/QUICDebugNames.h index 7b406d4..8ccac29 100644 --- a/iocore/net/quic/QUICDebugNames.h +++ b/iocore/net/quic/QUICDebugNames.h @@ -34,7 +34,7 @@ public: static const char *packet_type(QUICPacketType type); static const char *frame_type(QUICFrameType type); static const char *error_class(QUICErrorClass cls); - static const char *error_code(QUICErrorCode code); + static const char *error_code(QUICTransErrorCode code); static const char *transport_parameter_id(QUICTransportParameterId id); static const char *stream_state(QUICStreamState state); static const char *quic_event(int event); diff --git a/iocore/net/quic/QUICFlowController.cc b/iocore/net/quic/QUICFlowController.cc index 18deeea..6c497aa 100644 --- a/iocore/net/quic/QUICFlowController.cc +++ b/iocore/net/quic/QUICFlowController.cc @@ -46,7 +46,7 @@ QUICFlowController::update(QUICOffset offset) if (this->_offset <= offset) { // Assume flow control is not initialized if the limit was 0 if (this->_limit != 0 && offset > this->_limit) { - return QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::FLOW_CONTROL_ERROR)); + return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::FLOW_CONTROL_ERROR)); } this->_offset = offset; } diff --git a/iocore/net/quic/QUICFrame.cc b/iocore/net/quic/QUICFrame.cc index 4bb02b4..4fb864b 100644 --- a/iocore/net/quic/QUICFrame.cc +++ b/iocore/net/quic/QUICFrame.cc @@ -29,6 +29,7 @@ ClassAllocator<QUICAckFrame> quicAckFrameAllocator("quicAckFrameAllocator"); ClassAllocator<QUICPaddingFrame> quicPaddingFrameAllocator("quicPaddingFrameAllocator"); ClassAllocator<QUICRstStreamFrame> quicRstStreamFrameAllocator("quicRstStreamFrameAllocator"); ClassAllocator<QUICConnectionCloseFrame> quicConnectionCloseFrameAllocator("quicConnectionCloseFrameAllocator"); +ClassAllocator<QUICApplicationCloseFrame> quicApplicationCloseFrameAllocator("quicApplicationCloseFrameAllocator"); ClassAllocator<QUICMaxDataFrame> quicMaxDataFrameAllocator("quicMaxDataFrameAllocator"); ClassAllocator<QUICMaxStreamDataFrame> quicMaxStreamDataFrameAllocator("quicMaxStreamDataFrameAllocator"); ClassAllocator<QUICMaxStreamIdFrame> quicMaxStreamIdFrameAllocator("quicMaxStreamDataIdAllocator"); @@ -46,7 +47,6 @@ QUICFrame::type() const return QUICFrame::type(this->_buf); } -// XXX QUICFrameType: 0x03 (GOAWAY frame) is removed QUICFrameType QUICFrame::type(const uint8_t *buf) { @@ -54,7 +54,7 @@ QUICFrame::type(const uint8_t *buf) return QUICFrameType::STREAM; } else if (buf[0] >= static_cast<uint8_t>(QUICFrameType::ACK)) { return QUICFrameType::ACK; - } else if (buf[0] > static_cast<uint8_t>(QUICFrameType::STOP_SENDING) || buf[0] == 0x03) { + } else if (buf[0] > static_cast<uint8_t>(QUICFrameType::STOP_SENDING)) { return QUICFrameType::UNKNOWN; } else { return static_cast<QUICFrameType>(buf[0]); @@ -664,7 +664,7 @@ QUICAckFrame::TimestampSection::store(uint8_t *buf, size_t *len) const // RST_STREAM frame // -QUICRstStreamFrame::QUICRstStreamFrame(QUICStreamId stream_id, QUICErrorCode error_code, QUICOffset final_offset) +QUICRstStreamFrame::QUICRstStreamFrame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICOffset final_offset) : _stream_id(stream_id), _error_code(error_code), _final_offset(final_offset) { } @@ -675,10 +675,11 @@ QUICRstStreamFrame::type() const return QUICFrameType::RST_STREAM; } +// 8 + 32 + 16 + 64 bit size_t QUICRstStreamFrame::size() const { - return 17; + return 15; } void @@ -690,7 +691,7 @@ QUICRstStreamFrame::store(uint8_t *buf, size_t *len) const ++p; QUICTypeUtil::write_QUICStreamId(this->_stream_id, 4, p, &n); p += n; - QUICTypeUtil::write_QUICErrorCode(this->_error_code, p, &n); + QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, p, &n); p += n; QUICTypeUtil::write_QUICOffset(this->_final_offset, 8, p, &n); p += n; @@ -698,11 +699,11 @@ QUICRstStreamFrame::store(uint8_t *buf, size_t *len) const *len = p - buf; } -QUICErrorCode +QUICAppErrorCode QUICRstStreamFrame::error_code() const { if (this->_buf) { - return QUICTypeUtil::read_QUICErrorCode(this->_buf + 5); + return QUICTypeUtil::read_QUICAppErrorCode(this->_buf + 5); } else { return this->_error_code; } @@ -722,7 +723,7 @@ QUICOffset QUICRstStreamFrame::final_offset() const { if (this->_buf) { - return QUICTypeUtil::read_QUICOffset(this->_buf + 9, 8); + return QUICTypeUtil::read_QUICOffset(this->_buf + 7, 8); } else { return this->_final_offset; } @@ -775,8 +776,7 @@ QUICPaddingFrame::store(uint8_t *buf, size_t *len) const // // CONNECTION_CLOSE frame // - -QUICConnectionCloseFrame::QUICConnectionCloseFrame(QUICErrorCode error_code, uint16_t reason_phrase_length, +QUICConnectionCloseFrame::QUICConnectionCloseFrame(QUICTransErrorCode error_code, uint16_t reason_phrase_length, const char *reason_phrase) { this->_error_code = error_code; @@ -793,7 +793,7 @@ QUICConnectionCloseFrame::type() const size_t QUICConnectionCloseFrame::size() const { - return 7 + this->reason_phrase_length(); + return 5 + this->reason_phrase_length(); } void @@ -803,7 +803,7 @@ QUICConnectionCloseFrame::store(uint8_t *buf, size_t *len) const uint8_t *p = buf; *p = static_cast<uint8_t>(QUICFrameType::CONNECTION_CLOSE); ++p; - QUICTypeUtil::write_QUICErrorCode(this->_error_code, p, &n); + QUICTypeUtil::write_QUICTransErrorCode(this->_error_code, p, &n); p += n; QUICTypeUtil::write_uint_as_nbytes(this->_reason_phrase_length, 2, p, &n); p += n; @@ -815,11 +815,11 @@ QUICConnectionCloseFrame::store(uint8_t *buf, size_t *len) const *len = p - buf; } -QUICErrorCode +QUICTransErrorCode QUICConnectionCloseFrame::error_code() const { if (this->_buf) { - return QUICTypeUtil::read_QUICErrorCode(this->_buf + 1); + return QUICTypeUtil::read_QUICTransErrorCode(this->_buf + 1); } else { return this->_error_code; } @@ -829,7 +829,7 @@ uint16_t QUICConnectionCloseFrame::reason_phrase_length() const { if (this->_buf) { - return QUICTypeUtil::read_nbytes_as_uint(this->_buf + 5, 2); + return QUICTypeUtil::read_nbytes_as_uint(this->_buf + 3, 2); } else { return this->_reason_phrase_length; } @@ -839,7 +839,79 @@ const char * QUICConnectionCloseFrame::reason_phrase() const { if (this->_buf) { - return reinterpret_cast<const char *>(this->_buf + 7); + return reinterpret_cast<const char *>(this->_buf + 5); + } else { + return this->_reason_phrase; + } +} + +// +// APPLICATION_CLOSE frame +// +QUICApplicationCloseFrame::QUICApplicationCloseFrame(QUICAppErrorCode error_code, uint16_t reason_phrase_length, + const char *reason_phrase) +{ + this->_error_code = error_code; + this->_reason_phrase_length = reason_phrase_length; + this->_reason_phrase = reason_phrase; +} + +QUICFrameType +QUICApplicationCloseFrame::type() const +{ + return QUICFrameType::APPLICATION_CLOSE; +} + +size_t +QUICApplicationCloseFrame::size() const +{ + return 5 + this->reason_phrase_length(); +} + +void +QUICApplicationCloseFrame::store(uint8_t *buf, size_t *len) const +{ + size_t n; + uint8_t *p = buf; + *p = static_cast<uint8_t>(QUICFrameType::APPLICATION_CLOSE); + ++p; + QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, p, &n); + p += n; + QUICTypeUtil::write_uint_as_nbytes(this->_reason_phrase_length, 2, p, &n); + p += n; + if (this->_reason_phrase_length > 0) { + memcpy(p, this->_reason_phrase, this->_reason_phrase_length); + p += this->_reason_phrase_length; + } + + *len = p - buf; +} + +QUICAppErrorCode +QUICApplicationCloseFrame::error_code() const +{ + if (this->_buf) { + return QUICTypeUtil::read_QUICAppErrorCode(this->_buf + 1); + } else { + return this->_error_code; + } +} + +uint16_t +QUICApplicationCloseFrame::reason_phrase_length() const +{ + if (this->_buf) { + return QUICTypeUtil::read_nbytes_as_uint(this->_buf + 3, 2); + } else { + return this->_reason_phrase_length; + } +} + +const char * +QUICApplicationCloseFrame::reason_phrase() const +{ + if (this->_buf) { + return reinterpret_cast<const char *>(this->_buf + 5); } else { return this->_reason_phrase; } @@ -1135,7 +1207,7 @@ QUICNewConnectionIdFrame::connection_id() const // STOP_SENDING frame // -QUICStopSendingFrame::QUICStopSendingFrame(QUICStreamId stream_id, QUICErrorCode error_code) +QUICStopSendingFrame::QUICStopSendingFrame(QUICStreamId stream_id, QUICAppErrorCode error_code) : _stream_id(stream_id), _error_code(error_code) { } @@ -1149,7 +1221,7 @@ QUICStopSendingFrame::type() const size_t QUICStopSendingFrame::size() const { - return 9; + return 7; } void @@ -1161,17 +1233,17 @@ QUICStopSendingFrame::store(uint8_t *buf, size_t *len) const ++p; QUICTypeUtil::write_QUICStreamId(this->_stream_id, 4, p, &n); p += n; - QUICTypeUtil::write_QUICErrorCode(this->_error_code, p, &n); + QUICTypeUtil::write_QUICAppErrorCode(this->_error_code, p, &n); p += n; *len = p - buf; } -QUICErrorCode +QUICAppErrorCode QUICStopSendingFrame::error_code() const { if (this->_buf) { - return QUICTypeUtil::read_QUICErrorCode(this->_buf + 5); + return QUICTypeUtil::read_QUICAppErrorCode(this->_buf + 5); } else { return this->_error_code; } @@ -1249,6 +1321,10 @@ QUICFrameFactory::create(const uint8_t *buf, size_t len) frame = quicConnectionCloseFrameAllocator.alloc(); new (frame) QUICConnectionCloseFrame(buf, len); return QUICFrameUPtr(frame, &QUICFrameDeleter::delete_connection_close_frame); + case QUICFrameType::APPLICATION_CLOSE: + frame = quicApplicationCloseFrameAllocator.alloc(); + new (frame) QUICApplicationCloseFrame(buf, len); + return QUICFrameUPtr(frame, &QUICFrameDeleter::delete_application_close_frame); case QUICFrameType::MAX_DATA: frame = quicMaxDataFrameAllocator.alloc(); new (frame) QUICMaxDataFrame(buf, len); @@ -1332,7 +1408,8 @@ QUICFrameFactory::create_ack_frame(QUICPacketNumber largest_acknowledged, uint16 } std::unique_ptr<QUICConnectionCloseFrame, QUICFrameDeleterFunc> -QUICFrameFactory::create_connection_close_frame(QUICErrorCode error_code, uint16_t reason_phrase_length, const char *reason_phrase) +QUICFrameFactory::create_connection_close_frame(QUICTransErrorCode error_code, uint16_t reason_phrase_length, + const char *reason_phrase) { QUICConnectionCloseFrame *frame = quicConnectionCloseFrameAllocator.alloc(); new (frame) QUICConnectionCloseFrame(error_code, reason_phrase_length, reason_phrase); @@ -1342,10 +1419,31 @@ QUICFrameFactory::create_connection_close_frame(QUICErrorCode error_code, uint16 std::unique_ptr<QUICConnectionCloseFrame, QUICFrameDeleterFunc> QUICFrameFactory::create_connection_close_frame(QUICConnectionErrorUPtr error) { + ink_assert(error->cls == QUICErrorClass::TRANSPORT); + if (error->msg) { + return QUICFrameFactory::create_connection_close_frame(error->trans_error_code, strlen(error->msg), error->msg); + } else { + return QUICFrameFactory::create_connection_close_frame(error->trans_error_code); + } +} + +std::unique_ptr<QUICApplicationCloseFrame, QUICFrameDeleterFunc> +QUICFrameFactory::create_application_close_frame(QUICAppErrorCode error_code, uint16_t reason_phrase_length, + const char *reason_phrase) +{ + QUICApplicationCloseFrame *frame = quicApplicationCloseFrameAllocator.alloc(); + new (frame) QUICApplicationCloseFrame(error_code, reason_phrase_length, reason_phrase); + return std::unique_ptr<QUICApplicationCloseFrame, QUICFrameDeleterFunc>(frame, &QUICFrameDeleter::delete_connection_close_frame); +} + +std::unique_ptr<QUICApplicationCloseFrame, QUICFrameDeleterFunc> +QUICFrameFactory::create_application_close_frame(QUICConnectionErrorUPtr error) +{ + ink_assert(error->cls == QUICErrorClass::APPLICATION); if (error->msg) { - return QUICFrameFactory::create_connection_close_frame(error->code, strlen(error->msg), error->msg); + return QUICFrameFactory::create_application_close_frame(error->app_error_code, strlen(error->msg), error->msg); } else { - return QUICFrameFactory::create_connection_close_frame(error->code); + return QUICFrameFactory::create_application_close_frame(error->app_error_code); } } @@ -1382,7 +1480,7 @@ QUICFrameFactory::create_stream_blocked_frame(QUICStreamId stream_id) } std::unique_ptr<QUICRstStreamFrame, QUICFrameDeleterFunc> -QUICFrameFactory::create_rst_stream_frame(QUICStreamId stream_id, QUICErrorCode error_code, QUICOffset final_offset) +QUICFrameFactory::create_rst_stream_frame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICOffset final_offset) { QUICRstStreamFrame *frame = quicRstStreamFrameAllocator.alloc(); new (frame) QUICRstStreamFrame(stream_id, error_code, final_offset); @@ -1392,11 +1490,11 @@ QUICFrameFactory::create_rst_stream_frame(QUICStreamId stream_id, QUICErrorCode std::unique_ptr<QUICRstStreamFrame, QUICFrameDeleterFunc> QUICFrameFactory::create_rst_stream_frame(QUICStreamErrorUPtr error) { - return QUICFrameFactory::create_rst_stream_frame(error->stream->id(), error->code, error->stream->final_offset()); + return QUICFrameFactory::create_rst_stream_frame(error->stream->id(), error->app_error_code, error->stream->final_offset()); } std::unique_ptr<QUICStopSendingFrame, QUICFrameDeleterFunc> -QUICFrameFactory::create_stop_sending_frame(QUICStreamId stream_id, QUICErrorCode error_code) +QUICFrameFactory::create_stop_sending_frame(QUICStreamId stream_id, QUICAppErrorCode error_code) { QUICStopSendingFrame *frame = quicStopSendingFrameAllocator.alloc(); new (frame) QUICStopSendingFrame(stream_id, error_code); diff --git a/iocore/net/quic/QUICFrame.h b/iocore/net/quic/QUICFrame.h index dad9a6c..87509aa 100644 --- a/iocore/net/quic/QUICFrame.h +++ b/iocore/net/quic/QUICFrame.h @@ -219,18 +219,18 @@ class QUICRstStreamFrame : public QUICFrame public: QUICRstStreamFrame() : QUICFrame() {} QUICRstStreamFrame(const uint8_t *buf, size_t len) : QUICFrame(buf, len) {} - QUICRstStreamFrame(QUICStreamId stream_id, QUICErrorCode error_code, QUICOffset final_offset); + QUICRstStreamFrame(QUICStreamId stream_id, QUICAppErrorCode error_code, QUICOffset final_offset); virtual QUICFrameType type() const override; virtual size_t size() const override; virtual void store(uint8_t *buf, size_t *len) const override; - QUICErrorCode error_code() const; + QUICAppErrorCode error_code() const; QUICStreamId stream_id() const; QUICOffset final_offset() const; private: - QUICStreamId _stream_id = 0; - QUICErrorCode _error_code; - QUICOffset _final_offset = 0; + QUICStreamId _stream_id = 0; + QUICAppErrorCode _error_code = 0; + QUICOffset _final_offset = 0; }; // @@ -268,16 +268,39 @@ class QUICConnectionCloseFrame : public QUICFrame public: QUICConnectionCloseFrame() : QUICFrame() {} QUICConnectionCloseFrame(const uint8_t *buf, size_t len) : QUICFrame(buf, len) {} - QUICConnectionCloseFrame(QUICErrorCode error_code, uint16_t reason_phrase_length, const char *reason_phrase); + QUICConnectionCloseFrame(QUICTransErrorCode error_code, uint16_t reason_phrase_length, const char *reason_phrase); virtual QUICFrameType type() const override; virtual size_t size() const override; virtual void store(uint8_t *buf, size_t *len) const override; - QUICErrorCode error_code() const; + QUICTransErrorCode error_code() const; uint16_t reason_phrase_length() const; const char *reason_phrase() const; private: - QUICErrorCode _error_code; + QUICTransErrorCode _error_code; + uint16_t _reason_phrase_length = 0; + const char *_reason_phrase = nullptr; +}; + +// +// APPLICATION_CLOSE +// + +class QUICApplicationCloseFrame : public QUICFrame +{ +public: + QUICApplicationCloseFrame() : QUICFrame() {} + QUICApplicationCloseFrame(const uint8_t *buf, size_t len) : QUICFrame(buf, len) {} + QUICApplicationCloseFrame(QUICAppErrorCode error_code, uint16_t reason_phrase_length, const char *reason_phrase); + virtual QUICFrameType type() const override; + virtual size_t size() const override; + virtual void store(uint8_t *buf, size_t *len) const override; + QUICAppErrorCode error_code() const; + uint16_t reason_phrase_length() const; + const char *reason_phrase() const; + +private: + QUICAppErrorCode _error_code = 0; uint16_t _reason_phrase_length = 0; const char *_reason_phrase = nullptr; }; @@ -416,16 +439,16 @@ class QUICStopSendingFrame : public QUICFrame public: QUICStopSendingFrame() : QUICFrame() {} QUICStopSendingFrame(const uint8_t *buf, size_t len) : QUICFrame(buf, len) {} - QUICStopSendingFrame(QUICStreamId stream_id, QUICErrorCode error_code); + QUICStopSendingFrame(QUICStreamId stream_id, QUICAppErrorCode error_code); virtual QUICFrameType type() const override; virtual size_t size() const override; virtual void store(uint8_t *buf, size_t *len) const override; QUICStreamId stream_id() const; - QUICErrorCode error_code() const; + QUICAppErrorCode error_code() const; private: QUICStreamId _stream_id = 0; - QUICErrorCode _error_code; + QUICAppErrorCode _error_code; }; using QUICFrameDeleterFunc = void (*)(QUICFrame *p); @@ -457,6 +480,7 @@ extern ClassAllocator<QUICAckFrame> quicAckFrameAllocator; extern ClassAllocator<QUICPaddingFrame> quicPaddingFrameAllocator; extern ClassAllocator<QUICRstStreamFrame> quicRstStreamFrameAllocator; extern ClassAllocator<QUICConnectionCloseFrame> quicConnectionCloseFrameAllocator; +extern ClassAllocator<QUICApplicationCloseFrame> quicApplicationCloseFrameAllocator; extern ClassAllocator<QUICMaxDataFrame> quicMaxDataFrameAllocator; extern ClassAllocator<QUICMaxStreamDataFrame> quicMaxStreamDataFrameAllocator; extern ClassAllocator<QUICMaxStreamIdFrame> quicMaxStreamIdFrameAllocator; @@ -509,6 +533,12 @@ public: } static void + delete_application_close_frame(QUICFrame *frame) + { + quicApplicationCloseFrameAllocator.free(static_cast<QUICApplicationCloseFrame *>(frame)); + } + + static void delete_max_data_frame(QUICFrame *frame) { quicMaxDataFrameAllocator.free(static_cast<QUICMaxDataFrame *>(frame)); @@ -603,11 +633,19 @@ public: * Creates a CONNECTION_CLOSE frame. */ static std::unique_ptr<QUICConnectionCloseFrame, QUICFrameDeleterFunc> create_connection_close_frame( - QUICErrorCode error_code, uint16_t reason_phrase_length = 0, const char *reason_phrase = nullptr); + QUICTransErrorCode error_code, uint16_t reason_phrase_length = 0, const char *reason_phrase = nullptr); static std::unique_ptr<QUICConnectionCloseFrame, QUICFrameDeleterFunc> create_connection_close_frame( QUICConnectionErrorUPtr error); /* + * Creates a APPLICATION_CLOSE frame. + */ + static std::unique_ptr<QUICApplicationCloseFrame, QUICFrameDeleterFunc> create_application_close_frame( + QUICAppErrorCode error_code, uint16_t reason_phrase_length = 0, const char *reason_phrase = nullptr); + static std::unique_ptr<QUICApplicationCloseFrame, QUICFrameDeleterFunc> create_application_close_frame( + QUICConnectionErrorUPtr error); + + /* * Creates a MAX_DATA frame. */ static std::unique_ptr<QUICMaxDataFrame, QUICFrameDeleterFunc> create_max_data_frame(uint64_t maximum_data); @@ -632,7 +670,7 @@ public: * Creates a RST_STREAM frame. */ static std::unique_ptr<QUICRstStreamFrame, QUICFrameDeleterFunc> create_rst_stream_frame(QUICStreamId stream_id, - QUICErrorCode error_code, + QUICAppErrorCode error_code, QUICOffset final_offset); static std::unique_ptr<QUICRstStreamFrame, QUICFrameDeleterFunc> create_rst_stream_frame(QUICStreamErrorUPtr error); @@ -640,7 +678,7 @@ public: * Creates a STOP_SENDING frame. */ static std::unique_ptr<QUICStopSendingFrame, QUICFrameDeleterFunc> create_stop_sending_frame(QUICStreamId stream_id, - QUICErrorCode error_code); + QUICAppErrorCode error_code); /* * Creates a retransmission frame, which is very special. diff --git a/iocore/net/quic/QUICHandshake.cc b/iocore/net/quic/QUICHandshake.cc index d78b909..b23609f 100644 --- a/iocore/net/quic/QUICHandshake.cc +++ b/iocore/net/quic/QUICHandshake.cc @@ -105,7 +105,7 @@ QUICHandshake::start(const QUICPacket *initial_packet, QUICPacketFactory *packet // Negotiate version if (this->_version_negotiator->status() == QUICVersionNegotiationStatus::NOT_NEGOTIATED) { if (initial_packet->type() != QUICPacketType::CLIENT_INITIAL) { - return QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::PROTOCOL_VIOLATION)); + return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::PROTOCOL_VIOLATION)); } if (initial_packet->version()) { if (this->_version_negotiator->negotiate(initial_packet) == QUICVersionNegotiationStatus::NEGOTIATED) { @@ -117,7 +117,7 @@ QUICHandshake::start(const QUICPacket *initial_packet, QUICPacketFactory *packet DebugQHS("Version negotiation failed: %x", initial_packet->version()); } } else { - return QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::PROTOCOL_VIOLATION)); + return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::PROTOCOL_VIOLATION)); } } return QUICErrorUPtr(new QUICNoError()); @@ -163,8 +163,7 @@ QUICHandshake::set_transport_parameters(std::shared_ptr<QUICTransportParameters> if (tp_in_ch) { // Version revalidation if (this->_version_negotiator->revalidate(tp_in_ch) != QUICVersionNegotiationStatus::REVALIDATED) { - this->_client_qc->close( - QUICConnectionErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::VERSION_NEGOTIATION_ERROR))); + this->_client_qc->close(QUICConnectionErrorUPtr(new QUICConnectionError(QUICTransErrorCode::VERSION_NEGOTIATION_ERROR))); DebugQHS("Enter state_closed"); SET_HANDLER(&QUICHandshake::state_closed); return; @@ -212,8 +211,7 @@ QUICHandshake::state_read_client_hello(int event, Event *data) if (dynamic_cast<QUICConnectionError *>(error.get()) != nullptr) { this->_client_qc->close(QUICConnectionErrorUPtr(static_cast<QUICConnectionError *>(error.release()))); } else { - this->_client_qc->close( - QUICConnectionErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::PROTOCOL_VIOLATION))); + this->_client_qc->close(QUICConnectionErrorUPtr(new QUICConnectionError(QUICTransErrorCode::PROTOCOL_VIOLATION))); } DebugQHS("Enter state_closed"); SET_HANDLER(&QUICHandshake::state_closed); @@ -241,8 +239,7 @@ QUICHandshake::state_read_client_finished(int event, Event *data) if (dynamic_cast<QUICConnectionError *>(error.get()) != nullptr) { this->_client_qc->close(QUICConnectionErrorUPtr(static_cast<QUICConnectionError *>(error.release()))); } else { - this->_client_qc->close( - QUICConnectionErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::PROTOCOL_VIOLATION))); + this->_client_qc->close(QUICConnectionErrorUPtr(new QUICConnectionError(QUICTransErrorCode::PROTOCOL_VIOLATION))); } DebugQHS("Enter state_closed"); SET_HANDLER(&QUICHandshake::state_closed); @@ -345,7 +342,7 @@ QUICHandshake::_process_client_hello() return QUICErrorUPtr(new QUICNoError()); } else { - return QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::CRYPTOGRAPHIC, QUICErrorCode::TLS_HANDSHAKE_FAILED)); + return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::TLS_HANDSHAKE_FAILED)); } } @@ -394,7 +391,7 @@ QUICHandshake::_process_client_finished() return QUICErrorUPtr(new QUICNoError()); } else { - return QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::CRYPTOGRAPHIC, QUICErrorCode::TLS_HANDSHAKE_FAILED)); + return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::TLS_HANDSHAKE_FAILED)); } } diff --git a/iocore/net/quic/QUICIncomingFrameBuffer.cc b/iocore/net/quic/QUICIncomingFrameBuffer.cc index e769054..797b7b9 100644 --- a/iocore/net/quic/QUICIncomingFrameBuffer.cc +++ b/iocore/net/quic/QUICIncomingFrameBuffer.cc @@ -116,17 +116,17 @@ QUICIncomingFrameBuffer::_check_and_set_fin_flag(QUICOffset offset, size_t len, // dup fin frame return QUICErrorUPtr(new QUICNoError()); } - return QUICErrorUPtr(new QUICStreamError(this->_stream, QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::FINAL_OFFSET_ERROR)); + return QUICErrorUPtr(new QUICStreamError(this->_stream, QUICTransErrorCode::FINAL_OFFSET_ERROR)); } this->_fin_offset = offset; if (this->_max_offset >= this->_fin_offset) { - return QUICErrorUPtr(new QUICStreamError(this->_stream, QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::FINAL_OFFSET_ERROR)); + return QUICErrorUPtr(new QUICStreamError(this->_stream, QUICTransErrorCode::FINAL_OFFSET_ERROR)); } } else if (this->_fin_offset != UINT64_MAX && this->_fin_offset <= offset) { - return QUICErrorUPtr(new QUICStreamError(this->_stream, QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::FINAL_OFFSET_ERROR)); + return QUICErrorUPtr(new QUICStreamError(this->_stream, QUICTransErrorCode::FINAL_OFFSET_ERROR)); } this->_max_offset = std::max(offset, this->_max_offset); diff --git a/iocore/net/quic/QUICStream.cc b/iocore/net/quic/QUICStream.cc index 535b9f4..1017a9f 100644 --- a/iocore/net/quic/QUICStream.cc +++ b/iocore/net/quic/QUICStream.cc @@ -116,8 +116,14 @@ QUICStream::main_event_handler(int event, void *data) } if (error->cls != QUICErrorClass::NONE) { - DebugQUICStream("QUICError: %s (%u), %s (0x%x)", QUICDebugNames::error_class(error->cls), static_cast<unsigned int>(error->cls), - QUICDebugNames::error_code(error->code), static_cast<unsigned int>(error->code)); + if (error->cls == QUICErrorClass::TRANSPORT) { + DebugQUICStream("QUICError: %s (%u), %s (0x%x)", QUICDebugNames::error_class(error->cls), + static_cast<unsigned int>(error->cls), QUICDebugNames::error_code(error->trans_error_code), + static_cast<unsigned int>(error->trans_error_code)); + } else { + DebugQUICStream("QUICError: %s (%u), APPLICATION ERROR (0x%x)", QUICDebugNames::error_class(error->cls), + static_cast<unsigned int>(error->cls), static_cast<unsigned int>(error->app_error_code)); + } if (dynamic_cast<QUICStreamError *>(error.get()) != nullptr) { // Stream Error QUICStreamErrorUPtr serror = QUICStreamErrorUPtr(static_cast<QUICStreamError *>(error.get())); @@ -295,7 +301,7 @@ QUICStream::recv(const std::shared_ptr<const QUICStreamFrame> frame) // Check stream state - Do this first before accept the frame if (!this->_state.is_allowed_to_receive(*frame)) { - return QUICErrorUPtr(new QUICStreamError(this, QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::STREAM_STATE_ERROR)); + return QUICErrorUPtr(new QUICStreamError(this, QUICTransErrorCode::STREAM_STATE_ERROR)); } // Flow Control - Even if it's allowed to receive on the state, it may exceed the limit diff --git a/iocore/net/quic/QUICStreamManager.cc b/iocore/net/quic/QUICStreamManager.cc index 6bda170..64190e5 100644 --- a/iocore/net/quic/QUICStreamManager.cc +++ b/iocore/net/quic/QUICStreamManager.cc @@ -123,7 +123,7 @@ QUICStreamManager::_handle_frame(const std::shared_ptr<const QUICMaxStreamDataFr if (stream) { return stream->recv(frame); } else { - return QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::STREAM_ID_ERROR)); + return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::STREAM_ID_ERROR)); } } @@ -134,7 +134,7 @@ QUICStreamManager::_handle_frame(const std::shared_ptr<const QUICStreamBlockedFr if (stream) { return stream->recv(frame); } else { - return QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::STREAM_ID_ERROR)); + return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::STREAM_ID_ERROR)); } } @@ -143,7 +143,7 @@ QUICStreamManager::_handle_frame(const std::shared_ptr<const QUICStreamFrame> &f { QUICStream *stream = this->_find_or_create_stream(frame->stream_id()); if (!stream) { - return QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::STREAM_ID_ERROR)); + return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::STREAM_ID_ERROR)); } QUICApplication *application = this->_app_map->get(frame->stream_id()); @@ -170,7 +170,7 @@ QUICStreamManager::_handle_frame(const std::shared_ptr<const QUICRstStreamFrame> // TODO Reset the stream return QUICErrorUPtr(new QUICNoError()); } else { - return QUICErrorUPtr(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::STREAM_ID_ERROR)); + return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::STREAM_ID_ERROR)); } } diff --git a/iocore/net/quic/QUICTypes.cc b/iocore/net/quic/QUICTypes.cc index 40c8a02..7427d6a 100644 --- a/iocore/net/quic/QUICTypes.cc +++ b/iocore/net/quic/QUICTypes.cc @@ -77,10 +77,16 @@ QUICTypeUtil::read_QUICOffset(const uint8_t *buf, uint8_t len) return static_cast<QUICOffset>(read_nbytes_as_uint(buf, len)); } -QUICErrorCode -QUICTypeUtil::read_QUICErrorCode(const uint8_t *buf) +QUICTransErrorCode +QUICTypeUtil::read_QUICTransErrorCode(const uint8_t *buf) { - return static_cast<QUICErrorCode>(read_nbytes_as_uint(buf, 4)); + return static_cast<QUICTransErrorCode>(read_nbytes_as_uint(buf, 2)); +} + +QUICAppErrorCode +QUICTypeUtil::read_QUICAppErrorCode(const uint8_t *buf) +{ + return static_cast<QUICAppErrorCode>(read_nbytes_as_uint(buf, 2)); } uint64_t @@ -122,9 +128,15 @@ QUICTypeUtil::write_QUICOffset(QUICOffset offset, uint8_t n, uint8_t *buf, size_ } void -QUICTypeUtil::write_QUICErrorCode(QUICErrorCode error_code, uint8_t *buf, size_t *len) +QUICTypeUtil::write_QUICTransErrorCode(QUICTransErrorCode error_code, uint8_t *buf, size_t *len) +{ + write_uint_as_nbytes(static_cast<uint64_t>(error_code), 2, buf, len); +} + +void +QUICTypeUtil::write_QUICAppErrorCode(QUICAppErrorCode error_code, uint8_t *buf, size_t *len) { - write_uint_as_nbytes(static_cast<uint64_t>(error_code), 4, buf, len); + write_uint_as_nbytes(static_cast<uint64_t>(error_code), 2, buf, len); } void @@ -148,3 +160,9 @@ fnv1a(const uint8_t *data, size_t len, uint8_t *hash) } return QUICTypeUtil::write_uint_as_nbytes(h, 8, hash, &n); } + +uint16_t +QUICError::code() +{ + return static_cast<uint16_t>(this->trans_error_code); +} diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h index 5ea6993..2e78939 100644 --- a/iocore/net/quic/QUICTypes.h +++ b/iocore/net/quic/QUICTypes.h @@ -88,7 +88,8 @@ enum class QUICFrameType : int { PADDING = 0x00, RST_STREAM, CONNECTION_CLOSE, - MAX_DATA = 0x04, + APPLICATION_CLOSE, + MAX_DATA, MAX_STREAM_DATA, MAX_STREAM_ID, PING, @@ -117,47 +118,49 @@ enum class QUICKeyPhase : int { enum class QUICErrorClass { NONE, - AQPPLICATION_SPECIFIC, - HOST_LOCAL, - QUIC_TRANSPORT, - CRYPTOGRAPHIC, + TRANSPORT, + APPLICATION, }; -enum class QUICErrorCode : uint32_t { - APPLICATION_SPECIFIC_ERROR = 0, - HOST_LOCAL_ERROR = 0x40000000, - NO_ERROR = 0x80000000, +enum class QUICTransErrorCode : uint16_t { + NO_ERROR = 0x00, INTERNAL_ERROR, - CANCELLED, - FLOW_CONTROL_ERROR, + FLOW_CONTROL_ERROR = 0x03, STREAM_ID_ERROR, STREAM_STATE_ERROR, FINAL_OFFSET_ERROR, FRAME_FORMAT_ERROR, TRANSPORT_PARAMETER_ERROR, VERSION_NEGOTIATION_ERROR, - PROTOCOL_VIOLATION = 0x8000000A, - QUIC_RECEIVED_RST = 0x80000035, - FRAME_ERROR = 0x80000100, - CRYPTOGRAPHIC_ERROR = 0xC0000000, - TLS_HANDSHAKE_FAILED = 0xC000001C, + PROTOCOL_VIOLATION = 0x0A, + FRAME_ERROR = 0x0100, // 0x100 - 0x1FF + TLS_HANDSHAKE_FAILED = 0x0201, TLS_FATAL_ALERT_GENERATED, TLS_FATAL_ALERT_RECEIVED, - // TODO Add error codes }; +// Application Protocol Error Codes defined in application +using QUICAppErrorCode = uint16_t; + class QUICError { public: virtual ~QUICError() {} - QUICErrorClass cls; - QUICErrorCode code; - const char *msg; + uint16_t code(); + + QUICErrorClass cls = QUICErrorClass::NONE; + union { + QUICTransErrorCode trans_error_code = QUICTransErrorCode::NO_ERROR; + QUICAppErrorCode app_error_code; + }; + const char *msg = nullptr; protected: - QUICError(const QUICErrorClass error_class = QUICErrorClass::NONE, const QUICErrorCode error_code = QUICErrorCode::NO_ERROR, - const char *error_msg = nullptr) - : cls(error_class), code(error_code), msg(error_msg){}; + QUICError(){}; + QUICError(const QUICTransErrorCode error_code, const char *error_msg = nullptr) + : cls(QUICErrorClass::TRANSPORT), trans_error_code(error_code), msg(error_msg){}; + QUICError(const QUICAppErrorCode error_code, const char *error_msg = nullptr) + : cls(QUICErrorClass::APPLICATION), app_error_code(error_code), msg(error_msg){}; }; class QUICNoError : public QUICError @@ -170,8 +173,8 @@ class QUICConnectionError : public QUICError { public: QUICConnectionError() : QUICError() {} - QUICConnectionError(const QUICErrorClass error_class, const QUICErrorCode error_code, const char *error_msg = nullptr) - : QUICError(error_class, error_code, error_msg){}; + QUICConnectionError(const QUICTransErrorCode error_code, const char *error_msg = nullptr) : QUICError(error_code, error_msg){}; + QUICConnectionError(const QUICAppErrorCode error_code, const char *error_msg = nullptr) : QUICError(error_code, error_msg){}; }; class QUICStream; @@ -179,8 +182,12 @@ class QUICStream; class QUICStreamError : public QUICError { public: - QUICStreamError(QUICStream *s, const QUICErrorClass error_class, const QUICErrorCode error_code, const char *error_msg = nullptr) - : QUICError(error_class, error_code, error_msg), stream(s){}; + QUICStreamError() : QUICError() {} + QUICStreamError(QUICStream *s, const QUICTransErrorCode error_code, const char *error_msg = nullptr) + : QUICError(error_code, error_msg), stream(s){}; + QUICStreamError(QUICStream *s, const QUICAppErrorCode error_code, const char *error_msg = nullptr) + : QUICError(error_code, error_msg), stream(s){}; + QUICStream *stream; }; @@ -303,14 +310,16 @@ public: static QUICVersion read_QUICVersion(const uint8_t *buf); static QUICStreamId read_QUICStreamId(const uint8_t *buf, uint8_t n); static QUICOffset read_QUICOffset(const uint8_t *buf, uint8_t n); - static QUICErrorCode read_QUICErrorCode(const uint8_t *buf); + static QUICTransErrorCode read_QUICTransErrorCode(const uint8_t *buf); + static QUICAppErrorCode read_QUICAppErrorCode(const uint8_t *buf); static void write_QUICConnectionId(QUICConnectionId connection_id, uint8_t n, uint8_t *buf, size_t *len); static void write_QUICPacketNumber(QUICPacketNumber packet_number, uint8_t n, uint8_t *buf, size_t *len); static void write_QUICVersion(QUICVersion version, uint8_t *buf, size_t *len); static void write_QUICStreamId(QUICStreamId stream_id, uint8_t n, uint8_t *buf, size_t *len); static void write_QUICOffset(QUICOffset offset, uint8_t n, uint8_t *buf, size_t *len); - static void write_QUICErrorCode(QUICErrorCode error_code, uint8_t *buf, size_t *len); + static void write_QUICTransErrorCode(QUICTransErrorCode error_code, uint8_t *buf, size_t *len); + static void write_QUICAppErrorCode(QUICAppErrorCode error_code, uint8_t *buf, size_t *len); static uint64_t read_nbytes_as_uint(const uint8_t *buf, uint8_t n); static void write_uint_as_nbytes(uint64_t value, uint8_t n, uint8_t *buf, size_t *len); diff --git a/iocore/net/quic/test/test_QUICFlowController.cc b/iocore/net/quic/test/test_QUICFlowController.cc index e98278b..17a9472 100644 --- a/iocore/net/quic/test/test_QUICFlowController.cc +++ b/iocore/net/quic/test/test_QUICFlowController.cc @@ -68,7 +68,8 @@ TEST_CASE("QUICFlowController_Local_Connection", "[quic]") error = fc.update(1280); CHECK(fc.current_offset() == 1024); CHECK(fc.current_limit() == 1024); - CHECK(error->code == QUICErrorCode::FLOW_CONTROL_ERROR); + CHECK(error->cls == QUICErrorClass::TRANSPORT); + CHECK(error->trans_error_code == QUICTransErrorCode::FLOW_CONTROL_ERROR); // MAX_STREAM_DATA CHECK(tx.frameCount[static_cast<int>(QUICFrameType::MAX_DATA)] == 0); @@ -180,7 +181,8 @@ TEST_CASE("QUICFlowController_Local_Stream", "[quic]") error = fc.update(1280); CHECK(fc.current_offset() == 1024); CHECK(fc.current_limit() == 1024); - CHECK(error->code == QUICErrorCode::FLOW_CONTROL_ERROR); + CHECK(error->cls == QUICErrorClass::TRANSPORT); + CHECK(error->trans_error_code == QUICTransErrorCode::FLOW_CONTROL_ERROR); // MAX_STREAM_DATA CHECK(tx.frameCount[static_cast<int>(QUICFrameType::MAX_STREAM_DATA)] == 0); diff --git a/iocore/net/quic/test/test_QUICFrame.cc b/iocore/net/quic/test/test_QUICFrame.cc index 36f1eee..434ef93 100644 --- a/iocore/net/quic/test/test_QUICFrame.cc +++ b/iocore/net/quic/test/test_QUICFrame.cc @@ -32,6 +32,7 @@ TEST_CASE("QUICFrame Type", "[quic]") CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x00")) == QUICFrameType::PADDING); CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x01")) == QUICFrameType::RST_STREAM); CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x02")) == QUICFrameType::CONNECTION_CLOSE); + CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x03")) == QUICFrameType::APPLICATION_CLOSE); CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x04")) == QUICFrameType::MAX_DATA); CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x05")) == QUICFrameType::MAX_STREAM_DATA); CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x06")) == QUICFrameType::MAX_STREAM_ID); @@ -42,7 +43,6 @@ TEST_CASE("QUICFrame Type", "[quic]") CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0b")) == QUICFrameType::NEW_CONNECTION_ID); CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0c")) == QUICFrameType::STOP_SENDING); // Undefined ragne - CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x03")) == QUICFrameType::UNKNOWN); CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0d")) == QUICFrameType::UNKNOWN); CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x9f")) == QUICFrameType::UNKNOWN); // Range of ACK @@ -309,15 +309,15 @@ TEST_CASE("Load RST_STREAM Frame", "[quic]") uint8_t buf1[] = { 0x01, // Type 0x12, 0x34, 0x56, 0x78, // Stream ID - 0x80, 0x00, 0x00, 0x00, // Error Code + 0x00, 0x01, // Error Code 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 // Final Offset }; std::shared_ptr<const QUICFrame> frame1 = QUICFrameFactory::create(buf1, sizeof(buf1)); CHECK(frame1->type() == QUICFrameType::RST_STREAM); - CHECK(frame1->size() == 17); + CHECK(frame1->size() == 15); std::shared_ptr<const QUICRstStreamFrame> rst_stream_frame1 = std::dynamic_pointer_cast<const QUICRstStreamFrame>(frame1); CHECK(rst_stream_frame1 != nullptr); - CHECK(rst_stream_frame1->error_code() == QUICErrorCode::NO_ERROR); + CHECK(rst_stream_frame1->error_code() == 0x0001); CHECK(rst_stream_frame1->stream_id() == 0x12345678); CHECK(rst_stream_frame1->final_offset() == 0x1122334455667788); } @@ -330,12 +330,12 @@ TEST_CASE("Store RST_STREAM Frame", "[quic]") uint8_t expected[] = { 0x01, // Type 0x12, 0x34, 0x56, 0x78, // Stream ID - 0x80, 0x00, 0x00, 0x00, // Error Code + 0x00, 0x01, // Error Code 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 // Final Offset }; - QUICRstStreamFrame rst_stream_frame(0x12345678, QUICErrorCode::NO_ERROR, 0x1122334455667788); + QUICRstStreamFrame rst_stream_frame(0x12345678, 0x0001, 0x1122334455667788); rst_stream_frame.store(buf, &len); - CHECK(len == 17); + CHECK(len == 15); CHECK(memcmp(buf, expected, len) == 0); } @@ -395,33 +395,33 @@ TEST_CASE("Load ConnectionClose Frame", "[quic]") { uint8_t buf1[] = { 0x02, // Type - 0x80, 0x00, 0x00, 0x00, // Error Code + 0x00, 0x0A, // Error Code 0x00, 0x05, // Reason Phrase Length 0x41, 0x42, 0x43, 0x44, 0x45 // Reason Phrase ("ABCDE"); }; std::shared_ptr<const QUICFrame> frame1 = QUICFrameFactory::create(buf1, sizeof(buf1)); CHECK(frame1->type() == QUICFrameType::CONNECTION_CLOSE); - CHECK(frame1->size() == 12); + CHECK(frame1->size() == 10); std::shared_ptr<const QUICConnectionCloseFrame> connectionCloseFrame1 = std::dynamic_pointer_cast<const QUICConnectionCloseFrame>(frame1); CHECK(connectionCloseFrame1 != nullptr); - CHECK(connectionCloseFrame1->error_code() == QUICErrorCode::NO_ERROR); + CHECK(connectionCloseFrame1->error_code() == QUICTransErrorCode::PROTOCOL_VIOLATION); CHECK(connectionCloseFrame1->reason_phrase_length() == 5); - CHECK(memcmp(connectionCloseFrame1->reason_phrase(), buf1 + 7, 5) == 0); + CHECK(memcmp(connectionCloseFrame1->reason_phrase(), buf1 + 5, 5) == 0); // No reason phrase uint8_t buf2[] = { - 0x02, // Type - 0x80, 0x00, 0x00, 0x00, // Error Code - 0x00, 0x00, // Reason Phrase Length + 0x02, // Type + 0x00, 0x0A, // Error Code + 0x00, 0x00, // Reason Phrase Length }; std::shared_ptr<const QUICFrame> frame2 = QUICFrameFactory::create(buf2, sizeof(buf1)); CHECK(frame2->type() == QUICFrameType::CONNECTION_CLOSE); - CHECK(frame2->size() == 7); + CHECK(frame2->size() == 5); std::shared_ptr<const QUICConnectionCloseFrame> connectionCloseFrame2 = std::dynamic_pointer_cast<const QUICConnectionCloseFrame>(frame2); CHECK(connectionCloseFrame2 != nullptr); - CHECK(connectionCloseFrame2->error_code() == QUICErrorCode::NO_ERROR); + CHECK(connectionCloseFrame2->error_code() == QUICTransErrorCode::PROTOCOL_VIOLATION); CHECK(connectionCloseFrame2->reason_phrase_length() == 0); } @@ -432,23 +432,84 @@ TEST_CASE("Store ConnectionClose Frame", "[quic]") uint8_t expected1[] = { 0x02, // Type - 0x80, 0x00, 0x00, 0x00, // Error Code + 0x00, 0x0A, // Error Code 0x00, 0x05, // Reason Phrase Length 0x41, 0x42, 0x43, 0x44, 0x45 // Reason Phrase ("ABCDE"); }; - QUICConnectionCloseFrame connectionCloseFrame1(QUICErrorCode::NO_ERROR, 5, "ABCDE"); + QUICConnectionCloseFrame connectionCloseFrame1(QUICTransErrorCode::PROTOCOL_VIOLATION, 5, "ABCDE"); connectionCloseFrame1.store(buf, &len); - CHECK(len == 12); + CHECK(len == 10); CHECK(memcmp(buf, expected1, len) == 0); uint8_t expected2[] = { - 0x02, // Type - 0x80, 0x00, 0x00, 0x00, // Error Code - 0x00, 0x00, // Reason Phrase Length + 0x02, // Type + 0x00, 0x0A, // Error Code + 0x00, 0x00, // Reason Phrase Length }; - QUICConnectionCloseFrame connectionCloseFrame2(QUICErrorCode::NO_ERROR, 0, nullptr); + QUICConnectionCloseFrame connectionCloseFrame2(QUICTransErrorCode::PROTOCOL_VIOLATION, 0, nullptr); connectionCloseFrame2.store(buf, &len); - CHECK(len == 7); + CHECK(len == 5); + CHECK(memcmp(buf, expected2, len) == 0); +} + +TEST_CASE("Load ApplicationClose Frame", "[quic]") +{ + uint8_t buf1[] = { + 0x03, // Type + 0x00, 0x01, // Error Code + 0x00, 0x05, // Reason Phrase Length + 0x41, 0x42, 0x43, 0x44, 0x45 // Reason Phrase ("ABCDE"); + }; + std::shared_ptr<const QUICFrame> frame1 = QUICFrameFactory::create(buf1, sizeof(buf1)); + CHECK(frame1->type() == QUICFrameType::APPLICATION_CLOSE); + CHECK(frame1->size() == 10); + std::shared_ptr<const QUICApplicationCloseFrame> applicationCloseFrame1 = + std::dynamic_pointer_cast<const QUICApplicationCloseFrame>(frame1); + CHECK(applicationCloseFrame1 != nullptr); + CHECK(applicationCloseFrame1->error_code() == static_cast<QUICAppErrorCode>(0x01)); + CHECK(applicationCloseFrame1->reason_phrase_length() == 5); + CHECK(memcmp(applicationCloseFrame1->reason_phrase(), buf1 + 5, 5) == 0); + + // No reason phrase + uint8_t buf2[] = { + 0x03, // Type + 0x00, 0x01, // Error Code + 0x00, 0x00, // Reason Phrase Length + }; + std::shared_ptr<const QUICFrame> frame2 = QUICFrameFactory::create(buf2, sizeof(buf1)); + CHECK(frame2->type() == QUICFrameType::APPLICATION_CLOSE); + CHECK(frame2->size() == 5); + std::shared_ptr<const QUICApplicationCloseFrame> applicationCloseFrame2 = + std::dynamic_pointer_cast<const QUICApplicationCloseFrame>(frame2); + CHECK(applicationCloseFrame2 != nullptr); + CHECK(applicationCloseFrame2->error_code() == static_cast<QUICAppErrorCode>(0x01)); + CHECK(applicationCloseFrame2->reason_phrase_length() == 0); +} + +TEST_CASE("Store ApplicationClose Frame", "[quic]") +{ + uint8_t buf[65535]; + size_t len; + + uint8_t expected1[] = { + 0x03, // Type + 0x00, 0x01, // Error Code + 0x00, 0x05, // Reason Phrase Length + 0x41, 0x42, 0x43, 0x44, 0x45 // Reason Phrase ("ABCDE"); + }; + QUICApplicationCloseFrame applicationCloseFrame1(static_cast<QUICAppErrorCode>(0x01), 5, "ABCDE"); + applicationCloseFrame1.store(buf, &len); + CHECK(len == 10); + CHECK(memcmp(buf, expected1, len) == 0); + + uint8_t expected2[] = { + 0x03, // Type + 0x00, 0x01, // Error Code + 0x00, 0x00, // Reason Phrase Length + }; + QUICApplicationCloseFrame applicationCloseFrame2(static_cast<QUICAppErrorCode>(0x01), 0, nullptr); + applicationCloseFrame2.store(buf, &len); + CHECK(len == 5); CHECK(memcmp(buf, expected2, len) == 0); } @@ -664,16 +725,16 @@ TEST_CASE("Load STOP_SENDING Frame", "[quic]") uint8_t buf[] = { 0x0c, // Type 0x12, 0x34, 0x56, 0x78, // Stream ID - 0x80, 0x00, 0x00, 0x00, // Error Code + 0x00, 0x01, // Error Code }; std::shared_ptr<const QUICFrame> frame = QUICFrameFactory::create(buf, sizeof(buf)); CHECK(frame->type() == QUICFrameType::STOP_SENDING); - CHECK(frame->size() == 9); + CHECK(frame->size() == 7); std::shared_ptr<const QUICStopSendingFrame> stop_sending_frame = std::dynamic_pointer_cast<const QUICStopSendingFrame>(frame); CHECK(stop_sending_frame != nullptr); CHECK(stop_sending_frame->stream_id() == 0x12345678); - CHECK(stop_sending_frame->error_code() == QUICErrorCode::NO_ERROR); + CHECK(stop_sending_frame->error_code() == 0x0001); } TEST_CASE("Store STOP_SENDING Frame", "[quic]") @@ -684,11 +745,11 @@ TEST_CASE("Store STOP_SENDING Frame", "[quic]") uint8_t expected[] = { 0x0c, // Type 0x12, 0x34, 0x56, 0x78, // Stream ID - 0x80, 0x00, 0x00, 0x00, // Error Code + 0x00, 0x01, // Error Code }; - QUICStopSendingFrame stop_sending_frame(0x12345678, QUICErrorCode::NO_ERROR); + QUICStopSendingFrame stop_sending_frame(0x12345678, static_cast<QUICAppErrorCode>(0x01)); stop_sending_frame.store(buf, &len); - CHECK(len == 9); + CHECK(len == 7); CHECK(memcmp(buf, expected, len) == 0); } @@ -744,18 +805,17 @@ TEST_CASE("QUICFrameFactory Fast Create Unknown Frame", "[quic]") TEST_CASE("QUICFrameFactory Create CONNECTION_CLOSE with a QUICConnectionError", "[quic]") { std::unique_ptr<QUICConnectionError> error = - std::unique_ptr<QUICConnectionError>(new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::INTERNAL_ERROR)); + std::unique_ptr<QUICConnectionError>(new QUICConnectionError(QUICTransErrorCode::INTERNAL_ERROR)); std::unique_ptr<QUICConnectionCloseFrame, QUICFrameDeleterFunc> connection_close_frame1 = QUICFrameFactory::create_connection_close_frame(std::move(error)); - CHECK(connection_close_frame1->error_code() == QUICErrorCode::INTERNAL_ERROR); + CHECK(connection_close_frame1->error_code() == QUICTransErrorCode::INTERNAL_ERROR); CHECK(connection_close_frame1->reason_phrase_length() == 0); CHECK(connection_close_frame1->reason_phrase() == nullptr); - error = std::unique_ptr<QUICConnectionError>( - new QUICConnectionError(QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::INTERNAL_ERROR, "test")); + error = std::unique_ptr<QUICConnectionError>(new QUICConnectionError(QUICTransErrorCode::INTERNAL_ERROR, "test")); std::unique_ptr<QUICConnectionCloseFrame, QUICFrameDeleterFunc> connection_close_frame2 = QUICFrameFactory::create_connection_close_frame(std::move(error)); - CHECK(connection_close_frame2->error_code() == QUICErrorCode::INTERNAL_ERROR); + CHECK(connection_close_frame2->error_code() == QUICTransErrorCode::INTERNAL_ERROR); CHECK(connection_close_frame2->reason_phrase_length() == 4); CHECK(memcmp(connection_close_frame2->reason_phrase(), "test", 4) == 0); } @@ -765,10 +825,10 @@ TEST_CASE("QUICFrameFactory Create RST_STREAM with a QUICStreamError", "[quic]") QUICStream stream; stream.init(new MockQUICFrameTransmitter(), 0, 0x1234, 0, 0); std::unique_ptr<QUICStreamError> error = - std::unique_ptr<QUICStreamError>(new QUICStreamError(&stream, QUICErrorClass::QUIC_TRANSPORT, QUICErrorCode::INTERNAL_ERROR)); + std::unique_ptr<QUICStreamError>(new QUICStreamError(&stream, static_cast<QUICAppErrorCode>(0x01))); std::unique_ptr<QUICRstStreamFrame, QUICFrameDeleterFunc> rst_stream_frame1 = QUICFrameFactory::create_rst_stream_frame(std::move(error)); - CHECK(rst_stream_frame1->error_code() == QUICErrorCode::INTERNAL_ERROR); + CHECK(rst_stream_frame1->error_code() == 0x01); CHECK(rst_stream_frame1->stream_id() == 0x1234); CHECK(rst_stream_frame1->final_offset() == 0); } diff --git a/iocore/net/quic/test/test_QUICIncomingFrameBuffer.cc b/iocore/net/quic/test/test_QUICIncomingFrameBuffer.cc index 844607a..a42369b 100644 --- a/iocore/net/quic/test/test_QUICIncomingFrameBuffer.cc +++ b/iocore/net/quic/test/test_QUICIncomingFrameBuffer.cc @@ -45,7 +45,7 @@ TEST_CASE("QUICIncomingFrameBuffer_fin_offset", "[quic]") buffer.insert(stream1_frame_1_r); buffer.insert(stream1_frame_2_r); err = buffer.insert(stream1_frame_3_r); - CHECK(err->code == QUICErrorCode::FINAL_OFFSET_ERROR); + CHECK(err->trans_error_code == QUICTransErrorCode::FINAL_OFFSET_ERROR); QUICIncomingFrameBuffer buffer2(stream); @@ -53,13 +53,13 @@ TEST_CASE("QUICIncomingFrameBuffer_fin_offset", "[quic]") buffer2.insert(stream1_frame_0_r); buffer2.insert(stream1_frame_1_r); err = buffer2.insert(stream1_frame_2_r); - CHECK(err->code == QUICErrorCode::FINAL_OFFSET_ERROR); + CHECK(err->trans_error_code == QUICTransErrorCode::FINAL_OFFSET_ERROR); QUICIncomingFrameBuffer buffer3(stream); buffer3.insert(stream1_frame_4_r); err = buffer3.insert(stream1_frame_3_r); - CHECK(err->code == QUICErrorCode::FINAL_OFFSET_ERROR); + CHECK(err->trans_error_code == QUICTransErrorCode::FINAL_OFFSET_ERROR); delete stream; } diff --git a/iocore/net/quic/test/test_QUICStream.cc b/iocore/net/quic/test/test_QUICStream.cc index 5e63ade..bd2f648 100644 --- a/iocore/net/quic/test/test_QUICStream.cc +++ b/iocore/net/quic/test/test_QUICStream.cc @@ -179,7 +179,8 @@ TEST_CASE("QUICStream", "[quic]") CHECK(error->cls == QUICErrorClass::NONE); // this should exceed the limit error = stream->recv(std::make_shared<QUICStreamFrame>(ats_unique_malloc(1024), 1024, stream_id, 8192)); - CHECK(error->code == QUICErrorCode::FLOW_CONTROL_ERROR); + CHECK(error->cls == QUICErrorClass::TRANSPORT); + CHECK(error->trans_error_code == QUICTransErrorCode::FLOW_CONTROL_ERROR); } SECTION("QUICStream_flow_control_remote", "[quic]") diff --git a/iocore/net/quic/test/test_QUICStreamManager.cc b/iocore/net/quic/test/test_QUICStreamManager.cc index f9490c9..9af5433 100644 --- a/iocore/net/quic/test/test_QUICStreamManager.cc +++ b/iocore/net/quic/test/test_QUICStreamManager.cc @@ -53,7 +53,8 @@ TEST_CASE("QUICStreamManager_NewStream", "[quic]") CHECK(sm.stream_count() == 2); // RST_STREAM frames create new streams - std::shared_ptr<QUICFrame> rst_stream_frame = QUICFrameFactory::create_rst_stream_frame(2, QUICErrorCode::INTERNAL_ERROR, 0); + std::shared_ptr<QUICFrame> rst_stream_frame = + QUICFrameFactory::create_rst_stream_frame(2, static_cast<QUICAppErrorCode>(0x01), 0); sm.handle_frame(rst_stream_frame); CHECK(sm.stream_count() == 3); diff --git a/iocore/net/quic/test/test_QUICStreamState.cc b/iocore/net/quic/test/test_QUICStreamState.cc index ec30434..2bc3e68 100644 --- a/iocore/net/quic/test/test_QUICStreamState.cc +++ b/iocore/net/quic/test/test_QUICStreamState.cc @@ -31,7 +31,7 @@ TEST_CASE("QUICStreamState_Idle", "[quic]") { auto stream_frame = QUICFrameFactory::create_stream_frame(reinterpret_cast<const uint8_t *>("foo"), 4, 1, 0); - auto rst_stream_frame = QUICFrameFactory::create_rst_stream_frame(0, QUICErrorCode::NO_ERROR, 0); + auto rst_stream_frame = QUICFrameFactory::create_rst_stream_frame(0, static_cast<QUICAppErrorCode>(0x01), 0); auto max_stream_data_frame = QUICFrameFactory::create_max_stream_data_frame(0, 0); auto stream_blocked_frame = QUICFrameFactory::create_stream_blocked_frame(0); @@ -70,7 +70,7 @@ TEST_CASE("QUICStreamState_Open", "[quic]") { auto stream_frame = QUICFrameFactory::create_stream_frame(reinterpret_cast<const uint8_t *>("foo"), 4, 1, 0); auto stream_frame_with_fin = QUICFrameFactory::create_stream_frame(reinterpret_cast<const uint8_t *>("bar"), 4, 1, 0, true); - auto rst_stream_frame = QUICFrameFactory::create_rst_stream_frame(0, QUICErrorCode::NO_ERROR, 0); + auto rst_stream_frame = QUICFrameFactory::create_rst_stream_frame(0, static_cast<QUICAppErrorCode>(0x01), 0); // Case1. Send FIN in a STREAM QUICStreamState ss1; @@ -105,7 +105,7 @@ TEST_CASE("QUICStreamState_Half_Closed_Remote", "[quic]") { auto stream_frame = QUICFrameFactory::create_stream_frame(reinterpret_cast<const uint8_t *>("foo"), 4, 1, 0); auto stream_frame_with_fin = QUICFrameFactory::create_stream_frame(reinterpret_cast<const uint8_t *>("bar"), 4, 1, 0, true); - auto rst_stream_frame = QUICFrameFactory::create_rst_stream_frame(0, QUICErrorCode::NO_ERROR, 0); + auto rst_stream_frame = QUICFrameFactory::create_rst_stream_frame(0, static_cast<QUICAppErrorCode>(0x01), 0); // Case1. Send FIN in a STREAM QUICStreamState ss1; @@ -126,7 +126,7 @@ TEST_CASE("QUICStreamState_Half_Closed_Local", "[quic]") { auto stream_frame = QUICFrameFactory::create_stream_frame(reinterpret_cast<const uint8_t *>("foo"), 4, 1, 0); auto stream_frame_with_fin = QUICFrameFactory::create_stream_frame(reinterpret_cast<const uint8_t *>("bar"), 4, 1, 0, true); - auto rst_stream_frame = QUICFrameFactory::create_rst_stream_frame(0, QUICErrorCode::NO_ERROR, 0); + auto rst_stream_frame = QUICFrameFactory::create_rst_stream_frame(0, static_cast<QUICAppErrorCode>(0x01), 0); // Case1. Recv FIN in a STREAM QUICStreamState ss1; -- To stop receiving notification emails like this one, please contact ['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].