https://gitlab.synchro.net/main/sbbs/-/issues/617#note_3909
TL;DR: recv(n) sometimes seems to be returning n-1 characters but removing n from the input queue, causing data loss. This is only happening over secure wss://, not insecure ws://.What's happening is the client is sending 3 bytes (a telnet negotiation sequence), which results in a websocket frame with 5 bytes in the data payload (because of utf8 encoding). Websocket frames are masked with a random value, so those data bytes should appear to be random with each new connection, but they're not, which is why I think data loss is occurring.This first log output is when the currently committed code runs...it calls recv(5), gets 4 bytes back, so on the next loop calls recv(1):``` 9/6 03:01:35p 14444 WSS InStr[0] = 124 (|) 9/6 03:01:35p 14444 WSS InStr[1] = 229 (å) 9/6 03:01:35p 14444 WSS InStr[2] = 198 (Æ) 9/6 03:01:35p 14444 WSS InStr[3] = 99 (c) 9/6 03:01:35p 14444 WSS InStr[0] = 129 ()```The first 4 bytes are indeed random with each connection, but the fifth byte is always 129 (aka 0x81). 0x81 is what you would expect to see as the first byte in a websocket frame's header, so it appears as though recv(4) is returning 4 bytes but removing 5 bytes from the input queue, so then when recv(1) is called it doesn't get the last data payload byte, instead it gets the first byte of the next frame's header. This corrupts the demask/utf8 decode process, and results in the connection being closed.Just to make sure it wasn't something wrong with the loop (ie an extra recvBin happening and eating a byte) I put two recv() calls one immediately after the other, which showed the same behaviour. So then I tried calls of different sizes and found:- recv(4) then recv(1) returns 3+1 bytes- recv(3) then recv(2) returns 2+2 bytes- recv(2) then recv(3) returns 1+3 bytes- recv(1) then recv(4) returns 1+4 bytesAnd finally, the last tests are with a single recv() call of larger size:- recv(6) returns 5 bytes- recv(7) returns 6 bytes, and shows the 5 random bytes in the data payload followed by 129/0x81 signifying the
start of the next frame's header:``` 9/6 03:23:30p 16048 WSS InStr[0] = 138 (Š) 9/6 03:23:30p 16048 WSS InStr[1] = 118 (v) 9/6 03:23:30p 16048 WSS InStr[2] = 19 () 9/6 03:23:30p 16048 WSS InStr[3] = 101 (e) 9/6 03:23:30p 16048 WSS InStr[4] = 72 (H) 9/6 03:23:30p 16048 WSS InStr[5] = 129 ()```
--- SBBSecho 3.20-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)