Repository: envoyproxy/envoy
File: source/common/network/connection_impl.cc (C++)

Code before:

  // As the socket closes, drain any remaining data.
  // The data won't be written out at this point, and where there are reference
  // counted buffer fragments, it helps avoid lifetime issues with the
  // connection outlasting the subscriber.
  write_buffer_->drain(write_buffer_->length());

  connection_stats_.reset();

  if (detected_close_type_ == DetectedCloseType::RemoteReset ||
      detected_close_type_ == DetectedCloseType::LocalReset) {
#if ENVOY_PLATFORM_ENABLE_SEND_RST
    const bool ok = Network::Socket::applyOptions(
        Network::SocketOptionFactory::buildZeroSoLingerOptions(), *socket_,
        envoy::config::core::v3::SocketOption::STATE_LISTENING);
    if (!ok) {
      ENVOY_LOG_EVERY_POW_2(error, "rst setting so_linger=0 failed on connection {}", id());
    }
#endif
  }

  // It is safe to call close() since there is an IO handle check.
  socket_->close();

  // Propagate transport failure reason to StreamInfo before raising close events,
  // ensuring it's available to all filters and access loggers.
  stream_info_.setDownstreamTransportFailureReason(transportFailureReason());

  // Call the base class directly as close() is called in the destructor.
  ConnectionImpl::raiseEvent(close_type);
}

void ConnectionImpl::onConnected() {
  ASSERT(!connecting_);
  transport_socket_->onConnected();
}

void ConnectionImpl::noDelay(bool enable) {
  // There are cases where a connection to localhost can immediately fail (e.g., if the other end
  // does not have enough fds, reaches a backlog limit, etc.). Because we run with deferred error
  // events, the calling code may not yet know that the connection has failed. This is one call
  // where we go outside of libevent and hit the fd directly and this case can fail if the fd is
  // invalid. For this call instead of plumbing through logic that will immediately indicate that a
  // connect failed, we will just ignore the noDelay() call if the socket is invalid since error is
  // going to be raised shortly anyway and it makes the calling code simpler.
  if (!socket_->isOpen()) {
    return;
  }

  // Don't set NODELAY for unix domain sockets or internal socket.
  if (socket_->addressType() != Address::Type::Ip) {

Review comment (suggestion):
The HCM access loggers will still not access this connection stream info, could explicitly mention it.

Code after:

  // As the socket closes, drain any remaining data.
  // The data won't be written out at this point, and where there are reference
  // counted buffer fragments, it helps avoid lifetime issues with the
  // connection outlasting the subscriber.
  write_buffer_->drain(write_buffer_->length());

  connection_stats_.reset();

  if (detected_close_type_ == DetectedCloseType::RemoteReset ||
      detected_close_type_ == DetectedCloseType::LocalReset) {
#if ENVOY_PLATFORM_ENABLE_SEND_RST
    const bool ok = Network::Socket::applyOptions(
        Network::SocketOptionFactory::buildZeroSoLingerOptions(), *socket_,
        envoy::config::core::v3::SocketOption::STATE_LISTENING);
    if (!ok) {
      ENVOY_LOG_EVERY_POW_2(error, "rst setting so_linger=0 failed on connection {}", id());
    }
#endif
  }

  // It is safe to call close() since there is an IO handle check.
  socket_->close();

  // Propagate transport failure reason to StreamInfo before raising close events,
  // ensuring it's available to all filters and access loggers.
  // Only set if we have a valid failure reason to avoid accessing potentially invalid state.
  absl::string_view failure_reason = transportFailureReason();
  if (!failure_reason.empty()) {
    stream_info_.setDownstreamTransportFailureReason(failure_reason);
  }

  // Call the base class directly as close() is called in the destructor.
  ConnectionImpl::raiseEvent(close_type);
}

void ConnectionImpl::onConnected() {
  ASSERT(!connecting_);
  transport_socket_->onConnected();
}

void ConnectionImpl::noDelay(bool enable) {
  // There are cases where a connection to localhost can immediately fail (e.g., if the other end
  // does not have enough fds, reaches a backlog limit, etc.). Because we run with deferred error
  // events, the calling code may not yet know that the connection has failed. This is one call
  // where we go outside of libevent and hit the fd directly and this case can fail if the fd is
  // invalid. For this call instead of plumbing through logic that will immediately indicate that a
  // connect failed, we will just ignore the noDelay() call if the socket is invalid since error is
  // going to be raised shortly anyway and it makes the calling code simpler.
  if (!socket_->isOpen()) {
    return;