diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 255c5c1..e811672 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -496,6 +496,69 @@ typedef struct
      </listitem>
     </varlistentry>
 
+    <varlistentry id="libpq-pqconninfo">
+     <term><function>PQconninfo</function><indexterm><primary>PQconninfo</></></term>
+     <listitem>
+      <para>
+       Returns the connection options used by a live connection.
+<synopsis>
+PQconninfoOption *PQconninfo(PGconn *conn, int flags);
+</synopsis>
+      </para>
+
+      <para>
+       Returns a connection options array.  This can be used to determine
+       all possible <function>PQconnectdb</function> options and the
+       values that were used to connect to the server. The return
+       value points to an array of <structname>PQconninfoOption</structname>
+       structures, which ends with an entry having a null <structfield>keyword</>
+       pointer. All notes above for <function>PQconndefaults</function> also
+       apply to the result of <function>PQconninfo</function>.
+      </para>
+
+      <para>
+       The parameter <literal>flags</literal> is used to filter which
+       connection options are returned. The flags are a bitmask that can be
+       ORed together to return parameters of multiple types at the same time.
+
+       <variablelist>
+        <varlistentry>
+         <term><symbol>PG_CONNINFO_NORMAL</symbol></term>
+         <listitem>
+          <para>
+           All normal connection options.
+          </para>
+         </listitem>
+        </varlistentry>
+
+        <varlistentry>
+         <term><symbol>PG_CONNINFO_PASSWORD</symbol></term>
+         <listitem>
+          <para>
+           All connection options that include passwords or other
+           sensitive information.
+          </para>
+         </listitem>
+        </varlistentry>
+
+        <varlistentry>
+         <term><symbol>PG_CONNINFO_REPLICATION</symbol></term>
+         <listitem>
+          <para>
+           All connection options only used for replication
+           connections.
+          </para>
+         </listitem>
+        </varlistentry>
+       </variablelist>
+
+       It is also possible to specify <literal>PG_CONNINFO_ALL</literal>,
+       which will return all options, regardless of type.
+      </para>
+     </listitem>
+    </varlistentry>
+
+
     <varlistentry id="libpq-pqconninfoparse">
      <term><function>PQconninfoParse</function><indexterm><primary>PQconninfoParse</></></term>
      <listitem>
@@ -1178,28 +1241,6 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
       </listitem>
      </varlistentry>
 
-     <varlistentry id="libpq-connect-requiressl" xreflabel="requiressl">
-      <term><literal>requiressl</literal></term>
-      <listitem>
-       <para>
-        This option is deprecated in favor of the <literal>sslmode</>
-        setting.
-       </para>
-
-       <para>
-        If set to 1, an <acronym>SSL</acronym> connection to the server
-        is required (this is equivalent to <literal>sslmode</>
-        <literal>require</>).  <application>libpq</> will then refuse
-        to connect if the server does not accept an
-        <acronym>SSL</acronym> connection.  If set to 0 (default),
-        <application>libpq</> will negotiate the connection type with
-        the server (equivalent to <literal>sslmode</>
-        <literal>prefer</>).  This option is only available if
-        <productname>PostgreSQL</> is compiled with SSL support.
-       </para>
-      </listitem>
-     </varlistentry>
-
      <varlistentry id="libpq-connect-sslcompression" xreflabel="sslcompression">
       <term><literal>sslcompression</literal></term>
       <listitem>
@@ -6574,16 +6615,6 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
     <listitem>
      <para>
       <indexterm>
