xDS: NACK EDS if sum of locality weights in a priority exceeds uint32 max (#31272)

* xDS: NACK EDS if sum of locality weights in a priority exceeds uint32 max

* clang-format

* iwyu

* fix include order

* more iwyu
pull/31244/head
Mark D. Roth 2 years ago committed by GitHub
parent 63104ed440
commit a848bc919b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      src/core/ext/xds/xds_endpoint.cc
  2. 42
      test/core/xds/xds_endpoint_resource_type_test.cc

@ -21,6 +21,7 @@
#include <stdlib.h>
#include <algorithm>
#include <limits>
#include <vector>
#include "absl/status/status.h"
@ -366,6 +367,19 @@ absl::StatusOr<XdsEndpointResource> EdsResourceParse(
const auto& priority = eds_resource.priorities[i];
if (priority.localities.empty()) {
errors.AddError(absl::StrCat("priority ", i, " empty"));
} else {
// Check that the sum of the locality weights in this priority
// does not exceed the max value for a uint32.
uint64_t total_weight = 0;
for (const auto& p : priority.localities) {
total_weight += p.second.lb_weight;
if (total_weight > std::numeric_limits<uint32_t>::max()) {
errors.AddError(
absl::StrCat("sum of locality weights for priority ", i,
" exceeds uint32 max"));
break;
}
}
}
}
}

@ -14,6 +14,9 @@
// limitations under the License.
//
#include <stdint.h>
#include <limits>
#include <map>
#include <memory>
#include <string>
@ -610,6 +613,45 @@ TEST_F(XdsEndpointTest, SparsePriorityList) {
<< decode_result.resource.status();
}
TEST_F(XdsEndpointTest, LocalityWeightsWithinPriorityExceedUint32Max) {
ClusterLoadAssignment cla;
cla.set_cluster_name("foo");
// First locality has weight of 1.
auto* locality = cla.add_endpoints();
locality->mutable_load_balancing_weight()->set_value(1);
auto* locality_name = locality->mutable_locality();
locality_name->set_region("myregion");
locality_name->set_zone("myzone");
locality_name->set_sub_zone("mysubzone");
auto* socket_address = locality->add_lb_endpoints()
->mutable_endpoint()
->mutable_address()
->mutable_socket_address();
socket_address->set_address("127.0.0.1");
socket_address->set_port_value(443);
locality->set_priority(0);
// Second locality has weight of uint32 max.
locality = cla.add_endpoints();
*locality = cla.endpoints(0); // Copy first locality.
locality->mutable_locality()->set_region("myregion2");
locality->mutable_load_balancing_weight()->set_value(
std::numeric_limits<uint32_t>::max());
std::string serialized_resource;
ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
auto* resource_type = XdsEndpointResourceType::Get();
auto decode_result = resource_type->Decode(
decode_context_, serialized_resource, /*is_v2=*/false);
ASSERT_TRUE(decode_result.name.has_value());
EXPECT_EQ(*decode_result.name, "foo");
EXPECT_EQ(decode_result.resource.status().code(),
absl::StatusCode::kInvalidArgument);
EXPECT_EQ(decode_result.resource.status().message(),
"errors parsing EDS resource: ["
"field:endpoints error:sum of locality weights for priority 0 "
"exceeds uint32 max]")
<< decode_result.resource.status();
}
TEST_F(XdsEndpointTest, DropConfig) {
ClusterLoadAssignment cla;
cla.set_cluster_name("foo");

Loading…
Cancel
Save