diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec.h b/source/extensions/filters/network/mysql_proxy/mysql_codec.h index a0f01c2925b1c..d11a509ecc36a 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec.h @@ -99,7 +99,7 @@ class MySQLCodec : public Logger::Loggable { PACKED_STRUCT(struct header_fields { uint32_t length_ : 24; - uint32_t seq_ : 8; + uint8_t seq_ : 8; }); union MySQLHeader { @@ -109,20 +109,17 @@ class MySQLCodec : public Logger::Loggable { virtual ~MySQLCodec() {} - int decode(Buffer::Instance& data, uint64_t& offset, int seq, int len) { + int decode(Buffer::Instance& data, uint8_t seq, uint32_t len) { seq_ = seq; - const uint64_t prev_offset = offset; - int result = parseMessage(data, offset, len); - offset = prev_offset + len; // Ensure that the whole message was consumed - return result; + return parseMessage(data, len); } virtual std::string encode() PURE; protected: - virtual int parseMessage(Buffer::Instance& data, uint64_t& offset, int len) PURE; + virtual int parseMessage(Buffer::Instance& data, uint32_t len) PURE; - int seq_; + uint8_t seq_; }; } // namespace MySQLProxy diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin.cc b/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin.cc index 11d13fa44cf75..eee66db20d0af 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin.cc +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin.cc @@ -44,21 +44,21 @@ bool ClientLogin::isClientSecureConnection() const { return extended_client_cap_ & MYSQL_EXT_CL_SECURE_CONNECTION; } -int ClientLogin::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int) { +int ClientLogin::parseMessage(Buffer::Instance& buffer, uint32_t) { uint16_t client_cap = 0; - if (BufferHelper::peekUint16(buffer, offset, client_cap) != MYSQL_SUCCESS) { + if (BufferHelper::readUint16(buffer, client_cap) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing client_cap in mysql ClientLogin msg"); return MYSQL_FAILURE; } setClientCap(client_cap); uint16_t extended_client_cap = 0; - if (BufferHelper::peekUint16(buffer, offset, extended_client_cap) != MYSQL_SUCCESS) { + if (BufferHelper::readUint16(buffer, extended_client_cap) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing extended_client_cap in mysql ClientLogin msg"); return MYSQL_FAILURE; } setExtendedClientCap(extended_client_cap); uint32_t max_packet = 0; - if (BufferHelper::peekUint32(buffer, offset, max_packet) != MYSQL_SUCCESS) { + if (BufferHelper::readUint32(buffer, max_packet) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing max_packet in mysql ClientLogin msg"); return MYSQL_FAILURE; } @@ -68,17 +68,17 @@ int ClientLogin::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int) { return MYSQL_SUCCESS; } uint8_t charset = 0; - if (BufferHelper::peekUint8(buffer, offset, charset) != MYSQL_SUCCESS) { + if (BufferHelper::readUint8(buffer, charset) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing charset in mysql ClientLogin msg"); return MYSQL_FAILURE; } setCharset(charset); - if (BufferHelper::peekBytes(buffer, offset, UNSET_BYTES) != MYSQL_SUCCESS) { + if (BufferHelper::readBytes(buffer, UNSET_BYTES) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error skipping unset bytes in mysql ClientLogin msg"); return MYSQL_FAILURE; } std::string username; - if (BufferHelper::peekString(buffer, offset, username) != MYSQL_SUCCESS) { + if (BufferHelper::readString(buffer, username) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing username in mysql ClientLogin msg"); return MYSQL_FAILURE; } @@ -86,26 +86,26 @@ int ClientLogin::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int) { std::string auth_resp; if (isClientAuthLenClData()) { uint64_t auth_resp_len = 0; - if (BufferHelper::peekLengthEncodedInteger(buffer, offset, auth_resp_len) != MYSQL_SUCCESS) { + if (BufferHelper::readLengthEncodedInteger(buffer, auth_resp_len) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing LengthEncodedInteger in mysql ClientLogin msg"); return MYSQL_FAILURE; } - if (BufferHelper::peekStringBySize(buffer, offset, auth_resp_len, auth_resp) != MYSQL_SUCCESS) { + if (BufferHelper::readStringBySize(buffer, auth_resp_len, auth_resp) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing auth_resp in mysql ClientLogin msg"); return MYSQL_FAILURE; } } else if (isClientSecureConnection()) { uint8_t auth_resp_len = 0; - if (BufferHelper::peekUint8(buffer, offset, auth_resp_len) != MYSQL_SUCCESS) { + if (BufferHelper::readUint8(buffer, auth_resp_len) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing auth_resp_len in mysql ClientLogin msg"); return MYSQL_FAILURE; } - if (BufferHelper::peekStringBySize(buffer, offset, auth_resp_len, auth_resp) != MYSQL_SUCCESS) { + if (BufferHelper::readStringBySize(buffer, auth_resp_len, auth_resp) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing auth_resp in mysql ClientLogin msg"); return MYSQL_FAILURE; } } else { - if (BufferHelper::peekString(buffer, offset, auth_resp) != MYSQL_SUCCESS) { + if (BufferHelper::readString(buffer, auth_resp) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing auth_resp in mysql ClientLogin msg"); return MYSQL_FAILURE; } @@ -113,7 +113,7 @@ int ClientLogin::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int) { setAuthResp(auth_resp); if (isConnectWithDb()) { std::string db; - if (BufferHelper::peekString(buffer, offset, db) != MYSQL_SUCCESS) { + if (BufferHelper::readString(buffer, db) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing auth_resp in mysql ClientLogin msg"); return MYSQL_FAILURE; } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin.h b/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin.h index ec315c57f421f..0ce28edfb2d07 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin.h @@ -12,7 +12,7 @@ constexpr int UNSET_BYTES = 23; class ClientLogin : public MySQLCodec { public: // MySQLCodec - int parseMessage(Buffer::Instance& buffer, uint64_t& offset, int len) override; + int parseMessage(Buffer::Instance& buffer, uint32_t len) override; std::string encode() override; int getClientCap() const { return client_cap_; } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin_resp.cc b/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin_resp.cc index a684b26b3181a..dc7c1da36420f 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin_resp.cc +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin_resp.cc @@ -20,37 +20,37 @@ void ClientLoginResponse::setServerStatus(uint16_t status) { server_status_ = st void ClientLoginResponse::setWarnings(uint16_t warnings) { warnings_ = warnings; } -int ClientLoginResponse::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int) { +int ClientLoginResponse::parseMessage(Buffer::Instance& buffer, uint32_t) { uint8_t resp_code = 0; - if (BufferHelper::peekUint8(buffer, offset, resp_code) != MYSQL_SUCCESS) { + if (BufferHelper::readUint8(buffer, resp_code) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing response code in mysql Login Ok msg"); return MYSQL_FAILURE; } setRespCode(resp_code); - if ((resp_code == MYSQL_RESP_AUTH_SWITCH) && BufferHelper::endOfBuffer(buffer, offset)) { + if ((resp_code == MYSQL_RESP_AUTH_SWITCH) && BufferHelper::endOfBuffer(buffer)) { // OldAuthSwitchRequest return MYSQL_SUCCESS; } uint8_t affected_rows = 0; - if (BufferHelper::peekUint8(buffer, offset, affected_rows) != MYSQL_SUCCESS) { + if (BufferHelper::readUint8(buffer, affected_rows) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing affected_rows in mysql Login Ok msg"); return MYSQL_FAILURE; } setAffectedRows(affected_rows); uint8_t last_insert_id = 0; - if (BufferHelper::peekUint8(buffer, offset, last_insert_id) != MYSQL_SUCCESS) { + if (BufferHelper::readUint8(buffer, last_insert_id) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing last_insert_id in mysql Login Ok msg"); return MYSQL_FAILURE; } setLastInsertId(last_insert_id); uint16_t server_status = 0; - if (BufferHelper::peekUint16(buffer, offset, server_status) != MYSQL_SUCCESS) { + if (BufferHelper::readUint16(buffer, server_status) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing server_status in mysql Login Ok msg"); return MYSQL_FAILURE; } setServerStatus(server_status); uint16_t warnings = 0; - if (BufferHelper::peekUint16(buffer, offset, warnings) != MYSQL_SUCCESS) { + if (BufferHelper::readUint16(buffer, warnings) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing warnings in mysql Login Ok msg"); return MYSQL_FAILURE; } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin_resp.h b/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin_resp.h index 31ae89b36f6b7..cc7d5c25861d3 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin_resp.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_clogin_resp.h @@ -13,7 +13,7 @@ namespace MySQLProxy { class ClientLoginResponse : public MySQLCodec { public: // MySQLCodec - int parseMessage(Buffer::Instance& buffer, uint64_t& offset, int len) override; + int parseMessage(Buffer::Instance& buffer, uint32_t len) override; std::string encode() override; uint8_t getRespCode() const { return resp_code_; } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_command.cc b/source/extensions/filters/network/mysql_proxy/mysql_codec_command.cc index 4f39dfbc1ba29..fa265617e505a 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_command.cc +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_command.cc @@ -8,9 +8,9 @@ namespace Extensions { namespace NetworkFilters { namespace MySQLProxy { -Command::Cmd Command::parseCmd(Buffer::Instance& data, uint64_t& offset) { +Command::Cmd Command::parseCmd(Buffer::Instance& data) { uint8_t cmd; - if (BufferHelper::peekUint8(data, offset, cmd) != MYSQL_SUCCESS) { + if (BufferHelper::readUint8(data, cmd) != MYSQL_SUCCESS) { return Command::Cmd::COM_NULL; } return static_cast(cmd); @@ -20,8 +20,8 @@ void Command::setCmd(Command::Cmd cmd) { cmd_ = cmd; } void Command::setDb(std::string db) { db_ = db; } -int Command::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int len) { - Command::Cmd cmd = parseCmd(buffer, offset); +int Command::parseMessage(Buffer::Instance& buffer, uint32_t len) { + Command::Cmd cmd = parseCmd(buffer); setCmd(cmd); if (cmd == Command::Cmd::COM_NULL) { return MYSQL_FAILURE; @@ -32,7 +32,7 @@ int Command::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int len) { case Command::Cmd::COM_CREATE_DB: case Command::Cmd::COM_DROP_DB: { std::string db = ""; - BufferHelper::peekStringBySize(buffer, offset, len - 1, db); + BufferHelper::readStringBySize(buffer, len - 1, db); setDb(db); break; } @@ -40,7 +40,7 @@ int Command::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int len) { case Command::Cmd::COM_QUERY: is_query_ = true; // query string starts after one byte for comm type - BufferHelper::peekStringBySize(buffer, offset, len - 1, data_); + BufferHelper::readStringBySize(buffer, len - 1, data_); setDb(""); break; diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_command.h b/source/extensions/filters/network/mysql_proxy/mysql_codec_command.h index 804e9633f7841..1289aa89fbe2a 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_command.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_command.h @@ -35,10 +35,10 @@ class Command : public MySQLCodec { }; // MySQLCodec - int parseMessage(Buffer::Instance&, uint64_t& offset, int len) override; + int parseMessage(Buffer::Instance&, uint32_t len) override; std::string encode() override; - Cmd parseCmd(Buffer::Instance& data, uint64_t& offset); + Cmd parseCmd(Buffer::Instance& data); Cmd getCmd() const { return cmd_; } const std::string& getData() const { return data_; } std::string& getDb() { return db_; } @@ -57,7 +57,7 @@ class Command : public MySQLCodec { class CommandResponse : public MySQLCodec { public: // MySQLCodec - int parseMessage(Buffer::Instance&, uint64_t&, int) override { return MYSQL_SUCCESS; } + int parseMessage(Buffer::Instance&, uint32_t) override { return MYSQL_SUCCESS; } std::string encode() override { return ""; } uint16_t getServerStatus() const { return server_status_; } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_greeting.cc b/source/extensions/filters/network/mysql_proxy/mysql_codec_greeting.cc index 2938a1d8b2382..cccc07377a342 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_greeting.cc +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_greeting.cc @@ -24,27 +24,27 @@ void ServerGreeting::setServerStatus(int server_status) { server_status_ = serve void ServerGreeting::setExtServerCap(int ext_server_cap) { ext_server_cap_ = ext_server_cap; } -int ServerGreeting::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int) { +int ServerGreeting::parseMessage(Buffer::Instance& buffer, uint32_t) { uint8_t protocol = 0; - if (BufferHelper::peekUint8(buffer, offset, protocol) != MYSQL_SUCCESS) { + if (BufferHelper::readUint8(buffer, protocol) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing protocol in mysql Greeting msg"); return MYSQL_FAILURE; } setProtocol(protocol); std::string version; - if (BufferHelper::peekString(buffer, offset, version) != MYSQL_SUCCESS) { + if (BufferHelper::readString(buffer, version) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing version in mysql Greeting msg"); return MYSQL_FAILURE; } setVersion(version); uint32_t thread_id = 0; - if (BufferHelper::peekUint32(buffer, offset, thread_id) != MYSQL_SUCCESS) { + if (BufferHelper::readUint32(buffer, thread_id) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing thread_id in mysql Greeting msg"); return MYSQL_FAILURE; } setThreadId(thread_id); std::string salt; - if (BufferHelper::peekString(buffer, offset, salt) != MYSQL_SUCCESS) { + if (BufferHelper::readString(buffer, salt) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing salt in mysql Greeting msg"); return MYSQL_FAILURE; } @@ -54,29 +54,29 @@ int ServerGreeting::parseMessage(Buffer::Instance& buffer, uint64_t& offset, int return MYSQL_SUCCESS; } uint16_t server_cap = 0; - if (BufferHelper::peekUint16(buffer, offset, server_cap) != MYSQL_SUCCESS) { + if (BufferHelper::readUint16(buffer, server_cap) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing server_cap in mysql Greeting msg"); return MYSQL_FAILURE; } setServerCap(server_cap); - if (BufferHelper::endOfBuffer(buffer, offset) == true) { + if (BufferHelper::endOfBuffer(buffer)) { // HandshakeV10 can terminate after Server Capabilities return MYSQL_SUCCESS; } uint8_t server_language = 0; - if (BufferHelper::peekUint8(buffer, offset, server_language) != MYSQL_SUCCESS) { + if (BufferHelper::readUint8(buffer, server_language) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing server_language in mysql Greeting msg"); return MYSQL_FAILURE; } setServerLanguage(server_language); uint16_t server_status = 0; - if (BufferHelper::peekUint16(buffer, offset, server_status) != MYSQL_SUCCESS) { + if (BufferHelper::readUint16(buffer, server_status) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing server_status in mysql Greeting msg"); return MYSQL_FAILURE; } setServerStatus(server_status); uint16_t ext_server_cap = 0; - if (BufferHelper::peekUint16(buffer, offset, ext_server_cap) != MYSQL_SUCCESS) { + if (BufferHelper::readUint16(buffer, ext_server_cap) != MYSQL_SUCCESS) { ENVOY_LOG(info, "error parsing ext_server_cap in mysql Greeting msg"); return MYSQL_FAILURE; } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_greeting.h b/source/extensions/filters/network/mysql_proxy/mysql_codec_greeting.h index 4d10870f38f22..2e3f63dd548c7 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_greeting.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_greeting.h @@ -11,7 +11,7 @@ namespace MySQLProxy { class ServerGreeting : public MySQLCodec { public: // MySQLCodec - int parseMessage(Buffer::Instance& buffer, uint64_t& offset, int len) override; + int parseMessage(Buffer::Instance& buffer, uint32_t len) override; std::string encode() override; int getProtocol() const { return protocol_; } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_switch_resp.cc b/source/extensions/filters/network/mysql_proxy/mysql_codec_switch_resp.cc index a92b375506708..77f43d4d81c65 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_switch_resp.cc +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_switch_resp.cc @@ -12,7 +12,7 @@ void ClientSwitchResponse::setAuthPluginResp(std::string& auth_plugin_resp) { auth_plugin_resp_.assign(auth_plugin_resp); } -int ClientSwitchResponse::parseMessage(Buffer::Instance&, uint64_t&, int) { return MYSQL_SUCCESS; } +int ClientSwitchResponse::parseMessage(Buffer::Instance&, uint32_t) { return MYSQL_SUCCESS; } std::string ClientSwitchResponse::encode() { Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); diff --git a/source/extensions/filters/network/mysql_proxy/mysql_codec_switch_resp.h b/source/extensions/filters/network/mysql_proxy/mysql_codec_switch_resp.h index 9bf7acbaedd9c..5ed3d70c9c354 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_codec_switch_resp.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_codec_switch_resp.h @@ -11,7 +11,7 @@ namespace MySQLProxy { class ClientSwitchResponse : public MySQLCodec { public: // MySQLCodec - int parseMessage(Buffer::Instance& buffer, uint64_t& offset, int len) override; + int parseMessage(Buffer::Instance& buffer, uint32_t len) override; std::string encode() override; const std::string& getAuthPluginResp() const { return auth_plugin_resp_; } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_decoder.cc b/source/extensions/filters/network/mysql_proxy/mysql_decoder.cc index 885c03565514b..b59a5b4cde232 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_decoder.cc +++ b/source/extensions/filters/network/mysql_proxy/mysql_decoder.cc @@ -9,8 +9,8 @@ namespace Extensions { namespace NetworkFilters { namespace MySQLProxy { -void DecoderImpl::parseMessage(Buffer::Instance& message, uint64_t& offset, int seq, int len) { - ENVOY_LOG(trace, "mysql_proxy: parsing message, offset {}, seq {}, len {}", offset, seq, len); +void DecoderImpl::parseMessage(Buffer::Instance& message, uint8_t seq, uint32_t len) { + ENVOY_LOG(trace, "mysql_proxy: parsing message, seq {}, len {}", seq, len); // Run the MySQL state machine switch (session_.getState()) { @@ -18,7 +18,7 @@ void DecoderImpl::parseMessage(Buffer::Instance& message, uint64_t& offset, int // Expect Server Challenge packet case MySQLSession::State::MYSQL_INIT: { ServerGreeting greeting; - greeting.decode(message, offset, seq, len); + greeting.decode(message, seq, len); callbacks_.onServerGreeting(greeting); session_.setState(MySQLSession::State::MYSQL_CHALLENGE_REQ); @@ -28,7 +28,7 @@ void DecoderImpl::parseMessage(Buffer::Instance& message, uint64_t& offset, int // Process Client Handshake Response case MySQLSession::State::MYSQL_CHALLENGE_REQ: { ClientLogin client_login{}; - client_login.decode(message, offset, seq, len); + client_login.decode(message, seq, len); callbacks_.onClientLogin(client_login); if (client_login.isSSLRequest()) { @@ -47,7 +47,7 @@ void DecoderImpl::parseMessage(Buffer::Instance& message, uint64_t& offset, int case MySQLSession::State::MYSQL_CHALLENGE_RESP_41: case MySQLSession::State::MYSQL_CHALLENGE_RESP_320: { ClientLoginResponse client_login_resp{}; - client_login_resp.decode(message, offset, seq, len); + client_login_resp.decode(message, seq, len); callbacks_.onClientLoginResponse(client_login_resp); if (client_login_resp.getRespCode() == MYSQL_RESP_OK) { @@ -68,7 +68,7 @@ void DecoderImpl::parseMessage(Buffer::Instance& message, uint64_t& offset, int case MySQLSession::State::MYSQL_AUTH_SWITCH_RESP: { ClientSwitchResponse client_switch_resp{}; - client_switch_resp.decode(message, offset, seq, len); + client_switch_resp.decode(message, seq, len); callbacks_.onClientSwitchResponse(client_switch_resp); session_.setState(MySQLSession::State::MYSQL_AUTH_SWITCH_MORE); @@ -77,7 +77,7 @@ void DecoderImpl::parseMessage(Buffer::Instance& message, uint64_t& offset, int case MySQLSession::State::MYSQL_AUTH_SWITCH_MORE: { ClientLoginResponse client_login_resp{}; - client_login_resp.decode(message, offset, seq, len); + client_login_resp.decode(message, seq, len); callbacks_.onMoreClientLoginResponse(client_login_resp); if (client_login_resp.getRespCode() == MYSQL_RESP_OK) { @@ -104,25 +104,21 @@ void DecoderImpl::parseMessage(Buffer::Instance& message, uint64_t& offset, int // Process Command case MySQLSession::State::MYSQL_REQ: { Command command{}; - command.decode(message, offset, seq, len); + command.decode(message, seq, len); callbacks_.onCommand(command); - if (BufferHelper::endOfBuffer(message, offset)) { - session_.setState(MySQLSession::State::MYSQL_REQ_RESP); - } + session_.setState(MySQLSession::State::MYSQL_REQ_RESP); break; } // Process Command Response case MySQLSession::State::MYSQL_REQ_RESP: { CommandResponse command_resp{}; - command_resp.decode(message, offset, seq, len); + command_resp.decode(message, seq, len); callbacks_.onCommandResponse(command_resp); - if (BufferHelper::endOfBuffer(message, offset)) { - session_.setState(MySQLSession::State::MYSQL_REQ); - session_.setExpectedSeq(MYSQL_REQUEST_PKT_NUM); - } + session_.setState(MySQLSession::State::MYSQL_REQ); + session_.setExpectedSeq(MYSQL_REQUEST_PKT_NUM); break; } @@ -136,36 +132,47 @@ void DecoderImpl::parseMessage(Buffer::Instance& message, uint64_t& offset, int static_cast(session_.getState())); } -void DecoderImpl::decode(Buffer::Instance& data, uint64_t& offset) { - ENVOY_LOG(trace, "mysql_proxy: decoding {} bytes at offset {}", data.length(), offset); +bool DecoderImpl::decode(Buffer::Instance& data) { + ENVOY_LOG(trace, "mysql_proxy: decoding {} bytes", data.length()); - int len = 0; - int seq = 0; - if (BufferHelper::peekHdr(data, offset, len, seq) != MYSQL_SUCCESS) { + uint32_t len = 0; + uint8_t seq = 0; + if (BufferHelper::peekHdr(data, len, seq) != MYSQL_SUCCESS) { throw EnvoyException("error parsing mysql packet header"); } + // If message is split over multiple packets, hold off until the entire message is available. + // Consider the size of the header here as it's not consumed yet. + if (sizeof(uint32_t) + len > data.length()) { + return false; + } + + BufferHelper::consumeHdr(data); // Consume the header once the message is fully available. callbacks_.onNewMessage(session_.getState()); // Ignore duplicate and out-of-sync packets. if (seq != session_.getExpectedSeq()) { callbacks_.onProtocolError(); - offset += len; ENVOY_LOG(info, "mysql_proxy: ignoring out-of-sync packet"); - return; + data.drain(len); // Ensure that the whole message was consumed + return true; } + session_.setExpectedSeq(seq + 1); - parseMessage(data, offset, seq, len); - ENVOY_LOG(trace, "mysql_proxy: offset after decoding is {} out of {}", offset, data.length()); + const ssize_t data_len = data.length(); + parseMessage(data, seq, len); + const ssize_t consumed_len = data_len - data.length(); + data.drain(len - consumed_len); // Ensure that the whole message was consumed + + ENVOY_LOG(trace, "mysql_proxy: {} bytes remaining in buffer", data.length()); + return true; } void DecoderImpl::onData(Buffer::Instance& data) { // TODO(venilnoronha): handle messages over 16 mb. See - // https://dev.mysql.com/doc/dev/mysql-server/8.0.2/page_protocol_basic_packets.html#sect_protocol_basic_packets_sending_mt_16mb. - uint64_t offset = 0; - while (!BufferHelper::endOfBuffer(data, offset)) { - decode(data, offset); + // https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_packets.html#sect_protocol_basic_packets_sending_mt_16mb. + while (!BufferHelper::endOfBuffer(data) && decode(data)) { } } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_decoder.h b/source/extensions/filters/network/mysql_proxy/mysql_decoder.h index a44868f151fd4..3aa9a7224fa2c 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_decoder.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_decoder.h @@ -58,8 +58,8 @@ class DecoderImpl : public Decoder, Logger::Loggable { MySQLSession& getSession() override { return session_; } private: - void decode(Buffer::Instance& data, uint64_t& offset); - void parseMessage(Buffer::Instance& message, uint64_t& offset, int seq, int len); + bool decode(Buffer::Instance& data); + void parseMessage(Buffer::Instance& message, uint8_t seq, uint32_t len); DecoderCallbacks& callbacks_; MySQLSession session_; diff --git a/source/extensions/filters/network/mysql_proxy/mysql_filter.cc b/source/extensions/filters/network/mysql_proxy/mysql_filter.cc index bb920dafe0189..75f14d2d1de50 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_filter.cc +++ b/source/extensions/filters/network/mysql_proxy/mysql_filter.cc @@ -23,23 +23,26 @@ void MySQLFilter::initializeReadFilterCallbacks(Network::ReadFilterCallbacks& ca } Network::FilterStatus MySQLFilter::onData(Buffer::Instance& data, bool) { - doDecode(data); + // Safety measure just to make sure that if we have a decoding error we keep going and lose stats. + // This can be removed once we are more confident of this code. + if (sniffing_) { + read_buffer_.add(data); + doDecode(read_buffer_); + } return Network::FilterStatus::Continue; } Network::FilterStatus MySQLFilter::onWrite(Buffer::Instance& data, bool) { - doDecode(data); - return Network::FilterStatus::Continue; -} - -void MySQLFilter::doDecode(Buffer::Instance& buffer) { // Safety measure just to make sure that if we have a decoding error we keep going and lose stats. // This can be removed once we are more confident of this code. - if (!sniffing_) { - buffer.drain(buffer.length()); - return; + if (sniffing_) { + write_buffer_.add(data); + doDecode(write_buffer_); } + return Network::FilterStatus::Continue; +} +void MySQLFilter::doDecode(Buffer::Instance& buffer) { // Clear dynamic metadata. envoy::api::v2::core::Metadata& dynamic_metadata = read_callbacks_->connection().streamInfo().dynamicMetadata(); @@ -57,6 +60,8 @@ void MySQLFilter::doDecode(Buffer::Instance& buffer) { ENVOY_LOG(info, "mysql_proxy: decoding error: {}", e.what()); config_->stats_.decoder_errors_.inc(); sniffing_ = false; + read_buffer_.drain(read_buffer_.length()); + write_buffer_.drain(write_buffer_.length()); } } diff --git a/source/extensions/filters/network/mysql_proxy/mysql_filter.h b/source/extensions/filters/network/mysql_proxy/mysql_filter.h index 8a4295043a359..8ca5bb690785f 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_filter.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_filter.h @@ -103,6 +103,8 @@ class MySQLFilter : public Network::Filter, DecoderCallbacks, Logger::Loggable decoder_; bool sniffing_{true}; }; diff --git a/source/extensions/filters/network/mysql_proxy/mysql_session.h b/source/extensions/filters/network/mysql_proxy/mysql_session.h index 511ee2780c227..88c64c0248379 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_session.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_session.h @@ -29,12 +29,12 @@ class MySQLSession : Logger::Loggable { void setState(MySQLSession::State state) { state_ = state; } MySQLSession::State getState() { return state_; } - int getExpectedSeq() { return expected_seq_; } - void setExpectedSeq(int seq) { expected_seq_ = seq; } + uint8_t getExpectedSeq() { return expected_seq_; } + void setExpectedSeq(uint8_t seq) { expected_seq_ = seq; } private: MySQLSession::State state_{State::MYSQL_INIT}; - int expected_seq_{0}; + uint8_t expected_seq_{0}; }; } // namespace MySQLProxy diff --git a/source/extensions/filters/network/mysql_proxy/mysql_utils.cc b/source/extensions/filters/network/mysql_proxy/mysql_utils.cc index edb95e628c3ba..ed8a86f47c04b 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_utils.cc +++ b/source/extensions/filters/network/mysql_proxy/mysql_utils.cc @@ -21,7 +21,7 @@ void BufferHelper::addUint32(Buffer::Instance& buffer, uint32_t val) { void BufferHelper::addString(Buffer::Instance& buffer, const std::string& str) { buffer.add(str); } -std::string BufferHelper::encodeHdr(const std::string& cmd_str, int seq) { +std::string BufferHelper::encodeHdr(const std::string& cmd_str, uint8_t seq) { MySQLCodec::MySQLHeader mysqlhdr; mysqlhdr.fields_.length_ = cmd_str.length(); mysqlhdr.fields_.seq_ = seq; @@ -34,14 +34,12 @@ std::string BufferHelper::encodeHdr(const std::string& cmd_str, int seq) { return e_string; } -bool BufferHelper::endOfBuffer(Buffer::Instance& buffer, uint64_t& offset) { - return buffer.length() == offset; -} +bool BufferHelper::endOfBuffer(Buffer::Instance& buffer) { return buffer.length() == 0; } -int BufferHelper::peekUint8(Buffer::Instance& buffer, uint64_t& offset, uint8_t& val) { +int BufferHelper::readUint8(Buffer::Instance& buffer, uint8_t& val) { try { - val = buffer.peekLEInt(offset); - offset += sizeof(uint8_t); + val = buffer.peekLEInt(0); + buffer.drain(sizeof(uint8_t)); return MYSQL_SUCCESS; } catch (EnvoyException& e) { // buffer underflow @@ -49,10 +47,10 @@ int BufferHelper::peekUint8(Buffer::Instance& buffer, uint64_t& offset, uint8_t& } } -int BufferHelper::peekUint16(Buffer::Instance& buffer, uint64_t& offset, uint16_t& val) { +int BufferHelper::readUint16(Buffer::Instance& buffer, uint16_t& val) { try { - val = buffer.peekLEInt(offset); - offset += sizeof(uint16_t); + val = buffer.peekLEInt(0); + buffer.drain(sizeof(uint16_t)); return MYSQL_SUCCESS; } catch (EnvoyException& e) { // buffer underflow @@ -60,10 +58,10 @@ int BufferHelper::peekUint16(Buffer::Instance& buffer, uint64_t& offset, uint16_ } } -int BufferHelper::peekUint32(Buffer::Instance& buffer, uint64_t& offset, uint32_t& val) { +int BufferHelper::readUint32(Buffer::Instance& buffer, uint32_t& val) { try { - val = buffer.peekLEInt(offset); - offset += sizeof(uint32_t); + val = buffer.peekLEInt(0); + buffer.drain(sizeof(uint32_t)); return MYSQL_SUCCESS; } catch (EnvoyException& e) { // buffer underflow @@ -73,10 +71,9 @@ int BufferHelper::peekUint32(Buffer::Instance& buffer, uint64_t& offset, uint32_ // Implementation of MySQL lenenc encoder based on // https://dev.mysql.com/doc/internals/en/integer.html#packet-Protocol::LengthEncodedInteger -int BufferHelper::peekLengthEncodedInteger(Buffer::Instance& buffer, uint64_t& offset, - uint64_t& val) { +int BufferHelper::readLengthEncodedInteger(Buffer::Instance& buffer, uint64_t& val) { uint8_t byte_val = 0; - if (peekUint8(buffer, offset, byte_val) == MYSQL_FAILURE) { + if (readUint8(buffer, byte_val) == MYSQL_FAILURE) { return MYSQL_FAILURE; } if (byte_val < LENENCODINT_1BYTE) { @@ -86,14 +83,14 @@ int BufferHelper::peekLengthEncodedInteger(Buffer::Instance& buffer, uint64_t& o try { if (byte_val == LENENCODINT_2BYTES) { - val = buffer.peekLEInt(offset); - offset += sizeof(uint16_t); + val = buffer.peekLEInt(0); + buffer.drain(sizeof(uint16_t)); } else if (byte_val == LENENCODINT_3BYTES) { - val = buffer.peekLEInt(offset); - offset += sizeof(uint8_t) * 3; + val = buffer.peekLEInt(0); + buffer.drain(sizeof(uint8_t) * 3); } else if (byte_val == LENENCODINT_8BYTES) { - val = buffer.peekLEInt(offset); - offset += sizeof(uint64_t); + val = buffer.peekLEInt(0); + buffer.drain(sizeof(uint64_t)); } else { return MYSQL_FAILURE; } @@ -105,17 +102,17 @@ int BufferHelper::peekLengthEncodedInteger(Buffer::Instance& buffer, uint64_t& o return MYSQL_SUCCESS; } -int BufferHelper::peekBytes(Buffer::Instance& buffer, uint64_t& offset, int skip_bytes) { - if (buffer.length() < (offset + skip_bytes)) { +int BufferHelper::readBytes(Buffer::Instance& buffer, size_t skip_bytes) { + if (buffer.length() < skip_bytes) { return MYSQL_FAILURE; } - offset += skip_bytes; + buffer.drain(skip_bytes); return MYSQL_SUCCESS; } -int BufferHelper::peekString(Buffer::Instance& buffer, uint64_t& offset, std::string& str) { +int BufferHelper::readString(Buffer::Instance& buffer, std::string& str) { char end = MYSQL_STR_END; - ssize_t index = buffer.search(&end, sizeof(end), offset); + ssize_t index = buffer.search(&end, sizeof(end), 0); if (index == -1) { return MYSQL_FAILURE; } @@ -123,25 +120,36 @@ int BufferHelper::peekString(Buffer::Instance& buffer, uint64_t& offset, std::st return MYSQL_FAILURE; } str.assign(std::string(static_cast(buffer.linearize(index)), index)); - str = str.substr(offset); - offset = index + 1; + str = str.substr(0); + buffer.drain(index + 1); return MYSQL_SUCCESS; } -int BufferHelper::peekStringBySize(Buffer::Instance& buffer, uint64_t& offset, int len, - std::string& str) { - if (buffer.length() < (offset + len)) { +int BufferHelper::readStringBySize(Buffer::Instance& buffer, size_t len, std::string& str) { + if (buffer.length() < len) { return MYSQL_FAILURE; } - str.assign(std::string(static_cast(buffer.linearize(len + offset)), len + offset)); - str = str.substr(offset); - offset += len; + str.assign(std::string(static_cast(buffer.linearize(len)), len)); + str = str.substr(0); + buffer.drain(len); return MYSQL_SUCCESS; } -int BufferHelper::peekHdr(Buffer::Instance& buffer, uint64_t& offset, int& len, int& seq) { +int BufferHelper::peekUint32(Buffer::Instance& buffer, uint32_t& val) { + try { + val = buffer.peekLEInt(0); + return MYSQL_SUCCESS; + } catch (EnvoyException& e) { + // buffer underflow + return MYSQL_FAILURE; + } +} + +void BufferHelper::consumeHdr(Buffer::Instance& buffer) { buffer.drain(sizeof(uint32_t)); } + +int BufferHelper::peekHdr(Buffer::Instance& buffer, uint32_t& len, uint8_t& seq) { uint32_t val = 0; - if (peekUint32(buffer, offset, val) != MYSQL_SUCCESS) { + if (peekUint32(buffer, val) != MYSQL_SUCCESS) { return MYSQL_FAILURE; } seq = htonl(val) & MYSQL_HDR_SEQ_MASK; diff --git a/source/extensions/filters/network/mysql_proxy/mysql_utils.h b/source/extensions/filters/network/mysql_proxy/mysql_utils.h index a5eb420d2e604..75f1a46a11b07 100644 --- a/source/extensions/filters/network/mysql_proxy/mysql_utils.h +++ b/source/extensions/filters/network/mysql_proxy/mysql_utils.h @@ -29,17 +29,18 @@ class BufferHelper : public Logger::Loggable { static void addUint16(Buffer::Instance& buffer, uint16_t val); static void addUint32(Buffer::Instance& buffer, uint32_t val); static void addString(Buffer::Instance& buffer, const std::string& str); - static std::string encodeHdr(const std::string& cmd_str, int seq); - static bool endOfBuffer(Buffer::Instance& buffer, uint64_t& offset); - static int peekUint8(Buffer::Instance& buffer, uint64_t& offset, uint8_t& val); - static int peekUint16(Buffer::Instance& buffer, uint64_t& offset, uint16_t& val); - static int peekUint32(Buffer::Instance& buffer, uint64_t& offset, uint32_t& val); - static int peekLengthEncodedInteger(Buffer::Instance& buffer, uint64_t& offset, uint64_t& val); - static int peekBytes(Buffer::Instance& buffer, uint64_t& offset, int skip_bytes); - static int peekString(Buffer::Instance& buffer, uint64_t& offset, std::string& str); - static int peekStringBySize(Buffer::Instance& buffer, uint64_t& offset, int len, - std::string& str); - static int peekHdr(Buffer::Instance& buffer, uint64_t& offset, int& len, int& seq); + static std::string encodeHdr(const std::string& cmd_str, uint8_t seq); + static bool endOfBuffer(Buffer::Instance& buffer); + static int readUint8(Buffer::Instance& buffer, uint8_t& val); + static int readUint16(Buffer::Instance& buffer, uint16_t& val); + static int readUint32(Buffer::Instance& buffer, uint32_t& val); + static int readLengthEncodedInteger(Buffer::Instance& buffer, uint64_t& val); + static int readBytes(Buffer::Instance& buffer, size_t skip_bytes); + static int readString(Buffer::Instance& buffer, std::string& str); + static int readStringBySize(Buffer::Instance& buffer, size_t len, std::string& str); + static int peekUint32(Buffer::Instance& buffer, uint32_t& val); + static void consumeHdr(Buffer::Instance& buffer); + static int peekHdr(Buffer::Instance& buffer, uint32_t& len, uint8_t& seq); }; } // namespace MySQLProxy diff --git a/test/extensions/filters/network/mysql_proxy/mysql_codec_test.cc b/test/extensions/filters/network/mysql_proxy/mysql_codec_test.cc index 542daba4065c3..fb79a345d124c 100644 --- a/test/extensions/filters/network/mysql_proxy/mysql_codec_test.cc +++ b/test/extensions/filters/network/mysql_proxy/mysql_codec_test.cc @@ -19,10 +19,7 @@ constexpr int MYSQL_UT_LAST_ID = 0; constexpr int MYSQL_UT_SERVER_OK = 0; constexpr int MYSQL_UT_SERVER_WARNINGS = 0x0001; -class MySQLCodecTest : public testing::Test, public MySQLTestUtils { -protected: - uint64_t offset_{0}; -}; +class MySQLCodecTest : public testing::Test {}; TEST_F(MySQLCodecTest, MySQLServerChallengeV9EncDec) { ServerGreeting mysql_greet_encode{}; @@ -36,7 +33,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeV9EncDec) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getSalt(), mysql_greet_encode.getSalt()); EXPECT_EQ(mysql_greet_decode.getVersion(), mysql_greet_encode.getVersion()); EXPECT_EQ(mysql_greet_decode.getProtocol(), mysql_greet_encode.getProtocol()); @@ -68,7 +65,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeV10EncDec) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getSalt(), mysql_greet_encode.getSalt()); EXPECT_EQ(mysql_greet_decode.getVersion(), mysql_greet_encode.getVersion()); EXPECT_EQ(mysql_greet_decode.getProtocol(), mysql_greet_encode.getProtocol()); @@ -89,7 +86,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeIncompleteProtocol) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getProtocol(), 0); } @@ -106,7 +103,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeIncompleteVersion) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getVersion(), ""); EXPECT_EQ(mysql_greet_decode.getProtocol(), mysql_greet_encode.getProtocol()); } @@ -126,7 +123,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeIncompleteThreadId) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getVersion(), mysql_greet_encode.getVersion()); EXPECT_EQ(mysql_greet_decode.getProtocol(), mysql_greet_encode.getProtocol()); EXPECT_EQ(mysql_greet_decode.getThreadId(), 0); @@ -148,7 +145,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeIncompleteSalt) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getSalt(), ""); EXPECT_EQ(mysql_greet_decode.getVersion(), mysql_greet_encode.getVersion()); EXPECT_EQ(mysql_greet_decode.getProtocol(), mysql_greet_encode.getProtocol()); @@ -174,7 +171,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeIncompleteServerCap) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getSalt(), mysql_greet_encode.getSalt()); EXPECT_EQ(mysql_greet_decode.getVersion(), mysql_greet_encode.getVersion()); EXPECT_EQ(mysql_greet_decode.getProtocol(), mysql_greet_encode.getProtocol()); @@ -204,7 +201,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeIncompleteServerStatus) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getSalt(), mysql_greet_encode.getSalt()); EXPECT_EQ(mysql_greet_decode.getVersion(), mysql_greet_encode.getVersion()); EXPECT_EQ(mysql_greet_decode.getProtocol(), mysql_greet_encode.getProtocol()); @@ -237,7 +234,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeIncompleteExtServerCap) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getSalt(), mysql_greet_encode.getSalt()); EXPECT_EQ(mysql_greet_decode.getVersion(), mysql_greet_encode.getVersion()); EXPECT_EQ(mysql_greet_decode.getProtocol(), mysql_greet_encode.getProtocol()); @@ -267,7 +264,7 @@ TEST_F(MySQLCodecTest, MySQLServerChallengeP10ServerCapOnly) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ServerGreeting mysql_greet_decode{}; - mysql_greet_decode.decode(*decode_data, offset_, GREETING_SEQ_NUM, decode_data->length()); + mysql_greet_decode.decode(*decode_data, GREETING_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_greet_decode.getSalt(), mysql_greet_encode.getSalt()); EXPECT_EQ(mysql_greet_decode.getVersion(), mysql_greet_encode.getVersion()); EXPECT_EQ(mysql_greet_decode.getProtocol(), mysql_greet_encode.getProtocol()); @@ -299,7 +296,7 @@ TEST_F(MySQLCodecTest, MySQLClLoginV41PluginAuthEncDec) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.isResponse41(), true); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); @@ -334,7 +331,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin41SecureConnEncDec) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.isResponse41(), true); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); @@ -364,7 +361,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin41EncDec) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.isResponse41(), true); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); @@ -393,7 +390,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin320EncDec) { std::string data = mysql_clogin_encode.encode(); Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.isResponse320(), true); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); @@ -407,50 +404,46 @@ TEST_F(MySQLCodecTest, MySQLParseLengthEncodedInteger) { { // encode 2 byte value Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); - uint64_t offset = 0; uint64_t input_val = 5; uint64_t output_val = 0; BufferHelper::addUint8(*buffer, LENENCODINT_2BYTES); BufferHelper::addUint16(*buffer, input_val); - EXPECT_EQ(BufferHelper::peekLengthEncodedInteger(*buffer, offset, output_val), MYSQL_SUCCESS); + EXPECT_EQ(BufferHelper::readLengthEncodedInteger(*buffer, output_val), MYSQL_SUCCESS); EXPECT_EQ(input_val, output_val); } { // encode 3 byte value Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); - uint64_t offset = 0; uint64_t input_val = 5; uint64_t output_val = 0; BufferHelper::addUint8(*buffer, LENENCODINT_3BYTES); BufferHelper::addUint16(*buffer, input_val); BufferHelper::addUint8(*buffer, 0); - EXPECT_EQ(BufferHelper::peekLengthEncodedInteger(*buffer, offset, output_val), MYSQL_SUCCESS); + EXPECT_EQ(BufferHelper::readLengthEncodedInteger(*buffer, output_val), MYSQL_SUCCESS); EXPECT_EQ(input_val, output_val); } { // encode 8 byte value Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); - uint64_t offset = 0; uint64_t input_val = 5; uint64_t output_val = 0; BufferHelper::addUint8(*buffer, LENENCODINT_8BYTES); BufferHelper::addUint32(*buffer, input_val); BufferHelper::addUint32(*buffer, 0); - EXPECT_EQ(BufferHelper::peekLengthEncodedInteger(*buffer, offset, output_val), MYSQL_SUCCESS); + EXPECT_EQ(BufferHelper::readLengthEncodedInteger(*buffer, output_val), MYSQL_SUCCESS); EXPECT_EQ(input_val, output_val); } { // encode invalid length header Buffer::InstancePtr buffer(new Buffer::OwnedImpl()); - uint64_t offset = 0; uint64_t input_val = 5; uint64_t output_val = 0; BufferHelper::addUint8(*buffer, 0xff); BufferHelper::addUint32(*buffer, input_val); - EXPECT_EQ(BufferHelper::peekLengthEncodedInteger(*buffer, offset, output_val), MYSQL_FAILURE); + EXPECT_EQ(BufferHelper::readLengthEncodedInteger(*buffer, output_val), MYSQL_FAILURE); } } @@ -467,7 +460,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin320IncompleteClientCap) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), 0); } @@ -484,7 +477,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin320IncompleteExtClientCap) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), 0); } @@ -503,7 +496,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin320IncompleteMaxPacket) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), 0); @@ -525,7 +518,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin320IncompleteCharset) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), mysql_clogin_encode.getMaxPacket()); @@ -551,7 +544,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin320IncompleteUnsetBytes) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), mysql_clogin_encode.getMaxPacket()); @@ -577,7 +570,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin320IncompleteUser) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), mysql_clogin_encode.getMaxPacket()); @@ -607,7 +600,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin320IncompleteAuthLen) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), mysql_clogin_encode.getMaxPacket()); @@ -638,7 +631,7 @@ TEST_F(MySQLCodecTest, MySQLClientLogin320IncompleteAuthPasswd) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), mysql_clogin_encode.getMaxPacket()); @@ -669,7 +662,7 @@ TEST_F(MySQLCodecTest, MySQLClientSSLLoginIncompleteAuthLen) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), mysql_clogin_encode.getMaxPacket()); @@ -700,7 +693,7 @@ TEST_F(MySQLCodecTest, MySQLClientSSLLoginIncompleteAuthPasswd) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), mysql_clogin_encode.getMaxPacket()); @@ -731,7 +724,7 @@ TEST_F(MySQLCodecTest, MySQLClientLoginIncompleteAuthPasswd) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), mysql_clogin_encode.getMaxPacket()); @@ -762,7 +755,7 @@ TEST_F(MySQLCodecTest, MySQLClientLoginIncompleteConnectDb) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); EXPECT_EQ(mysql_clogin_decode.getMaxPacket(), mysql_clogin_encode.getMaxPacket()); @@ -790,7 +783,7 @@ TEST_F(MySQLCodecTest, MySQLClientLoginSSLEncDec) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLogin mysql_clogin_decode{}; - mysql_clogin_decode.decode(*decode_data, offset_, CHALLENGE_SEQ_NUM, decode_data->length()); + mysql_clogin_decode.decode(*decode_data, CHALLENGE_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_clogin_decode.isSSLRequest(), true); EXPECT_EQ(mysql_clogin_decode.getClientCap(), mysql_clogin_encode.getClientCap()); EXPECT_EQ(mysql_clogin_decode.getExtendedClientCap(), mysql_clogin_encode.getExtendedClientCap()); @@ -813,7 +806,7 @@ TEST_F(MySQLCodecTest, MySQLLoginOkEncDec) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLoginResponse mysql_loginok_decode{}; - mysql_loginok_decode.decode(*decode_data, offset_, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); + mysql_loginok_decode.decode(*decode_data, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_loginok_decode.getRespCode(), mysql_loginok_encode.getRespCode()); EXPECT_EQ(mysql_loginok_decode.getAffectedRows(), mysql_loginok_encode.getAffectedRows()); EXPECT_EQ(mysql_loginok_decode.getLastInsertId(), mysql_loginok_encode.getLastInsertId()); @@ -834,7 +827,7 @@ TEST_F(MySQLCodecTest, MySQLLoginOldAuthSwitch) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLoginResponse mysql_loginok_decode{}; - mysql_loginok_decode.decode(*decode_data, offset_, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); + mysql_loginok_decode.decode(*decode_data, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_loginok_decode.getRespCode(), mysql_loginok_encode.getRespCode()); } @@ -849,7 +842,7 @@ TEST_F(MySQLCodecTest, MySQLLoginOkIncompleteRespCode) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLoginResponse mysql_loginok_decode{}; - mysql_loginok_decode.decode(*decode_data, offset_, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); + mysql_loginok_decode.decode(*decode_data, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_loginok_decode.getRespCode(), 0); } @@ -866,7 +859,7 @@ TEST_F(MySQLCodecTest, MySQLLoginOkIncompleteAffectedRows) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLoginResponse mysql_loginok_decode{}; - mysql_loginok_decode.decode(*decode_data, offset_, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); + mysql_loginok_decode.decode(*decode_data, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_loginok_decode.getRespCode(), mysql_loginok_encode.getRespCode()); } @@ -884,7 +877,7 @@ TEST_F(MySQLCodecTest, MySQLLoginOkIncompleteLastInsertId) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLoginResponse mysql_loginok_decode{}; - mysql_loginok_decode.decode(*decode_data, offset_, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); + mysql_loginok_decode.decode(*decode_data, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_loginok_decode.getRespCode(), mysql_loginok_encode.getRespCode()); EXPECT_EQ(mysql_loginok_decode.getAffectedRows(), mysql_loginok_encode.getAffectedRows()); } @@ -904,7 +897,7 @@ TEST_F(MySQLCodecTest, MySQLLoginOkIncompleteServerStatus) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLoginResponse mysql_loginok_decode{}; - mysql_loginok_decode.decode(*decode_data, offset_, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); + mysql_loginok_decode.decode(*decode_data, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_loginok_decode.getRespCode(), mysql_loginok_encode.getRespCode()); EXPECT_EQ(mysql_loginok_decode.getAffectedRows(), mysql_loginok_encode.getAffectedRows()); EXPECT_EQ(mysql_loginok_decode.getLastInsertId(), mysql_loginok_encode.getLastInsertId()); @@ -927,7 +920,7 @@ TEST_F(MySQLCodecTest, MySQLLoginOkIncompleteWarnings) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); ClientLoginResponse mysql_loginok_decode{}; - mysql_loginok_decode.decode(*decode_data, offset_, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); + mysql_loginok_decode.decode(*decode_data, CHALLENGE_RESP_SEQ_NUM, decode_data->length()); EXPECT_EQ(mysql_loginok_decode.getRespCode(), mysql_loginok_encode.getRespCode()); EXPECT_EQ(mysql_loginok_decode.getAffectedRows(), mysql_loginok_encode.getAffectedRows()); EXPECT_EQ(mysql_loginok_decode.getLastInsertId(), mysql_loginok_encode.getLastInsertId()); @@ -942,8 +935,8 @@ TEST_F(MySQLCodecTest, MySQLCommandError) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(data)); Command mysql_cmd_decode{}; - uint64_t offset = 4; - mysql_cmd_decode.decode(*decode_data, offset, 0, 0); + decode_data->drain(4); + mysql_cmd_decode.decode(*decode_data, 0, 0); EXPECT_EQ(mysql_cmd_decode.getCmd(), Command::Cmd::COM_NULL); } @@ -958,8 +951,8 @@ TEST_F(MySQLCodecTest, MySQLCommandInitDb) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(mysql_msg)); Command mysql_cmd_decode{}; - uint64_t offset = 4; - mysql_cmd_decode.decode(*decode_data, offset, 0, db.length() + 1); + decode_data->drain(4); + mysql_cmd_decode.decode(*decode_data, 0, db.length() + 1); EXPECT_EQ(mysql_cmd_decode.getDb(), db); } @@ -974,8 +967,8 @@ TEST_F(MySQLCodecTest, MySQLCommandCreateDb) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(mysql_msg)); Command mysql_cmd_decode{}; - uint64_t offset = 4; - mysql_cmd_decode.decode(*decode_data, offset, 0, db.length() + 1); + decode_data->drain(4); + mysql_cmd_decode.decode(*decode_data, 0, db.length() + 1); EXPECT_EQ(mysql_cmd_decode.getDb(), db); } @@ -990,8 +983,8 @@ TEST_F(MySQLCodecTest, MySQLCommandDropDb) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(mysql_msg)); Command mysql_cmd_decode{}; - uint64_t offset = 4; - mysql_cmd_decode.decode(*decode_data, offset, 0, db.length() + 1); + decode_data->drain(4); + mysql_cmd_decode.decode(*decode_data, 0, db.length() + 1); EXPECT_EQ(mysql_cmd_decode.getDb(), db); } @@ -1004,8 +997,8 @@ TEST_F(MySQLCodecTest, MySQLCommandOther) { Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(mysql_msg)); Command mysql_cmd_decode{}; - uint64_t offset = 4; - mysql_cmd_decode.decode(*decode_data, offset, 0, 0); + decode_data->drain(4); + mysql_cmd_decode.decode(*decode_data, 0, 0); EXPECT_EQ(mysql_cmd_decode.getCmd(), Command::Cmd::COM_FIELD_LIST); } diff --git a/test/extensions/filters/network/mysql_proxy/mysql_command_test.cc b/test/extensions/filters/network/mysql_proxy/mysql_command_test.cc index ab82d6fd1a57e..76a7f35a7a0fc 100644 --- a/test/extensions/filters/network/mysql_proxy/mysql_command_test.cc +++ b/test/extensions/filters/network/mysql_proxy/mysql_command_test.cc @@ -1,3 +1,5 @@ +#include + #include "extensions/filters/network/mysql_proxy/mysql_codec.h" #include "extensions/filters/network/mysql_proxy/mysql_codec_clogin.h" #include "extensions/filters/network/mysql_proxy/mysql_codec_clogin_resp.h" @@ -20,19 +22,19 @@ class MySQLCommandTest : public testing::Test, public MySQLTestUtils { int encodeQuery(std::string query, hsql::SQLParserResult& result) { Command mysql_cmd_encode{}; Command mysql_cmd_decode{}; - uint64_t offset = 0; - int seq = 0; - int len = 0; + uint8_t seq = 0u; + uint32_t len = 0u; mysql_cmd_encode.setCmd(Command::Cmd::COM_QUERY); mysql_cmd_encode.setData(query); std::string data = mysql_cmd_encode.encode(); std::string mysql_msg = BufferHelper::encodeHdr(data, 0); Buffer::InstancePtr decode_data(new Buffer::OwnedImpl(mysql_msg)); - if (BufferHelper::peekHdr(*decode_data, offset, len, seq) != MYSQL_SUCCESS) { + if (BufferHelper::peekHdr(*decode_data, len, seq) != MYSQL_SUCCESS) { return MYSQL_FAILURE; } - if (mysql_cmd_decode.decode(*decode_data, offset, seq, len) != MYSQL_SUCCESS) { + BufferHelper::consumeHdr(*decode_data); + if (mysql_cmd_decode.decode(*decode_data, seq, len) != MYSQL_SUCCESS) { return MYSQL_FAILURE; } hsql::SQLParser::parse(mysql_cmd_decode.getData(), &result); diff --git a/test/extensions/filters/network/mysql_proxy/mysql_filter_test.cc b/test/extensions/filters/network/mysql_proxy/mysql_filter_test.cc index 68c036d06143d..5d10600a940e2 100644 --- a/test/extensions/filters/network/mysql_proxy/mysql_filter_test.cc +++ b/test/extensions/filters/network/mysql_proxy/mysql_filter_test.cc @@ -51,7 +51,7 @@ TEST_F(MySQLFilterTest, MySqlFallbackToTcpProxy) { EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onNewConnection()); EXPECT_EQ(1UL, config_->stats().sessions_.value()); - Buffer::InstancePtr greet_data(new Buffer::OwnedImpl("scooby doo - part 1!")); + Buffer::InstancePtr greet_data(new Buffer::OwnedImpl(" ")); EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onData(*greet_data, false)); EXPECT_EQ(1UL, config_->stats().decoder_errors_.value()); @@ -88,6 +88,115 @@ TEST_F(MySQLFilterTest, MySqlHandshake41OkTest) { EXPECT_EQ(MySQLSession::State::MYSQL_REQ, filter_->getSession().getState()); } +/** + * Test MySQL Handshake with partial messages. + * SM: greeting(p=10) -> challenge-req(v41) -> serv-resp-ok + */ +TEST_F(MySQLFilterTest, MySqlHandshake41PartialMessagesTest) { + initialize(); + + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onNewConnection()); + EXPECT_EQ(1UL, config_->stats().sessions_.value()); + + std::string greeting_data = encodeServerGreeting(MYSQL_PROTOCOL_10); + + Buffer::InstancePtr greet_data_part_1( + new Buffer::OwnedImpl(greeting_data.substr(0, greeting_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onWrite(*greet_data_part_1, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_INIT, filter_->getSession().getState()); + + Buffer::InstancePtr greet_data_part_2( + new Buffer::OwnedImpl(greeting_data.substr(greeting_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onWrite(*greet_data_part_2, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_CHALLENGE_REQ, filter_->getSession().getState()); + + std::string clogin_data = + encodeClientLogin(MYSQL_CLIENT_CAPAB_41VS320, "user1", CHALLENGE_SEQ_NUM); + + Buffer::InstancePtr client_login_data_part_1( + new Buffer::OwnedImpl(clogin_data.substr(0, clogin_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onData(*client_login_data_part_1, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_CHALLENGE_REQ, filter_->getSession().getState()); + + Buffer::InstancePtr client_login_data_part_2( + new Buffer::OwnedImpl(clogin_data.substr(clogin_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onData(*client_login_data_part_2, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_CHALLENGE_RESP_41, filter_->getSession().getState()); + EXPECT_EQ(1UL, config_->stats().login_attempts_.value()); + + std::string srv_resp_data = encodeClientLoginResp(MYSQL_RESP_OK); + + Buffer::InstancePtr server_resp_data_part_1( + new Buffer::OwnedImpl(srv_resp_data.substr(0, srv_resp_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onWrite(*server_resp_data_part_1, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_CHALLENGE_RESP_41, filter_->getSession().getState()); + + Buffer::InstancePtr server_resp_data_part_2( + new Buffer::OwnedImpl(srv_resp_data.substr(srv_resp_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onWrite(*server_resp_data_part_2, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_REQ, filter_->getSession().getState()); +} + +/** + * Test that the filter falls back to tcp proxy if it cant decode partial messages. + */ +TEST_F(MySQLFilterTest, MySqlFallbackPartialMessagesTest) { + initialize(); + + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onNewConnection()); + EXPECT_EQ(1UL, config_->stats().sessions_.value()); + + std::string greeting_data = encodeServerGreeting(MYSQL_PROTOCOL_10); + + Buffer::InstancePtr greet_data_part_1( + new Buffer::OwnedImpl(greeting_data.substr(0, greeting_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onWrite(*greet_data_part_1, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_INIT, filter_->getSession().getState()); + + Buffer::InstancePtr corrupt_data(new Buffer::OwnedImpl(" ")); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onData(*corrupt_data, false)); + EXPECT_EQ(1UL, config_->stats().decoder_errors_.value()); + + Buffer::InstancePtr greet_data_part_2( + new Buffer::OwnedImpl(greeting_data.substr(greeting_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, filter_->onWrite(*greet_data_part_2, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_INIT, filter_->getSession().getState()); + + std::string clogin_data = + encodeClientLogin(MYSQL_CLIENT_CAPAB_41VS320, "user1", CHALLENGE_SEQ_NUM); + + Buffer::InstancePtr client_login_data_part_1( + new Buffer::OwnedImpl(clogin_data.substr(0, clogin_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onData(*client_login_data_part_1, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_INIT, filter_->getSession().getState()); + + Buffer::InstancePtr client_login_data_part_2( + new Buffer::OwnedImpl(clogin_data.substr(clogin_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onData(*client_login_data_part_2, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_INIT, filter_->getSession().getState()); + EXPECT_EQ(0UL, config_->stats().login_attempts_.value()); + + std::string srv_resp_data = encodeClientLoginResp(MYSQL_RESP_OK); + + Buffer::InstancePtr server_resp_data_part_1( + new Buffer::OwnedImpl(srv_resp_data.substr(0, srv_resp_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onWrite(*server_resp_data_part_1, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_INIT, filter_->getSession().getState()); + + Buffer::InstancePtr server_resp_data_part_2( + new Buffer::OwnedImpl(srv_resp_data.substr(srv_resp_data.length() / 2))); + EXPECT_EQ(Envoy::Network::FilterStatus::Continue, + filter_->onWrite(*server_resp_data_part_2, false)); + EXPECT_EQ(MySQLSession::State::MYSQL_INIT, filter_->getSession().getState()); +} + /** * Test MySQL Handshake with protocol version 41 * Server responds with Error diff --git a/test/extensions/filters/network/mysql_proxy/mysql_test_utils.cc b/test/extensions/filters/network/mysql_proxy/mysql_test_utils.cc index b2424bc730ba8..a72e503009b9f 100644 --- a/test/extensions/filters/network/mysql_proxy/mysql_test_utils.cc +++ b/test/extensions/filters/network/mysql_proxy/mysql_test_utils.cc @@ -43,7 +43,7 @@ std::string MySQLTestUtils::encodeClientLogin(uint16_t client_cap, std::string u return mysql_msg; } -std::string MySQLTestUtils::encodeClientLoginResp(uint8_t srv_resp, int it, int seq_force) { +std::string MySQLTestUtils::encodeClientLoginResp(uint8_t srv_resp, uint8_t it, uint8_t seq_force) { ClientLoginResponse mysql_loginok_encode{}; mysql_loginok_encode.setRespCode(srv_resp); mysql_loginok_encode.setAffectedRows(MYSQL_SM_AFFECTED_ROWS); @@ -51,7 +51,7 @@ std::string MySQLTestUtils::encodeClientLoginResp(uint8_t srv_resp, int it, int mysql_loginok_encode.setServerStatus(MYSQL_SM_SERVER_OK); mysql_loginok_encode.setWarnings(MYSQL_SM_SERVER_WARNINGS); std::string data = mysql_loginok_encode.encode(); - int seq = CHALLENGE_RESP_SEQ_NUM + 2 * it; + uint8_t seq = CHALLENGE_RESP_SEQ_NUM + 2 * it; if (seq_force > 0) { seq = seq_force; } diff --git a/test/extensions/filters/network/mysql_proxy/mysql_test_utils.h b/test/extensions/filters/network/mysql_proxy/mysql_test_utils.h index 87b8c19b26a59..e39a353ddf447 100644 --- a/test/extensions/filters/network/mysql_proxy/mysql_test_utils.h +++ b/test/extensions/filters/network/mysql_proxy/mysql_test_utils.h @@ -27,7 +27,7 @@ class MySQLTestUtils { std::string encodeServerGreeting(int protocol); std::string encodeClientLogin(uint16_t client_cap, std::string user, uint8_t seq); - std::string encodeClientLoginResp(uint8_t srv_resp, int it = 0, int seq_force = 0); + std::string encodeClientLoginResp(uint8_t srv_resp, uint8_t it = 0, uint8_t seq_force = 0); std::string encodeAuthSwitchResp(); };