Parsing Initial handshake from MySQL Server

I’m trying to parse a binary coming from the mysql server (Client-Server) protocol

iex(22)> {:ok, socket} = :gen_tcp.connect('localhost', 3306, socket_opts)

{:ok, #Port<0.5301>}

iex(23)> <<10::size(8), rest::binary-size(24)>> = :gen_tcp.recv(socket, 4)

** (MatchError) no match of right hand side value: {:ok, <<74, 0, 0, 0>>}

Protocol for Initial handshake

https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake

the first byte is <<10>>

What are your socket_opts?

Quoting @fishcakez

the mysql protocol is very complex and the docs very poor, if you want to use the mysql protcol you will need to be spend time comparing what the docs say to what mysql does

as I help maintain mariaex I think your issue is that mysql is sending a 32 bit len header for the packet

if you try to receive 5 bytes the fifth may be 10 (edited)

however what you should really do is receive 4 bytes, to work out the length, in this case 74, as mysql uses little endian, and then receive the remaining bytes. I can’t remember if this will be 74 or 70 (74 -4)

I think for mysql it might be 24 bit little endian and then a sequence id as 4 th byte, that happens to be 0, followed by message of length of the 24bit integer

https://dev.mysql.com/doc/internals/en/mysql-packet.html

[packet: :raw, mode: :binary, active: false]

Each packet has a header which describes payload_length, sequence_id, and payload itself
for example
This is 4 byte header <<74, 0, 0, 0>> if i pattern match it

<<payload_length::little-integer-size(24), seqnum::integer>> = data

payload_length = 74 bytes and sequence number is 0