-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Description
I did this
I wrote code that created a WebSocket connection and used it do download data for multiple days.
I expected the following
I expected the WebSocket connection to be stable for extended periods of time. (Yes, I do know this is experimental.)
What actually happened
The connection remained stable for a while, but then received unexpected data, often with an unknown opcode.
- WS: 347 bytes left to decode (0 frame bytes left)
- WS:235 received FIN bit 1
- WS: received OPCODE TEXT
- WS: received 164 bytes payload (0 left, buflen was 347)
- WS: 179 bytes left to decode (0 frame bytes left)
- WS:235 received FIN bit 1
- WS: received OPCODE TEXT
- WS: received 172 bytes payload (0 left, buflen was 179)
- WS: 3 bytes left to decode (0 frame bytes left)
- WS:235 received FIN bit 1
- WS: received OPCODE TEXT
- WS:276 plen == 3, EAGAIN
- reached easy.c:1231
- WS: 1983 bytes left to decode (0 frame bytes left)
- WS:235 received FIN bit 0
- WS: received OPCODE CLOSE
- WS: received 49 bytes payload (0 left, buflen was 1983)
- WS: 1932 bytes left to decode (0 frame bytes left)
- WS:235 received FIN bit 0
- WS: received OPCODE CONT
- WS: received 34 bytes payload (0 left, buflen was 1932)
- WS: 1896 bytes left to decode (0 frame bytes left)
- WS:235 received FIN bit 0
- WS: unknown opcode: 5
Note that after the EAGAIN message, we read a packet header with FIN 0, OPCODE CLOSE where before we read FIN 1, OPCODE TEXT.
I dug into this behavior and believe I have found the source of the problem in ws.c. I believe I introduced this defect in my prior suggestion. When ws_decode returns EAGAIN (https://github.com/curl/curl/blob/master/lib/ws.c#L451), the next read happens at the beginning of buffer, even if the previous fragment is not located there. I suggest updating these lines to:
if(result == CURLE_AGAIN) {
/* a packet fragment only, loop and try reading more */
memmove(data->state.buffer, wsp->stillb, wsp->stillblen);
continue;
}
curl/libcurl version
curl 7.88.1 (x86_64-pc-linux-gnu) libcurl/7.88.1 OpenSSL/3.0.2 zlib/1.2.11
Release-Date: 2023-02-20
Protocols: dict file ftp ftps gopher gophers http https imap imaps mqtt pop3 pop3s rtsp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS HSTS HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL threadsafe TLS-SRP UnixSockets
operating system
Linux virt-linux 5.19.0-35-generic #36 SMP PREEMPT_DYNAMIC Fri Feb 17 15:17:25 UTC 2 x86_64 x86_64 x86_64 GNU/Linux