RFR [13] JDK-8224829 : AsyncSSLSocketClose.java has timing issue

Daniel Fuchs daniel.fuchs at oracle.com
Wed Jun 12 15:19:04 UTC 2019


Hi Xuelei,

I am not an expert of the field so please get another
reviewer for this change:

  656                     if (!super.isOutputShutdown() &&
                          ...
  661                     } else if (!super.isOutputShutdown()) {

I think it might be clearer with a nested if:

    if (!super.isOutputShutdown()) {
        if (isLayered() && !autoClose) {
            throw exception ...
        } else {
            super.shutdownOutput();
            log ...
        }
    }

Could lines 630 .. 647 be moved to a private method?
Something like:

      private void handleClosedNotifyAlert() {
  630     try {
              // send a user_canceled alert if needed.
              if (useUserCanceled) {
                  conContext.warning(Alert.USER_CANCELED);
              }

              // send a close_notify alert
              conContext.warning(Alert.CLOSE_NOTIFY);
          } finally {
              if (!conContext.isOutboundClosed()) {
                  conContext.outputRecord.close();
              }

              if (!super.isOutputShutdown() &&
                      (autoClose || !isLayered())) {
                  super.shutdownOutput();
  647         }
           }
       }

because if I'm not mistaken this exact same piece of code
appears at lines 700 - 717.

I believe this would simplify this long method a little bit,
and possibly makes what is happening here clearer:

  623     if (linger >= 0) {
             // don't wait more than SO_LINGER for obtaining the
             // the lock...
              ...
  626         try {
  627             if (conContext.outputRecord.recordLock.tryLock() ||
  628                     conContext.outputRecord.recordLock.tryLock(
  629                             linger, TimeUnit.SECONDS)) {
                      try {
                          handleClosedNotifyAlert();
                      } finally {
                          conContext.outputRecord.recordLock.unlock();
                      }
  652             } else {
  653                 // For layered, non-autoclose sockets, we are not
  654                 // able to bring them into a usable state, so we
  655                 // treat it as fatal error.
                      ...
  688             }
  689         } catch (InterruptedException ex) {
                ...
  692         }
  693
  694         // restore the interrupted status
              ...
  698     } else {
  699         conContext.outputRecord.recordLock.lock();
  700         try {
                  handleClosedNotifyAlert();
              } finally {
                  conContext.outputRecord.recordLock.unlock();
              }
           }
           ...


BlockedAsyncClose.java:

    Can you bind the server to the loopback instead of the
    wildcard? My experience is that it make tests more reliable.

              InetAddress loopback = InetAddress.getLoopbackAddress();
   74         ss = (SSLServerSocket) sslssf.createServerSocket();
              ss.bind(new InetSosketAddress(loopback, 0));
   75
   76         SSLSocketFactory sslsf =
   77             (SSLSocketFactory)SSLSocketFactory.getDefault();
              socket = (SSLSocket)sslsf.createSocket(loopback, 
ss.getLocalPort());


best regards,

-- daniel

On 12/06/2019 14:51, Xuelei Fan wrote:
> ping ...
> 
> On 6/4/2019 11:10 AM, Xuelei Fan wrote:
>> Hi,
>>
>> Could I get the following update reviewed?
>>     http://cr.openjdk.java.net/~xuelei/8224829/webrev.00/
>>
>> If using one thread for closing, one thread for writing.  Closing and 
>> writing threads are synchronized in order to delivery close_notify TLS 
>> record.  There are could be race between the two threads.  If the 
>> output stream buffer reach the limit, the write will be blocked, and 
>> then the close thread may be pending.
>>
>> The SO_LINGER is used to resolve the issue for general socket.  With 
>> the above update, the SSLSocket implementation will check the 
>> SO_LINGER as well.  If SO_LINGER is on, the SSLSocket close will try 
>> to get the synchronization lock in the time of SO_LINGER value.  If 
>> timeout, the close process will move on, and close the underlying 
>> socket by force.
>>
>> Thanks,
>> Xuelei




More information about the security-dev mailing list