Repository: envoyproxy/envoy
File: source/extensions/filters/network/reverse_tunnel/reverse_tunnel_filter.cc (C++)

Code before:

  // Extract node/cluster/tenant identifiers from HTTP headers.
  const auto node_vals =
      headers_->get(Extensions::Bootstrap::ReverseConnection::reverseTunnelNodeIdHeader());
  const auto cluster_vals =
      headers_->get(Extensions::Bootstrap::ReverseConnection::reverseTunnelClusterIdHeader());
  const auto tenant_vals =
      headers_->get(Extensions::Bootstrap::ReverseConnection::reverseTunnelTenantIdHeader());

  if (node_vals.empty() || cluster_vals.empty() || tenant_vals.empty()) {
    parent_.stats_.parse_error_.inc();
    ENVOY_CONN_LOG(debug, "reverse_tunnel: missing required headers (node/cluster/tenant)",
                   parent_.read_callbacks_->connection());
    sendLocalReply(Http::Code::BadRequest, "Missing required reverse tunnel headers", nullptr,
                   absl::nullopt, "reverse_tunnel_missing_headers");
    // Close the connection after sending the response.
    parent_.read_callbacks_->connection().close(Network::ConnectionCloseType::FlushWrite);
    return;
  }

  const absl::string_view node_id = node_vals[0]->value().getStringView();
  const absl::string_view cluster_id = cluster_vals[0]->value().getStringView();
  const absl::string_view tenant_id = tenant_vals[0]->value().getStringView();

  // Check for upstream cluster name header and validate if enforcement is enabled.
  if (parent_.config_->enforceClusterMatch() && !parent_.config_->name().empty()) {
    const auto upstream_cluster_vals = headers_->get(
        Extensions::Bootstrap::ReverseConnection::reverseTunnelUpstreamClusterNameHeader());

    if (upstream_cluster_vals.empty()) {
      parent_.stats_.parse_error_.inc();
      ENVOY_CONN_LOG(
          debug, "reverse_tunnel: missing upstream cluster name header when enforcement is enabled",
          parent_.read_callbacks_->connection());
      sendLocalReply(Http::Code::BadRequest, "Missing upstream cluster name", nullptr,
                     absl::nullopt, "reverse_tunnel_missing_cluster_name");
      parent_.read_callbacks_->connection().close(Network::ConnectionCloseType::FlushWrite);
      return;
    }

    const absl::string_view upstream_cluster_name =
        upstream_cluster_vals[0]->value().getStringView();
    if (upstream_cluster_name != parent_.config_->name()) {
      parent_.stats_.validation_failed_.inc();
      ENVOY_CONN_LOG(
          debug, "reverse_tunnel: upstream cluster name mismatch. Expected: '{}', Actual: '{}'",
          parent_.read_callbacks_->connection(), parent_.config_->name(), upstream_cluster_name);
      sendLocalReply(Http::Code::BadRequest, "Cluster name mismatch", nullptr, absl::nullopt,
                     "reverse_tunnel_cluster_mismatch");
      parent_.read_callbacks_->connection().close(Network::ConnectionCloseType::FlushWrite);
      return;

Review comment (suggestion):
We need to handle the case where enforce_cluster_match = true but name is not set. We can log a warning and set it to a default, "responder-envoy".

Code after:
    parent_.read_callbacks_->connection().close(Network::ConnectionCloseType::FlushWrite);
    return;
  }

  // Extract node/cluster/tenant identifiers from HTTP headers.
  const auto node_vals =
      headers_->get(Extensions::Bootstrap::ReverseConnection::reverseTunnelNodeIdHeader());
  const auto cluster_vals =
      headers_->get(Extensions::Bootstrap::ReverseConnection::reverseTunnelClusterIdHeader());
  const auto tenant_vals =
      headers_->get(Extensions::Bootstrap::ReverseConnection::reverseTunnelTenantIdHeader());

  if (node_vals.empty() || cluster_vals.empty() || tenant_vals.empty()) {
    parent_.stats_.parse_error_.inc();
    ENVOY_CONN_LOG(debug, "reverse_tunnel: missing required headers (node/cluster/tenant)",
                   parent_.read_callbacks_->connection());
    sendLocalReply(Http::Code::BadRequest, "Missing required reverse tunnel headers", nullptr,
                   absl::nullopt, "reverse_tunnel_missing_headers");
    // Close the connection after sending the response.
    parent_.read_callbacks_->connection().close(Network::ConnectionCloseType::FlushWrite);
    return;
  }

  const absl::string_view node_id = node_vals[0]->value().getStringView();
  const absl::string_view cluster_id = cluster_vals[0]->value().getStringView();
  const absl::string_view tenant_id = tenant_vals[0]->value().getStringView();

  // Check for upstream cluster name header and validate if required.
  if (!parent_.config_->requiredClusterName().empty()) {
    const auto upstream_cluster_vals = headers_->get(
        Extensions::Bootstrap::ReverseConnection::reverseTunnelUpstreamClusterNameHeader());

    if (upstream_cluster_vals.empty()) {
      parent_.stats_.parse_error_.inc();
      ENVOY_CONN_LOG(
          debug, "reverse_tunnel: missing upstream cluster name header when enforcement is enabled",
          parent_.read_callbacks_->connection());
      sendLocalReply(Http::Code::BadRequest, "Missing upstream cluster name header", nullptr,
                     absl::nullopt, "reverse_tunnel_missing_cluster_name_header");
      parent_.read_callbacks_->connection().close(Network::ConnectionCloseType::FlushWrite);
      return;
    }

    const absl::string_view upstream_cluster_name =
        upstream_cluster_vals[0]->value().getStringView();
    if (upstream_cluster_name != parent_.config_->requiredClusterName()) {
      parent_.stats_.validation_failed_.inc();
      ENVOY_CONN_LOG(debug,
                     "reverse_tunnel: upstream cluster name mismatch. Expected: '{}', Actual: '{}'",
                     parent_.read_callbacks_->connection(), parent_.config_->requiredClusterName(),
                     upstream_cluster_name);