Instead of a bare recv() to read the server's response to an SSL
request packet, use pqReadData(). This has the same effect since conn->ssl isn't set yet and we aren't expecting more than one byte. The advantage is that we will correctly detect loss-of-connection instead of going into an infinite loop. Per report from Hannu Krosing.
This commit is contained in:
parent
a3f98d5795
commit
4717992b4e
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.297 2005/01/06 18:29:10 tgl Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.298 2005/01/06 20:06:58 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -1452,30 +1452,36 @@ keep_going: /* We will come back to here until there
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On first time through, get the postmaster's response to
|
* On first time through, get the postmaster's response to
|
||||||
* our SSL negotiation packet. Be careful to read only
|
* our SSL negotiation packet.
|
||||||
* one byte (if there's more, it could be SSL data).
|
|
||||||
*/
|
*/
|
||||||
if (conn->ssl == NULL)
|
if (conn->ssl == NULL)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* We use pqReadData here since it has the logic to
|
||||||
|
* distinguish no-data-yet from connection closure.
|
||||||
|
* Since conn->ssl isn't set, a plain recv() will occur.
|
||||||
|
*/
|
||||||
char SSLok;
|
char SSLok;
|
||||||
int nread;
|
int rdresult;
|
||||||
|
|
||||||
retry_ssl_read:
|
rdresult = pqReadData(conn);
|
||||||
nread = recv(conn->sock, &SSLok, 1, 0);
|
if (rdresult < 0)
|
||||||
if (nread < 0)
|
|
||||||
{
|
{
|
||||||
if (SOCK_ERRNO == EINTR)
|
/* errorMessage is already filled in */
|
||||||
/* Interrupted system call - just try again */
|
|
||||||
goto retry_ssl_read;
|
|
||||||
|
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
|
||||||
libpq_gettext("could not receive server response to SSL negotiation packet: %s\n"),
|
|
||||||
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
|
|
||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
if (nread == 0)
|
if (rdresult == 0)
|
||||||
|
{
|
||||||
/* caller failed to wait for data */
|
/* caller failed to wait for data */
|
||||||
return PGRES_POLLING_READING;
|
return PGRES_POLLING_READING;
|
||||||
|
}
|
||||||
|
if (pqGetc(&SSLok, conn) < 0)
|
||||||
|
{
|
||||||
|
/* should not happen really */
|
||||||
|
return PGRES_POLLING_READING;
|
||||||
|
}
|
||||||
|
/* mark byte consumed */
|
||||||
|
conn->inStart = conn->inCursor;
|
||||||
if (SSLok == 'S')
|
if (SSLok == 'S')
|
||||||
{
|
{
|
||||||
/* Do one-time setup; this creates conn->ssl */
|
/* Do one-time setup; this creates conn->ssl */
|
||||||
|
|
Loading…
Reference in New Issue