@Override public void run() { if (promise.isDone()) { // Received a response before the query times out. return; } setFailure("query timed out after " + queryTimeoutMillis + " milliseconds", null); } }, queryTimeoutMillis, TimeUnit.MILLISECONDS);
@Override public void run() { if (promise.isDone()) { return; } try { notifyHandshakeFailure(HANDSHAKE_TIMED_OUT); } finally { releaseAndFailAll(HANDSHAKE_TIMED_OUT); } } }, handshakeTimeoutMillis, TimeUnit.MILLISECONDS);
@Override public void read(ChannelHandlerContext ctx) throws Exception { if (!handshakePromise.isDone()) { readDuringHandshake = true; } ctx.read(); }
/** * Works around some Android {@link SSLEngine} implementations that skip {@link HandshakeStatus#FINISHED} and * go straight into {@link HandshakeStatus#NOT_HANDSHAKING} when handshake is finished. * * @return {@code true} if and only if the workaround has been applied and thus {@link #handshakeFuture} has been * marked as success by this method */ private boolean setHandshakeSuccessIfStillHandshaking() { if (!handshakePromise.isDone()) { setHandshakeSuccess(); return true; } return false; }
private void readIfNeeded(ChannelHandlerContext ctx) { // If handshake is not finished yet, we need more data. if (!ctx.channel().config().isAutoRead() && (!firedChannelRead || !handshakePromise.isDone())) { // No auto-read used and no message passed through the ChannelPipeline or the handshake was not complete // yet, which means we need to trigger the read to ensure we not encounter any stalls. ctx.read(); } }
private void applyHandshakeTimeout(Promise<Channel> p) { final Promise<Channel> promise = p == null ? handshakePromise : p; // Set timeout if necessary. final long handshakeTimeoutMillis = this.handshakeTimeoutMillis; if (handshakeTimeoutMillis <= 0 || promise.isDone()) { return; } final ScheduledFuture<?> timeoutFuture = ctx.executor().schedule(new Runnable() { @Override public void run() { if (promise.isDone()) { return; } try { notifyHandshakeFailure(HANDSHAKE_TIMED_OUT); } finally { releaseAndFailAll(HANDSHAKE_TIMED_OUT); } } }, handshakeTimeoutMillis, TimeUnit.MILLISECONDS); // Cancel the handshake timeout when handshake is finished. promise.addListener(new FutureListener<Channel>() { @Override public void operationComplete(Future<Channel> f) throws Exception { timeoutFuture.cancel(false); } }); }
private void wrapAndFlush(ChannelHandlerContext ctx) throws SSLException { if (pendingUnencryptedWrites.isEmpty()) { // It's important to NOT use a voidPromise here as the user // may want to add a ChannelFutureListener to the ChannelPromise later. // // See https://github.com/netty/netty/issues/3364 pendingUnencryptedWrites.add(Unpooled.EMPTY_BUFFER, ctx.newPromise()); } if (!handshakePromise.isDone()) { flushedBeforeHandshake = true; } try { wrap(ctx, false); } finally { // We may have written some parts of data before an exception was thrown so ensure we always flush. // See https://github.com/netty/netty/issues/3900#issuecomment-172481830 forceFlush(ctx); } }
@Override public void operationComplete(Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> future) { queriesInProgress.remove(future); if (promise.isDone() || future.isCancelled()) { queryLifecycleObserver.queryCancelled(allowedQueries); return; } try { if (future.isSuccess()) { onResponse(nameServerAddrStream, nameServerAddrStreamIndex, question, future.getNow(), queryLifecycleObserver, promise); } else { // Server did not respond or I/O error occurred; try again. queryLifecycleObserver.queryFailed(future.cause()); query(nameServerAddrStream, nameServerAddrStreamIndex + 1, question, promise); } } finally { tryToFinishResolve(nameServerAddrStream, nameServerAddrStreamIndex, question, // queryLifecycleObserver has already been terminated at this point so we must // not allow it to be terminated again by tryToFinishResolve. NoopDnsQueryLifecycleObserver.INSTANCE, promise); } } });