1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-13 16:22:44 +03:00

libpq: Handle NegotiateProtocolVersion message differently

Previously libpq would always error out if the server sends a
NegotiateProtocolVersion message. This was fine because libpq only
supported a single protocol version and did not support any protocol
parameters. But in the upcoming commits, we will introduce a new
protocol version and the NegotiateProtocolVersion message starts to
actually be used.

This patch modifies the client side checks to allow a range of
supported protocol versions, instead of only allowing the exact
version that was requested. Currently this "range" only contains the
3.0 version, but in a future commit we'll change this.

Also clarify the error messages, making them suitable for the world
where libpq will support multiple protocol versions and protocol
extensions.

Note that until the later commits that introduce new protocol version,
this change does not have any behavioural effect, because libpq will
only request version 3.0 and will never send protocol parameters, and
therefore will never receive a NegotiateProtocolVersion message from
the server.

Author: Jelte Fennema-Nio <postgres@jeltef.nl>
Reviewed-by: Robert Haas <robertmhaas@gmail.com> (earlier versions)
Discussion: https://www.postgresql.org/message-id/CAGECzQTfc_O%2BHXqAo5_-xG4r3EFVsTefUeQzSvhEyyLDba-O9w@mail.gmail.com
Discussion: https://www.postgresql.org/message-id/CAGECzQRbAGqJnnJJxTdKewTsNOovUt4bsx3NFfofz3m2j-t7tA@mail.gmail.com
This commit is contained in:
Heikki Linnakangas
2025-04-02 16:41:42 +03:00
parent 748e98d05b
commit 5070349102
3 changed files with 72 additions and 36 deletions

View File

@@ -667,6 +667,7 @@ pqDropServerData(PGconn *conn)
/* Reset assorted other per-connection state */
conn->last_sqlstate[0] = '\0';
conn->pversion_negotiated = false;
conn->auth_req_received = false;
conn->client_finished_auth = false;
conn->password_needed = false;
@@ -4084,16 +4085,24 @@ keep_going: /* We will come back to here until there is
CONNECTION_FAILED();
}
/* Handle NegotiateProtocolVersion */
else if (beresp == PqMsg_NegotiateProtocolVersion)
{
if (pqGetNegotiateProtocolVersion3(conn))
if (conn->pversion_negotiated)
{
libpq_append_conn_error(conn, "received invalid protocol negotiation message");
libpq_append_conn_error(conn, "received duplicate protocol negotiation message");
goto error_return;
}
if (pqGetNegotiateProtocolVersion3(conn))
{
/* pqGetNegotiateProtocolVersion3 set error already */
goto error_return;
}
conn->pversion_negotiated = true;
/* OK, we read the message; mark data consumed */
pqParseDone(conn, conn->inCursor);
goto error_return;
goto keep_going;
}
/* It is an authentication request. */