From: Tom Lane Date: Sat, 27 Aug 2011 18:16:30 +0000 (-0400) Subject: Ensure we discard unread/unsent data when abandoning a connection attempt. X-Git-Tag: REL8_4_9~23 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c68561cbea123dbd0bfdaaab7fbcb1dac7053326;p=postgresql Ensure we discard unread/unsent data when abandoning a connection attempt. 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. --- diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 75faacb8af..9727b0cfa5 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -1449,6 +1449,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 @@ -1486,6 +1489,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; } } @@ -1599,6 +1605,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; } @@ -1666,6 +1675,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; } @@ -1685,6 +1697,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