|
22 | 22 | import java.net.InetSocketAddress; |
23 | 23 | import java.util.ArrayList; |
24 | 24 | import java.util.List; |
| 25 | +import java.util.concurrent.atomic.AtomicBoolean; |
25 | 26 |
|
26 | 27 | import javax.net.ssl.SSLContext; |
27 | 28 | import javax.net.ssl.SSLEngine; |
@@ -497,59 +498,69 @@ public void messageReceived(NextFilter nextFilter, IoSession session, Object mes |
497 | 498 | } |
498 | 499 |
|
499 | 500 | SslHandler sslHandler = getSslSessionHandler(session); |
| 501 | + AtomicBoolean canPushMessage = new AtomicBoolean( false ); |
| 502 | + |
| 503 | + // The SslHandler instance is *guaranteed* to nit be null here |
500 | 504 |
|
501 | | - synchronized (sslHandler) { |
502 | | - if (!isSslStarted(session) && sslHandler.isInboundDone()) { |
503 | | - // The SSL session must be established first before we |
504 | | - // can push data to the application. Store the incoming |
505 | | - // data into a queue for a later processing |
506 | | - sslHandler.scheduleMessageReceived(nextFilter, message); |
507 | | - } else { |
508 | | - IoBuffer buf = (IoBuffer) message; |
509 | | - |
510 | | - try { |
511 | | - if (sslHandler.isOutboundDone()) { |
512 | | - sslHandler.destroy(); |
513 | | - throw new SSLException("Outbound done"); |
514 | | - } |
515 | | - |
516 | | - // forward read encrypted data to SSL handler |
517 | | - sslHandler.messageReceived(nextFilter, buf.buf()); |
518 | | - |
519 | | - // Handle data to be forwarded to application or written to net |
520 | | - handleSslData(nextFilter, sslHandler); |
521 | | - |
522 | | - if (sslHandler.isInboundDone()) { |
523 | | - if (sslHandler.isOutboundDone()) { |
524 | | - sslHandler.destroy(); |
525 | | - } else { |
526 | | - initiateClosure(nextFilter, session); |
527 | | - } |
528 | | - |
529 | | - if (buf.hasRemaining()) { |
530 | | - // Forward the data received after closure. |
531 | | - sslHandler.scheduleMessageReceived(nextFilter, buf); |
532 | | - } |
533 | | - } |
534 | | - } catch (SSLException ssle) { |
535 | | - if (!sslHandler.isHandshakeComplete()) { |
536 | | - SSLException newSsle = new SSLHandshakeException("SSL handshake failed."); |
537 | | - newSsle.initCause(ssle); |
538 | | - ssle = newSsle; |
539 | | - |
540 | | - // Close the session immediately, the handshake has failed |
541 | | - session.closeNow(); |
542 | | - } else { |
543 | | - // Free the SSL Handler buffers |
544 | | - sslHandler.release(); |
545 | | - } |
546 | | - |
547 | | - throw ssle; |
548 | | - } |
549 | | - } |
550 | | - } |
551 | | - |
552 | | - sslHandler.flushMessageReceived(); |
| 505 | + synchronized (sslHandler) { |
| 506 | + if (sslHandler.isOutboundDone() && sslHandler.isInboundDone()) { |
| 507 | + // We aren't handshaking here. Let's push the message to the next filter |
| 508 | + |
| 509 | + // Note: we can push the message to the queue immediately, |
| 510 | + // but don't do so in the synchronized block. We use a protected |
| 511 | + // flag to do so. |
| 512 | + canPushMessage.set( true ); |
| 513 | + } else { |
| 514 | + canPushMessage.set( false ); |
| 515 | + IoBuffer buf = (IoBuffer) message; |
| 516 | + |
| 517 | + try { |
| 518 | + if (sslHandler.isOutboundDone()) { |
| 519 | + sslHandler.destroy(); |
| 520 | + throw new SSLException("Outbound done"); |
| 521 | + } |
| 522 | + |
| 523 | + // forward read encrypted data to SSL handler |
| 524 | + sslHandler.messageReceived(nextFilter, buf.buf()); |
| 525 | + |
| 526 | + // Handle data to be forwarded to application or written to net |
| 527 | + handleSslData(nextFilter, sslHandler); |
| 528 | + |
| 529 | + if (sslHandler.isInboundDone()) { |
| 530 | + if (sslHandler.isOutboundDone()) { |
| 531 | + sslHandler.destroy(); |
| 532 | + } else { |
| 533 | + initiateClosure(nextFilter, session); |
| 534 | + } |
| 535 | + |
| 536 | + if (buf.hasRemaining()) { |
| 537 | + // Forward the data received after closure. |
| 538 | + sslHandler.scheduleMessageReceived(nextFilter, buf); |
| 539 | + } |
| 540 | + } |
| 541 | + } catch (SSLException ssle) { |
| 542 | + if (!sslHandler.isHandshakeComplete()) { |
| 543 | + SSLException newSsle = new SSLHandshakeException("SSL handshake failed."); |
| 544 | + newSsle.initCause(ssle); |
| 545 | + ssle = newSsle; |
| 546 | + |
| 547 | + // Close the session immediately, the handshake has failed |
| 548 | + session.closeNow(); |
| 549 | + } else { |
| 550 | + // Free the SSL Handler buffers |
| 551 | + sslHandler.release(); |
| 552 | + } |
| 553 | + |
| 554 | + throw ssle; |
| 555 | + } |
| 556 | + } |
| 557 | + } |
| 558 | + |
| 559 | + if (canPushMessage.get()) { |
| 560 | + nextFilter.messageReceived(session, message); |
| 561 | + } else { |
| 562 | + sslHandler.flushMessageReceived(); |
| 563 | + } |
553 | 564 | } |
554 | 565 |
|
555 | 566 | @Override |
|
0 commit comments