]> granicus.if.org Git - postgresql/commitdiff
On further testing, PQping also needs an explicit check for AUTH_REQ.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 27 Nov 2010 07:11:45 +0000 (02:11 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 27 Nov 2010 07:11:45 +0000 (02:11 -0500)
The pg_fe_sendauth code might fail if it can't handle the authentication
request message type --- if so, ping should still say the server is up.

src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/libpq-int.h

index bff9b478f6602a6440646231a22a5102d8040d5c..b1523a6a893422af5df9bd25abbe6da9d554aa42 100644 (file)
@@ -2321,6 +2321,8 @@ keep_going:                                               /* We will come back to here until there is
                                }
 
                                /* It is an authentication request. */
+                               conn->auth_req_received = true;
+
                                /* Get the type of request. */
                                if (pqGetInt((int *) &areq, 4, conn))
                                {
@@ -2589,11 +2591,18 @@ internal_ping(PGconn *conn)
                return PQPING_OK;
 
        /*
-        * Here is the interesting part of "ping": determine the cause of the
+        * Here begins the interesting part of "ping": determine the cause of the
         * failure in sufficient detail to decide what to return.  We do not want
         * to report that the server is not up just because we didn't have a valid
-        * password, for example.
-        *
+        * password, for example.  In fact, any sort of authentication request
+        * implies the server is up.  (We need this check since the libpq side
+        * of things might have pulled the plug on the connection before getting
+        * an error as such from the postmaster.)
+        */
+       if (conn->auth_req_received)
+               return PQPING_OK;
+
+       /*
         * If we failed to get any ERROR response from the postmaster, report
         * PQPING_NO_RESPONSE.  This result could be somewhat misleading for a
         * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
@@ -2672,6 +2681,7 @@ makeEmptyPGconn(void)
        conn->std_strings = false;      /* unless server says differently */
        conn->verbosity = PQERRORS_DEFAULT;
        conn->sock = -1;
+       conn->auth_req_received = false;
        conn->password_needed = false;
        conn->dot_pgpass_used = false;
 #ifdef USE_SSL
index f6a7f39065a74b090a8bbd03de3fc8e8473fa8a0..ce5f330f9ea47a69fc5cb611aa30ddf518b243f3 100644 (file)
@@ -349,6 +349,7 @@ struct pg_conn
        SockAddr        raddr;                  /* Remote address */
        ProtocolVersion pversion;       /* FE/BE protocol version in use */
        int                     sversion;               /* server version, e.g. 70401 for 7.4.1 */
+       bool            auth_req_received;      /* true if any type of auth req received */
        bool            password_needed;        /* true if server demanded a password */
        bool            dot_pgpass_used;        /* true if used .pgpass */
        bool            sigpipe_so;             /* have we masked SIGPIPE via SO_NOSIGPIPE? */