-       <primary><envar>PGREQUIRESSL</envar></primary>
-      </indexterm>
-      <envar>PGREQUIRESSL</envar> behaves the same as the <xref
-      linkend="libpq-connect-requiressl"> connection parameter.
-     </para>
-    </listitem>
-
-    <listitem>
-     <para>
-      <indexterm>
        <primary><envar>PGSSLCOMPRESSION</envar></primary>
       </indexterm>
       <envar>PGSSLCOMPRESSION</envar> behaves the same as the <xref
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
index 56d0bb8..93da50d 100644
--- a/src/interfaces/libpq/exports.txt
+++ b/src/interfaces/libpq/exports.txt
@@ -164,3 +164,4 @@ PQsetSingleRowMode        161
 lo_lseek64                162
 lo_tell64                 163
 lo_truncate64             164
+PQconninfo                165
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 9eaf410..b66c6ee 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -137,81 +137,113 @@ static int ldapServiceLookup(const char *purl, PQconninfoOption *options,
  * PQconninfoOptions[] *must* be NULL.	In a working copy, non-null "val"
  * fields point to malloc'd strings that should be freed when the working
  * array is freed (see PQconninfoFree).
+ *
+ * The first part of each struct is identical to the one in libpq-fe.h,
+ * which is required since we memcpy() data between the two!
  * ----------
  */
-static const PQconninfoOption PQconninfoOptions[] = {
+typedef struct _internalPQconninfoOption
+{
+	char	   *keyword;		/* The keyword of the option			*/
+	char	   *envvar;			/* Fallback environment variable name	*/
+	char	   *compiled;		/* Fallback compiled in default value	*/
+	char	   *val;			/* Option's current value, or NULL		 */
+	char	   *label;			/* Label for field in connect dialog	*/
+	char	   *dispchar;		/* Indicates how to display this field in a
+								 * connect dialog. Values are: "" Display
+								 * entered value as is "*" Password field -
+								 * hide value "D"  Debug option - don't show
+								 * by default */
+	int			dispsize;		/* Field size in characters for dialog	*/
+	/* ---
+	 * Anything above this comment must be synchronized with
+	 * PQconninfoOption in libpq-fe.h, since we memcpy() data
+	 * between them!
+	 * ---
+	 */
+	off_t		connofs;		/* Offset into PGconn struct, -1 if not there */
+	unsigned int	flags;			/* type of option */
+} internalPQconninfoOption;
+
+static const internalPQconninfoOption PQconninfoOptions[] = {
 	/*
 	 * "authtype" is no longer used, so mark it "don't show".  We keep it in
 	 * the array so as not to reject conninfo strings from old apps that might
 	 * still try to set it.
 	 */
 	{"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
-	"Database-Authtype", "D", 20},
+	 "Database-Authtype", "D", 20, -1, 0},
 
 	{"service", "PGSERVICE", NULL, NULL,
-	"Database-Service", "", 20},
+	 "Database-Service", "", 20, -1, 0},
 
 	{"user", "PGUSER", NULL, NULL,
-	"Database-User", "", 20},
+	 "Database-User", "", 20,
+	 offsetof(struct pg_conn, pguser), PG_CONNINFO_NORMAL},
 
 	{"password", "PGPASSWORD", NULL, NULL,
-	"Database-Password", "*", 20},
+	 "Database-Password", "*", 20,
+	 offsetof(struct pg_conn, pgpass), PG_CONNINFO_PASSWORD},
 
 	{"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL,
-	"Connect-timeout", "", 10}, /* strlen(INT32_MAX) == 10 */
+	 "Connect-timeout", "", 10, /* strlen(INT32_MAX) == 10 */
+	 offsetof(struct pg_conn, connect_timeout), PG_CONNINFO_NORMAL},
 
 	{"dbname", "PGDATABASE", NULL, NULL,
-	"Database-Name", "", 20},
+	 "Database-Name", "", 20,
+	 offsetof(struct pg_conn, dbName), PG_CONNINFO_NORMAL},
 
 	{"host", "PGHOST", NULL, NULL,
-	"Database-Host", "", 40},
+	 "Database-Host", "", 40,
+	 offsetof(struct pg_conn, pghost), PG_CONNINFO_NORMAL},
 
 	{"hostaddr", "PGHOSTADDR", NULL, NULL,
-	"Database-Host-IP-Address", "", 45},
+	 "Database-Host-IP-Address", "", 45,
+	 offsetof(struct pg_conn, pghostaddr), PG_CONNINFO_NORMAL},
 
 	{"port", "PGPORT", DEF_PGPORT_STR, NULL,
-	"Database-Port", "", 6},
+	 "Database-Port", "", 6,
+	 offsetof(struct pg_conn, pgport), PG_CONNINFO_NORMAL},
 
 	{"client_encoding", "PGCLIENTENCODING", NULL, NULL,
-	"Client-Encoding", "", 10},
+	 "Client-Encoding", "", 10,
+	 offsetof(struct pg_conn, client_encoding_initial), PG_CONNINFO_NORMAL},
 
 	/*
 	 * "tty" is no longer used either, but keep it present for backwards
 	 * compatibility.
 	 */
 	{"tty", "PGTTY", DefaultTty, NULL,
-	"Backend-Debug-TTY", "D", 40},
+	 "Backend-Debug-TTY", "D", 40,
+	 offsetof(struct pg_conn, pgtty), PG_CONNINFO_NORMAL},
 
 	{"options", "PGOPTIONS", DefaultOption, NULL,
-	"Backend-Debug-Options", "D", 40},
+	 "Backend-Debug-Options", "D", 40,
+	 offsetof(struct pg_conn, pgoptions), PG_CONNINFO_NORMAL},
 
 	{"application_name", "PGAPPNAME", NULL, NULL,
-	"Application-Name", "", 64},
+	 "Application-Name", "", 64,
+	 offsetof(struct pg_conn, appname), PG_CONNINFO_NORMAL},
 
 	{"fallback_application_name", NULL, NULL, NULL,
-	"Fallback-Application-Name", "", 64},
+	 "Fallback-Application-Name", "", 64,
+	 offsetof(struct pg_conn, fbappname), PG_CONNINFO_NORMAL},
 
 	{"keepalives", NULL, NULL, NULL,
-	"TCP-Keepalives", "", 1},	/* should be just '0' or '1' */
+	 "TCP-Keepalives", "", 1,	/* should be just '0' or '1' */
+	 offsetof(struct pg_conn, keepalives), PG_CONNINFO_NORMAL},
 
 	{"keepalives_idle", NULL, NULL, NULL,
-	"TCP-Keepalives-Idle", "", 10},		/* strlen(INT32_MAX) == 10 */
+	"TCP-Keepalives-Idle", "", 10,		/* strlen(INT32_MAX) == 10 */
+	 offsetof(struct pg_conn, keepalives_idle), PG_CONNINFO_NORMAL},
 
 	{"keepalives_interval", NULL, NULL, NULL,
-	"TCP-Keepalives-Interval", "", 10}, /* strlen(INT32_MAX) == 10 */
+	"TCP-Keepalives-Interval", "", 10, /* strlen(INT32_MAX) == 10 */
+	 offsetof(struct pg_conn, keepalives_interval), PG_CONNINFO_NORMAL},
 
 	{"keepalives_count", NULL, NULL, NULL,
-	"TCP-Keepalives-Count", "", 10},	/* strlen(INT32_MAX) == 10 */
-
-#ifdef USE_SSL
-
-	/*
-	 * "requiressl" is deprecated, its purpose having been taken over by
-	 * "sslmode". It remains for backwards compatibility.
-	 */
-	{"requiressl", "PGREQUIRESSL", "0", NULL,
-	"Require-SSL", "D", 1},
-#endif
+	"TCP-Keepalives-Count", "", 10,	/* strlen(INT32_MAX) == 10 */
+	 offsetof(struct pg_conn, keepalives_count), PG_CONNINFO_NORMAL},
 
 	/*
 	 * ssl options are allowed even without client SSL support because the
@@ -220,30 +252,38 @@ static const PQconninfoOption PQconninfoOptions[] = {
 	 * to exclude them since none of them are mandatory.
 	 */
 	{"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
-	"SSL-Mode", "", 8},			/* sizeof("disable") == 8 */
+	"SSL-Mode", "", 8,			/* sizeof("disable") == 8 */
+	 offsetof(struct pg_conn, sslmode), PG_CONNINFO_NORMAL},
 
 	{"sslcompression", "PGSSLCOMPRESSION", "1", NULL,
-	"SSL-Compression", "", 1},
+	 "SSL-Compression", "", 1,
+	 offsetof(struct pg_conn, sslcompression), PG_CONNINFO_NORMAL},
 
 	{"sslcert", "PGSSLCERT", NULL, NULL,
-	"SSL-Client-Cert", "", 64},
+	 "SSL-Client-Cert", "", 64,
+	 offsetof(struct pg_conn, sslcert), PG_CONNINFO_NORMAL},
 
 	{"sslkey", "PGSSLKEY", NULL, NULL,
-	"SSL-Client-Key", "", 64},
+	 "SSL-Client-Key", "", 64,
+	 offsetof(struct pg_conn, sslkey), PG_CONNINFO_NORMAL},
 
 	{"sslrootcert", "PGSSLROOTCERT", NULL, NULL,
-	"SSL-Root-Certificate", "", 64},
+	 "SSL-Root-Certificate", "", 64,
+	 offsetof(struct pg_conn, sslrootcert), PG_CONNINFO_NORMAL},
 
 	{"sslcrl", "PGSSLCRL", NULL, NULL,
-	"SSL-Revocation-List", "", 64},
+	 "SSL-Revocation-List", "", 64,
+	 offsetof(struct pg_conn, sslcrl), PG_CONNINFO_NORMAL},
 
 	{"requirepeer", "PGREQUIREPEER", NULL, NULL,
-	"Require-Peer", "", 10},
+	 "Require-Peer", "", 10,
+	 offsetof(struct pg_conn, requirepeer), PG_CONNINFO_NORMAL},
 
 #if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
 	/* Kerberos and GSSAPI authentication support specifying the service name */
 	{"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
-	"Kerberos-service-name", "", 20},
+	 "Kerberos-service-name", "", 20,
+	 offsetof(struct pg_conn, krbsrvname), PG_CONNINFO_NORMAL},
 #endif
 
 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
