summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-08-27 14:16:14 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-08-27 14:16:14 -0400
commit724e30c9f886efd852f714d47c56336ffa6916ec (patch)
treef0e1ae925df18fefb48dcce7e34a33df1664760d /src
parent4bd7333b14786a2d757195e907709d2aee116809 (diff)
downloadpostgresql-724e30c9f886efd852f714d47c56336ffa6916ec.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/libpq/fe-connect.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 3523582145..bf6aaae761 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -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;
}
}