Пример #1
0
 @Override
 public void inboundBufferUpdated(ChannelHandlerContext ctx) throws Exception {
   ByteBuf buf = ctx.inboundByteBuffer();
   if (logger.isEnabled(internalLevel)) {
     logger.log(internalLevel, format(ctx, formatBuffer("RECEIVED", buf)));
   }
   ctx.nextInboundByteBuffer().writeBytes(buf);
   ctx.fireInboundBufferUpdated();
 }
Пример #2
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();
      }
    }
  }
Пример #3
0
  @Override
  public void flush(final ChannelHandlerContext ctx, ChannelFuture future) throws Exception {
    final ByteBuf in = ctx.outboundByteBuffer();
    final ByteBuf out = ctx.nextOutboundByteBuffer();

    out.unsafe().discardSomeReadBytes();

    // Do not encrypt the first write request if this handler is
    // created with startTLS flag turned on.
    if (startTls && !sentFirstMessage) {
      sentFirstMessage = true;
      out.writeBytes(in);
      ctx.flush(future);
      return;
    }

    if (ctx.executor() == ctx.channel().eventLoop()) {
      flushFutureNotifier.addFlushFuture(future, in.readableBytes());
    } else {
      synchronized (flushFutureNotifier) {
        flushFutureNotifier.addFlushFuture(future, in.readableBytes());
      }
    }

    boolean unwrapLater = false;
    int bytesConsumed = 0;
    try {
      for (; ; ) {
        SSLEngineResult result = wrap(engine, in, out);
        bytesConsumed += result.bytesConsumed();
        if (result.getStatus() == Status.CLOSED) {
          // SSLEngine has been closed already.
          // Any further write attempts should be denied.
          if (in.readable()) {
            in.clear();
            SSLException e = new SSLException("SSLEngine already closed");
            future.setFailure(e);
            ctx.fireExceptionCaught(e);
            flush0(ctx, bytesConsumed, e);
            bytesConsumed = 0;
          }
          break;
        } else {
          switch (result.getHandshakeStatus()) {
            case NEED_WRAP:
              ctx.flush();
              continue;
            case NEED_UNWRAP:
              if (ctx.inboundByteBuffer().readable()) {
                unwrapLater = true;
              }
              break;
            case NEED_TASK:
              runDelegatedTasks();
              continue;
            case FINISHED:
              setHandshakeSuccess();
              continue;
            case NOT_HANDSHAKING:
              break;
            default:
              throw new IllegalStateException(
                  "Unknown handshake status: " + result.getHandshakeStatus());
          }

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

      if (unwrapLater) {
        inboundBufferUpdated(ctx);
      }
    } catch (SSLException e) {
      setHandshakeFailure(e);
      throw e;
    } finally {
      in.unsafe().discardSomeReadBytes();
      flush0(ctx, bytesConsumed);
    }
  }