@@ -253,11 +293,13 @@ static const PQconninfoOption PQconninfoOptions[] = {
 	 * default
 	 */
 	{"gsslib", "PGGSSLIB", NULL, NULL,
-	"GSS-library", "", 7},		/* sizeof("gssapi") = 7 */
+	"GSS-library", "", 7,		/* sizeof("gssapi") = 7 */
+	 offsetof(struct pg_conn, gsslib), PG_CONNINFO_NORMAL},
 #endif
 
 	{"replication", NULL, NULL, NULL,
-	"Replication", "D", 5},
+	 "Replication", "D", 5,
+	 offsetof(struct pg_conn, replication), PG_CONNINFO_REPLICATION},
 
 	/* Terminating entry --- MUST BE LAST */
 	{NULL, NULL, NULL, NULL,
@@ -295,7 +337,8 @@ static PGconn *makeEmptyPGconn(void);
 static void fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
 static void freePGconn(PGconn *conn);
 static void closePGconn(PGconn *conn);
-static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage);
+static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage,
+						int flags);
 static PQconninfoOption *parse_connection_string(const char *conninfo,
 						PQExpBuffer errorMessage, bool use_defaults);
 static int	uri_prefix_length(const char *connstr);
@@ -627,7 +670,7 @@ PQconnectStart(const char *conninfo)
 static void
 fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
 {
-	const char *tmp;
+	const internalPQconninfoOption *option;
 
 	/*
 	 * Move option values into conn structure
@@ -637,72 +680,19 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
 	 *
 	 * XXX: probably worth checking strdup() return value here...
 	 */
-	tmp = conninfo_getval(connOptions, "hostaddr");
-	conn->pghostaddr = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "host");
-	conn->pghost = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "port");
-	conn->pgport = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "tty");
-	conn->pgtty = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "options");
-	conn->pgoptions = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "application_name");
-	conn->appname = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "fallback_application_name");
-	conn->fbappname = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "dbname");
-	conn->dbName = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "user");
-	conn->pguser = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "password");
-	conn->pgpass = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "connect_timeout");
-	conn->connect_timeout = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "client_encoding");
-	conn->client_encoding_initial = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "keepalives");
-	conn->keepalives = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "keepalives_idle");
-	conn->keepalives_idle = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "keepalives_interval");
-	conn->keepalives_interval = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "keepalives_count");
-	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");
-	conn->sslcert = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "sslrootcert");
-	conn->sslrootcert = tmp ? strdup(tmp) : NULL;
-	tmp = conninfo_getval(connOptions, "sslcrl");
-	conn->sslcrl = tmp ? strdup(tmp) : NULL;
-#ifdef USE_SSL
-	tmp = conninfo_getval(connOptions, "requiressl");
-	if (tmp && tmp[0] == '1')
+	for (option = PQconninfoOptions; option->keyword; option++)
 	{
-		/* here warn that the requiressl option is deprecated? */
-		if (conn->sslmode)
-			free(conn->sslmode);
-		conn->sslmode = strdup("require");
+		const char *tmp = conninfo_getval(connOptions, option->keyword);
+
+		if (tmp && option->connofs >= 0)
+		{
+			char **connmember = (char **)((char *)conn + option->connofs);
+
+			if (*connmember)
+				free(*connmember);
+			*connmember = tmp ? strdup(tmp) : NULL;
+		}
 	}
