引き続きpacketについて
- int<3> payload_length
- int<1> sequence_id
- string payload [len=payload_length]
packetの説明にある型にかんしてはここ https://dev.mysql.com/doc/internals/en/describing-packets.html
sequence_idについてはhttps://dev.mysql.com/doc/internals/en/sequence-id.htmlでパケットごとに1加算、wrap aroundする。 Command phaseで新しいコマンドが始まったら0にリセットされるとある。
ドキュメントの章立て良くない気がするんだけど、Connection Lifecycleのところで、2つのphaseに分けれられるように書かれている。
Connection Phase
https://dev.mysql.com/doc/internals/en/connection-phase.html ここの簡易状態遷移図がわかりやすい
実際のパケットの中身はここ
https://dev.mysql.com/doc/internals/en/connection-phase-packets.html
Command Phase
https://dev.mysql.com/doc/internals/en/command-phase.html
クライアントはsequence_idを[00]で送る。 コマンドフェーズであれば、payloadの先頭のバイトでコマンドのタイプが分かる。
prepared statement, stored procedureもそれぞれcommand phaseでのコマンドタイプで判断できそうだけど、command phase, connection phaseをどうやって区別するかがわからない。connectionの途中や、command phaseからパケットを見ることもあり得るのでどうしたものか?
パケットのキャプチャをしているツールを参考にしてみる。
tools
- tshark
tshark -i en0 -d tcp.port==3306,mysql -T fields -e mysql.query 'port 3306'
こんな感じでmysql.queryを持ってこれた。簡単。com_queryでないパケットでも1行分の空行が出るので、それだけ無視してあげて、あとはqueryベースでフィルタすることだけ考えれば良い。