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 dbdd3d2 Check version in QUICPacketHandlerIn
dbdd3d2 is described below
commit dbdd3d29115d11d474c3d18c2474c0cd530b5a24
Author: Masaori Koshiba <[email protected]>
AuthorDate: Fri Jun 15 10:25:30 2018 +0900
Check version in QUICPacketHandlerIn
---
.gitignore | 1 +
iocore/net/P_QUICPacketHandler.h | 2 -
iocore/net/QUICPacketHandler.cc | 136 +++++++++++--------
iocore/net/quic/QUICConfig.h | 2 +
iocore/net/quic/QUICHandshake.cc | 3 +-
iocore/net/quic/QUICPacket.cc | 10 +-
iocore/net/quic/QUICPacket.h | 10 +-
iocore/net/quic/QUICTypes.cc | 96 +++++++++++++-
iocore/net/quic/QUICTypes.h | 21 ++-
iocore/net/quic/test/Makefile.am | 17 +++
iocore/net/quic/test/test_QUICInvariants.cc | 147 +++++++++++++++++++++
iocore/net/quic/test/test_QUICPacketFactory.cc | 30 +----
iocore/net/quic/test/test_QUICVersionNegotiator.cc | 3 +-
13 files changed, 385 insertions(+), 93 deletions(-)
diff --git a/.gitignore b/.gitignore
index 5514f1c..2f58694 100644
--- a/.gitignore
+++ b/.gitignore
@@ -99,6 +99,7 @@ iocore/net/quic/test/test_QUICFrameDispatcher
iocore/net/quic/test/test_QUICLossDetector
iocore/net/quic/test/test_QUICHandshake
iocore/net/quic/test/test_QUICIncomingFrameBuffer
+iocore/net/quic/test/test_QUICInvariants
iocore/net/quic/test/test_QUICKeyGenerator
iocore/net/quic/test/test_QUICPacket
iocore/net/quic/test/test_QUICPacketFactory
diff --git a/iocore/net/P_QUICPacketHandler.h b/iocore/net/P_QUICPacketHandler.h
index dd7067d..3e982bc 100644
--- a/iocore/net/P_QUICPacketHandler.h
+++ b/iocore/net/P_QUICPacketHandler.h
@@ -44,8 +44,6 @@ public:
protected:
static void _send_packet(Continuation *c, const QUICPacket &packet,
UDPConnection *udp_con, IpEndpoint &addr, uint32_t pmtu);
- static QUICConnectionId _read_destination_connection_id(IOBufferBlock
*block);
- static QUICConnectionId _read_source_connection_id(IOBufferBlock *block);
Event *_collector_event = nullptr;
QUICClosedConCollector *_closed_con_collector = nullptr;
diff --git a/iocore/net/QUICPacketHandler.cc b/iocore/net/QUICPacketHandler.cc
index 732a1ae..a596c35 100644
--- a/iocore/net/QUICPacketHandler.cc
+++ b/iocore/net/QUICPacketHandler.cc
@@ -30,11 +30,13 @@
#include "QUICDebugNames.h"
#include "QUICEvents.h"
-#define QUICDebugQC(qc, fmt, ...) Debug("quic_sec", "[%s] " fmt,
qc->cids().data(), ##__VA_ARGS__)
+static constexpr char tag[] = "quic_sec";
+
+#define QUICDebug(fmt, ...) Debug(tag, fmt, ##__VA_ARGS__)
+#define QUICDebugQC(qc, fmt, ...) Debug(tag, "[%s] " fmt, qc->cids().data(),
##__VA_ARGS__)
// ["local dcid" - "local scid"]
-#define QUICDebugDS(dcid, scid, fmt, ...) \
- Debug("quic_sec", "[%08" PRIx32 "-%08" PRIx32 "] " fmt, dcid.h32(),
scid.h32(), ##__VA_ARGS__)
+#define QUICDebugDS(dcid, scid, fmt, ...) Debug(tag, "[%08" PRIx32 "-%08"
PRIx32 "] " fmt, dcid.h32(), scid.h32(), ##__VA_ARGS__)
//
// QUICPacketHandler
@@ -78,33 +80,21 @@ QUICPacketHandler::_send_packet(Continuation *c, const
QUICPacket &packet, UDPCo
UDPPacket *udp_packet = new_UDPPacket(addr, 0, udp_payload);
- // NOTE: p will be enqueued to udpOutQueue of UDPNetHandler
- ip_port_text_buffer ipb;
- QUICConnectionId dcid = packet.destination_cid();
- QUICConnectionId scid = QUICConnectionId::ZERO();
- if (packet.type() != QUICPacketType::PROTECTED) {
- scid = packet.source_cid();
+ if (is_debug_tag_set(tag)) {
+ ip_port_text_buffer ipb;
+ QUICConnectionId dcid = packet.destination_cid();
+ QUICConnectionId scid = QUICConnectionId::ZERO();
+ if (packet.type() != QUICPacketType::PROTECTED) {
+ scid = packet.source_cid();
+ }
+ QUICDebugDS(dcid, scid, "send %s packet to %s size=%" PRId64,
QUICDebugNames::packet_type(packet.type()),
+ ats_ip_nptop(&udp_packet->to.sa, ipb, sizeof(ipb)),
udp_packet->getPktLength());
}
- QUICDebugDS(dcid, scid, "send %s packet to %s size=%" PRId64,
QUICDebugNames::packet_type(packet.type()),
- ats_ip_nptop(&udp_packet->to.sa, ipb, sizeof(ipb)),
udp_packet->getPktLength());
+ // NOTE: packet will be enqueued to udpOutQueue of UDPNetHandler
udp_con->send(c, udp_packet);
}
-QUICConnectionId
-QUICPacketHandler::_read_destination_connection_id(IOBufferBlock *block)
-{
- const uint8_t *buf = reinterpret_cast<const uint8_t *>(block->buf());
- return QUICPacket::destination_connection_id(buf);
-}
-
-QUICConnectionId
-QUICPacketHandler::_read_source_connection_id(IOBufferBlock *block)
-{
- const uint8_t *buf = reinterpret_cast<const uint8_t *>(block->buf());
- return QUICPacket::source_connection_id(buf);
-}
-
//
// QUICPacketHandlerIn
//
@@ -182,54 +172,91 @@ QUICPacketHandlerIn::init_accept(EThread *t = nullptr)
void
QUICPacketHandlerIn::_recv_packet(int event, UDPPacket *udp_packet)
{
- EThread *eth = nullptr;
- QUICPollEvent *qe = nullptr;
- QUICNetVConnection *vc = nullptr;
- IOBufferBlock *block = udp_packet->getIOBlockChain();
+ // Assumption: udp_packet has only one IOBufferBlock
+ IOBufferBlock *block = udp_packet->getIOBlockChain();
+ const uint8_t *buf = reinterpret_cast<uint8_t *>(block->buf());
+ uint64_t buf_len = block->size();
- if (is_debug_tag_set("quic_sec")) {
- ip_port_text_buffer ipb;
- QUICConnectionId dcid = this->_read_destination_connection_id(block);
- QUICConnectionId scid = QUICConnectionId::ZERO();
- if (QUICTypeUtil::has_long_header(reinterpret_cast<const uint8_t
*>(block->buf()))) {
- scid = this->_read_source_connection_id(block);
+ if (buf_len == 0) {
+ QUICDebug("Ignore packet - payload is too small");
+ udp_packet->free();
+ return;
+ }
+
+ QUICConnectionId dcid = QUICConnectionId::ZERO();
+ QUICConnectionId scid = QUICConnectionId::ZERO();
+
+ // TODO: lookup by 5-Tuple
+ // When ATS omits SCID, endpoint omits DCID. In this case, we can't get DCID
from SH packet, we need to lookup QC by 5-Tuple.
+ if (!QUICInvariants::dcid(dcid, buf, buf_len)) {
+ QUICDebug("Ignore packet - payload is too small");
+ udp_packet->free();
+ return;
+ }
+
+ if (QUICInvariants::is_long_header(buf)) {
+ if (!QUICInvariants::scid(scid, buf, buf_len)) {
+ QUICDebug("Ignore packet - payload is too small");
+ udp_packet->free();
+ return;
+ }
+
+ if (is_debug_tag_set(tag)) {
+ ip_port_text_buffer ipb;
+ QUICDebugDS(scid, dcid, "recv LH packet from %s size=%" PRId64,
ats_ip_nptop(&udp_packet->from.sa, ipb, sizeof(ipb)),
+ udp_packet->getPktLength());
+ }
+
+ QUICVersion v;
+ if (unlikely(!QUICInvariants::version(v, buf, buf_len))) {
+ QUICDebug("Ignore packet - payload is too small");
+ udp_packet->free();
+ return;
+ }
+
+ if (!QUICInvariants::is_version_negotiation(v) &&
!QUICTypeUtil::is_supported_version(v)) {
+ QUICDebugDS(scid, dcid, "Unsupported version: 0x%x", v);
+
+ QUICPacketUPtr vn =
QUICPacketFactory::create_version_negotiation_packet(scid, dcid);
+ this->_send_packet(this, *vn, udp_packet->getConnection(),
udp_packet->from, 1200);
+ udp_packet->free();
+ return;
+ }
+ } else {
+ if (is_debug_tag_set(tag)) {
+ ip_port_text_buffer ipb;
+ QUICDebugDS(scid, dcid, "recv SH packet from %s size=%" PRId64,
ats_ip_nptop(&udp_packet->from.sa, ipb, sizeof(ipb)),
+ udp_packet->getPktLength());
}
- // Remote dst cid is src cid in local
- // TODO: print packet type
- QUICDebugDS(scid, dcid, "recv packet from %s, size=%" PRId64,
ats_ip_nptop(&udp_packet->from.sa, ipb, sizeof(ipb)),
- udp_packet->getPktLength());
}
- QUICConnection *qc =
- this->_ctable->lookup(reinterpret_cast<const uint8_t *>(block->buf()),
{udp_packet->from, udp_packet->to, SOCK_DGRAM});
+ QUICConnection *qc = this->_ctable->lookup(buf, {udp_packet->from,
udp_packet->to, SOCK_DGRAM});
+ QUICNetVConnection *vc = static_cast<QUICNetVConnection *>(qc);
- vc = static_cast<QUICNetVConnection *>(qc);
// 7.1. Matching Packets to Connections
// A server that discards a packet that cannot be associated with a
connection MAY also generate a stateless reset
// Send stateless reset if the packet is not a initial packet or connection
is closed.
if ((!vc && !QUICTypeUtil::has_long_header(reinterpret_cast<const uint8_t
*>(block->buf()))) || (vc && vc->in_closed_queue)) {
- Connection con;
- con.setRemote(&udp_packet->from.sa);
- QUICConnectionId cid = this->_read_destination_connection_id(block);
QUICStatelessResetToken token;
{
QUICConfig::scoped_config params;
- token.generate(cid, params->server_id());
+ token.generate(dcid, params->server_id());
}
- auto packet = QUICPacketFactory::create_stateless_reset_packet(cid, token);
- this->_send_packet(this, *packet, udp_packet->getConnection(), con.addr,
1200);
+ auto packet = QUICPacketFactory::create_stateless_reset_packet(dcid,
token);
+ this->_send_packet(this, *packet, udp_packet->getConnection(),
udp_packet->from, 1200);
udp_packet->free();
return;
}
+ EThread *eth = nullptr;
if (!vc) {
+ // Create a new NetVConnection
Connection con;
con.setRemote(&udp_packet->from.sa);
- eth = eventProcessor.assign_thread(ET_NET);
- // Create a new NetVConnection
- QUICConnectionId original_cid =
this->_read_destination_connection_id(block);
- QUICConnectionId peer_cid = this->_read_source_connection_id(block);
+ eth = eventProcessor.assign_thread(ET_NET);
+ QUICConnectionId original_cid = dcid;
+ QUICConnectionId peer_cid = scid;
if (is_debug_tag_set("quic_sec")) {
char client_dcid_hex_str[QUICConnectionId::MAX_HEX_STR_LENGTH];
@@ -256,11 +283,12 @@ QUICPacketHandlerIn::_recv_packet(int event, UDPPacket
*udp_packet)
eth = vc->thread;
}
- qe = quicPollEventAllocator.alloc();
-
+ QUICPollEvent *qe = quicPollEventAllocator.alloc();
qe->init(qc, static_cast<UDPPacketInternal *>(udp_packet));
// Push the packet into QUICPollCont
get_QUICPollCont(eth)->inQueue.push(qe);
+
+ return;
}
// TODO: Should be called via eventProcessor?
diff --git a/iocore/net/quic/QUICConfig.h b/iocore/net/quic/QUICConfig.h
index 36a7ee4..5b403bb 100644
--- a/iocore/net/quic/QUICConfig.h
+++ b/iocore/net/quic/QUICConfig.h
@@ -69,6 +69,8 @@ public:
uint32_t cc_minimum_window() const;
float cc_loss_reduction_factor() const;
+ static const uint8_t SCIL = 5;
+
private:
static int _connection_table_size;
diff --git a/iocore/net/quic/QUICHandshake.cc b/iocore/net/quic/QUICHandshake.cc
index ea1c7fe..7ef84ae 100644
--- a/iocore/net/quic/QUICHandshake.cc
+++ b/iocore/net/quic/QUICHandshake.cc
@@ -141,8 +141,7 @@ QUICHandshake::start(const QUICPacket *initial_packet,
QUICPacketFactory *packet
this->_load_local_server_transport_parameters(initial_packet->version());
packet_factory->set_version(this->_version_negotiator->negotiated_version());
} else {
-
this->_qc->transmit_packet(packet_factory->create_version_negotiation_packet(initial_packet));
- QUICHSDebug("Version negotiation failed: %x",
initial_packet->version());
+ ink_assert(!"Unsupported version initial packet should be droped
QUICPakcetHandler");
}
} else {
return QUICErrorUPtr(new
QUICConnectionError(QUICTransErrorCode::PROTOCOL_VIOLATION));
diff --git a/iocore/net/quic/QUICPacket.cc b/iocore/net/quic/QUICPacket.cc
index 247e6cd..9b09c6d 100644
--- a/iocore/net/quic/QUICPacket.cc
+++ b/iocore/net/quic/QUICPacket.cc
@@ -21,11 +21,14 @@
* limitations under the License.
*/
+#include "QUICPacket.h"
+
#include <ts/ink_assert.h>
#include <ts/Diags.h>
+
#include "QUICIntUtil.h"
-#include "QUICPacket.h"
#include "QUICDebugNames.h"
+#include "QUICConfig.h"
static constexpr std::string_view tag = "quic_packet"sv;
static constexpr uint64_t aead_tag_len = 16;
@@ -821,7 +824,7 @@ QUICPacketFactory::create(IpEndpoint from, ats_unique_buf
buf, size_t len, QUICP
}
QUICPacketUPtr
-QUICPacketFactory::create_version_negotiation_packet(const QUICPacket
*packet_sent_by_client)
+QUICPacketFactory::create_version_negotiation_packet(QUICConnectionId dcid,
QUICConnectionId scid)
{
size_t len = sizeof(QUICVersion) * countof(QUIC_SUPPORTED_VERSIONS);
ats_unique_buf versions(reinterpret_cast<uint8_t *>(ats_malloc(len)),
[](void *p) { ats_free(p); });
@@ -835,8 +838,7 @@ QUICPacketFactory::create_version_negotiation_packet(const
QUICPacket *packet_se
// VN packet dosen't have packet number field and version field is always
0x00000000
QUICPacketHeaderUPtr header =
- QUICPacketHeader::build(QUICPacketType::VERSION_NEGOTIATION,
packet_sent_by_client->source_cid(),
- packet_sent_by_client->destination_cid(), 0x00,
0x00, 0x00, std::move(versions), len);
+ QUICPacketHeader::build(QUICPacketType::VERSION_NEGOTIATION, dcid, scid,
0x00, 0x00, 0x00, std::move(versions), len);
return QUICPacketFactory::_create_unprotected_packet(std::move(header));
}
diff --git a/iocore/net/quic/QUICPacket.h b/iocore/net/quic/QUICPacket.h
index febd398..f95c9bf 100644
--- a/iocore/net/quic/QUICPacket.h
+++ b/iocore/net/quic/QUICPacket.h
@@ -362,10 +362,12 @@ class QUICPacketFactory
{
public:
static QUICPacketUPtr create_null_packet();
+ static QUICPacketUPtr create_version_negotiation_packet(QUICConnectionId
dcid, QUICConnectionId scid);
+ static QUICPacketUPtr create_stateless_reset_packet(QUICConnectionId
connection_id,
+ QUICStatelessResetToken
stateless_reset_token);
QUICPacketUPtr create(IpEndpoint from, ats_unique_buf buf, size_t len,
QUICPacketNumber base_packet_number,
QUICPacketCreationResult &result);
- QUICPacketUPtr create_version_negotiation_packet(const QUICPacket
*packet_sent_by_client);
QUICPacketUPtr create_initial_packet(QUICConnectionId destination_cid,
QUICConnectionId source_cid,
QUICPacketNumber base_packet_number,
ats_unique_buf payload, size_t len);
QUICPacketUPtr create_retry_packet(QUICConnectionId destination_cid,
QUICConnectionId source_cid, ats_unique_buf payload,
@@ -375,18 +377,16 @@ public:
bool retransmittable);
QUICPacketUPtr create_server_protected_packet(QUICConnectionId
connection_id, QUICPacketNumber base_packet_number,
ats_unique_buf payload, size_t
len, bool retransmittable);
- static QUICPacketUPtr create_stateless_reset_packet(QUICConnectionId
connection_id,
- QUICStatelessResetToken
stateless_reset_token);
void set_version(QUICVersion negotiated_version);
void set_hs_protocol(QUICHandshakeProtocol *hs_protocol);
- void set_dcil(uint8_t len);
+ [[deprecated]] void set_dcil(uint8_t len);
private:
QUICVersion _version = QUIC_SUPPORTED_VERSIONS[0];
QUICHandshakeProtocol *_hs_protocol = nullptr;
QUICPacketNumberGenerator _packet_number_generator;
- uint8_t _dcil = 0;
static QUICPacketUPtr _create_unprotected_packet(QUICPacketHeaderUPtr
header);
QUICPacketUPtr _create_encrypted_packet(QUICPacketHeaderUPtr header, bool
retransmittable);
+ [[deprecated]] uint8_t _dcil = 0;
};
diff --git a/iocore/net/quic/QUICTypes.cc b/iocore/net/quic/QUICTypes.cc
index b84b568..faf3bb6 100644
--- a/iocore/net/quic/QUICTypes.cc
+++ b/iocore/net/quic/QUICTypes.cc
@@ -24,6 +24,7 @@
#include <algorithm>
#include "QUICTypes.h"
#include "QUICIntUtil.h"
+#include "QUICConfig.h"
// TODO: move to somewhere in lib/ts/
static int
@@ -46,7 +47,6 @@ to_hex_str(char *dst, size_t dst_len, const uint8_t *src,
size_t src_len)
}
bool
-#include <algorithm>
QUICTypeUtil::has_long_header(const uint8_t *buf)
{
return (buf[0] & 0x80) != 0;
@@ -337,3 +337,97 @@ QUICConnectionId::hex(char *buf, size_t len) const
{
return to_hex_str(buf, len, this->_id, this->_len);
}
+
+//
+// QUICInvariants
+//
+bool
+QUICInvariants::is_long_header(const uint8_t *buf)
+{
+ return (buf[0] & 0x80) != 0;
+}
+
+bool
+QUICInvariants::is_version_negotiation(QUICVersion v)
+{
+ return v == 0x0;
+}
+
+bool
+QUICInvariants::version(QUICVersion &dst, const uint8_t *buf, uint64_t buf_len)
+{
+ if (!QUICInvariants::is_long_header(buf) || buf_len <
QUICInvariants::LH_DCIL_OFFSET) {
+ return false;
+ }
+
+ dst = QUICTypeUtil::read_QUICVersion(buf +
QUICInvariants::LH_VERSION_OFFSET);
+
+ return true;
+}
+
+bool
+QUICInvariants::dcid(QUICConnectionId &dst, const uint8_t *buf, uint64_t
buf_len)
+{
+ uint8_t dcil = 0;
+ size_t dcid_offset = 0;
+
+ if (QUICInvariants::is_long_header(buf)) {
+ if (buf_len < QUICInvariants::LH_DCIL_OFFSET) {
+ return false;
+ }
+
+ dcil = buf[QUICInvariants::LH_DCIL_OFFSET] >> 4;
+ if (dcil) {
+ dcil += QUICInvariants::CIL_BASE;
+ } else {
+ dst = QUICConnectionId::ZERO();
+ return true;
+ }
+
+ dcid_offset = QUICInvariants::LH_DCID_OFFSET;
+ } else {
+ // remote dcil is local scil
+ dcil = QUICConfigParams::SCIL + QUICInvariants::CIL_BASE;
+ dcid_offset = QUICInvariants::SH_DCID_OFFSET;
+ }
+
+ if (dcid_offset + dcil > buf_len) {
+ return false;
+ }
+
+ dst = QUICTypeUtil::read_QUICConnectionId(buf + dcid_offset, dcil);
+
+ return true;
+}
+
+bool
+QUICInvariants::scid(QUICConnectionId &dst, const uint8_t *buf, uint64_t
buf_len)
+{
+ ink_assert(QUICInvariants::is_long_header(buf));
+
+ if (buf_len < QUICInvariants::LH_DCIL_OFFSET) {
+ return false;
+ }
+
+ uint8_t dcil = buf[QUICInvariants::LH_DCIL_OFFSET] >> 4;
+ if (dcil) {
+ dcil += CIL_BASE;
+ }
+
+ uint8_t scid_offset = QUICInvariants::LH_DCID_OFFSET + dcil;
+ uint8_t scil = buf[QUICInvariants::LH_DCIL_OFFSET] & 0x0F;
+ if (scil) {
+ scil += CIL_BASE;
+ } else {
+ dst = QUICConnectionId::ZERO();
+ return true;
+ }
+
+ if (scid_offset + scil > buf_len) {
+ return false;
+ }
+
+ dst = QUICTypeUtil::read_QUICConnectionId(buf + scid_offset, scil);
+
+ return true;
+}
diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h
index 54646f8..307a447 100644
--- a/iocore/net/quic/QUICTypes.h
+++ b/iocore/net/quic/QUICTypes.h
@@ -312,10 +312,11 @@ private:
uint64_t _hash_code = 0;
};
+// TODO: move version independent functions to QUICInvariants
class QUICTypeUtil
{
public:
- static bool has_long_header(const uint8_t *buf);
+ [[deprecated]] static bool has_long_header(const uint8_t *buf);
static bool has_connection_id(const uint8_t *buf);
static bool is_supported_version(QUICVersion version);
static QUICStreamType detect_stream_type(QUICStreamId id);
@@ -341,3 +342,21 @@ public:
private:
};
+
+class QUICInvariants
+{
+public:
+ static bool is_long_header(const uint8_t *buf);
+ static bool is_version_negotiation(QUICVersion v);
+ static bool version(QUICVersion &dst, const uint8_t *buf, uint64_t buf_len);
+ static bool dcid(QUICConnectionId &dst, const uint8_t *buf, uint64_t
buf_len);
+ static bool scid(QUICConnectionId &dst, const uint8_t *buf, uint64_t
buf_len);
+
+ const static size_t CIL_BASE = 3;
+ const static size_t LH_VERSION_OFFSET = 1;
+ const static size_t LH_DCIL_OFFSET = 5;
+ const static size_t LH_DCID_OFFSET = 6;
+ const static size_t SH_DCID_OFFSET = 1;
+ const static size_t LH_MIN_LEN = 6;
+ const static size_t SH_MIN_LEN = 1;
+};
diff --git a/iocore/net/quic/test/Makefile.am b/iocore/net/quic/test/Makefile.am
index 3634ae5..b28e654 100644
--- a/iocore/net/quic/test/Makefile.am
+++ b/iocore/net/quic/test/Makefile.am
@@ -18,6 +18,7 @@
TESTS = $(check_PROGRAMS)
check_PROGRAMS = \
+ test_QUICInvariants \
test_QUICPacket \
test_QUICPacketFactory \
test_QUICFrame \
@@ -80,6 +81,22 @@ test_LDADD = \
@HWLOC_LIBS@
#
+# test_QUICInvariants
+#
+test_QUICInvariants_CPPFLAGS = \
+ $(AM_CPPFLAGS)
+
+test_QUICInvariants_LDFLAGS = \
+ @AM_LDFLAGS@
+
+test_QUICInvariants_SOURCES = \
+ $(catch_main) \
+ test_QUICInvariants.cc
+
+test_QUICInvariants_LDADD = \
+ $(test_LDADD)
+
+#
# test_QUICPacket
#
test_QUICPacket_CPPFLAGS = \
diff --git a/iocore/net/quic/test/test_QUICInvariants.cc
b/iocore/net/quic/test/test_QUICInvariants.cc
new file mode 100644
index 0000000..4f7ad05
--- /dev/null
+++ b/iocore/net/quic/test/test_QUICInvariants.cc
@@ -0,0 +1,147 @@
+/** @file
+ *
+ * A brief file description
+ *
+ * @section license License
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "catch.hpp"
+
+#include "quic/QUICTypes.h"
+
+TEST_CASE("Long Header - regular case", "[quic]")
+{
+ const uint8_t buf[] = {
+ 0x80, // Long header, Type: NONE
+ 0x11, 0x22, 0x33, 0x44, // Version
+ 0x55, // DCIL/SCIL
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Destination Connection
ID
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, // Source Connection ID
+ };
+ uint64_t buf_len = sizeof(buf);
+
+ const uint8_t raw_dcid[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+ const uint8_t raw_scid[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
+ QUICConnectionId expected_dcid(raw_dcid, 8);
+ QUICConnectionId expected_scid(raw_scid, 8);
+
+ QUICVersion version = 0;
+ QUICConnectionId dcid = QUICConnectionId::ZERO();
+ QUICConnectionId scid = QUICConnectionId::ZERO();
+
+ CHECK(QUICInvariants::version(version, buf, buf_len));
+ CHECK(version == 0x11223344);
+ CHECK(QUICInvariants::dcid(dcid, buf, buf_len));
+ CHECK(dcid == expected_dcid);
+ CHECK(QUICInvariants::scid(scid, buf, buf_len));
+ CHECK(scid == expected_scid);
+}
+
+TEST_CASE("Long Header - error cases", "[quic]")
+{
+ SECTION("version")
+ {
+ const uint8_t buf[] = {
+ 0x80, // Long header, Type: NONE
+ };
+ uint64_t buf_len = sizeof(buf);
+
+ QUICVersion version = 0;
+
+ CHECK(QUICInvariants::version(version, buf, buf_len) == false);
+ }
+
+ SECTION("dcid")
+ {
+ const uint8_t buf[] = {
+ 0x80, // Long header, Type: NONE
+ 0x11, 0x22, 0x33, 0x44, // Version
+ 0x55, // DCIL/SCIL
+ 0x01, 0x02, 0x03, 0x04, // Invalid Destination Connection ID
+ };
+ uint64_t buf_len = sizeof(buf);
+
+ const uint8_t raw_dcid[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08};
+ QUICConnectionId expected_dcid(raw_dcid, 8);
+
+ QUICVersion version = 0;
+ QUICConnectionId dcid = QUICConnectionId::ZERO();
+
+ CHECK(QUICInvariants::version(version, buf, buf_len));
+ CHECK(version == 0x11223344);
+ CHECK(QUICInvariants::dcid(dcid, buf, buf_len) == false);
+ }
+
+ SECTION("scid")
+ {
+ const uint8_t buf[] = {
+ 0x80, // Long header, Type:
NONE
+ 0x11, 0x22, 0x33, 0x44, // Version
+ 0x55, // DCIL/SCIL
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Destination
Connection ID
+ 0x11, 0x12, 0x13, 0x14, // Invalid Source
Connection ID
+ };
+ uint64_t buf_len = sizeof(buf);
+
+ const uint8_t raw_dcid[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08};
+ const uint8_t raw_scid[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18};
+ QUICConnectionId expected_dcid(raw_dcid, 8);
+ QUICConnectionId expected_scid(raw_scid, 8);
+
+ QUICVersion version = 0;
+ QUICConnectionId dcid = QUICConnectionId::ZERO();
+ QUICConnectionId scid = QUICConnectionId::ZERO();
+
+ CHECK(QUICInvariants::version(version, buf, buf_len));
+ CHECK(version == 0x11223344);
+ CHECK(QUICInvariants::dcid(dcid, buf, buf_len));
+ CHECK(dcid == expected_dcid);
+ CHECK(QUICInvariants::scid(scid, buf, buf_len) == false);
+ }
+}
+
+TEST_CASE("Short Header - regular case", "[quic]")
+{
+ const uint8_t buf[] = {
+ 0x00, // Long header, Type: NONE
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Destination Connection
ID
+ };
+ uint64_t buf_len = sizeof(buf);
+
+ const uint8_t raw_dcid[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+ QUICConnectionId expected_dcid(raw_dcid, 8);
+
+ QUICConnectionId dcid = QUICConnectionId::ZERO();
+
+ CHECK(QUICInvariants::dcid(dcid, buf, buf_len));
+ CHECK(dcid == expected_dcid);
+}
+
+// When ATS change QUICConfigParams::SCIL, this test should be failed
+TEST_CASE("Short Header - error case", "[quic]")
+{
+ const uint8_t buf[] = {
+ 0x00, // Long header, Type: NONE
+ 0x01, 0x02, 0x03, 0x04, // Invalid Destination Connection ID
+ };
+ uint64_t buf_len = sizeof(buf);
+
+ QUICConnectionId dcid = QUICConnectionId::ZERO();
+ CHECK(QUICInvariants::dcid(dcid, buf, buf_len) == false);
+}
diff --git a/iocore/net/quic/test/test_QUICPacketFactory.cc
b/iocore/net/quic/test/test_QUICPacketFactory.cc
index 0ebc38b..cd3bb50 100644
--- a/iocore/net/quic/test/test_QUICPacketFactory.cc
+++ b/iocore/net/quic/test/test_QUICPacketFactory.cc
@@ -32,32 +32,16 @@
TEST_CASE("QUICPacketFactory_Create_VersionNegotiationPacket", "[quic]")
MockQUICHandshakeProtocol hs_protocol;
factory.set_hs_protocol(&hs_protocol);
- uint8_t initial_packet_header[] = {
- 0xFF, // Type
- 0xaa, 0xbb, 0xcc, 0xdd, // Version
- 0x55, // DCIL/SCIL
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Destination Connection
id
- 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, // Source Connection id
- 0x01, // Payload Length
- 0x00, 0x00, 0x00, 0x00, // Packet number
- };
- uint8_t initial_packet_payload[] = {
- 0x00 // Payload
- };
-
- QUICPacketHeaderUPtr header =
- QUICPacketHeader::load({}, {initial_packet_header, [](void *) {}},
sizeof(initial_packet_header), 0, 8);
-
- QUICPacket initial_packet(std::move(header),
ats_unique_buf(initial_packet_payload, [](void *) {}),
- sizeof(initial_packet_payload), 0);
+ const uint8_t raw_dcid[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+ const uint8_t raw_scid[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
+ QUICConnectionId dcid(raw_dcid, 8);
+ QUICConnectionId scid(raw_scid, 8);
- QUICPacketUPtr vn_packet =
factory.create_version_negotiation_packet(&initial_packet);
+ QUICPacketUPtr vn_packet = factory.create_version_negotiation_packet(scid,
dcid);
CHECK(vn_packet->type() == QUICPacketType::VERSION_NEGOTIATION);
- uint8_t dst_cid[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
- uint8_t src_cid[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
- CHECK((vn_packet->source_cid() == QUICConnectionId(dst_cid,
sizeof(dst_cid))));
- CHECK((vn_packet->destination_cid() == QUICConnectionId(src_cid,
sizeof(src_cid))));
+ CHECK(vn_packet->destination_cid() == scid);
+ CHECK(vn_packet->source_cid() == dcid);
CHECK(vn_packet->version() == 0x00);
QUICVersion supported_version =
QUICTypeUtil::read_QUICVersion(vn_packet->payload());
diff --git a/iocore/net/quic/test/test_QUICVersionNegotiator.cc
b/iocore/net/quic/test/test_QUICVersionNegotiator.cc
index 07dcdd7..78142b6 100644
--- a/iocore/net/quic/test/test_QUICVersionNegotiator.cc
+++ b/iocore/net/quic/test/test_QUICVersionNegotiator.cc
@@ -121,7 +121,8 @@ TEST_CASE("QUICVersionNegotiator - Client Side", "[quic]")
QUICPacketUPtr initial_packet = packet_factory.create_initial_packet({},
{}, 0, ats_unique_malloc(0), 0);
// Server send VN packet based on Initial packet
- QUICPacketUPtr vn_packet =
packet_factory.create_version_negotiation_packet(initial_packet.get());
+ QUICPacketUPtr vn_packet =
+
packet_factory.create_version_negotiation_packet(initial_packet->source_cid(),
initial_packet->destination_cid());
// Negotiate version
vn.negotiate(vn_packet.get());
--
To stop receiving notification emails like this one, please contact
[email protected].