-#endif
-	tmp = conninfo_getval(connOptions, "requirepeer");
-	conn->requirepeer = tmp ? strdup(tmp) : NULL;
-#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI)
-	tmp = conninfo_getval(connOptions, "krbsrvname");
-	conn->krbsrvname = tmp ? strdup(tmp) : NULL;
-#endif
-#if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
-	tmp = conninfo_getval(connOptions, "gsslib");
-	conn->gsslib = tmp ? strdup(tmp) : NULL;
-#endif
-	tmp = conninfo_getval(connOptions, "replication");
-	conn->replication = tmp ? strdup(tmp) : NULL;
 }
 
 /*
@@ -884,7 +874,7 @@ PQconndefaults(void)
 	if (PQExpBufferDataBroken(errorBuf))
 		return NULL;			/* out of memory already :-( */
 
-	connOptions = conninfo_init(&errorBuf);
+	connOptions = conninfo_init(&errorBuf, PG_CONNINFO_ALL);
 	if (connOptions != NULL)
 	{
 		if (!conninfo_add_defaults(connOptions, &errorBuf))
@@ -4008,18 +3998,35 @@ PQconninfoParse(const char *conninfo, char **errmsg)
  * Build a working copy of the constant PQconninfoOptions array.
  */
 static PQconninfoOption *
-conninfo_init(PQExpBuffer errorMessage)
+conninfo_init(PQExpBuffer errorMessage, int flags)
 {
 	PQconninfoOption *options;
+	PQconninfoOption *opt_dest;
+	const internalPQconninfoOption *cur_opt;
 
-	options = (PQconninfoOption *) malloc(sizeof(PQconninfoOptions));
+	/*
+	 * Get enough memory for all optoins in PQconninfoOptions, even if some
+	 * end up being filtered out.
+	 */
+	options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions)/sizeof(PQconninfoOptions[0]));
 	if (options == NULL)
 	{
 		printfPQExpBuffer(errorMessage,
 						  libpq_gettext("out of memory\n"));
 		return NULL;
 	}
