Robert Haas wrote:
On Fri, Feb 13, 2009 at 12:06 PM, Andrew Chernow <a...@esilo.com> wrote:
Patch attached.
One thing I noticed is the ssl_open_connections variable is ref counting
connections when pq_initssllib is true. But, it now only affects crypto
library init and cleanup calls. Point is, ref counting is only needed if
pq_initcryptolib is true and it should be renamed to
crypto_open_connections. I didn't do this in the patch. Its the same old
name and the counter is incremented if pq_initssllib or pq_initcryptolib is
true. Please advise.
I'll review this in more detail when I have a chance, but it certainly
won't be committable without doc changes, and it's probably best if
you write those and include them in the patch.
...Robert
Okay. Added docs in the same place PQinitSSL is. Apparently, initssl
doesn't have formal func docs.
--
Andrew Chernow
eSilo, LLC
every bit counts
http://www.esilo.com/
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/libpq.sgml,v
retrieving revision 1.278
diff -C6 -r1.278 libpq.sgml
*** doc/src/sgml/libpq.sgml 11 Feb 2009 04:08:47 -0000 1.278
--- doc/src/sgml/libpq.sgml 13 Feb 2009 18:11:40 -0000
***************
*** 60,72 ****
<function>PQsetdbLogin</>. Note that these functions will always
return a non-null object pointer, unless perhaps there is too
little memory even to allocate the <structname>PGconn</> object.
The <function>PQstatus</> function should be called to check
whether a connection was successfully made before queries are sent
via the connection object.
!
<note>
<para>
On Windows, there is a way to improve performance if a single
database connection is repeatedly started and shutdown. Internally,
libpq calls WSAStartup() and WSACleanup() for connection startup
and shutdown, respectively. WSAStartup() increments an internal
--- 60,72 ----
<function>PQsetdbLogin</>. Note that these functions will always
return a non-null object pointer, unless perhaps there is too
little memory even to allocate the <structname>PGconn</> object.
The <function>PQstatus</> function should be called to check
whether a connection was successfully made before queries are sent
via the connection object.
!
<note>
<para>
On Windows, there is a way to improve performance if a single
database connection is repeatedly started and shutdown. Internally,
libpq calls WSAStartup() and WSACleanup() for connection startup
and shutdown, respectively. WSAStartup() increments an internal
***************
*** 6169,6181 ****
<para>
If you are using <acronym>SSL</> inside your application (in addition
to inside <application>libpq</application>), you can call
<function>PQinitSSL(int)</> with <literal>0</> to tell
<application>libpq</application> that the <acronym>SSL</> library
! has already been initialized by your application.
<!-- If this URL changes replace it with a URL to www.archive.org. -->
See <ulink
url="http://h71000.www7.hp.com/doc/83final/BA554_90007/ch04.html"></ulink>
for details on the SSL API.
</para>
--- 6169,6184 ----
<para>
If you are using <acronym>SSL</> inside your application (in addition
to inside <application>libpq</application>), you can call
<function>PQinitSSL(int)</> with <literal>0</> to tell
<application>libpq</application> that the <acronym>SSL</> library
! has already been initialized by your application. Additionally, you
! can call <function>PQinitCrypto(int)</> with <literal>0</> to tell
! <application>libpq</application> that the <acronym>Crypto</> library has
! already been initialized by your application.
<!-- If this URL changes replace it with a URL to www.archive.org. -->
See <ulink
url="http://h71000.www7.hp.com/doc/83final/BA554_90007/ch04.html"></ulink>
for details on the SSL API.
</para>
Index: src/interfaces/libpq/exports.txt
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/exports.txt,v
retrieving revision 1.22
diff -C6 -r1.22 exports.txt
*** src/interfaces/libpq/exports.txt 22 Sep 2008 13:55:14 -0000 1.22
--- src/interfaces/libpq/exports.txt 13 Feb 2009 18:11:40 -0000
***************
*** 149,154 ****
--- 149,155 ----
PQinstanceData 147
PQsetInstanceData 148
PQresultInstanceData 149
PQresultSetInstanceData 150
PQfireResultCreateEvents 151
PQconninfoParse 152
+ PQinitCrypto 153
\ No newline at end of file
Index: src/interfaces/libpq/fe-secure.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.119
diff -C6 -r1.119 fe-secure.c
*** src/interfaces/libpq/fe-secure.c 28 Jan 2009 15:06:47 -0000 1.119
--- src/interfaces/libpq/fe-secure.c 13 Feb 2009 18:11:40 -0000
***************
*** 96,107 ****
--- 96,108 ----
static PostgresPollingStatusType open_client_SSL(PGconn *);
static void close_SSL(PGconn *);
static char *SSLerrmessage(void);
static void SSLerrfree(char *buf);
static bool pq_initssllib = true;
+ static bool pq_initcryptolib = true;
static SSL_CTX *SSL_context = NULL;
#ifdef ENABLE_THREAD_SAFETY
static int ssl_open_connections = 0;
#ifndef WIN32
***************
*** 175,186 ****
--- 176,199 ----
#ifdef USE_SSL
pq_initssllib = do_init;
#endif
}
/*
+ * Exported function to allow application to tell us it's already
+ * initialized the OpenSSL Crypto library.
+ */
+ void
+ PQinitCrypto(int do_init)
+ {
+ #ifdef USE_SSL
+ pq_initcryptolib = do_init;
+ #endif
+ }
+
+ /*
* Initialize global context
*/
int
pqsecure_initialize(PGconn *conn)
{
int r = 0;
***************
*** 820,831 ****
--- 833,846 ----
* message - no connection local setup is made.
*/
static int
init_ssl_system(PGconn *conn)
{
#ifdef ENABLE_THREAD_SAFETY
+ int num_ssl_conns = 0;
+
#ifdef WIN32
/* Also see similar code in fe-connect.c, default_threadlock() */
if (ssl_config_mutex == NULL)
{
while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
/* loop, another thread own the lock */ ;
***************
*** 837,849 ****
InterlockedExchange(&win32_ssl_create_mutex, 0);
}
#endif
if (pthread_mutex_lock(&ssl_config_mutex))
return -1;
! if (pq_initssllib)
{
/*
* If necessary, set up an array to hold locks for OpenSSL.
OpenSSL will
* tell us how big to make this array.
*/
if (pq_lockarray == NULL)
--- 852,873 ----
InterlockedExchange(&win32_ssl_create_mutex, 0);
}
#endif
if (pthread_mutex_lock(&ssl_config_mutex))
return -1;
! /*
! * Increment connection count if we are responsible for
! * intiializing the SSL or Crypto library. Currently, only
! * crypto needs this during setup and cleanup. That may
! * change in the future so we always update the counter.
! */
! if (pq_initssllib || pq_initcryptolib)
! num_ssl_conns = ssl_open_connections++;
!
! if (pq_initcryptolib)
{
/*
* If necessary, set up an array to hold locks for OpenSSL.
OpenSSL will
* tell us how big to make this array.
*/
if (pq_lockarray == NULL)
***************
*** 865,877 ****
pthread_mutex_unlock(&ssl_config_mutex);
return -1;
}
}
}
! if (ssl_open_connections++ == 0)
{
/* These are only required for threaded SSL
applications */
CRYPTO_set_id_callback(pq_threadidcallback);
CRYPTO_set_locking_callback(pq_lockingcallback);
}
}
--- 889,901 ----
pthread_mutex_unlock(&ssl_config_mutex);
return -1;
}
}
}
! if (num_ssl_conns == 0)
{
/* These are only required for threaded SSL
applications */
CRYPTO_set_id_callback(pq_threadidcallback);
CRYPTO_set_locking_callback(pq_lockingcallback);
}
}
***************
*** 924,955 ****
{
#ifdef ENABLE_THREAD_SAFETY
/* Mutex is created in initialize_ssl_system() */
if (pthread_mutex_lock(&ssl_config_mutex))
return;
! if (pq_initssllib)
{
! if (ssl_open_connections > 0)
! --ssl_open_connections;
! if (ssl_open_connections == 0)
! {
! /* No connections left, unregister all callbacks */
! CRYPTO_set_locking_callback(NULL);
! CRYPTO_set_id_callback(NULL);
!
! /*
! * We don't free the lock array. If we get another
connection
! * from the same caller, we will just re-use it with
the existing
! * mutexes.
! *
! * This means we leak a little memory on repeated
load/unload
! * of the library.
! */
! }
}
pthread_mutex_unlock(&ssl_config_mutex);
#endif
return;
}
--- 948,976 ----
{
#ifdef ENABLE_THREAD_SAFETY
/* Mutex is created in initialize_ssl_system() */
if (pthread_mutex_lock(&ssl_config_mutex))
return;
! if ((pq_initssllib || pq_initcryptolib) && ssl_open_connections > 0)
! --ssl_open_connections;
!
! if (pq_initcryptolib && ssl_open_connections == 0)
{
! /* No connections left, unregister all callbacks */
! CRYPTO_set_locking_callback(NULL);
! CRYPTO_set_id_callback(NULL);
! /*
! * We don't free the lock array. If we get another connection
! * from the same caller, we will just re-use it with the
existing
! * mutexes.
! *
! * This means we leak a little memory on repeated load/unload
! * of the library.
! */
}
pthread_mutex_unlock(&ssl_config_mutex);
#endif
return;
}
Index: src/interfaces/libpq/libpq-fe.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/libpq/libpq-fe.h,v
retrieving revision 1.145
diff -C6 -r1.145 libpq-fe.h
*** src/interfaces/libpq/libpq-fe.h 1 Jan 2009 17:24:03 -0000 1.145
--- src/interfaces/libpq/libpq-fe.h 13 Feb 2009 18:11:40 -0000
***************
*** 299,310 ****
--- 299,313 ----
* unencrypted connections or if any other TLS library is in use. */
extern void *PQgetssl(PGconn *conn);
/* Tell libpq whether it needs to initialize OpenSSL */
extern void PQinitSSL(int do_init);
+ /* Tell libpq whether it needs to initialize the OpenSSL Crypto library. */
+ extern void PQinitCrypto(int do_init)
+
/* Set verbosity for PQerrorMessage and PQresultErrorMessage */
extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
/* Enable/disable tracing */
extern void PQtrace(PGconn *conn, FILE *debug_port);
extern void PQuntrace(PGconn *conn);
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers