From 64aea1ebc70dc597b79e2f7f4451472510a1e9bf Mon Sep 17 00:00:00 2001
From: Magnus Hagander <magnus@hagander.net>
Date: Mon, 28 Nov 2011 13:13:42 +0100
Subject: [PATCH] Add libpq connection option to disable SSL compression

This can be used to remove the overhead of SSL compression on
fast networks.

Laurenz Albe
---
 doc/src/sgml/libpq.sgml           | 32 +++++++++++++++++++++++++++++++
 src/interfaces/libpq/fe-connect.c |  5 +++++
 src/interfaces/libpq/fe-secure.c  | 10 ++++++++++
 src/interfaces/libpq/libpq-int.h  |  1 +
 4 files changed, 48 insertions(+)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 3d5f98ba2a6..252ff8cc855 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -494,6 +494,28 @@ PGconn *PQconnectdbParams(const char * const *keywords,
          </listitem>
         </varlistentry>
 
+        <varlistentry id="libpq-connect-sslcompression" xreflabel="sslcompression">
+         <term><literal>sslcompression</literal></term>
+         <listitem>
+          <para>
+           If set to 1 (default), data sent over SSL connections will be
+           compressed (this requires <productname>OpenSSL</> version
+           0.9.8 or later).
+           If set to 0, compression will be disabled (this requires
+           <productname>OpenSSL</> 1.0.0 or later).
+           This parameter is ignored if a connection without SSL is made,
+           or if the version of <productname>OpenSSL</> used does not support
+           it.
+          </para>
+          <para>
+           Compression uses CPU time, but can improve throughput if
+           the network is the bottleneck.
+           Disabling compression can improve response time and throughput
+           if CPU performance is the limiting factor.
+          </para>
+         </listitem>
+        </varlistentry>
+
         <varlistentry id="libpq-connect-sslcert" xreflabel="sslcert">
          <term><literal>sslcert</literal></term>
          <listitem>
@@ -6308,6 +6330,16 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
      </para>
     </listitem>
 
+    <listitem>
+     <para>
+      <indexterm>
+       <primary><envar>PGSSLCOMPRESSION</envar></primary>
+      </indexterm>
+      <envar>PGSSLCOMPRESSION</envar> behaves the same as the <xref
+      linkend="libpq-connect-sslcompression"> connection parameter.
+     </para>
+    </listitem>
+
     <listitem>
      <para>
       <indexterm>
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index ed9dce941e1..50f3f83aaeb 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -222,6 +222,9 @@ static const PQconninfoOption PQconninfoOptions[] = {
 	{"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
 	"SSL-Mode", "", 8},			/* sizeof("disable") == 8 */
 
+	{"sslcompression", "PGSSLCOMPRESSION", "1", NULL,
+	"SSL-Compression", "", 1},
+
 	{"sslcert", "PGSSLCERT", NULL, NULL,
 	"SSL-Client-Cert", "", 64},
 
@@ -621,6 +624,8 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
 	conn->keepalives_count = tmp ? strdup(tmp) : NULL;
 	tmp = conninfo_getval(connOptions, "sslmode");
 	conn->sslmode = tmp ? strdup(tmp) : NULL;
+	tmp = conninfo_getval(connOptions, "sslcompression");
+	conn->sslcompression = tmp ? strdup(tmp) : NULL;
 	tmp = conninfo_getval(connOptions, "sslkey");
 	conn->sslkey = tmp ? strdup(tmp) : NULL;
 	tmp = conninfo_getval(connOptions, "sslcert");
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 9c6ced6a828..c6963bed948 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -1292,6 +1292,16 @@ initialize_SSL(PGconn *conn)
 		}
 	}
 
+	/*
+	 * If the OpenSSL version used supports it (from 1.0.0 on)
+	 * and the user requested it, disable SSL compression.
+	 */
+#ifdef SSL_OP_NO_COMPRESSION
+	if (conn->sslcompression && conn->sslcompression[0] == '0') {
+		SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION);
+	}
+#endif
+
 	return 0;
 }
 
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index d56ef5d489b..64dfcb27fb1 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -310,6 +310,7 @@ struct pg_conn
 	char	   *keepalives_count;		/* maximum number of TCP keepalive
 										 * retransmits */
 	char	   *sslmode;		/* SSL mode (require,prefer,allow,disable) */
+	char	   *sslcompression;	/* SSL compression (0 or 1) */
 	char	   *sslkey;			/* client key filename */
 	char	   *sslcert;		/* client certificate filename */
 	char	   *sslrootcert;	/* root certificate filename */
-- 
GitLab