mirror of https://github.com/status-im/nim-eth.git
Fix sudden window drop bug (#465)
Fixes problem which caused drop of maxWindow to the size of only one packet in case of only one packet hitting timeout.
This commit is contained in:
parent
45348e7664
commit
4e2b340af6
|
@ -469,8 +469,10 @@ proc checkTimeouts(socket: UtpSocket) {.async.} =
|
||||||
socket.sendBufferTracker.maxRemoteWindow,
|
socket.sendBufferTracker.maxRemoteWindow,
|
||||||
newMaxWindow
|
newMaxWindow
|
||||||
)
|
)
|
||||||
else:
|
elif (socket.sendBufferTracker.maxWindow < currentPacketSize):
|
||||||
|
# due to high delay window has shrunk below packet size
|
||||||
|
# which means that we cannot send more data
|
||||||
|
# reset it to fit at least one packet
|
||||||
debug "Reseting window size do fit a least one packet",
|
debug "Reseting window size do fit a least one packet",
|
||||||
oldWindowSize = socket.sendBufferTracker.maxWindow,
|
oldWindowSize = socket.sendBufferTracker.maxWindow,
|
||||||
newWindowSize = currentPacketSize
|
newWindowSize = currentPacketSize
|
||||||
|
|
|
@ -354,6 +354,72 @@ procSuite "Utp socket unit test":
|
||||||
|
|
||||||
await outgoingSocket.destroyWait()
|
await outgoingSocket.destroyWait()
|
||||||
|
|
||||||
|
proc ackAllPacket(
|
||||||
|
socket: UtpSocket[TransportAddress],
|
||||||
|
queue: AsyncQueue[Packet],
|
||||||
|
initialRemoteSeq: uint16): Future[void] {.async.} =
|
||||||
|
try:
|
||||||
|
while true:
|
||||||
|
let sentPacket = await queue.get()
|
||||||
|
let ack = ackPacket(
|
||||||
|
initialRemoteSeq,
|
||||||
|
sentPacket.header.connectionId,
|
||||||
|
sentPacket.header.seqNr,
|
||||||
|
1024 * 1024,
|
||||||
|
1000'u32
|
||||||
|
)
|
||||||
|
await socket.processPacket(ack)
|
||||||
|
except CancelledError:
|
||||||
|
echo "foo"
|
||||||
|
|
||||||
|
asyncTest "Hitting RTO timeout with packets in flight should not decay window":
|
||||||
|
let q = newAsyncQueue[Packet]()
|
||||||
|
let initialRemoteSeq = 10'u16
|
||||||
|
|
||||||
|
# lot of data which will generate at least 5 packets
|
||||||
|
let bigDataTowWrite = generateByteArray(rng[], 10000)
|
||||||
|
let (outgoingSocket, initialPacket) = connectOutGoingSocket(initialRemoteSeq, q)
|
||||||
|
|
||||||
|
let acker = outgoingSocket.ackAllPacket(q, initialRemoteSeq)
|
||||||
|
let bytesWritten = await outgoingSocket.write(bigDataTowWrite)
|
||||||
|
|
||||||
|
check:
|
||||||
|
bytesWritten.get() == len(bigDataTowWrite)
|
||||||
|
|
||||||
|
await waitUntil(proc (): bool = outgoingSocket.numPacketsInOutGoingBuffer() == 0)
|
||||||
|
|
||||||
|
let maxWindowAfterSuccesfulSends = outgoingSocket.currentMaxWindowSize()
|
||||||
|
|
||||||
|
check:
|
||||||
|
# after processing a lot of data, our window size should be a lot bigger than our packet size
|
||||||
|
maxWindowAfterSuccesfulSends > uint32(outgoingSocket.getPacketSize())
|
||||||
|
|
||||||
|
# cancel acking process, next writes will for sure timeout
|
||||||
|
await acker.cancelAndWait()
|
||||||
|
|
||||||
|
# data which fits one packet and will timeout
|
||||||
|
let smallerData = generateByteArray(rng[], 100)
|
||||||
|
|
||||||
|
let bytesWritten1 = await outgoingSocket.write(smallerData)
|
||||||
|
|
||||||
|
# ignore standard sent packet
|
||||||
|
discard await q.get()
|
||||||
|
|
||||||
|
check:
|
||||||
|
bytesWritten1.get() == len(smallerData)
|
||||||
|
|
||||||
|
# ignore also first re-send
|
||||||
|
discard await q.get()
|
||||||
|
|
||||||
|
let maxWindowAfterTimeout = outgoingSocket.currentMaxWindowSize()
|
||||||
|
|
||||||
|
check:
|
||||||
|
# After standard timeout window should not decay and must be bigger than packet size
|
||||||
|
maxWindowAfterTimeout > uint32(outgoingSocket.getPacketSize())
|
||||||
|
maxWindowAfterTimeout == maxWindowAfterSuccesfulSends
|
||||||
|
|
||||||
|
await outgoingSocket.destroyWait()
|
||||||
|
|
||||||
asyncTest "Blocked writing futures should be properly finished when socket is closed":
|
asyncTest "Blocked writing futures should be properly finished when socket is closed":
|
||||||
let q = newAsyncQueue[Packet]()
|
let q = newAsyncQueue[Packet]()
|
||||||
let initialRemoteSeq = 10'u16
|
let initialRemoteSeq = 10'u16
|
||||||
|
|
Loading…
Reference in New Issue