Re: [Possible Bug] EnableSSL method has no socket timeout, threadhangs indefinitely

Поиск
Список
Период
Сортировка
От Dave Cramer
Тема Re: [Possible Bug] EnableSSL method has no socket timeout, threadhangs indefinitely
Дата
Msg-id CADK3HHKV7xeVDX1qXYNJs9=BA8-dUgDwvwWPH0JVJCgt4mPWsQ@mail.gmail.com
обсуждение исходный текст
Ответ на [Possible Bug] EnableSSL method has no socket timeout, thread hangs indefinitely  (Ray Hu <rayhu92@gmail.com>)
Список pgsql-jdbc



On Fri, 7 Dec 2018 at 18:54, Ray Hu <rayhu92@gmail.com> wrote:
Hi all

During my usage of the JDBC library, I was performing some error handling tests by introducing network packet loss between my application and the database and I found that my application’s thread count began rising, I did a thread dump of my application and found many of the following stack trace:

"PostgreSQL JDBC driver connection thread" #4645 daemon prio=5 os_prio=0 tid=0x967d7c00 nid=0x6c8e runnable [0x901ac000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        at java.net.SocketInputStream.read(SocketInputStream.java:171)
        at java.net.SocketInputStream.read(SocketInputStream.java:141)
        at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
        at sun.security.ssl.InputRecord.read(InputRecord.java:503)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
        - locked <0xd1aca150> (a java.lang.Object)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
        - locked <0xd1aca120> (a java.lang.Object)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
        at org.postgresql.ssl.jdbc4.AbstractJdbc4MakeSSL.convert(AbstractJdbc4MakeSSL.java:119)
        at org.postgresql.core.v3.ConnectionFactoryImpl.enableSSL(ConnectionFactoryImpl.java:331)
        at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:125)
        at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
        at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:127)
        at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:29)
        at org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:21)
        at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:41)
        at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24)
        at org.postgresql.Driver.makeConnection(Driver.java:414)
        at org.postgresql.Driver.access$100(Driver.java:47)
        at org.postgresql.Driver$ConnectThread.run(Driver.java:325)
        at java.lang.Thread.run(Thread.java:748)


These threads were permanently stuck in the above state and they did not recover even after the network recovered

I checked the source code of the latest PostgreSQL JDBC library (42.2.5) and found the following code:
In class ConnectionFactoryImpl.java
Line 85:
  private PGStream tryConnect(String user, String database,
      Properties info, SocketFactory socketFactory, HostSpec hostSpec,
      SslMode sslMode)
      throws SQLException, IOException {
    int connectTimeout = PGProperty.CONNECT_TIMEOUT.getInt(info) * 1000;

    PGStream newStream = new PGStream(socketFactory, hostSpec, connectTimeout);

    // Construct and send an ssl startup packet if requested.
    newStream = enableSSL(newStream, sslMode, info, connectTimeout);

    // Set the socket timeout if the "socketTimeout" property has been set.
    int socketTimeout = PGProperty.SOCKET_TIMEOUT.getInt(info);
    if (socketTimeout > 0) {
      newStream.getSocket().setSoTimeout(socketTimeout * 1000);
    }



From what I see, the enableSSL method is called *before* the socket timeout is set, so when java.net.SocketInputStream.socketRead0 is called, it has no timeout and will wait infinitely for its peer to reply back. Which matches up with the behavior that I see in my stack trace.

Is this a bug?

Note: I’m aware that the stack trace that I supplied uses an older version of the JDBC library,  I’ve repeated the test with the latest library version and the issue persisted. I can run the tests again and supply the new stack trace if needed.

Can you file an issue on github https://github.com/pgjdbc/pgjdbc/issues

Thanks,

 

Thank you

В списке pgsql-jdbc по дате отправления:

Предыдущее
От: davecramer
Дата:
Сообщение: [pgjdbc/pgjdbc]
Следующее
От: Sehrope Sarkuni
Дата:
Сообщение: [pgjdbc/pgjdbc] 9b45e7: refactor: Clean up loading of reading ofkeydata f...