Search in sources :

Example 1 with MySQLPayloadType

use of io.mycat.proxy.packet.MySQLPayloadType in project Mycat2 by MyCATApache.

the class BackendConCreateHandler method handle.

public void handle(MySQLClientSession mysql) throws Exception {
    ProxyBuffer proxyBuffer = mysql.currentProxyBuffer().newBufferIfNeed();
    int totalPacketEndIndex = proxyBuffer.channelReadEndIndex();
    if (!mysql.readProxyPayloadFully()) {
        return;
    }
    MySQLPayloadType payloadType = mysql.getPayloadType();
    if (!welcomePkgReceived) {
        writeClientAuth(mysql);
        return;
    }
    // 收到切换登陆插件的包
    if (mysql.getPayloadType() == MySQLPayloadType.FIRST_EOF && mysql.getBackendPacketResolver().getState() == ComQueryState.AUTH_SWITCH_PLUGIN_RESPONSE) {
        // 重新发送密码验证
        MySQLPacket mySQLPacket = mysql.currentProxyPayload();
        AuthSwitchRequestPacket authSwitchRequestPacket = new AuthSwitchRequestPacket();
        authSwitchRequestPacket.readPayload(mySQLPacket);
        byte[] password = generatePassword(authSwitchRequestPacket);
        mySQLPacket = mysql.newCurrentProxyPacket(1024);
        mySQLPacket.writeBytes(password);
        mysql.writeCurrentProxyPacket(mySQLPacket, mysql.getPacketId() + 1);
        mysql.getBackendPacketResolver().setIsClientLoginRequest(true);
        return;
    }
    // 验证成功
    if (payloadType == MySQLPayloadType.FIRST_OK) {
        mysql.switchNioHandler(null);
        mysql.resetPacket();
        mysql.getBackendPacketResolver().setIsClientLoginRequest(false);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("successful create mysql backend connection:{}", mysql.sessionId());
        }
        callback.complete(mysql);
        return;
    }
    MySQLPacket mySQLPacket = mysql.getBackendPacketResolver().currentPayload();
    // 用公钥进行密码加密
    if (STR_CACHING_AUTH_STAGE.equals(stage) && authPluginName.equals(CachingSha2PasswordPlugin.PROTOCOL_PLUGIN_NAME)) {
        LOGGER.info("authPluginName:{} ", authPluginName);
        String publicKeyString = mySQLPacket.readEOFString();
        byte[] payload = CachingSha2PasswordPlugin.encrypt(mysqlVersion, publicKeyString, datasource.getPassword(), seed, CharsetUtil.getCharset(charsetIndex));
        mySQLPacket = mysql.newCurrentProxyPacket(1024);
        mySQLPacket.writeBytes(payload);
        mysql.writeCurrentProxyPacket(mySQLPacket, mysql.getPacketId() + 1);
        mysql.getBackendPacketResolver().setIsClientLoginRequest(true);
        stage = null;
        return;
    }
    int status = mySQLPacket.getByte(4) & 0xff;
    int fastAuthResult = mySQLPacket.getByte(5) & 0xff;
    if (status == 1 && fastAuthResult == 3) {
        // 验证成功继续 读取认证的ok包
        mysql.resetCurrentProxyPayload();
        proxyBuffer.channelReadEndIndex(totalPacketEndIndex);
        MySQLPacketResolver packetResolver = mysql.getBackendPacketResolver();
        mySQLPacket.packetReadStartIndex(packetResolver.getEndPos());
        mysql.getBackendPacketResolver().setIsClientLoginRequest(true);
        handle(mysql);
        return;
    }
    if (status == 1 && fastAuthResult == 4) {
        // 发送payload为02的包 然后读取公钥加密密码
        byte[] payload = { (byte) 2 };
        mySQLPacket = mysql.newCurrentProxyPacket(1024);
        mySQLPacket.writeBytes(payload);
        mysql.writeCurrentProxyPacket(mySQLPacket, 3);
        stage = STR_CACHING_AUTH_STAGE;
        mysql.getBackendPacketResolver().setIsClientLoginRequest(true);
        return;
    }
    // 连接不上
    ErrorPacketImpl errorPacket = new ErrorPacketImpl();
    errorPacket.readPayload(mySQLPacket);
    onException(mysql, new MycatException(errorPacket.getErrorCode(), errorPacket.getErrorMessageString()));
}
Also used : MycatException(io.mycat.MycatException) MySQLPayloadType(io.mycat.proxy.packet.MySQLPayloadType) MySQLPacketResolver(io.mycat.proxy.packet.MySQLPacketResolver)

