]> granicus.if.org Git - postgresql/commitdiff
Ensure we discard unread/unsent data when abandoning a connection attempt.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 27 Aug 2011 18:16:19 +0000 (14:16 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 27 Aug 2011 18:16:19 +0000 (14:16 -0400)
There are assorted situations wherein PQconnectPoll() will abandon a
connection attempt and try again with different parameters (eg, SSL versus
not SSL).  However, the code forgot to discard any pending data in libpq's
I/O buffers when doing this.  In at least one case (server returns E
message during SSL negotiation), there is unread input data which bollixes
the next connection attempt.  I have not checked to see whether this is
possible in the other cases where we close the socket and retry, but it
seems like a matter of good defensive programming to add explicit
buffer-flushing code to all of them.

This is one of several issues exposed by Daniel Farina's report of
misbehavior after a server-side fork failure.

This has been wrong since forever, so back-patch to all supported branches.

src/interfaces/libpq/fe-connect.c

index 9e4807e8a96cac13c40e38a24bdb845c4824f1e6..72796aa47597bf9cac8ee201cacbd8b6eca5ef46 100644 (file)
@@ -2068,6 +2068,9 @@ keep_going:                                               /* We will come back to here until there is
                                                closesocket(conn->sock);
                                                conn->sock = -1;
                                                conn->status = CONNECTION_NEEDED;
+                                               /* Discard any unread/unsent data */
+                                               conn->inStart = conn->inCursor = conn->inEnd = 0;
+                                               conn->outCount = 0;
                                                goto keep_going;
                                        }
                                        else
@@ -2105,6 +2108,9 @@ keep_going:                                               /* We will come back to here until there is
                                                closesocket(conn->sock);
                                                conn->sock = -1;
                                                conn->status = CONNECTION_NEEDED;
+                                               /* Discard any unread/unsent data */
+                                               conn->inStart = conn->inCursor = conn->inEnd = 0;
+                                               conn->outCount = 0;
                                                goto keep_going;
                                        }
                                }
@@ -2218,6 +2224,9 @@ keep_going:                                               /* We will come back to here until there is
                                                closesocket(conn->sock);
                                                conn->sock = -1;
                                                conn->status = CONNECTION_NEEDED;
+                                               /* Discard any unread/unsent data */
+                                               conn->inStart = conn->inCursor = conn->inEnd = 0;
+                                               conn->outCount = 0;
                                                goto keep_going;
                                        }
 
@@ -2285,6 +2294,9 @@ keep_going:                                               /* We will come back to here until there is
                                                closesocket(conn->sock);
                                                conn->sock = -1;
                                                conn->status = CONNECTION_NEEDED;
+                                               /* Discard any unread/unsent data */
+                                               conn->inStart = conn->inCursor = conn->inEnd = 0;
+                                               conn->outCount = 0;
                                                goto keep_going;
                                        }
 
@@ -2304,6 +2316,9 @@ keep_going:                                               /* We will come back to here until there is
                                                closesocket(conn->sock);
                                                conn->sock = -1;
                                                conn->status = CONNECTION_NEEDED;
+                                               /* Discard any unread/unsent data */
+                                               conn->inStart = conn->inCursor = conn->inEnd = 0;
+                                               conn->outCount = 0;
                                                goto keep_going;
                                        }
 #endif
@@ -2467,6 +2482,9 @@ keep_going:                                               /* We will come back to here until there is
                                                        closesocket(conn->sock);
                                                        conn->sock = -1;
                                                        conn->status = CONNECTION_NEEDED;
+                                                       /* Discard any unread/unsent data */
+                                                       conn->inStart = conn->inCursor = conn->inEnd = 0;
+                                                       conn->outCount = 0;
                                                        goto keep_going;
                                                }
                                        }