Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client gets disconnected due to race condition (enable_multithread) #210

Open
rabrahamkns opened this issue Apr 16, 2020 · 0 comments
Open

Comments

@rabrahamkns
Copy link

Hello
I found a race condition where a websocket server will disconnect a socketIO-client. This is happening because of a race condition between the ping loop thread and the data thread (where data is being sent). Here is how it goes:
If one thread starts sending a large frame, and it is broken into chunks, and then the second thread sends its data in the middle of the chunks, it breaks the socket io protocol. The header of each frame contains the length and some meta data, which match to a complete frame. But now the frame is polluted with data from 2 threads. As a result, the server drops the client’s connection since the header data is bad with "transport error" (“reserved fields must be empty”).
This is happening python2.7/dist-packages/websocket/_core.py line #276, send_frame method:

` def send_frame(self, frame):
"""
Send the data frame.

    frame: frame data created  by ABNF.create_frame

    >>> ws = create_connection("ws://echo.websocket.org/")
    >>> frame = ABNF.create_frame("Hello", ABNF.OPCODE_TEXT)
    >>> ws.send_frame(frame)
    >>> cont_frame = ABNF.create_frame("My name is ", ABNF.OPCODE_CONT, 0)
    >>> ws.send_frame(frame)
    >>> cont_frame = ABNF.create_frame("Foo Bar", ABNF.OPCODE_CONT, 1)
    >>> ws.send_frame(frame)

    """
    if self.get_mask_key:
        frame.get_mask_key = self.get_mask_key
    data = frame.format()
    length = len(data)
    trace("send: " + repr(data))

    with self.lock:
        while data:
            l = self._send(data)
            data = data[l:]

    return length

`

in socketIO-client lock is defined as NoLock, so it does nothing.
This is happening because enable_multithread in python2.7/dist-packages/websocket/_core.py inside craete_connection() is False by default, and I could not find a way to turn this on from socketIO-client.
To fix this I added this python2.7/dist-packages/socketIO_client/transports.py line #139:
kw['enable_multithread'] = True

And now the websocket send() method is guarded.
My server is websocket for node v4.5.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant