Uploaded image for project: 'MariaDB Connector/C'
  1. MariaDB Connector/C
  2. CONC-130

Initial wait on connect is wrong direction

Details

    • Bug
    • Status: Closed (View Workflow)
    • Minor
    • Resolution: Fixed
    • 2.1
    • 2.2.0
    • None
    • None
    • All

    Description

      This is the block of code from libmariadb.c:

        if (mysql->options.connect_timeout >= 0 &&
            vio_wait_or_timeout(net->vio, FALSE, mysql->options.connect_timeout * 1000) < 1)
        {
          my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
                       ER(CR_SERVER_LOST_EXTENDED),
                       "handshake: waiting for inital communication packet",
                       errno);
          goto error;
        }

      The second option of vio_wait_or_timeout() is "my_bool is_read". If set to true, it waits for a read. If set to false, it waits for a write. The code above is waiting to read a packet from the server, so it should be TRUE. However, it is false, so it waits for a write instead. Since this happens immediately after it has already waited for the connection, this always returns immediately. However, on async it passes the wrong flags (i.e. WAIT_WRITE instead of WAIT_READ) to the async caller, which messes up edge-triggered event handling. It also means that it does not actually wait for the timeout that it is supposed to be waiting for.

      Attachments

        Activity

          A812371 Matt Fagan created issue -
          georg Georg Richter made changes -
          Field Original Value New Value
          Description This is the block of code from libmariadb.c:

            if (mysql->options.connect_timeout >= 0 &&
                vio_wait_or_timeout(net->vio, FALSE, mysql->options.connect_timeout * 1000) < 1)
            {
              my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
                           ER(CR_SERVER_LOST_EXTENDED),
                           "handshake: waiting for inital communication packet",
                           errno);
              goto error;
            }

          The second option of vio_wait_or_timeout() is "my_bool is_read". If set to true, it waits for a read. If set to false, it waits for a write. The code above is waiting to read a packet from the server, so it should be TRUE. However, it is false, so it waits for a write instead. Since this happens immediately after it has already waited for the connection, this always returns immediately. However, on async it passes the wrong flags (i.e. WAIT_WRITE instead of WAIT_READ) to the async caller, which messes up edge-triggered event handling. It also means that it does not actually wait for the timeout that it is supposed to be waiting for.
          This is the block of code from libmariadb.c:
          {code}
            if (mysql->options.connect_timeout >= 0 &&
                vio_wait_or_timeout(net->vio, FALSE, mysql->options.connect_timeout * 1000) < 1)
            {
              my_set_error(mysql, CR_SERVER_LOST, SQLSTATE_UNKNOWN,
                           ER(CR_SERVER_LOST_EXTENDED),
                           "handshake: waiting for inital communication packet",
                           errno);
              goto error;
            }
          {code}

          The second option of vio_wait_or_timeout() is "my_bool is_read". If set to true, it waits for a read. If set to false, it waits for a write. The code above is waiting to read a packet from the server, so it should be TRUE. However, it is false, so it waits for a write instead. Since this happens immediately after it has already waited for the connection, this always returns immediately. However, on async it passes the wrong flags (i.e. WAIT_WRITE instead of WAIT_READ) to the async caller, which messes up edge-triggered event handling. It also means that it does not actually wait for the timeout that it is supposed to be waiting for.
          georg Georg Richter added a comment -

          Fixed in C/C 2.2: commit 7b59e09cf5eecda2029295db10fdc98dfb5dacc3

          georg Georg Richter added a comment - Fixed in C/C 2.2: commit 7b59e09cf5eecda2029295db10fdc98dfb5dacc3
          georg Georg Richter made changes -
          Fix Version/s 2.2.0 [ 19500 ]
          Resolution Fixed [ 1 ]
          Status Open [ 1 ] Closed [ 6 ]

          Seems this patch also slipped in a change to switch the socket to non-blocking mode:

          {{- else if (socket_block(sock, 1) == SOCKET_ERROR)
          + else if (socket_block(sock, 0) == SOCKET_ERROR)
          }}
          This causes mysql_real_connect() to fail with "Lost connection to MySQL server at 'handshake: reading inital communication packet', system error: 11" for some remote connections.
          Errno 11 is EAGAIN.

          grubba Henrik Grubbström added a comment - Seems this patch also slipped in a change to switch the socket to non-blocking mode: {{- else if (socket_block(sock, 1) == SOCKET_ERROR) + else if (socket_block(sock, 0) == SOCKET_ERROR) }} This causes mysql_real_connect() to fail with "Lost connection to MySQL server at 'handshake: reading inital communication packet', system error: 11" for some remote connections. Errno 11 is EAGAIN.
          julien.fritsch Julien Fritsch made changes -
          Workflow MariaDB connectors [ 69869 ] MariaDB v4 [ 160990 ]

          People

            georg Georg Richter
            A812371 Matt Fagan
            Votes:
            0 Vote for this issue
            Watchers:
            3 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.