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

Xuelei Fan xuelei.fan at oracle.com
Thu Jun 13 19:59:29 UTC 2019


Hi Daniel,

All good points.  Here is the update webrev:
   http://cr.openjdk.java.net/~xuelei/8224829/webrev.01/

Thanks,
Xuelei

On 6/12/2019 8:19 AM, Daniel Fuchs wrote:
> 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