简介
此文主要是自己在mysql中间件开发过程中遇到的坑之权能标志CLIENT_DEPRECATE_EOF,以及根据这个标志怎么对拿到的mysql包进行处理
正文
在中间件开发过程测试发现mysql5.7的客户端连接mysql5.6服务器连接不上,经过对mysql包进行抓取发现,mysql5.6的回包是没有问题的,但是我们这面根据客户端返回来的CLIENT_DEPRECATE_EOF权能标志将其归结为mysql5.7.5之后的OK_Packet代替EOF_Packet的情况。经过查阅资料,mysql在握手阶段的权能位分为低、高16位权能,主要的功能是保证服务器与客户端通讯的兼容性。经过抓包和查看源码,在服务器与客户端进行握手的阶段,客户端收到服务器的包后,解析出服务器发送过来包的权能标志后,进行如下的处理:
mysql->client_flag=mysql->client_flag &
(~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41) |
mysql->server_capabilities)
下面对CLIENT_COMPRESS、CLIENT_SSL进行处理,然后发送给服务器
上面通过代码可以看到,客户端拿到服务器的权能标志并不是与自己的简单的与,比如CLIENT_DEPRECATE_EOF标志,客户端发送给服务器的标志位为1,并不代表服务器、客户端均支持,这个仅仅代表客户端自己支持(我之前认为是客户端发送过来权能标志是服务器和客户端均支持的)。在源码里面,如果自己能够识别这个标志,都会再去判断对方是否支持。
解决方法中间件在收到客户端和服务器的握手包时,将里面的CLIENT_DEPRECATE_EOF权能标志均置为0,再发给对方,这样不管是什么版本的客户端和服务器,均不进行替换(即OK_Packet不替换EOF_Packet)。
中间件拿到服务器和客户端的关于CLIENT_DEPRECATE_EOF权能的值,均为1才走OK_Packet代替EOF_Packet流程
在中间件正常处理获得的包,对读取的包的EOF包的格式进行判断,5.7.5版本之前的是0500 0005 fe00 0002 00而之后的版本是0700 0002 0000 0002 000000,官方文档给出包OK包替换EOF包后,包的类型判断方法:
OK: header = 0x00 and length of packet > 7
EOF: header = 0xfe and length of packet < 9