package org.opencloudb.net.mysql; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import java.net.InetSocketAddress; import java.util.concurrent.atomic.AtomicLong; import org.opencloudb.MycatSystem; import org.opencloudb.config.Capabilities; import org.opencloudb.config.Versions; import org.opencloudb.net.ConnectionInfo; import org.opencloudb.util.RandomUtil; public class FrontMysqlProtocalHandler extends ChannelHandlerAdapter { private AtomicLong idGen = new AtomicLong(0); @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { System.out.println("exceptionCaught " + ctx); cause.printStackTrace(); } public void channelActive(ChannelHandlerContext ctx) throws Exception { // 生成认证数据 byte[] rand1 = RandomUtil.randomBytes(8); byte[] rand2 = RandomUtil.randomBytes(12); // 保存认证数据 byte[] seed = new byte[rand1.length + rand2.length]; System.arraycopy(rand1, 0, seed, 0, rand1.length); System.arraycopy(rand2, 0, seed, rand1.length, rand2.length); ConnectionInfo conInf = new ConnectionInfo(); MycatSystem.getInstance().getConfig().getSystem() .setConnectionParams(conInf); conInf.setAddress((InetSocketAddress) ctx.channel().remoteAddress(), (InetSocketAddress) ctx.channel().localAddress()); conInf.setSeed(seed); NettyUtil.setConnectionInfo(ctx, conInf); // 发送握手数据包 HandshakePacket hs = new HandshakePacket(); hs.packetId = 0; hs.protocolVersion = Versions.PROTOCOL_VERSION; hs.serverVersion = Versions.SERVER_VERSION; hs.threadId = idGen.incrementAndGet(); hs.seed = rand1; hs.serverCapabilities = getServerCapabilities(); hs.serverCharsetIndex = (byte) (conInf.getCharsetIndex() & 0xff); hs.serverStatus = 2; hs.restOfScrambleBuff = rand2; ByteBuf buf = ctx.alloc().ioBuffer(hs.calcPacketSize(), 1024); hs.writeBuf(buf); ctx.writeAndFlush(buf); NettyUtil.setConnectionHandler(ctx, FrontendAuthenticator.INSTANCE); ctx.read(); } protected int getServerCapabilities() { int flag = 0; flag |= Capabilities.CLIENT_LONG_PASSWORD; flag |= Capabilities.CLIENT_FOUND_ROWS; flag |= Capabilities.CLIENT_LONG_FLAG; flag |= Capabilities.CLIENT_CONNECT_WITH_DB; // flag |= Capabilities.CLIENT_NO_SCHEMA; // flag |= Capabilities.CLIENT_COMPRESS; flag |= Capabilities.CLIENT_ODBC; // flag |= Capabilities.CLIENT_LOCAL_FILES; flag |= Capabilities.CLIENT_IGNORE_SPACE; flag |= Capabilities.CLIENT_PROTOCOL_41; flag |= Capabilities.CLIENT_INTERACTIVE; // flag |= Capabilities.CLIENT_SSL; flag |= Capabilities.CLIENT_IGNORE_SIGPIPE; flag |= Capabilities.CLIENT_TRANSACTIONS; // flag |= ServerDefs.CLIENT_RESERVED; flag |= Capabilities.CLIENT_SECURE_CONNECTION; return flag; } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { byte[] mysqlData = (byte[]) msg; // System.out.println("channelRead " + ctx + " " + new // String(mysqlData)); NettyUtil.getConnectionHandler(ctx).handle(ctx, mysqlData); } @Override public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { super.disconnect(ctx, promise); System.out.println("disconnect " + ctx); } @Override public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { super.close(ctx, promise); System.out.println("close " + ctx); } }