Example 2 with MySQLPayloadType

use of io.mycat.proxy.packet.MySQLPayloadType in project Mycat2 by MyCATApache.

the class ResultSetHandler method onSocketRead.

// /**
// * 该方法可能会被重写
// */
// default void onFinishedCollect(MySQLClientSession mysql, boolean success, String errorMessage) {
// ResultSetCallBack callBack = mysql.getCallBackAndReset();
// assert callBack != null;
// if (success) {
// callBack.onFinishedCollect(mysql, this, true, getResult(), null);
// } else {
// callBack.onFinishedCollect(mysql, this, false, errorMessage, null);
// }
// }
/**
 * 读事件处理
 */
@Override
default void onSocketRead(MySQLClientSession mysql) {
    assert mysql.getCurNIOHandler() == this;
    if (!mysql.checkOpen()) {
        ResultSetCallBack callBackAndReset = mysql.getCallBack();
        ClosedChannelException closedChannelException = new ClosedChannelException();
        onException(mysql, closedChannelException);
        callBackAndReset.onFinishedException(closedChannelException, this, null);
        return;
    }
    try {
        MySQLPacketResolver resolver = mysql.getBackendPacketResolver();
        ProxyBuffer proxyBuffer = mysql.currentProxyBuffer();
        proxyBuffer.newBufferIfNeed();
        if (!mysql.readFromChannel()) {
            return;
        }
        mysql.setRequestSuccess(true);
        int totalPacketEndIndex = proxyBuffer.channelReadEndIndex();
        MySQLPacket mySQLPacket = (MySQLPacket) proxyBuffer;
        boolean isResponseFinished = false;
        ErrorPacketImpl errorPacket = null;
        while (mysql.readProxyPayloadFully()) {
            MySQLPayloadType type = mysql.getBackendPacketResolver().getMySQLPayloadType();
            isResponseFinished = mysql.isResponseFinished();
            MySQLPacket payload = mysql.currentProxyPayload();
            int startPos = payload.packetReadStartIndex();
            int endPos = payload.packetReadEndIndex();
            switch(type) {
                case REQUEST:
                    this.onRequest(mySQLPacket, startPos, endPos);
                    break;
                case LOAD_DATA_REQUEST:
                    this.onLoadDataRequest(mySQLPacket, startPos, endPos);
                    break;
                case REQUEST_COM_QUERY:
                    this.onRequestComQuery(mySQLPacket, startPos, endPos);
                    break;
                case REQUEST_SEND_LONG_DATA:
                    this.onPrepareLongData(mySQLPacket, startPos, endPos);
                    break;
                case REQUEST_PREPARE:
                    this.onReqeustPrepareStatement(mySQLPacket, startPos, endPos);
                    break;
                case REQUEST_COM_STMT_CLOSE:
                    this.onRequestComStmtClose(mySQLPacket, startPos, endPos);
                    break;
                case FIRST_ERROR:
                    {
                        ErrorPacketImpl packet = new ErrorPacketImpl();
                        errorPacket = packet;
                        packet.readPayload(mySQLPacket);
                        this.onFirstError(packet);
                        break;
                    }
                case FIRST_OK:
                    MycatMonitor.onResultSetEnd(mysql);
                    this.onOk(mySQLPacket, startPos, endPos);
                    break;
                case FIRST_EOF:
                    this.onEof(mySQLPacket, startPos, endPos);
                    break;
                case COLUMN_COUNT:
                    this.onColumnCount(resolver.getColumnCount());
                    break;
                case COLUMN_DEF:
                    this.onColumnDef(mySQLPacket, startPos, endPos);
                    break;
                case COLUMN_EOF:
                    this.onColumnDefEof(mySQLPacket, startPos, endPos);
                    break;
                case TEXT_ROW:
                    this.onTextRow(mySQLPacket, startPos, endPos);
                    break;
                case BINARY_ROW:
                    this.onBinaryRow(mySQLPacket, startPos, endPos);
                    break;
                case ROW_EOF:
                case ROW_OK:
                    MycatMonitor.onResultSetEnd(mysql);
                    this.onRowOk(mySQLPacket, startPos, endPos);
                    break;
                case ROW_ERROR:
                    ErrorPacketImpl packet = new ErrorPacketImpl();
                    errorPacket = packet;
                    packet.readPayload(mySQLPacket);
                    this.onRowError(packet, startPos, endPos);
                    break;
                case PREPARE_OK:
                    this.onPrepareOk(resolver);
                    break;
                case PREPARE_OK_PARAMER_DEF:
                    this.onPrepareOkParameterDef(mySQLPacket, startPos, endPos);
                    break;
                case PREPARE_OK_COLUMN_DEF:
                    this.onPrepareOkColumnDef(mySQLPacket, startPos, endPos);
                    break;
                case PREPARE_OK_COLUMN_DEF_EOF:
                    this.onPrepareOkColumnDefEof(resolver);
                    break;
                case PREPARE_OK_PARAMER_DEF_EOF:
                    this.onPrepareOkParameterDefEof(resolver);
                    break;
            }
            mysql.resetCurrentProxyPayload();
            proxyBuffer.channelReadEndIndex(totalPacketEndIndex);
            if (isResponseFinished) {
                break;
            }
            assert mysql.getCurNIOHandler() == this;
            MySQLPacketResolver packetResolver = mysql.getBackendPacketResolver();
            mySQLPacket.packetReadStartIndex(packetResolver.getEndPos());
        }
        if (isResponseFinished) {
            ByteBuffer allocate = ByteBuffer.allocate(8192);
            if (mysql.channel().read(allocate) > 0) {
                throw new IllegalArgumentException();
            }
            boolean responseFinished = mysql.isResponseFinished();
            mysql.getBackendPacketResolver().setState(MySQLPacketResolver.ComQueryState.QUERY_PACKET);
            ResultSetCallBack callBackAndReset = mysql.getCallBack();
            mysql.setCallBack(null);
            onFinishedCollect(mysql);
            onClear(mysql);
            if (errorPacket == null) {
                callBackAndReset.onFinished(mysql.isMonopolized(), mysql, this, null);
            } else {
                callBackAndReset.onErrorPacket(errorPacket, mysql.isMonopolized(), mysql, this, null);
            }
            return;
        }
    } catch (Exception e) {
        LOGGER.error("", e);
        ResultSetCallBack callBackAndReset = mysql.getCallBack();
        Objects.requireNonNull(callBackAndReset);
        mysql.setCallBack(null);
        if (mysql.isRequestSuccess()) {
            MycatMonitor.onResultSetReadException(mysql, e);
            onFinishedCollectException(mysql, e);
            onException(mysql, e);
            callBackAndReset.onFinishedException(e, this, null);
            return;
        } else {
            MycatMonitor.onResultSetWriteException(mysql, e);
            onFinishedCollectException(mysql, e);
            onException(mysql, e);
            callBackAndReset.onFinishedSendException(e, this, null);
            return;
        }
    }
}
Also used : ClosedChannelException(java.nio.channels.ClosedChannelException) MySQLPayloadType(io.mycat.proxy.packet.MySQLPayloadType) MySQLPacket(io.mycat.beans.mysql.packet.MySQLPacket) ResultSetCallBack(io.mycat.proxy.callback.ResultSetCallBack) ProxyBuffer(io.mycat.beans.mysql.packet.ProxyBuffer) MySQLPacketResolver(io.mycat.proxy.packet.MySQLPacketResolver) ByteBuffer(java.nio.ByteBuffer) ErrorPacketImpl(io.mycat.beans.mysql.packet.ErrorPacketImpl) MycatException(io.mycat.MycatException) ClosedChannelException(java.nio.channels.ClosedChannelException)

Aggregations

MycatException (io.mycat.MycatException)2 MySQLPacketResolver (io.mycat.proxy.packet.MySQLPacketResolver)2 MySQLPayloadType (io.mycat.proxy.packet.MySQLPayloadType)2 ErrorPacketImpl (io.mycat.beans.mysql.packet.ErrorPacketImpl)1 MySQLPacket (io.mycat.beans.mysql.packet.MySQLPacket)1 ProxyBuffer (io.mycat.beans.mysql.packet.ProxyBuffer)1 ResultSetCallBack (io.mycat.proxy.callback.ResultSetCallBack)1 ByteBuffer (java.nio.ByteBuffer)1 ClosedChannelException (java.nio.channels.ClosedChannelException)1