11use crate :: myc:: constants:: { CapabilityFlags , Command as CommandByte } ;
2- use nom;
32
43#[ derive( Debug ) ]
54pub struct ClientHandshake < ' a > {
@@ -10,21 +9,49 @@ pub struct ClientHandshake<'a> {
109}
1110
1211pub fn client_handshake ( i : & [ u8 ] ) -> nom:: IResult < & [ u8 ] , ClientHandshake < ' _ > > {
13- let ( i, cap) = nom:: number:: complete:: le_u32 ( i) ?;
14- let ( i, maxps) = nom:: number:: complete:: le_u32 ( i) ?;
15- let ( i, collation) = nom:: bytes:: complete:: take ( 1u8 ) ( i) ?;
16- let ( i, _) = nom:: bytes:: complete:: take ( 23u8 ) ( i) ?;
17- let ( i, username) = nom:: bytes:: complete:: take_until ( & b"\0 " [ ..] ) ( i) ?;
18- let ( i, _) = nom:: bytes:: complete:: tag ( b"\0 " ) ( i) ?;
19- Ok ( (
20- i,
21- ClientHandshake {
22- capabilities : CapabilityFlags :: from_bits_truncate ( cap) ,
23- maxps,
24- collation : u16:: from ( collation[ 0 ] ) ,
25- username,
26- } ,
27- ) )
12+ // mysql handshake protocol documentation
13+ // https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_handshake_response.html
14+
15+ let ( i, cap) = nom:: number:: complete:: le_u16 ( i) ?;
16+
17+ if CapabilityFlags :: from_bits_truncate ( cap as u32 ) . contains ( CapabilityFlags :: CLIENT_PROTOCOL_41 )
18+ {
19+ // HandshakeResponse41
20+ let ( i, cap2) = nom:: number:: complete:: le_u16 ( i) ?;
21+ let cap = ( cap2 as u32 ) << 16 | cap as u32 ;
22+
23+ let ( i, maxps) = nom:: number:: complete:: le_u32 ( i) ?;
24+ let ( i, collation) = nom:: bytes:: complete:: take ( 1u8 ) ( i) ?;
25+ let ( i, _) = nom:: bytes:: complete:: take ( 23u8 ) ( i) ?;
26+ let ( i, username) = nom:: bytes:: complete:: take_until ( & b"\0 " [ ..] ) ( i) ?;
27+ let ( i, _) = nom:: bytes:: complete:: tag ( b"\0 " ) ( i) ?;
28+
29+ Ok ( (
30+ i,
31+ ClientHandshake {
32+ capabilities : CapabilityFlags :: from_bits_truncate ( cap) ,
33+ maxps,
34+ collation : u16:: from ( collation[ 0 ] ) ,
35+ username,
36+ } ,
37+ ) )
38+ } else {
39+ // HandshakeResponse320
40+ let ( i, maxps1) = nom:: number:: complete:: le_u16 ( i) ?;
41+ let ( i, maxps2) = nom:: number:: complete:: le_u8 ( i) ?;
42+ let maxps = ( maxps2 as u32 ) << 16 | maxps1 as u32 ;
43+ let ( i, username) = nom:: bytes:: complete:: take_until ( & b"\0 " [ ..] ) ( i) ?;
44+
45+ Ok ( (
46+ i,
47+ ClientHandshake {
48+ capabilities : CapabilityFlags :: from_bits_truncate ( cap as u32 ) ,
49+ maxps,
50+ collation : 0 ,
51+ username,
52+ } ,
53+ ) )
54+ }
2855}
2956
3057#[ derive( Debug , PartialEq , Eq ) ]
0 commit comments