Ejemplo n.º 1
0
  private void flush0(
      final ChannelHandlerContext ctx, final int bytesConsumed, final Throwable cause) {
    ChannelFuture flushFuture =
        ctx.flush(
            ctx.newFuture()
                .addListener(
                    new ChannelFutureListener() {
                      @Override
                      public void operationComplete(ChannelFuture future) throws Exception {
                        if (ctx.executor() == ctx.channel().eventLoop()) {
                          notifyFlushFutures(bytesConsumed, cause, future);
                        } else {
                          synchronized (flushFutureNotifier) {
                            notifyFlushFutures(bytesConsumed, cause, future);
                          }
                        }
                      }

                      private void notifyFlushFutures(
                          int bytesConsumed, Throwable cause, ChannelFuture future) {
                        flushFutureNotifier.increaseWriteCounter(bytesConsumed);
                        if (future.isSuccess()) {
                          flushFutureNotifier.notifyFlushFutures(cause);
                        } else {
                          flushFutureNotifier.notifyFlushFutures(cause, future.cause());
                        }
                      }
                    }));

    safeClose(ctx, flushFuture, ctx.newFuture());
  }
Ejemplo n.º 2
0
  private void closeOutboundAndChannel(
      final ChannelHandlerContext ctx, final ChannelFuture future, boolean disconnect)
      throws Exception {
    if (!ctx.channel().isActive()) {
      if (disconnect) {
        ctx.disconnect(future);
      } else {
        ctx.close(future);
      }
      return;
    }

    engine.closeOutbound();

    ChannelFuture closeNotifyFuture = ctx.newFuture();
    flush(ctx, closeNotifyFuture);
    safeClose(ctx, closeNotifyFuture, future);
  }
Ejemplo n.º 3
0
  @Override
  public void inboundBufferUpdated(final ChannelHandlerContext ctx) throws Exception {
    final ByteBuf in = ctx.inboundByteBuffer();

    if (in.readableBytes() < 5) {
      return;
    }

    int packetLength = getEncryptedPacketLength(in);

    if (packetLength == -1) {
      // Bad data - discard the buffer and raise an exception.
      NotSslRecordException e =
          new NotSslRecordException("not an SSL/TLS record: " + ByteBufUtil.hexDump(in));
      in.skipBytes(in.readableBytes());
      ctx.fireExceptionCaught(e);
      setHandshakeFailure(e);
      return;
    }

    assert packetLength > 0;

    final ByteBuf out = ctx.nextInboundByteBuffer();
    out.discardReadBytes();

    boolean wrapLater = false;
    int bytesProduced = 0;
    try {
      loop:
      for (; ; ) {
        SSLEngineResult result = unwrap(engine, in, out);
        bytesProduced += result.bytesProduced();

        switch (result.getStatus()) {
          case CLOSED:
            // notify about the CLOSED state of the SSLEngine. See #137
            sslCloseFuture.setClosed();
            break;
          case BUFFER_UNDERFLOW:
            break loop;
        }

        switch (result.getHandshakeStatus()) {
          case NEED_UNWRAP:
            break;
          case NEED_WRAP:
            wrapLater = true;
            break;
          case NEED_TASK:
            runDelegatedTasks();
            break;
          case FINISHED:
            setHandshakeSuccess();
            wrapLater = true;
            continue;
          case NOT_HANDSHAKING:
            break;
          default:
            throw new IllegalStateException(
                "Unknown handshake status: " + result.getHandshakeStatus());
        }

        if (result.bytesConsumed() == 0 && result.bytesProduced() == 0) {
          break;
        }
      }

      if (wrapLater) {
        flush(ctx, ctx.newFuture());
      }
    } catch (SSLException e) {
      setHandshakeFailure(e);
      throw e;
    } finally {
      if (bytesProduced > 0) {
        in.discardReadBytes();
        ctx.fireInboundBufferUpdated();
      }
    }
  }
Ejemplo n.º 4
0
 /**
  * Sends an SSL {@code close_notify} message to the specified channel and destroys the underlying
  * {@link SSLEngine}.
  */
 public ChannelFuture close() {
   return close(ctx.newFuture());
 }
Ejemplo n.º 5
0
 /**
  * Starts the SSL / TLS handshake and returns a {@link ChannelFuture} that will get notified once
  * the handshake completes.
  */
 public ChannelFuture handshake() {
   return handshake(ctx.newFuture());
 }