I've modified my dev branch to output the packet contents which are below, also I've broken down the packets into their constituent parts.
I'm testing with the Ubuntu 10.10 5.1.49 x64 server on my local computer and the latest Percona server remotely on a Rackspace Cloud node running Ubuntu 10.04. I also test against MySQL 5.5 and MariaDb 5.1 but not really important for this example as except for some handshake packet changes to 5.5 (extra undocumented bytes on the end of the packet) they're the same as MySQL 5.1.
I'm using the same database on both servers called gomysql_test and with user root and the password.
Here is handshake with MySQL 5.1:
2011/02/02 11:47:38 === Begin connect ===
2011/02/02 11:47:38 Connecting to server via tcp to localhost:3306
2011/02/02 11:47:38 Connected to server
2011/02/02 11:47:38 Reading handshake initialization packet from server
[]byte{0x3f, 0x0, 0x0, 0x0, 0xa, 0x35, 0x2e, 0x31, 0x2e, 0x34, 0x39, 0x2d, 0x31, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x38, 0x2e, 0x31, 0x0, 0x9c, 0x0, 0x0, 0x0, 0x4c, 0x5d, 0x6d, 0x2e, 0x3b, 0x7b, 0x7a, 0x75, 0x0, 0xff, 0xf7, 0x8, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, 0x46, 0x30, 0x58, 0x4d, 0x5a, 0x5c, 0x41, 0x6c, 0x7b, 0x49, 0x3a, 0x0}
2011/02/02 11:47:38 [0] Received handshake initialization packet
2011/02/02 11:47:38 Sending authentication packet to server
[]byte{0x47, 0x0, 0x0, 0x1, 0xd, 0xa2, 0x3, 0x0, 0xff, 0xff, 0xff, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x6f, 0x6f, 0x74, 0x0, 0x14, 0xd, 0x99, 0xdb, 0x54, 0xd9, 0x2a, 0x9f, 0xe2, 0x6e, 0x6c, 0x0, 0x8f, 0xbc, 0xa5, 0xd5, 0x5a, 0x72, 0xc5, 0xef, 0x0, 0x67, 0x6f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x0}
2011/02/02 11:47:38 [1] Sent authentication packet
2011/02/02 11:47:38 Reading result packet from server
[]byte{0x7, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0}
2011/02/02 11:47:38 [2] Received OK packet
Here is a 4.1 handshake with Percona:
2011/02/02 11:37:29 === Begin connect ===
2011/02/02 11:37:29 Connected to server
2011/02/02 11:37:29 Reading handshake initialization packet from server
[]byte{0x3c, 0x0, 0x0, 0x0, 0xa, 0x35, 0x2e, 0x31, 0x2e, 0x35, 0x34, 0x2d, 0x72, 0x65, 0x6c, 0x31, 0x32, 0x2e, 0x35, 0x0, 0x23, 0x0, 0x0, 0x0, 0x6e, 0x62, 0x25, 0x2b, 0x48, 0x68, 0x53, 0x47, 0x0, 0xff, 0xf7, 0x8, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x77, 0x3f, 0x70, 0x38, 0x66, 0x77, 0x43, 0x2b, 0x4a, 0x73, 0x28, 0x0}
2011/02/02 11:37:29 [0] Received handshake initialization packet
2011/02/02 11:37:29 Sending authentication packet to server
[]byte{0x47, 0x0, 0x0, 0x1, 0xd, 0xa2, 0x3, 0x0, 0xff, 0xff, 0xff, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x72, 0x6f, 0x6f, 0x74, 0x0, 0x14, 0xdb, 0x47, 0xe2, 0xb7, 0x92, 0x95, 0xbc, 0x8d, 0x2b, 0x55, 0x5e, 0x92, 0xfa, 0x67, 0xc3, 0x6a, 0xad, 0x19, 0x38, 0x5e, 0x67, 0x6f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x0}
2011/02/02 11:37:29 [1] Sent authentication packet
2011/02/02 11:37:29 Reading result packet from server
[]byte{0x1, 0x0, 0x0, 0x2, 0xfe}
Connect err: "Unknown or unexpected packet or packet type"
If we break the packets down, starting with MySQL 5.1:
Handshake from server to client:
0x3f, 0x0, 0x0 Packet length
0x0 Sequence number
0xa Protocol version
0x35, 0x2e, 0x31, 0x2e, 0x34, 0x39, 0x2d, 0x31, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x38, 0x2e, 0x31, 0x0 Server version "5.1.49-1ubuntu8.1"
0x9c, 0x0, 0x0, 0x0 Thread id
0x4c, 0x5d, 0x6d, 0x2e, 0x3b, 0x7b, 0x7a, 0x75 Scramble buffer
0x0 Filler
0xff, 0xf7 Server capabilities
0x8 Server language
0x2, 0x0 Server status
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 Filler
0x5b, 0x46, 0x30, 0x58, 0x4d, 0x5a, 0x5c, 0x41, 0x6c, 0x7b, 0x49, 0x3a, 0x0 Rest of scramble buffer
Auth from client to server:
0x47, 0x0, 0x0 Packet length
0x1 Sequence number
0xd, 0xa2, 0x3, 0x0 Client flags
0xff, 0xff, 0xff, 0x0 Max packet size
0x8 Character set
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 Filler
0x72, 0x6f, 0x6f, 0x74, 0x0 Username
0x14, 0xd, 0x99, 0xdb, 0x54, 0xd9, 0x2a, 0x9f, 0xe2, 0x6e, 0x6c, 0x0, 0x8f, 0xbc, 0xa5, 0xd5, 0x5a, 0x72, 0xc5, 0xef, 0x0 Password scrambled
0x67, 0x6f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x0 Database name
Response:
0x7, 0x0, 0x0 Packet length
0x2 Sequence number
0x0 Field count
0x0 Affected rows
0x0 Insert id
0x2, 0x0 Server status
0x0 Warning count
0x0 Message
Here is the same breakdown of the Percona packets:
Handshake from server to client:
0x3c, 0x0, 0x0 Packet length
0x0 Sequence number
0xa Protocol version
0x35, 0x2e, 0x31, 0x2e, 0x35, 0x34, 0x2d, 0x72, 0x65, 0x6c, 0x31, 0x32, 0x2e, 0x35, 0x0 Server version "5.1.54-rel12.5"
0x23, 0x0, 0x0, 0x0 Thread id
0x6e, 0x62, 0x25, 0x2b, 0x48, 0x68, 0x53, 0x47 Scramble buffer
0x0 Filler
0xff, 0xf7 Server capabilities
0x8 Server language
0x2, 0x0 Server status
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 Filler
0x49, 0x77, 0x3f, 0x70, 0x38, 0x66, 0x77, 0x43, 0x2b, 0x4a, 0x73, 0x28, 0x0 Rest of scramble buffer
Auth from client to server:
0x47, 0x0, 0x0 Packet length
0x1 Sequence number
0xd, 0xa2, 0x3, 0x0 Client flags
0xff, 0xff, 0xff, 0x0 Max packet size
0x8 Character set
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 Filler
0x72, 0x6f, 0x6f, 0x74, 0x0 Username
0x14, 0xdb, 0x47, 0xe2, 0xb7, 0x92, 0x95, 0xbc, 0x8d, 0x2b, 0x55, 0x5e, 0x92, 0xfa, 0x67, 0xc3, 0x6a, 0xad, 0x19, 0x38, 0x5e Password scrambled
0x67, 0x6f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x0 Database name
Response:
0x1, 0x0, 0x0 Packet length
0x2 Sequence number
0xfe Packet body
Besides the response and the different password scrambles, the packets formats are identical.
So, I fired up Wireshark and started capturing packets for the authentication process between the MySQL client on my machine, here is what happened:
1181 209.174863 46.38.161.86 192.168.0.5 MySQL Server Greeting proto=10 version=5.1.54-rel12.5
1183 209.262974 192.168.0.5 46.38.161.86 MySQL Login Request user=root
1185 209.296204 46.38.161.86 192.168.0.5 MySQL Response
1187 209.296607 192.168.0.5 46.38.161.86 MySQL Request Unknown (87)
1188 209.329171 46.38.161.86 192.168.0.5 MySQL Response OK
The 'Response' was the same as I received, a 1 byte long packet with 0xfe, however the client then sends the unknown response command which triggers and OK response.
The OK response was: 07 00 00 04 00 00 00 02 00 00 00
This is is in the correct format for the 4.1 protocol.
I then repeated this to a MySQL 5.1 server on my local network:
253 79.675149 192.168.0.12 192.168.0.5 MySQL Server Greeting proto=10 version=5.1.49-1ubuntu8.1
255 79.699164 192.168.0.5 192.168.0.12 MySQL Login Request user=root
257 79.707357 192.168.0.12 192.168.0.5 MySQL Response OK
So the 2 servers DO behave differently, but the client was able to recover the initial "invalid" response from Percona using a conveniently undocumented "unknown response" command which then seems to trigger normal operation. I ran a few queries and the packets all look to be in 4.1 format.
I guess I need to implement the "invalid response", will delve into the source and see if I can find anything on this. If anyone knows anything about this, please let me know!
Cheers,
Phil.