Uploaded image for project: 'MariaDB MaxScale'
  1. MariaDB MaxScale
  2. MXS-257

filters not always intercept 'USE db' calls

Details

    • New Feature
    • Status: Closed (View Workflow)
    • Minor
    • Resolution: Not a Bug
    • None
    • 1.3.0
    • Plugin
    • None

    Description

      In my filter, I would like to know when users connect to which DB. Currently, Maxscale allows clients to specify DB to connect to in the handshake reply, and the filter is not being called.

      This leads to inconsistent behavior of the filter: if the user specifies a database in the connection string, the filter does not know about it, but if database is not specified, and USE db is issued later, that goes through the filter.

      A quick solution to this is to remove the GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB bit from the capabilities. This will force the clients to call USE db explicitly after connecting, regardless of the connection string supplied by the user.

      An alternative would be to let the filter know somehow that a database has been selected.

      I'm using this patch for the first alternative:

      diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c
      index abdb442..58292e7 100644
      --- a/server/modules/protocol/mysql_client.c
      +++ b/server/modules/protocol/mysql_client.c
      @@ -320,6 +320,7 @@ MySQLSendHandshake(DCB* dcb)
       
               mysql_server_capabilities_one[0] &= ~GW_MYSQL_CAPABILITIES_COMPRESS;
               mysql_server_capabilities_one[0] &= ~GW_MYSQL_CAPABILITIES_SSL;
      +        mysql_server_capabilities_one[0] &= ~GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB;
       
               memcpy(mysql_handshake_payload, mysql_server_capabilities_one, sizeof(mysql_server_capabilities_one));
               mysql_handshake_payload = mysql_handshake_payload + sizeof(mysql_server_capabilities_one);
      @@ -392,7 +393,7 @@ MySQLSendHandshake(DCB* dcb)
       static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
              MySQLProtocol *protocol = NULL;
              /* int compress = -1; */
      -       int connect_with_db = -1;
      +       int connect_with_db = 0;
              uint8_t *client_auth_packet = GWBUF_DATA(queue);
              int client_auth_packet_size = 0;
              char *username =  NULL;
      @@ -442,9 +443,11 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
       
              memcpy(&protocol->client_capabilities, client_auth_packet + 4, 4);
       
      +        /*
              connect_with_db =
                       GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB & gw_mysql_get_byte4(
                               (uint32_t *)&protocol->client_capabilities);
      +        */
               /*
              compress =
                       GW_MYSQL_CAPABILITIES_COMPRESS & gw_mysql_get_byte4(

      Attachments

        Activity

          markus makela markus makela added a comment - - edited

          The connection default database is stored in the initial authentication. The contents are stored at the protocol level which can be accessed through the client session. Since it's a void pointer and MaxScale is capable of supporting multiple protocols, this needs to be called with the SESSION_PROTOCOL(session,MySQLProtocol) macro where session is the pointer to the client SESSION structure. This assumes that the MySQLClient protocol is used.

          markus makela markus makela added a comment - - edited The connection default database is stored in the initial authentication. The contents are stored at the protocol level which can be accessed through the client session. Since it's a void pointer and MaxScale is capable of supporting multiple protocols, this needs to be called with the SESSION_PROTOCOL(session,MySQLProtocol) macro where session is the pointer to the client SESSION structure. This assumes that the MySQLClient protocol is used.
          markus makela markus makela added a comment -

          Closing as this is already implemented.

          markus makela markus makela added a comment - Closing as this is already implemented.
          yhager Yuval Hager added a comment -

          Thanks, that's helpful. Do you mean that the db name can be found in the MySQLProtocol struct? Looking at mysql_client_server_protocol.h, it's not obvious to me where.

          yhager Yuval Hager added a comment - Thanks, that's helpful. Do you mean that the db name can be found in the MySQLProtocol struct? Looking at mysql_client_server_protocol.h, it's not obvious to me where.
          markus makela markus makela added a comment -

          yhagerMy apologies, the database name is in the MySQL_session structure. This is the session->data pointer and for MySQLClient protocol, it is a pointer to a MySQL_session struct. This struct has the database, username and sha1 of the password.

          markus makela markus makela added a comment - yhager My apologies, the database name is in the MySQL_session structure. This is the session->data pointer and for MySQLClient protocol, it is a pointer to a MySQL_session struct. This struct has the database, username and sha1 of the password.
          yhager Yuval Hager added a comment -

          Oh, thanks. Actually I do have that in my code, but I got an empty db in there on the newSession callback. However, I was using a rather outdated version of the develop branch - I have since updated to release-1.2. If it's still missing from there, I'll open a bug report specifically about this. It's not going to be this week, so let's leave this one closed.

          yhager Yuval Hager added a comment - Oh, thanks. Actually I do have that in my code, but I got an empty db in there on the newSession callback. However, I was using a rather outdated version of the develop branch - I have since updated to release-1.2. If it's still missing from there, I'll open a bug report specifically about this. It's not going to be this week, so let's leave this one closed.

          People

            markus makela markus makela
            yhager Yuval Hager
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.