Skip to content

Commit

Permalink
Replace all the existing source connection IDs if we find the collisi…
Browse files Browse the repository at this point in the history
…on in adding a source connection ID to a newly opened bindings
  • Loading branch information
masa-koz committed Dec 18, 2024
1 parent 9e287a7 commit 5da50d7
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 31 deletions.
1 change: 0 additions & 1 deletion src/core/binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,6 @@ QuicBindingAddAllSourceConnectionIDs(
QUIC_CID_SLIST_ENTRY,
Link);
if (!QuicBindingAddSourceConnectionID(Binding, Entry)) {
QuicBindingRemoveAllSourceConnectionIDs(Binding, Connection);
return FALSE;

Check warning on line 586 in src/core/binding.c

View check run for this annotation

Codecov / codecov/patch

src/core/binding.c#L586

Added line #L586 was not covered by tests
}
}
Expand Down
91 changes: 61 additions & 30 deletions src/core/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,27 @@ QuicConnGenerateNewSourceCid(
return NULL;
}

//
// Find all the bindings that are currently in use by this connection.
//
QUIC_BINDING* Bindings[QUIC_MAX_PATH_COUNT] = {NULL};
uint8_t BindingsCount = 0;

for (uint8_t i = 0; i < Connection->PathsCount; ++i) {
if (Connection->Paths[i].Binding != NULL) {
BOOLEAN NewBinding = TRUE;
for (uint8_t j = 0; j < BindingsCount; ++j) {
if (Connection->Paths[i].Binding == Bindings[j]) {
NewBinding = FALSE;
break;
}
}
if (NewBinding) {
Bindings[BindingsCount++] = Connection->Paths[i].Binding;
}
}
}

//
// Keep randomly generating new source CIDs until we find one that doesn't
// collide with an existing one.
Expand All @@ -867,33 +888,38 @@ QuicConnGenerateNewSourceCid(
}

BOOLEAN Collision = FALSE;

CxPlatDispatchLockAcquire(&MsQuicLib.DatapathLock);

//
// Check whether a new sourceCid collides with any sourceCid which belong to all
// the bindings including the ones which this connection doesn't bound.
//
for (CXPLAT_LIST_ENTRY* Link = MsQuicLib.Bindings.Flink;
Link != &MsQuicLib.Bindings;
Link = Link->Flink) {

QUIC_BINDING* Binding =
CXPLAT_CONTAINING_RECORD(Link, QUIC_BINDING, Link);
QUIC_CONNECTION* Connection1 =
QuicLookupFindConnectionByLocalCid(
&Binding->Lookup,
SourceCid->CID.Data,
SourceCid->CID.Length);
if (Connection1 != NULL) {
int8_t Revert = -1;
for (uint8_t i = 0; i < BindingsCount; ++i) {
if (!QuicBindingAddSourceConnectionID(Bindings[i], SourceCid)) {
Collision = TRUE;
if (i > 0) {
Revert = i - 1;

Check warning on line 896 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L896

Added line #L896 was not covered by tests
}
break;
}
}
}

CxPlatDispatchLockRelease(&MsQuicLib.DatapathLock);

if (Collision) {
if (Revert >= 0) {
for (int8_t i = Revert; i >= 0; --i) {
if (Bindings[i] != NULL) {
while (SourceCid->HashEntries.Next != NULL) {
QUIC_CID_HASH_ENTRY* CID =

Check warning on line 907 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L904-L907

Added lines #L904 - L907 were not covered by tests
CXPLAT_CONTAINING_RECORD(
CxPlatListPopEntry(&SourceCid->HashEntries),
QUIC_CID_HASH_ENTRY,
Link);
if (CID->Binding == Bindings[i]) {
QuicBindingRemoveSourceConnectionID(

Check warning on line 913 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L912-L913

Added lines #L912 - L913 were not covered by tests
Bindings[i],
CID);
CXPLAT_FREE(CID, QUIC_POOL_CIDHASH);
break;

Check warning on line 917 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L916-L917

Added lines #L916 - L917 were not covered by tests
}
}

Check warning on line 919 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L919

Added line #L919 was not covered by tests
}
}

Check warning on line 921 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L921

Added line #L921 was not covered by tests
}
CXPLAT_FREE(SourceCid, QUIC_POOL_CIDSLIST);
SourceCid = NULL;
if (++TryCount > QUIC_CID_MAX_COLLISION_RETRY) {
Expand All @@ -912,12 +938,6 @@ QuicConnGenerateNewSourceCid(
}
} while (SourceCid == NULL);

for (uint8_t i = 0; i < Connection->PathsCount; ++i) {
if (Connection->Paths[i].Binding != NULL) {
QuicBindingAddSourceConnectionID(Connection->Paths[i].Binding, SourceCid);
}
}

SourceCid->CID.SequenceNumber = Connection->NextSourceCidSequenceNumber++;

QuicTraceEvent(
Expand Down Expand Up @@ -6336,7 +6356,7 @@ QuicConnOpenNewPath(
}
} else {
if (!QuicBindingAddAllSourceConnectionIDs(NewBinding, Connection)) {
return QUIC_STATUS_OUT_OF_MEMORY;
QuicConnGenerateNewSourceCids(Connection, TRUE);

Check warning on line 6359 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L6359

Added line #L6359 was not covered by tests
}
}

Expand Down Expand Up @@ -6637,7 +6657,18 @@ QuicConnParamSet(
// TODO - Need to free any queued recv packets from old binding.
//

QuicBindingAddAllSourceConnectionIDs(Connection->Paths[0].Binding, Connection);
if (!Connection->State.ShareBinding) {
if (!QuicBindingAddAllSourceConnectionIDs(Connection->Paths[0].Binding, Connection)) {
QuicLibraryReleaseBinding(Connection->Paths[0].Binding);
Connection->Paths[0].Binding = OldBinding;
Status = QUIC_STATUS_OUT_OF_MEMORY;
break;

Check warning on line 6665 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L6662-L6665

Added lines #L6662 - L6665 were not covered by tests
}
} else {
if (!QuicBindingAddAllSourceConnectionIDs(Connection->Paths[0].Binding, Connection)) {
QuicConnGenerateNewSourceCids(Connection, TRUE);

Check warning on line 6669 in src/core/connection.c

View check run for this annotation

Codecov / codecov/patch

src/core/connection.c#L6669

Added line #L6669 was not covered by tests
}
}
QuicBindingRemoveAllSourceConnectionIDs(OldBinding, Connection);
QuicLibraryReleaseBinding(OldBinding);

Expand Down

0 comments on commit 5da50d7

Please sign in to comment.