diff options
author | Tom Lane | 2011-08-27 18:16:39 +0000 |
---|---|---|
committer | Tom Lane | 2011-08-27 18:16:39 +0000 |
commit | bb42ad1231f4e9fa4c774e797882bf2d5a7f8f58 (patch) | |
tree | eb191f2aa55aee32c0c779abe76cddeba34c617a | |
parent | ae42744e4ebd961e8dc66ca4836bff99b714a2b3 (diff) |
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.
-rw-r--r-- | src/interfaces/libpq/fe-connect.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 58d70bd4d96..318edd41065 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -1379,6 +1379,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 @@ -1416,6 +1419,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; } } @@ -1528,6 +1534,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; } @@ -1594,6 +1603,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; } @@ -1613,6 +1625,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 |