-	memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
+	opt_dest = options;
+
+	for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
+	{
+		if (!(cur_opt->flags & flags))
+			continue;
+
+		/* Only copy the public part of the struct, not the full internal */
+		memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
+		opt_dest++;
+	}
+	MemSet(opt_dest, 0, sizeof(PQconninfoOption));
 
 	return options;
 }
@@ -4095,7 +4102,7 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
 	PQconninfoOption *options;
 
 	/* Make a working copy of PQconninfoOptions */
-	options = conninfo_init(errorMessage);
+	options = conninfo_init(errorMessage, PG_CONNINFO_ALL);
 	if (options == NULL)
 		return NULL;
 
@@ -4295,7 +4302,7 @@ conninfo_array_parse(const char *const * keywords, const char *const * values,
 	}
 
 	/* Make a working copy of PQconninfoOptions */
-	options = conninfo_init(errorMessage);
+	options = conninfo_init(errorMessage, PG_CONNINFO_ALL);
 	if (options == NULL)
 	{
 		PQconninfoFree(dbname_options);
@@ -4485,7 +4492,7 @@ conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage,
 	PQconninfoOption *options;
 
 	/* Make a working copy of PQconninfoOptions */
-	options = conninfo_init(errorMessage);
+	options = conninfo_init(errorMessage, PG_CONNINFO_ALL);
 	if (options == NULL)
 		return NULL;
 
@@ -5066,6 +5073,50 @@ conninfo_find(PQconninfoOption *connOptions, const char *keyword)
 }
 
 
