</thead>
<tbody>
+ <row>
+ <entry>3.9999</entry>
+ <entry>-</entry>
+ <entry>Reserved for protocol greasing. libpq may use this version, which
+ is higher than any minor version the project ever expects to use, to
+ test that servers and middleware properly implement protocol version
+ negotiation. Servers <emphasis>must not</emphasis> add special-case
+ logic for this version; they should simply compare it to their latest
+ supported version (which will always be smaller) and downgrade via a
+ NegotiateProtocolVersion message.
+ </entry>
+ </row>
<row>
<entry>3.1</entry>
<entry>-</entry>
otherwise continue the connection.
</entry>
</row>
+
+ <row>
+ <entry><literal>_pq_.test_protocol_negotiation</literal></entry>
+ <entry>Reserved for protocol greasing. libpq may send this extension to
+ test that servers and middleware properly implement protocol extension
+ negotiation. Servers <emphasis>must not</emphasis> add special-case
+ logic for this parameter; they should simply send the list of all
+ unsupported options (including this one) via a NegotiateProtocolVersion
+ message.
+ </entry>
+ </row>
</tbody>
</tgroup>
</table>
*/
#define PG_PROTOCOL_RESERVED_31 PG_PROTOCOL(3,1)
+/*
+ * PG_PROTOCOL_GREASE is an intentionally unsupported protocol version used
+ * for "greasing" (the practice of sending valid, but extraneous or otherwise
+ * unusual, messages to keep peer implementations honest). This helps ensure
+ * that servers properly implement protocol version negotiation. Version 3.9999
+ * was chosen since it is safely within the valid range, it is representable
+ * via PQfullProtocolVersion, and it is unlikely to ever be needed in practice.
+ */
+#define PG_PROTOCOL_GREASE PG_PROTOCOL(3,9999)
+
/*
* A client can send a cancel-current-operation request to the postmaster.
* This is uglier than sending it directly to the client's backend, but it
if (pqGetInt(&num, 4, conn) != 0)
goto eof;
- /* Check the protocol version */
+ /*
+ * Check the protocol version.
+ *
+ * PG_PROTOCOL_GREASE is intentionally unsupported and reserved. It's
+ * higher than any real version, so check for that first, to get the most
+ * specific error message. Then check the upper and lower bounds.
+ */
+ if (their_version == PG_PROTOCOL_GREASE)
+ {
+ libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested \"grease\" protocol version 3.9999");
+ goto failure;
+ }
+
if (their_version > conn->pversion)
{
libpq_append_conn_error(conn, "received invalid protocol negotiation message: server requested downgrade to a higher-numbered version");