php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #47641 mysql_connect() using TCP with connect_timeout not equal to -1
Submitted: 2009-03-13 10:31 UTC Modified: 2009-06-10 01:00 UTC
Votes:1
Avg. Score:1.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: dima at dimych dot sumy dot ua Assigned:
Status: No Feedback Package: MySQL related
PHP Version: 5.2.9 OS: FreeBSD 7.1
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: dima at dimych dot sumy dot ua
New email:
PHP Version: OS:

 

 [2009-03-13 10:31 UTC] dima at dimych dot sumy dot ua
Description:
------------
connecting to mysql server using TCP 
with mysql.connect_timeout set not equal to "-1" in php.ini produces error:
Can't connect to MySQL server on '127.0.0.1' (0)


Reproduce code:
---------------
1 in php.ini set:
   mysql.connect_timeout = 60

2 create user test with password test in local database

3 create file test.php:
<?php
mysql_connect("127.0.0.1", 'test', 'test');
?>

Expected result:
----------------
Successful connection to database like for:
<?php
mysql_connect("localhost", 'test', 'test');
?>
or connection to 127.0.0.1 with mysql.connect_timeout = -1




Actual result:
--------------
PHP Warning:  mysql_connect(): Can't connect to MySQL server on '127.0.0.1' (0) in /usr/home/dima/test.php on line 2


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-03-13 10:49 UTC] dima at dimych dot sumy dot ua
I`m investigated this bug using mysql client trace file.
For additional debug info I modified mysql client library file 
sql-common/client.c. Modifications done in functions mysql_options, my_connect, wait_for_data. This is diff for source of modified functions (need for understanding new trace data):
--- client.c    2008-11-14 18:37:28.000000000 +0200
+++ client.c.new        2009-03-13 12:36:36.000000000 +0200
@@ -143,7 +143,14 @@
 int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
               uint timeout)
 {
+  DBUG_ENTER("my_connect");
+  DBUG_PRINT("enter", ("socket: %d name:{%d,%d,[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]} namelen: %lu timeout: %lu",

+                       fd, timeout, name->sa_len, name->sa_family, name->sa_data[0], name->sa_data[1],
+                       name->sa_data[2],name->sa_data[3],name->sa_data[4],name->sa_data[5],name->sa_data[6],
+                       name->sa_data[7],name->sa_data[8],name->sa_data[9],name->sa_data[10],name->sa_data[11],
+                       name->sa_data[12],name->sa_data[13],namelen,timeout));
 #if defined(__WIN__) || defined(__NETWARE__)
+  DBUG_RETURN(0);
   return connect(fd, (struct sockaddr*) name, namelen);
 #else
   int flags, res, s_err;
@@ -153,11 +160,14 @@
     exactly like the normal connect() call does.
   */

-  if (timeout == 0)
+  if (timeout == 0) {
+    DBUG_PRINT("info", ("timeout == 0"));
+    DBUG_RETURN(0);
     return connect(fd, (struct sockaddr*) name, namelen);
-
+  }
   flags = fcntl(fd, F_GETFL, 0);         /* Set socket to not block */
 #ifdef O_NONBLOCK
+  DBUG_PRINT("info", ("O_NONBLOCK"));
   fcntl(fd, F_SETFL, flags | O_NONBLOCK);  /* and save the flags..  */
 #endif

@@ -167,10 +177,15 @@
   if ((res != 0) && (s_err != EINPROGRESS))
   {
     errno= s_err;                      /* Restore it */
+    DBUG_PRINT("error", ("res != 0. res: %d errno: %d", res, errno));
+    DBUG_RETURN(-1);
     return(-1);
   }
-  if (res == 0)                                /* Connected quickly! */
+  if (res == 0)                                /* Connected quickly! */ {
+    DBUG_PRINT("info", ("res == 0"));
+    DBUG_RETURN(0);
     return(0);
+  }
   return wait_for_data(fd, timeout);
 #endif
 }
@@ -187,7 +202,10 @@

 static int wait_for_data(my_socket fd, uint timeout)
 {
+  DBUG_ENTER("wait_for_data");
+  DBUG_PRINT("enter", ("timeout :%lu", timeout));
 #ifdef HAVE_POLL
+  DBUG_PRINT("info:", ("wait using poll"));
   struct pollfd ufds;
   int res;

@@ -196,20 +214,30 @@
   if (!(res= poll(&ufds, 1, (int) timeout*1000)))
   {
     errno= EINTR;
+    DBUG_PRINT("error:", ("EINTR"));
+    DBUG_RETURN(-1);
     return -1;
   }
-  if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
+  if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI))) {
+    DBUG_PRINT("error:", ("res < 0"));
+    DBUG_RETURN(-1);
     return -1;
+  }
+  DBUG_RETURN(0);
   return 0;
 #else
+  DBUG_PRINT("info:", ("wait using loop"));
   SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
   fd_set sfds;
   struct timeval tv;
   time_t start_time, now_time;
   int res, s_err;

-  if (fd >= FD_SETSIZE)                                /* Check if wrong error */
+  if (fd >= FD_SETSIZE) {                              /* Check if wrong error */
+  DBUG_PRINT("info:", ("wait using loop"));
+    DBUG_RETURN(0);
     return 0;                                  /* Can't use timeout */
+  }

   /*
     Our connection is "in progress."  We can use the select() call to wait
@@ -252,8 +280,11 @@
       return -1;
     now_time= my_time(0);
     timeout-= (uint) (now_time - start_time);
-    if (errno != EINTR || (int) timeout <= 0)
+    if (errno != EINTR || (int) timeout <= 0) {
+      DBUG_PRINT("error:", ("errno != EINTR. errno: %d", errno));
+      DBUG_RETURN(-1);
       return -1;
+    }
   }

   /*
@@ -263,14 +294,19 @@
   */

   s_err=0;
-  if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
+  if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) {
+    DBUG_PRINT("error:", ("getscokopt"));
+    DBUG_RETURN(-1);
     return(-1);
-
+  }
   if (s_err)
   {                                            /* getsockopt could succeed */
     errno = s_err;
+    DBUG_PRINT("error:", ("getsockopt errno: %d", errno));
+    DBUG_RETURN(-1);
     return(-1);                                        /* but return an error... */
   }
+  DBUG_RETURN(0);
   return (0);                                  /* ok */
 #endif /* HAVE_POLL */
 }
@@ -3023,6 +3059,7 @@
   DBUG_PRINT("enter",("option: %d",(int) option));
   switch (option) {
   case MYSQL_OPT_CONNECT_TIMEOUT:
+  DBUG_PRINT("enter",("arg: %lu",*(uint*) arg));
     mysql->options.connect_timeout= *(uint*) arg;
     break;
   case MYSQL_OPT_READ_TIMEOUT:

--- END OF DIFF ---
doing connect using
<?php mysql_connect("127.0.0.1", 'test', 'test'); ?>

trace file contains this:
>mysql_option
| enter: option: 0
| enter: arg: 60
<mysql_option
>mysql_real_connect
| enter: host: 127.0.0.1  db: (Null)  user: test
| info: Server name: '127.0.0.1'.  TCP sock: 3306
| >vio_new
| | enter: sd: 4
| | >my_malloc
| | | my: size: 152  my_flags: 16
| | | exit: ptr: 0x2972c340
| | <my_malloc
| | >vio_init
| | | enter: type: 1  sd: 4  flags: 2
| | | >my_malloc
| | | | my: size: 16384  my_flags: 16
| | | | exit: ptr: 0x297c6000
| | | <my_malloc
| | <vio_init
| <vio_new
| >my_connect
| | enter: socket: 4 name:{60,0,[2,12,-22,127,0,0,1,0,0,0,0,0,0,0]} namelen: 0 timeout: 16
| | info:: O_NONBLOCK
| | error:: res != 0. res: -1 errno: 0
| <my_connect
| error: Got error 0 on connect to '127.0.0.1'
| >set_mysql_extended_error
| | enter: error :2003 'Can't connect to MySQL server on '%-.100s' (%d)'
| <set_mysql_extended_error
| error: message: 2003/HY000 (Can't connect to MySQL server on '127.0.0.1' (0))
| >end_server

--- END OF TRACE FILE ---
Doing connect with command line utility "mysql":
mysql -u test -ptest -h 127.0.0.1 --connect_timeout=60 --debug=d:t:O,/tmp/client.trace

Trace file contains:
| >my_malloc
| | my: size: 16  my_flags: 16
| | exit: ptr: 0x2840e050
| <my_malloc
| >my_malloc
| | my: size: 520  my_flags: 16
| | exit: ptr: 0x28410000
| <my_malloc
| >my_malloc
| | my: size: 512  my_flags: 48
| | exit: ptr: 0x2842f200
| <my_malloc
| >init_alloc_root
| | enter: root: 0x805f968
| <init_alloc_root
| >init_alloc_root
| | enter: root: 0x805f9a0
| <init_alloc_root
| >mysql_option
| | enter: option: 0
| | enter: arg: 60
| <mysql_option
| >mysql_real_connect
| | enter: host: 127.0.0.1  db: (Null)  user: test
| | info: Server name: '127.0.0.1'.  TCP sock: 3306
| | >vio_new
| | | enter: sd: 4
| | | >my_malloc
| | | | my: size: 152  my_flags: 16
| | | | exit: ptr: 0x284280c0
| | | <my_malloc
| | | >vio_init
| | | | enter: type: 1  sd: 4  flags: 2
| | | | >my_malloc
| | | | | my: size: 16384  my_flags: 16
| | | | | exit: ptr: 0x28437000
| | | | <my_malloc
| | | <vio_init
| | <vio_new
| | >my_connect
| | | enter: socket: 4 name:{60,0,[2,12,-22,127,0,0,1,0,0,0,0,0,0,0]} namelen: 0 timeout: 16
| | | info:: O_NONBLOCK
| | | >wait_for_data
| | | | enter: timeout :60
| | | | info:: wait using poll
| | | <wait_for_data
| | | >my_net_init

--- END OF TRACE FILE ---
setting mysql.connect_timeout = -1 in php.ini and doing connect using
<?php mysql_connect("127.0.0.1", 'test', 'test'); ?>

trace file contains this:
>mysql_real_connect
| enter: host: 127.0.0.1  db: (Null)  user: test
| info: Server name: '127.0.0.1'.  TCP sock: 3306
| >vio_new
| | enter: sd: 4
| | >my_malloc
| | | my: size: 152  my_flags: 16
| | | exit: ptr: 0x2972c340
| | <my_malloc
| | >vio_init
| | | enter: type: 1  sd: 4  flags: 2
| | | >my_malloc
| | | | my: size: 16384  my_flags: 16
| | | | exit: ptr: 0x297c6000
| | | <my_malloc
| | <vio_init
| <vio_new
| >my_connect
| | enter: socket: 4 name:{0,0,[2,12,-22,127,0,0,1,0,0,0,0,0,0,0]} namelen: 0 timeout: 16
| | info:: timeout == 0
| <my_connect
| >my_net_init

--- END OF TRACE FILE ---
 [2009-06-02 08:34 UTC] jani@php.net
Exactly what mysql version are you trying this with? As for me it works 
perfectly fine with PHP compiled with Mysql 5.0.37 client lib.

Tried with:

# php -n -d mysql.connect_timeout=60 -r 'mysql_connect("127.0.0.1", 
"test", "");'

 [2009-06-02 10:06 UTC] dima at dimych dot sumy dot ua
ttyp3[root@noc-12:35:15]/home/dima# php -n -d mysql.connect_timeout=60 -r 'mysql_connect("127.0.0.1", "test", "");'

Fatal error: Call to undefined function mysql_connect() in Command line code on line 1

ttyp3[root@noc-12:35:19]/home/dima# php -d mysql.connect_timeout=60 -r 'mysql_connect("127.0.0.1", "test", "");'
PHP Warning:  mysql_connect(): Can't connect to MySQL server on '127.0.0.1' (0) in Command line code on line 1

ttyp3[root@noc-12:36:17]/home/dima# php -d mysql.connect_timeout=60 -r 'mysql_connect("localhost", "test", "");'
PHP Warning:  mysql_connect(): Access denied for user 'test'@'localhost' (using password: NO) in Command line code on li
ne 1

ttyp3[root@noc-12:37:05]/home/dima# mysql -V
mysql  Ver 14.14 Distrib 5.1.32, for portbld-freebsd7.1 (i386) using  5.2
 [2009-06-10 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 18:01:29 2024 UTC