msquic
msquic copied to clipboard
StreamSend method hangs when called in an infinite loop
Describe the bug
A crash occurs if StreamSend called in an infinite loop.
Affected OS
- [ ] Windows
- [X] Linux
- [ ] macOS
- [ ] Other (specify below)
Additional OS information
Ubuntu 22.04.3 LTS
MsQuic version
main
Steps taken to reproduce bug
- Run
uint64_t i = 0;
char numStr[100];
while (TRUE)
{
QUIC_BUFFER *msg = (QUIC_BUFFER *)malloc(sizeof(QUIC_BUFFER) + sizeof(i));
msg->Length = sizeof(i);
sprintf(numStr, "%ld\n", i);
msg->Buffer = numStr;
MsQuic->StreamSend(Stream, msg, 1, flags, msg);
i++;
}
- View output on the server
- See the broken order of numbers, then the slowdown of incoming messages to the server, and finally the connection is broken.
Expected behavior
- Run
uint64_t i = 0;
char numStr[100];
while (TRUE)
{
QUIC_BUFFER *msg = (QUIC_BUFFER *)malloc(sizeof(QUIC_BUFFER) + sizeof(i));
msg->Length = sizeof(i);
sprintf(numStr, "%ld\n", i);
msg->Buffer = numStr;
MsQuic->StreamSend(Stream, msg, 1, flags, msg);
usleep(1);
i++;
}
- View output on the server
- See the correct order of numbers.
350543
350544
350545
350546
350547
350548
350549
350550
350551
350552
350553
350554
350555
350556
350557
350558
350559
350560
350561
Actual outcome
249944
249944
249944
249944
249944
249944
249944
249944
249944
249944
249944
249944
249944
249944
249944
249944
249944
249945
249945
249945
249945
249945
249945
249945
249945
249945
249945
249945
249945
24994
[conn][0x7fef28061120] Shut down by transport, 0x6e
Additional details
No response
All your sends point to the same memory, 'numStr', for which you continue to change. Send just queues to the MsQuic thread and immediately returns. You cannot reuse that memory until you get a send completion.
Yes, memory, I apologize for such trivial mistakes, I recently got acquainted with C. It helped with the order of numbers, but the main problem remained. 1-2 packets of 10k-20k messages are sent to the server. After that, the connection is interrupted.
That error, 0x6e, refers to QUIC_STATUS_CONNECTION_TIMEOUT, which indicates the connection is timing out (i.e. getting 'disconnected'). Are you doing printf, or some other blocking call, on the MsQuic callback? My guess is that you are delaying the peer from responding long enough that the connection dies.
Disabled everything that could block in callbacks (except error output), the error changes between 0x6e and 0x3e.
That error is QUIC_STATUS_CONNECTION_IDLE, which means the connection is torn down because it's been unused for too long. So it looks like you fixed it! 😄
It would be nice, but there is a StreamSend call in an infinite loop... Therefore, in theory, the connection should not be idle.
If you continue to call send, but the connection says idle, that likely means flow control kicked in, blocking further sends. This can happen if you're not draining the data in the receive callback. I recommend you grab some logs and take a look.