Add test cases for QuicDrill Initial Packet fuzzing (#44)

These test cases cover fuzzing the Connection ID (CID) in the initial packet, as well the optional Token field.
Changes are passing in both TAEF and gtest.
This commit is contained in:
Anthony 2020-01-16 14:08:52 -08:00 коммит произвёл GitHub
Родитель e7bc785c09
Коммит 74cc1a5b73
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 619 добавлений и 24 удалений

Просмотреть файл

@ -219,6 +219,20 @@ void
QuicDrillTestVarIntEncoder(
);
void
QuicDrillTestInitialCid(
_In_ int Family,
_In_ bool Source, // or Dest
_In_ bool ValidActualLength, // or invalid
_In_ bool Short, // or long
_In_ bool ValidLengthField // or invalid
);
void
QuicDrillTestInitialToken(
_In_ int Family
);
//
// Platform Specific Functions
//
@ -470,6 +484,22 @@ typedef struct {
#define IOCTL_QUIC_RUN_DRILL_ENCODE_VAR_INT \
QUIC_CTL_CODE(35, METHOD_BUFFERED, FILE_WRITE_DATA)
#define QUIC_MAX_IOCTL_FUNC_CODE 35
typedef struct {
INT32 Family;
BOOLEAN SourceOrDest;
BOOLEAN ActualCidLengthValid;
BOOLEAN ShortCidLength;
BOOLEAN CidLengthFieldValid;
} QUIC_RUN_DRILL_INITIAL_PACKET_CID_PARAMS;
#define IOCTL_QUIC_RUN_DRILL_INITIAL_PACKET_CID \
QUIC_CTL_CODE(36, METHOD_BUFFERED, FILE_WRITE_DATA)
// QUIC_RUN_DRILL_INITIAL_PACKET_CID_PARAMS
#define IOCTL_QUIC_RUN_DRILL_INITIAL_PACKET_TOKEN \
QUIC_CTL_CODE(37, METHOD_BUFFERED, FILE_WRITE_DATA)
// INT32 - Family
#define QUIC_MAX_IOCTL_FUNC_CODE 37
#endif // _WIN32

Просмотреть файл

@ -19,8 +19,13 @@ QUIC_SEC_CONFIG* SecurityConfig;
extern "C" _IRQL_requires_max_(PASSIVE_LEVEL) void QuicTraceRundown(void) { }
class QuicTestEnvironment : public ::testing::Environment {
bool PlatformInitialized;
public:
void SetUp() override {
if (QUIC_FAILED(QuicPlatformInitialize())) {
return; // TODO - FAIL SetUp
}
PlatformInitialized = true;
if (QUIC_FAILED(MsQuicOpenV1(&MsQuic))) {
return; // TODO - FAIL SetUp
}
@ -51,6 +56,9 @@ public:
Registration = nullptr;
MsQuicClose(MsQuic);
MsQuic = nullptr;
if (PlatformInitialized) {
QuicPlatformUninitialize();
}
}
_Function_class_(QUIC_SEC_CONFIG_CREATE_COMPLETE)
static void
@ -419,6 +427,21 @@ TEST_P(WithReceiveResumeNoDataArgs, ReceiveResumeNoData) {
QuicTestReceiveResumeNoData(GetParam().Family, GetParam().ShutdownType);
}
TEST_P(WithDrillInitialPacketCidArgs, DrillInitialPacketCids) {
TestLoggerT<ParamType> Logger("QuicDrillInitialPacketCids", GetParam());
QuicDrillTestInitialCid(
GetParam().Family,
GetParam().SourceOrDest,
GetParam().ActualCidLengthValid,
GetParam().ShortCidLength,
GetParam().CidLengthFieldValid);
}
TEST_P(WithDrillInitialPacketTokenArgs, DrillInitialPacketToken) {
TestLoggerT<ParamType> Logger("QuicDrillInitialPacketToken", GetParam());
QuicDrillTestInitialToken(GetParam().Family);
}
INSTANTIATE_TEST_CASE_P(
ParameterValidation,
WithBool,
@ -479,6 +502,16 @@ INSTANTIATE_TEST_CASE_P(
WithReceiveResumeNoDataArgs,
testing::ValuesIn(ReceiveResumeNoDataArgs::Generate()));
INSTANTIATE_TEST_CASE_P(
Drill,
WithDrillInitialPacketCidArgs,
testing::ValuesIn(DrillInitialPacketCidArgs::Generate()));
INSTANTIATE_TEST_CASE_P(
Drill,
WithDrillInitialPacketTokenArgs,
testing::ValuesIn(DrillInitialPacketTokenArgs::Generate()));
int main(int argc, char** argv) {
::testing::AddGlobalTestEnvironment(new QuicTestEnvironment);
::testing::InitGoogleTest(&argc, argv);

Просмотреть файл

@ -318,3 +318,55 @@ std::ostream& operator << (std::ostream& o, const ReceiveResumeNoDataArgs& args)
class WithReceiveResumeNoDataArgs : public testing::Test,
public testing::WithParamInterface<ReceiveResumeNoDataArgs> {
};
struct DrillInitialPacketCidArgs {
int Family;
bool SourceOrDest;
bool ActualCidLengthValid;
bool ShortCidLength;
bool CidLengthFieldValid;
static ::std::vector<DrillInitialPacketCidArgs> Generate() {
::std::vector<DrillInitialPacketCidArgs> list;
for (int Family : { 4, 6 })
for (bool SourceOrDest : { true, false })
for (bool ActualCidLengthValid : { true, false })
for (bool ShortCidLength : { true, false })
for (bool CidLengthFieldValid : { true, false })
list.push_back({ Family, SourceOrDest, ActualCidLengthValid, ShortCidLength, CidLengthFieldValid });
return list;
}
};
std::ostream& operator << (std::ostream& o, const DrillInitialPacketCidArgs& args) {
return o <<
(args.Family == 4 ? "v4" : "v6") << "/" <<
(args.SourceOrDest ? "SourceCid" : "DestCid") << "/" <<
(args.ActualCidLengthValid ? "Valid" : "Invalid") << "/" <<
(args.ShortCidLength ? "Short" : "Long") << "/" <<
(args.CidLengthFieldValid ? "Valid" : "Invalid") << " length";
}
class WithDrillInitialPacketCidArgs: public testing::Test,
public testing::WithParamInterface<DrillInitialPacketCidArgs> {
};
struct DrillInitialPacketTokenArgs {
int Family;
static ::std::vector<DrillInitialPacketTokenArgs> Generate() {
::std::vector<DrillInitialPacketTokenArgs> list;
for (int Family : { 4, 6 })
list.push_back({ Family, });
return list;
}
};
std::ostream& operator << (std::ostream& o, const DrillInitialPacketTokenArgs& args) {
return o <<
(args.Family == 4 ? "v4" : "v6");
}
class WithDrillInitialPacketTokenArgs: public testing::Test,
public testing::WithParamInterface<DrillInitialPacketTokenArgs> {
};

Просмотреть файл

@ -9,23 +9,28 @@
DrillBuffer
QuicDrillEncodeQuicVarInt(
uint64_t input
uint64_t input,
const DrillVarIntSize size
)
{
DrillBuffer result;
uint8_t* inputPointer = ((uint8_t*)&input);
if (input < 0x40) {
if (size == OneByte) {
QUIC_FRE_ASSERT(input < 0x40);
result.push_back((uint8_t) input);
} else if (input < 0x4000) {
} else if (size == TwoBytes) {
QUIC_FRE_ASSERT(input < 0x4000);
result.push_back(0x40 | inputPointer[1]);
result.push_back(inputPointer[0]);
} else if (input < 0x40000000) {
} else if (size == FourBytes) {
QUIC_FRE_ASSERT(input < 0x40000000);
result.push_back(0x80 | inputPointer[3]);
result.push_back(inputPointer[2]);
result.push_back(inputPointer[1]);
result.push_back(inputPointer[0]);
} else if (input < 0x4000000000000000ull) {
} else if (size == EightBytes) {
QUIC_FRE_ASSERT(input < 0x4000000000000000ull);
result.push_back(0xc0 | inputPointer[7]);
result.push_back(inputPointer[6]);
result.push_back(inputPointer[5]);
@ -36,15 +41,37 @@ QuicDrillEncodeQuicVarInt(
result.push_back(inputPointer[0]);
} else {
QUIC_FRE_ASSERTMSG(
input < 0x4000000000000000ull,
"Supplied value is larger than QUIC_VAR_INT allowed (2^62)");
size == EightBytes,
"Supplied size is not a valid QUIC_VAR_INT size");
}
return result;
}
DrillBuffer
DrillPacketDescriptor::write(
QuicDrillEncodeQuicVarInt (
uint64_t input
)
{
if (input < 0x40) {
return QuicDrillEncodeQuicVarInt(input, OneByte);
} else if (input < 0x4000) {
return QuicDrillEncodeQuicVarInt(input, TwoBytes);
} else if (input < 0x40000000) {
return QuicDrillEncodeQuicVarInt(input, FourBytes);
} else if (input < 0x4000000000000000ull) {
return QuicDrillEncodeQuicVarInt(input, EightBytes);
} else {
QUIC_FRE_ASSERTMSG(
input < 0x4000000000000000ull,
"Supplied value is larger than QUIC_VAR_INT allowed (2^62)");
return DrillBuffer();
}
return DrillBuffer();
}
DrillBuffer
DrillPacketDescriptor::write(
) const
{
size_t RequiredSize = 0;
@ -52,11 +79,11 @@ DrillPacketDescriptor::write(
// Calculate the size required to write the packet.
//
RequiredSize += 1; // For the bit fields.
RequiredSize += sizeof(this->Version);
RequiredSize += sizeof(Version);
RequiredSize += 1; // For the size of DestCid.
RequiredSize += this->DestCid.size();
RequiredSize += DestCid.size();
RequiredSize += 1; // For the size of SourceCid.
RequiredSize += this->SourceCid.size();
RequiredSize += SourceCid.size();
QUIC_FRE_ASSERTMSG(
RequiredSize <= UINT16_MAX,
@ -77,8 +104,8 @@ DrillPacketDescriptor::write(
//
// Copy version.
//
for (int i = 0; i < sizeof(this->Version); ++i) {
PacketBuffer.push_back((uint8_t) (Version >> ((3 - i) * 8)));
for (int i = 0; i < sizeof(Version); ++i) {
PacketBuffer.push_back((uint8_t) (Version >> (((sizeof(Version) - 1) - i) * 8)));
}
//
@ -109,17 +136,23 @@ DrillPacketDescriptor::write(
}
DrillInitialPacketDescriptor::DrillInitialPacketDescriptor(
)
) : DrillPacketDescriptor(), TokenLen(nullptr), PacketLength(nullptr), PacketNumber(0)
{
this->Type = Initial;
this->Header.LongHeader = 1;
this->Header.FixedBit = 1;
this->Version = 1;
Type = Initial;
Header.LongHeader = 1;
Header.FixedBit = 1;
Version = QUIC_VERSION_LATEST_H;
const uint8_t CidValMax = 8;
for (uint8_t CidVal = 0; CidVal <= CidValMax; CidVal++) {
DestCid.push_back(CidVal);
SourceCid.push_back(CidValMax - CidVal);
}
}
DrillBuffer
DrillInitialPacketDescriptor::write(
)
) const
{
DrillBuffer PacketBuffer = DrillPacketDescriptor::write();

Просмотреть файл

@ -18,7 +18,9 @@ class DrillBuffer : public Rtl::KArray<uint8_t>
QUIC_FRE_ASSERT(append(value));
}
size_t size() { return count(); }
const uint8_t* data() const { return &(*this)[0]; }
size_t size() const { return count(); }
void
insert(
@ -80,10 +82,12 @@ struct DrillPacketDescriptor {
uint8_t* SourceCidLen;
DrillBuffer SourceCid;
DrillPacketDescriptor() : SourceCidLen(nullptr), DestCidLen(nullptr) {};
//
// Write this descriptor to a byte array to send on the wire.
//
virtual DrillBuffer write();
virtual DrillBuffer write() const;
};
@ -117,10 +121,23 @@ struct DrillInitialPacketDescriptor : DrillPacketDescriptor {
//
// Write this descriptor to a byte array to send on the wire.
//
virtual DrillBuffer write();
virtual DrillBuffer write() const;
};
enum DrillVarIntSize {
OneByte = 1,
TwoBytes = 2,
FourBytes = 4,
EightBytes = 8
};
DrillBuffer
QuicDrillEncodeQuicVarInt (
const uint64_t input,
const DrillVarIntSize size
);
DrillBuffer
QuicDrillEncodeQuicVarInt(
uint64_t input
);
);

Просмотреть файл

@ -7,9 +7,18 @@ Abstract:
MsQuic Packet-level tests.
Future:
Additional test cases to implement:
* Test packet number encoded larger than necessary with valid Initial
packet.
* Test reserved header flags, and packet number size mismatch.
--*/
#include "precomp.h"
extern "C" {
#include <quic_datapath.h>
}
void
QuicDrillTestVarIntEncoder(
@ -56,4 +65,409 @@ QuicDrillTestVarIntEncoder(
TEST_EQUAL(output[5], 0xff);
TEST_EQUAL(output[6], 0xff);
TEST_EQUAL(output[7], 0xff);
}
_IRQL_requires_max_(PASSIVE_LEVEL)
_Function_class_(NEW_CONNECTION_CALLBACK)
static
void
QuicDrillConnectionCallbackHandler(
_In_ TestListener* /* Listener */,
_In_ HQUIC ConnectionHandle
)
{
TEST_FAILURE("Quic Drill listener received an unexpected event!");
MsQuic->ConnectionClose(ConnectionHandle);
}
struct DrillSender {
QUIC_DATAPATH* Datapath;
QUIC_DATAPATH_BINDING* Binding;
QUIC_ADDR ServerAddress;
_IRQL_requires_max_(DISPATCH_LEVEL)
_Function_class_(QUIC_DATAPATH_RECEIVE_CALLBACK)
static void
DrillUdpRecvCallback(
_In_ QUIC_DATAPATH_BINDING* /* Binding */,
_In_ void* /* Context */,
_In_ QUIC_RECV_DATAGRAM* RecvBufferChain
)
{
QuicDataPathBindingReturnRecvDatagrams(RecvBufferChain);
}
_IRQL_requires_max_(DISPATCH_LEVEL)
_Function_class_(QUIC_DATAPATH_UNREACHABLE_CALLBACK)
static void
DrillUdpUnreachCallback(
_In_ QUIC_DATAPATH_BINDING* /* Binding */,
_In_ void* /* Context */,
_In_ const QUIC_ADDR* /* RemoteAddress */
)
{
}
DrillSender() : Datapath(nullptr), Binding(nullptr) {}
~DrillSender() {
if (Binding != nullptr) {
QuicDataPathBindingDelete(Binding);
}
if (Datapath != nullptr) {
QuicDataPathUninitialize(Datapath);
}
}
QUIC_STATUS
Initialize(
_In_ const char* HostName,
_In_ QUIC_ADDRESS_FAMILY Family,
_In_ uint16_t NetworkPort
)
{
QUIC_ADDR ServerAddress;
QUIC_STATUS Status =
QuicDataPathInitialize(
0,
DrillUdpRecvCallback,
DrillUdpUnreachCallback,
&Datapath);
if (QUIC_FAILED(Status)) {
TEST_FAILURE("Datapath init failed 0x%x", Status);
return Status;
}
ServerAddress.si_family = Family;
Status =
QuicDataPathResolveAddress(
Datapath,
HostName,
&ServerAddress);
if (QUIC_FAILED(Status)) {
TEST_FAILURE("Address resolution failed 0x%x", Status);
return Status;
}
if (Family == AF_INET) {
ServerAddress.Ipv4.sin_port = NetworkPort;
} else {
ServerAddress.Ipv6.sin6_port = NetworkPort;
}
Status =
QuicDataPathBindingCreate(
Datapath,
nullptr,
&ServerAddress,
this,
&Binding);
if (QUIC_FAILED(Status)) {
TEST_FAILURE("Binding failed: 0x%x", Status);
}
return Status;
}
QUIC_STATUS
Send(
_In_ const DrillBuffer* PacketBuffer
)
{
QUIC_STATUS Status = QUIC_STATUS_SUCCESS;
QUIC_FRE_ASSERT(PacketBuffer->size() <= UINT16_MAX);
const uint16_t DatagramLength = (uint16_t) PacketBuffer->size();
QUIC_DATAPATH_SEND_CONTEXT* SendContext =
QuicDataPathBindingAllocSendContext(Binding, DatagramLength);
QUIC_BUFFER* SendBuffer =
QuicDataPathBindingAllocSendDatagram(SendContext, DatagramLength);
if (SendBuffer == nullptr) {
TEST_FAILURE("Buffer null");
Status = QUIC_STATUS_OUT_OF_MEMORY;
return Status;
}
// Copy test packet into SendBuffer.
memcpy(SendBuffer->Buffer, PacketBuffer->data(), DatagramLength);
QuicDataPathBindingSendTo(
Binding,
&ServerAddress,
SendContext);
return Status;
}
};
bool
QuicDrillInitialPacketFailureTest(
_In_ QUIC_ADDRESS_FAMILY QuicAddrFamily,
_In_ const DrillInitialPacketDescriptor& InitialPacketDescriptor
)
{
QUIC_STATUS Status;
QUIC_LISTENER_STATISTICS Stats;
uint64_t DroppedPacketsBefore;
uint64_t DroppedPacketsAfter;
uint8_t Disabled = FALSE;
QuicAddr ServerAddress(QuicAddrFamily);
MsQuicRegistration QuicDrillRegistration;
if (!QuicDrillRegistration.IsValid()) {
TEST_FAILURE("QuicDrillRegistration not valid!");
return false;
}
DrillSender Sender;
Status =
MsQuic->SetParam(
QuicDrillRegistration,
QUIC_PARAM_LEVEL_REGISTRATION,
QUIC_PARAM_REGISTRATION_ENCRYPTION,
sizeof(Disabled),
&Disabled);
if (QUIC_FAILED(Status)) {
TEST_FAILURE("Failed to disable encryption for test. 0x%x", Status);
return false;
}
MsQuicSession Session(QuicDrillRegistration);
if (!Session.IsValid()) {
TEST_FAILURE("Session not valid!");
return false;
}
{
//
// Start the server.
//
TestListener Listener(Session.Handle, QuicDrillConnectionCallbackHandler);
Status = Listener.Start(&ServerAddress.SockAddr);
if (QUIC_FAILED(Status)) {
TEST_FAILURE("ListenerStart failed, 0x%x.", Status);
return false;
}
//
// Get server address (port) here.
//
Status = Listener.GetLocalAddr(ServerAddress);
if (QUIC_FAILED(Status)) {
TEST_FAILURE("MsQuic->GetParam failed, 0x%x.", Status);
return false;
}
Status =
Sender.Initialize(
QUIC_LOCALHOST_FOR_AF(QuicAddrFamily),
QuicAddrFamily,
(QuicAddrFamily == AF_INET) ?
ServerAddress.SockAddr.Ipv4.sin_port :
ServerAddress.SockAddr.Ipv6.sin6_port);
if (QUIC_FAILED(Status)) {
return false;
}
DrillBuffer PacketBuffer = InitialPacketDescriptor.write();
Status = Listener.GetStatistics(Stats);
if (QUIC_FAILED(Status)) {
TEST_FAILURE("Get Listener statistics before test failed, 0x%x.", Status);
return false;
}
DroppedPacketsBefore = Stats.Binding.Recv.DroppedPackets;
//
// Send test packet to the server.
//
Status = Sender.Send(&PacketBuffer);
if (QUIC_FAILED(Status)) {
return false;
}
//
// Generously wait for server to process packet.
//
QuicSleep(100);
Status = Listener.GetStatistics(Stats);
if (QUIC_FAILED(Status)) {
TEST_FAILURE("Get Listener statistics after test failed, 0x%x.", Status);
return false;
}
DroppedPacketsAfter = Stats.Binding.Recv.DroppedPackets;
//
// Validate the server rejected the packet just sent.
// N.B. Could fail if the server has other packets sent to it accidentally.
//
if (DroppedPacketsAfter - DroppedPacketsBefore != 1) {
TEST_FAILURE("DroppedPacketsAfter - DroppedPacketsBefore not equal to 1");
return false;
}
}
return true;
}
#define VALID_CID_LENGTH_SHORT 8
#define VALID_CID_LENGTH_LONG 20
#define INVALID_CID_LENGTH_SHORT 7
#define INVALID_CID_LENGTH_LONG 21
void
QuicDrillTestInitialCid(
_In_ int Family,
_In_ bool Source, // or Dest
_In_ bool ValidActualLength, // or invalid
_In_ bool Short, // or long
_In_ bool ValidLengthField // or invalid
)
{
/**
* SourceCid valid length, but longer than valid length field indicates.
* SourceCid valid length, but shorter than valid length field indicates.
* SourceCid valid length, but shorter than invalid length field.
* SourceCid valid length, but longer than invalid length field.
* SourceCid invalidly short, but length field indicates valid length.
* SourceCid invalidly long, but length field indicates valid length.
* SourceCid invalidly short, and length field matches.
* SourceCid invalidly long, and length field matches.
* (Ditto for DestCid)
(source, dest), [(valid length, invalid length), (valid length field, invalid length field)], (short, long)
*/
uint8_t ActualCidLength;
uint8_t CidLengthField;
QUIC_ADDRESS_FAMILY QuicAddrFamily = (Family == 4) ? AF_INET : AF_INET6;
DrillInitialPacketDescriptor InitialDescriptor;
// Calculate the test parameters
if (ValidActualLength) {
if (Short) {
ActualCidLength = VALID_CID_LENGTH_SHORT;
} else {
ActualCidLength = VALID_CID_LENGTH_LONG;
}
if (ValidLengthField) {
// When both lengths are valid, we want to make the field different
// than the actual length so they don't agree.
if (!Short) {
CidLengthField = VALID_CID_LENGTH_SHORT;
} else {
CidLengthField = VALID_CID_LENGTH_LONG;
}
} else {
// When the length field is invalid, but the actual length valid,
// we want to make the length field very invalid.
if (!Short) {
CidLengthField = INVALID_CID_LENGTH_SHORT;
} else {
CidLengthField = INVALID_CID_LENGTH_LONG;
}
}
} else {
if (Short) {
ActualCidLength = INVALID_CID_LENGTH_SHORT;
} else {
ActualCidLength = INVALID_CID_LENGTH_LONG;
}
if (ValidLengthField) {
// When the actual length is invalid, but the length field valid,
// make the field the closest valid value.
if (Short) {
CidLengthField = VALID_CID_LENGTH_SHORT;
} else {
CidLengthField = VALID_CID_LENGTH_LONG;
}
} else {
// When both length field and actual length are invalid, make the
// values agree.
if (Short) {
CidLengthField = INVALID_CID_LENGTH_SHORT;
} else {
CidLengthField = INVALID_CID_LENGTH_LONG;
}
}
}
DrillBuffer TestCid;
for (int value = 0; value < ActualCidLength; value++) {
TestCid.push_back(0xff - (uint8_t) value); // Make this Cid look different from the default one.
}
if (Source) {
InitialDescriptor.SourceCid.clear();
InitialDescriptor.SourceCid.insert(InitialDescriptor.SourceCid.begin(), TestCid.begin(), TestCid.end());
InitialDescriptor.SourceCidLen = &CidLengthField;
} else {
InitialDescriptor.DestCid.clear();
InitialDescriptor.DestCid.insert(InitialDescriptor.DestCid.begin(), TestCid.begin(), TestCid.end());
InitialDescriptor.DestCidLen = &CidLengthField;
}
QuicDrillInitialPacketFailureTest(QuicAddrFamily, InitialDescriptor);
}
void
QuicDrillTestInitialToken(
_In_ int Family
)
{
QUIC_ADDRESS_FAMILY QuicAddrFamily = (Family == 4) ? AF_INET : AF_INET6;
const uint8_t GeneratedTokenLength = 20;
uint64_t TokenLen;
// Token length is larger than actual token.
{
DrillInitialPacketDescriptor InitialDescriptor;
for (uint8_t TokenValue = 0; TokenValue < GeneratedTokenLength; TokenValue++) {
InitialDescriptor.Token.push_back(TokenValue);
}
TokenLen = GeneratedTokenLength + 1;
InitialDescriptor.TokenLen = &TokenLen;
if (!QuicDrillInitialPacketFailureTest(QuicAddrFamily, InitialDescriptor)) {
return;
}
}
// Token length is shorter than actual token.
{
DrillInitialPacketDescriptor InitialDescriptor;
for (uint8_t TokenValue = 0; TokenValue < GeneratedTokenLength; TokenValue++) {
InitialDescriptor.Token.push_back(TokenValue);
}
TokenLen = GeneratedTokenLength - 1;
InitialDescriptor.TokenLen = &TokenLen;
if (!QuicDrillInitialPacketFailureTest(QuicAddrFamily, InitialDescriptor)) {
return;
}
}
// Token length is non-zero and token is not present.
{
DrillInitialPacketDescriptor InitialDescriptor;
TokenLen = 1;
InitialDescriptor.TokenLen = &TokenLen;
if (!QuicDrillInitialPacketFailureTest(QuicAddrFamily, InitialDescriptor)) {
return;
}
}
}

Просмотреть файл

@ -78,6 +78,21 @@ TestListener::GetLocalAddr(
&localAddr.SockAddr);
}
QUIC_STATUS
TestListener::GetStatistics(
_Out_ QUIC_LISTENER_STATISTICS &stats
)
{
uint32_t Size = sizeof(stats);
return
MsQuic->GetParam(
QuicListener,
QUIC_PARAM_LEVEL_LISTENER,
QUIC_PARAM_LISTENER_STATS,
&Size,
&stats);
}
QUIC_STATUS
TestListener::HandleListenerEvent(
_Inout_ QUIC_LISTENER_EVENT* Event

Просмотреть файл

@ -92,4 +92,5 @@ public:
//
QUIC_STATUS GetLocalAddr(_Out_ QuicAddr &localAddr);
QUIC_STATUS GetStatistics(_Out_ QUIC_LISTENER_STATISTICS &stats);
};