Shroedinger's Variable?
The sysop of Tucumcari BBS reported garbage input when trying to log in via fTelnet. Dove-net post for reference: https://vert.synchro.net/?page=001-forum.ssjs&sub=sync&thread=52391
- I asked him to roll back websocketservice.js to a previous version, and input worked good with it
- I modified the latest version of websocketservice.js to output debug information, which indicated the issue is related to the XORing used to unmask incoming websocket data frames.
- For example, if I hit the "a" key, the debug output showed that a masking byte of 212 and a data byte of 181 were received, and when XORed they should have resulted in an input byte of 97 to match the "a" key I pressed, but instead the input byte was still 181 like the raw data byte. This means either the XOR was skipped, or somehow 181 XOR 0 ran instead of 181 XOR 212.
- I made a second modification to output a bit more debug information to determine whether the XOR was being skipped, or the XOR 0 was happening, and unexpectedly input worked good with it!
- I asked him to run both of my modified versions on different ports, to see whether the first debug version now works, but it still has garbage input
- I took a closer look at the output from the first debug version, and found that it actually starts unmasking correctly, but seems to reliably fail at the same point on repeated connection attempts:
- 255 252 1 received OK
- 255 251 23 received OK
- 255 253 29 not OK (29 should have been 1)
- Everything after that is not unmasking
The difference between the first debug version and the second debug version is the addition of this line, which references several variables but does not modify any of them:
SendToWebSocketClient_RickDebug(' InByte = ' + InByte + ', FFrameMasked = ' + FFrameMasked + ', FFramePayloadReceived = ' + FFramePayloadReceived + ', Mask = ' + FFrameMask[FFramePayloadReceived % 4] + ', OutByte = ' + (InByte ^ FFrameMask[FFramePayloadReceived % 4]) + '\r\n');
And in case it helps, this is the commit that introduces the garbage input behaviour. It switches from reading one byte at a time to reading a message at a time, to speed up file transfers. The line responsible for unmasking the data didn't change though. fbefb47f
@echicken mentioned he ran into something like this sometime last year, and suggests changing options controlling JS runtime behaviour. Is this something that can be done via configuration options? Or only at compile time? And however it's done, do you have any suggestions on what to change and what to change it to? (And thanks for the suggestion @echicken -- my VPS is down so I can't reply via dove-net right now)
Here's links to connect to the two debug versions of websocketservice.js, if you'd like to see the issue in action (scrollback is limited so you won't be able to see the earliest debug output, but it's all visible in developer tools console)