+/*
+ * Return the connection options used for the connections
+ */
+PQconninfoOption *
+PQconninfo(PGconn *conn, unsigned int flags)
+{
+	PQExpBufferData errorBuf;
+	PQconninfoOption *connOptions;
+
+	if (conn == NULL)
+		return NULL;
+
+	/* We don't actually report any errors here, but callees want a buffer */
+	initPQExpBuffer(&errorBuf);
+	if (PQExpBufferDataBroken(errorBuf))
+		return NULL;		/* out of memory already :-( */
+
+	connOptions = conninfo_init(&errorBuf, flags);
+
+	if (connOptions != NULL)
+	{
+		const internalPQconninfoOption *option;
+
+		for (option = PQconninfoOptions; option->keyword; option++)
+		{
+			char **connmember;
+
+			if (option->connofs < 0)
+				continue;
+
+			connmember = (char **)((char *)conn + option->connofs);
+
+			if (*connmember)
+				conninfo_storeval(connOptions, option->keyword, *connmember,
+					&errorBuf, false, false);
+		}
+	}
+
+	termPQExpBuffer(&errorBuf);
+
+	return connOptions;
+}
+
+
 void
 PQconninfoFree(PQconninfoOption *connOptions)
 {
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 0b8d9a6..5038fce 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -36,6 +36,14 @@ extern		"C"
 #define PG_COPYRES_EVENTS		  0x04
 #define PG_COPYRES_NOTICEHOOKS	  0x08
 
+/*
+ * Option flags for PQconninfo
+ */
+#define PG_CONNINFO_NORMAL		0x01
+#define PG_CONNINFO_PASSWORD		0x02
+#define PG_CONNINFO_REPLICATION		0x04
+#define PG_CONNINFO_ALL				0xFFFFFFFF
+
 /* Application-visible enum types */
 
 /*
@@ -262,6 +270,9 @@ extern PQconninfoOption *PQconndefaults(void);
 /* parse connection options in same way as PQconnectdb */
 extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
 
+/* return the connection options used by a live connection */
+extern PQconninfoOption *PQconninfo(PGconn *conn, unsigned int flags);
+
 /* free the data structure returned by PQconndefaults() or PQconninfoParse() */
 extern void PQconninfoFree(PQconninfoOption *connOptions);
 