xref: /aosp_15_r20/external/grpc-grpc/src/core/lib/transport/metadata_info.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2023 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_INFO_H
16 #define GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_INFO_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include "src/core/ext/transport/chttp2/transport/hpack_constants.h"
21 #include "src/core/lib/channel/call_tracer.h"
22 #include "src/core/lib/channel/channel_args.h"
23 #include "src/core/lib/transport/metadata_batch.h"
24 
25 namespace grpc_core {
26 
27 #define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
28 #define DEFAULT_MAX_HEADER_LIST_SIZE_SOFT_LIMIT (8 * 1024)
29 
GetSoftLimitFromChannelArgs(const ChannelArgs & args)30 inline uint32_t GetSoftLimitFromChannelArgs(const ChannelArgs& args) {
31   const int soft_limit = args.GetInt(GRPC_ARG_MAX_METADATA_SIZE).value_or(-1);
32   if (soft_limit < 0) {
33     // Set soft limit to 0.8 * hard limit if this is larger than
34     // `DEFAULT_MAX_HEADER_LIST_SIZE_SOFT_LIMIT` and
35     // `GRPC_ARG_MAX_METADATA_SIZE` is not set.
36     return std::max(
37         DEFAULT_MAX_HEADER_LIST_SIZE_SOFT_LIMIT,
38         static_cast<int>(
39             0.8 *
40             args.GetInt(GRPC_ARG_ABSOLUTE_MAX_METADATA_SIZE).value_or(-1)));
41   } else {
42     return soft_limit;
43   }
44 }
45 
GetHardLimitFromChannelArgs(const ChannelArgs & args)46 inline uint32_t GetHardLimitFromChannelArgs(const ChannelArgs& args) {
47   int hard_limit =
48       args.GetInt(GRPC_ARG_ABSOLUTE_MAX_METADATA_SIZE).value_or(-1);
49   if (hard_limit >= 0) {
50     return hard_limit;
51   } else {
52     // Set value to 1.25 * soft limit if this is larger than
53     // `DEFAULT_MAX_HEADER_LIST_SIZE` and
54     // `GRPC_ARG_ABSOLUTE_MAX_METADATA_SIZE` is not set.
55     const int soft_limit = args.GetInt(GRPC_ARG_MAX_METADATA_SIZE).value_or(-1);
56     const int value = (soft_limit >= 0 && soft_limit < (INT_MAX / 1.25))
57                           ? static_cast<int>(soft_limit * 1.25)
58                           : soft_limit;
59     return std::max(value, DEFAULT_MAX_HEADER_LIST_SIZE);
60   }
61 }
62 
63 class MetadataSizesAnnotation
64     : public CallTracerAnnotationInterface::Annotation {
65  public:
MetadataSizesAnnotation(grpc_metadata_batch * metadata_buffer,uint64_t soft_limit,uint64_t hard_limit)66   MetadataSizesAnnotation(grpc_metadata_batch* metadata_buffer,
67                           uint64_t soft_limit, uint64_t hard_limit)
68       : CallTracerAnnotationInterface::Annotation(
69             CallTracerAnnotationInterface::AnnotationType::kMetadataSizes),
70         metadata_buffer_(metadata_buffer),
71         soft_limit_(soft_limit),
72         hard_limit_(hard_limit) {}
73 
74   std::string ToString() const override;
75 
76  private:
77   class MetadataSizeEncoder;
78   grpc_metadata_batch* metadata_buffer_;
79   uint64_t soft_limit_;
80   uint64_t hard_limit_;
81 };
82 
83 }  // namespace grpc_core
84 
85 #endif  // GRPC_SRC_CORE_LIB_TRANSPORT_METADATA_INFO_H