Search code examples
pythonwebsocketrfc

Websocket first byte returns opcode 0x8 every time


Im doing some tests to Websocket protocol https://www.rfc-editor.org/rfc/rfc6455#section-5.2

I have troubles with opcode (bit 4 to 7) because i don't understand why it returns 8 opcode every time, is that a normal behaviour ?

I checked on Google Chrome browser and in Mozilla Firefox (the connection test was performed with WebSocket class JS), seems to be a normal behaviour but why ?

The first packet starts with byte 0x81, translated to bits is 10000001, for get the opcode value what i'm doing is do a right shift 4, 10000001 => 00001000 which is equal to 8, what i expect is something different to 8, like 1(expecting text frame).

As a code demostration, i will use Python for show the example:

data = bytearray(b'\x81\x8c\xf9t&\x90\x91\x1bJ\xf1\xd9\x07C\xe2\x8f\x11T\xb1')
print(data[0] >> 4)
assert(1 == (data[0] >> 4))

In that specific case what i expect on the first byte is 0x17 (00010001).

If i send connection close, the first byte returns 0x88 which isn't very different from the first one, that one too have close connection opcode 0x88 => 10001000(bits) => 00001000(shifted right 4 bits) => 8(decimal).


Solution

  • If i do right shift, what im doing is moving the FIN, RSV1, RSV2 and RSV3, removing the opcode(4 to 7), if i want to know the value of opcode the simple way is do a "bitwise and" from 0 to 3 bit.

     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     | |1|2|3|       |K|             |                               |
     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
    

    As an example of 0x81 and 0x88.

    0x81 => 10000001

    10000001 & 00001111(0xF hex) = 00000001 (text frame)

    0x88 => 10001000

    10001000 & 00001111(0xF hex) = 00001000 (close connection)