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
1 change: 1 addition & 0 deletions lsquic/engine_config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ proc initSettings*(
settings.es_base_plpmtu = 1280
settings.es_init_max_streams_bidi = 100
settings.es_honor_prst = 1
settings.es_ping_period = 15 # both sides ping, as in go-libp2p
settings.es_max_cfcw =
if server:
1536 * 1024
Expand Down
63 changes: 63 additions & 0 deletions tests/test_connection.nim
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,63 @@ proc runChunkedReadTest(peers: ConnectedPeers, bufSize, payloadSize: int) {.asyn

await allFuturesRaising(sender(), receiver()).wait(streamTimeout)

proc exchangeOnStream(outgoingConn, incomingConn: Connection): Future[bool] {.async.} =
let payload = @[1'u8, 2, 3]
let sender = proc() {.async.} =
let stream = await outgoingConn.openStream()
await stream.write(payload)
await stream.close()
discard await readStreamTillEOF(stream)
await stream.closed.wait()

let receiver = proc(): Future[seq[byte]] {.async.} =
let stream = await incomingConn.incomingStream()
let received = await readStreamTillEOF(stream)
await stream.close()
await stream.closed.wait()
received
Comment thread
gmelodie marked this conversation as resolved.
Resolved

let receiving = receiver()
await allFuturesRaising(sender(), receiving).wait(streamTimeout)
receiving.read() == payload

proc idleConnectionSurvives(
address: TransportAddress, closeStreamFirst: bool
): Future[bool] {.async.} =
let idleTimeout = 3.seconds
let client = QuicClient.new(
makeTLSConfig(),
engineConfig = QuicEngineConfig(
idleTimeout: Opt.some(idleTimeout), pingPeriod: Opt.some(1.seconds)
),
)
let server = QuicServer.new(
makeTLSConfig(), engineConfig = QuicEngineConfig(idleTimeout: Opt.some(idleTimeout))
)
let listener = server.listen(address)
defer:
await allFutures(client.stop(), listener.stop())
let accepting = listener.accept()
let outgoingConn = await client.dial(listener.localAddress())
let incomingConn = await accepting

let usedBefore =
not closeStreamFirst or await exchangeOnStream(outgoingConn, incomingConn)

# Wait past the 7 s of NEW_CONNECTION_ID frames, which also keep the connection alive.
await sleepAsync(idleTimeout * 4)

let survived =
usedBefore and not outgoingConn.closedFuture().finished() and
not incomingConn.closedFuture().finished() and
await exchangeOnStream(outgoingConn, incomingConn)

outgoingConn.close()
incomingConn.close()
await allFutures(outgoingConn.closedFuture(), incomingConn.closedFuture())

survived

suite "connection":
teardown:
checkTrackers()
Expand All @@ -473,6 +530,12 @@ suite "connection":
asyncTest "connection survives client address migration":
await runClientAddressMigrationTest(AutoAddressIP4)

asyncTest "connection without streams outlives the idle timeout":
check await idleConnectionSurvives(AutoAddressIP4, closeStreamFirst = false)

asyncTest "connection outlives the idle timeout after its last stream closes":
check await idleConnectionSurvives(AutoAddressIP4, closeStreamFirst = true)

asyncTest "multiple concurrent stream opens":
await runConcurrentStreamOpenTest(AutoAddressIP4)

Expand Down
Loading