Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Sources/SwiftNetwork/QUIC/Ack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ final class Ack: PrefixedLoggable, TimerUser {
setAckFrame: connection.scheduleAckFrame,
ecn: connection.ecn
) {
connection.sendFrames()
connection.sendFrames(delayedACK: true)
}
}

Expand Down Expand Up @@ -718,7 +718,7 @@ final class Ack: PrefixedLoggable, TimerUser {
)
}

private func scheduleDelayedAck() {
func scheduleDelayedAck() {
// ACK timer is already scheduled
if timerScheduled {
return
Expand Down
13 changes: 10 additions & 3 deletions Sources/SwiftNetwork/QUIC/QUICConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2923,14 +2923,21 @@ public final class QUICConnection: ManyToManyApplicationStreamProtocol,
}

@discardableResult
func sendFrames(ignoreCongestionWindow: Bool = false) -> Bool {
// Make sure there is something to send first
func sendFrames(ignoreCongestionWindow: Bool = false, delayedACK: Bool = false) -> Bool {
// Make sure there are packets to send
guard
initialPendingItems.hasPendingItems || handshakePendingItems.hasPendingItems
initialPendingItems.hasPendingItems
|| handshakePendingItems.hasPendingItems
|| applicationPendingItems.hasPendingItems
else {
return false
}
// For ACK bundling purposes make sure to rely on the ACK-delay timer as much as possible
guard !applicationPendingItems.isAckOnly || delayedACK else {
// Make sure the ack-delay timer is armed if returning early
ack.scheduleDelayedAck()
return false
}
return withCurrentPath { path in
var sentPackets = NetworkUniqueDeque<SentPacketRecord>(minimumCapacity: capacityForPacketNumberSpace())
var discardInitialRecoveryState = false
Expand Down
2 changes: 1 addition & 1 deletion Tests/SwiftNetworkTests/QUICTestHarness.swift
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,7 @@ final class QUICTestHarness {
generator = TestDataGenerator(
blockSize: blockSize,
numberOfBlocks: blockCount,
uniqueBits: UInt8(index),
uniqueBits: UInt8(clamping: index),
sendFIN: sendFIN
)
}
Expand Down
10 changes: 8 additions & 2 deletions Tests/SwiftNetworkTests/SwiftNetworkQUICEarlyDataTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -413,15 +413,21 @@ final class SwiftNetworkQUICEarlyDataTests: NetTestCase {
let receiveExpectation = XCTestExpectation()
context.async {
Logger.test.info("Trying to read data")
for _ in 0..<10 {
func attemptServerRead() {
if pairedPathsArray.first?.transferPackets() == 0 {
break
// Wait for new writes from the client to be sent
context.async {
attemptServerRead()
}
return
}
Logger.test.info("Trying to read data")
if let readData = serverUpperHarness?.upperHarnesses.first?.read() {
XCTAssertEqual(readData, dataToSend)
receiveExpectation.fulfill()
}
}
attemptServerRead()
}
wait(for: [receiveExpectation], timeout: 5.0)
}
Expand Down
11 changes: 11 additions & 0 deletions Tests/SwiftNetworkTests/SwiftNetworkQUICHarnessTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,17 @@ final class SwiftNetworkQUICHarnessTests: NetTestCase {
)
}

func testQUIC1000BidirectionalStreamsEcho1k() {
let serverOptions = QUICProtocol.options()
serverOptions.connectionOptions.initialMaxStreamsBidirectional = 1000
QUICTestHarness().runQUICTest(
streamCount: 1000,
blockSize: 1000,
blockCount: 1,
serverOptions: serverOptions
)
}

func testQUICConnectionCloseError() {
QUICTestHarness().runQUICTest(
streamCount: 2,
Expand Down
Loading