forked from microsoft/msquic
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clear out rebound paths upon path exhaustion (microsoft#1783)
* Clear out rebound paths upon path exhaustion Currently we have a hard limit of 4 paths for a connection. Rebinding can possibly fill up these paths, causing the connection to be dropped. As a solution, if we detect we're out of paths, we can see if any of the non active paths are on the same local address, and the same remote IP address, but just a different port, and if so we can discard the old paths, as if theyre used again they'll just show up as another rebind. Also adds a test that rebinds 50 times * Test and code cleanup * Fix review comments * Avoid address copy * Fix path test on linux, only consider non retired CID's as unused * Fix mtu * Increase wait timeout * Wait for server to respond
- Loading branch information
Showing
9 changed files
with
177 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/*++ | ||
Copyright (c) Microsoft Corporation. | ||
Licensed under the MIT License. | ||
Abstract: | ||
MsQuic Path Unittest | ||
--*/ | ||
|
||
#include "precomp.h" | ||
#ifdef QUIC_CLOG | ||
#include "PathTest.cpp.clog.h" | ||
#endif | ||
|
||
struct PathTestContext { | ||
CxPlatEvent HandshakeCompleteEvent; | ||
CxPlatEvent ShutdownEvent; | ||
MsQuicConnection* Connection {nullptr}; | ||
CxPlatEvent PeerAddrChangedEvent; | ||
|
||
static QUIC_STATUS ConnCallback(_In_ MsQuicConnection* Conn, _In_opt_ void* Context, _Inout_ QUIC_CONNECTION_EVENT* Event) { | ||
PathTestContext* Ctx = static_cast<PathTestContext*>(Context); | ||
Ctx->Connection = Conn; | ||
if (Event->Type == QUIC_CONNECTION_EVENT_SHUTDOWN_COMPLETE) { | ||
Ctx->Connection = nullptr; | ||
Ctx->PeerAddrChangedEvent.Set(); | ||
Ctx->ShutdownEvent.Set(); | ||
Ctx->HandshakeCompleteEvent.Set(); | ||
} else if (Event->Type == QUIC_CONNECTION_EVENT_CONNECTED) { | ||
Ctx->HandshakeCompleteEvent.Set(); | ||
} else if (Event->Type == QUIC_CONNECTION_EVENT_PEER_ADDRESS_CHANGED) { | ||
MsQuicSettings Settings; | ||
Conn->GetSettings(&Settings); | ||
Settings.IsSetFlags = 0; | ||
Settings.SetPeerBidiStreamCount(Settings.PeerBidiStreamCount + 1); | ||
Conn->SetSettings(Settings); | ||
Ctx->PeerAddrChangedEvent.Set(); | ||
} | ||
return QUIC_STATUS_SUCCESS; | ||
} | ||
}; | ||
|
||
static | ||
QUIC_STATUS | ||
QUIC_API | ||
ClientCallback( | ||
_In_ MsQuicConnection* /* Connection */, | ||
_In_opt_ void* Context, | ||
_Inout_ QUIC_CONNECTION_EVENT* Event | ||
) noexcept | ||
{ | ||
if (Event->Type == QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED) { | ||
MsQuic->StreamClose(Event->PEER_STREAM_STARTED.Stream); | ||
} else if (Event->Type == QUIC_CONNECTION_EVENT_STREAMS_AVAILABLE) { | ||
CxPlatEvent* StreamCountEvent = static_cast<CxPlatEvent*>(Context); | ||
StreamCountEvent->Set(); | ||
} | ||
return QUIC_STATUS_SUCCESS; | ||
} | ||
|
||
void | ||
QuicTestLocalPathChanges( | ||
_In_ int Family | ||
) | ||
{ | ||
PathTestContext Context; | ||
CxPlatEvent PeerStreamsChanged; | ||
MsQuicRegistration Registration{true}; | ||
TEST_QUIC_SUCCEEDED(Registration.GetInitStatus()); | ||
|
||
MsQuicSettings Settings; | ||
Settings.SetMinimumMtu(1280).SetMaximumMtu(1280); | ||
|
||
MsQuicConfiguration ServerConfiguration(Registration, "MsQuicTest", Settings, ServerSelfSignedCredConfig); | ||
TEST_QUIC_SUCCEEDED(ServerConfiguration.GetInitStatus()); | ||
|
||
MsQuicConfiguration ClientConfiguration(Registration, "MsQuicTest", Settings, MsQuicCredentialConfig{}); | ||
TEST_QUIC_SUCCEEDED(ClientConfiguration.GetInitStatus()); | ||
|
||
MsQuicAutoAcceptListener Listener(Registration, ServerConfiguration, PathTestContext::ConnCallback, &Context); | ||
TEST_QUIC_SUCCEEDED(Listener.GetInitStatus()); | ||
QUIC_ADDRESS_FAMILY QuicAddrFamily = (Family == 4) ? QUIC_ADDRESS_FAMILY_INET : QUIC_ADDRESS_FAMILY_INET6; | ||
QuicAddr ServerLocalAddr(QuicAddrFamily); | ||
TEST_QUIC_SUCCEEDED(Listener.Start("MsQuicTest", &ServerLocalAddr.SockAddr)); | ||
TEST_QUIC_SUCCEEDED(Listener.GetLocalAddr(ServerLocalAddr)); | ||
|
||
MsQuicConnection Connection(Registration, CleanUpManual, ClientCallback, &PeerStreamsChanged); | ||
TEST_QUIC_SUCCEEDED(Connection.GetInitStatus()); | ||
|
||
TEST_QUIC_SUCCEEDED(Connection.StartLocalhost(ClientConfiguration, ServerLocalAddr)); | ||
TEST_TRUE(Connection.HandshakeCompleteEvent.WaitTimeout(TestWaitTimeout)); | ||
TEST_NOT_EQUAL(nullptr, Context.Connection); | ||
TEST_TRUE(Context.Connection->HandshakeCompleteEvent.WaitTimeout(TestWaitTimeout)); | ||
|
||
QuicAddr OrigLocalAddr; | ||
TEST_QUIC_SUCCEEDED(Connection.GetLocalAddr(OrigLocalAddr)); | ||
ReplaceAddressHelper AddrHelper(OrigLocalAddr.SockAddr, OrigLocalAddr.SockAddr); | ||
|
||
for (int i = 0; i < 50; i++) { | ||
QuicAddrSetPort(&AddrHelper.New, QuicAddrGetPort(&AddrHelper.New) + 1); | ||
Connection.SetSettings(MsQuicSettings{}.SetKeepAlive(25)); | ||
|
||
TEST_TRUE(Context.PeerAddrChangedEvent.WaitTimeout(1500)); | ||
Context.PeerAddrChangedEvent.Reset(); | ||
QuicAddr ServerRemoteAddr; | ||
TEST_QUIC_SUCCEEDED(Context.Connection->GetRemoteAddr(ServerRemoteAddr)); | ||
TEST_TRUE(QuicAddrCompare(&AddrHelper.New, &ServerRemoteAddr.SockAddr)); | ||
Connection.SetSettings(MsQuicSettings{}.SetKeepAlive(0)); | ||
TEST_TRUE(PeerStreamsChanged.WaitTimeout(1500)); | ||
PeerStreamsChanged.Reset(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters