// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifdef UNSAFE_BUFFERS_BUILD // TODO(crbug.com/40284755): Remove this and spanify to fix the errors. #pragma allow_unsafe_buffers #endif #ifndef NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_ #define NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_ #include <cstdint> #include "base/check.h" #include "base/notreached.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #if BUILDFLAG(IS_ANDROID) #include "base/android/scoped_java_ref.h" #endif namespace { // Recursively compute hash code of the given string as a constant expression. template <int N> constexpr uint32_t recursive_hash(const char* str) { … } // Recursion stopper for the above function. Note that string of size 0 will // result in compile error. template <> constexpr uint32_t recursive_hash<1>(const char* str) { … } // Entry point to function that computes hash as constant expression. #define COMPUTE_NETWORK_TRAFFIC_ANNOTATION_ID_HASH(S) … constexpr int TRAFFIC_ANNOTATION_UNINITIALIZED = …; } // namespace namespace net { struct PartialNetworkTrafficAnnotationTag; // Defined types for network traffic annotation tags. struct NetworkTrafficAnnotationTag { … }; struct PartialNetworkTrafficAnnotationTag { … }; // Function to convert a network traffic annotation's unique id and protobuf // text into a NetworkTrafficAnnotationTag. // // This function serves as a tag that can be discovered and extracted via // clang tools. This allows reviewing all network traffic that is generated // and annotated by Chrome. // // |unique_id| should be a string that uniquely identifies this annotation // across all of Chromium source code. |unique_id| should be kept unchanged // as long as possible as its hashed value will be used for differnt logging, // debugging, or auditing tasks. Unique ids should include only alphanumeric // characters and underline. // |proto| is a text-encoded NetworkTrafficAnnotation protobuf (see // chrome/browser/privacy/traffic_annotation.proto) // // An empty and a sample template for the text-encoded protobuf can be found in // tools/traffic_annotation/sample_traffic_annotation.cc. // TODO(crbug.com/40505662): Add tools to check annotation text's format during // presubmit checks. template <size_t N1, size_t N2> constexpr NetworkTrafficAnnotationTag DefineNetworkTrafficAnnotation( const char (&unique_id)[N1], const char (&proto)[N2]) { … } // There are cases where the network traffic annotation cannot be fully // specified in one place. For example, in one place we know the trigger of a // network request and in another place we know the data that will be sent. In // these cases, we prefer that both parts of the annotation appear in context so // that they are updated if code changes. The following functions help splitting // the network traffic annotation into two pieces. Please refer to // tools/traffic_annotation/sample_traffic_annotation.cc for usage samples. // This function can be used to define a partial annotation that will be // completed later. The completing annotation can be defined with either of // 'CompleteNetworkTrafficAnnotation' or // 'BranchedCompleteNetworkTrafficAnnotation' functions. In case of // CompleteNetworkTrafficAnnotation, |completing_id| is the unique id of the // annotation that will complete it. In the case of // BranchedCompleteNetworkTrafficAnnotation, |completing_id| is the group id // of the completing annotations. template <size_t N1, size_t N2, size_t N3> constexpr PartialNetworkTrafficAnnotationTag DefinePartialNetworkTrafficAnnotation(const char (&unique_id)[N1], const char (&completing_id)[N2], const char (&proto)[N3]) { … } // This function can be used to define a completing partial annotation. This // annotation adds details to another annotation that is defined before. // |partial_annotation| is the PartialNetworkTrafficAnnotationTag returned // by a call to DefinePartialNetworkTrafficAnnotation(). template <size_t N1, size_t N2> NetworkTrafficAnnotationTag CompleteNetworkTrafficAnnotation( const char (&unique_id)[N1], const PartialNetworkTrafficAnnotationTag& partial_annotation, const char (&proto)[N2]) { … } // This function can be used to define a completing partial annotation that is // branched into several annotations. In this case, |group_id| is a common id // that is used by all members of the branch and referenced by partial // annotation that is completed by them. template <size_t N1, size_t N2, size_t N3> NetworkTrafficAnnotationTag BranchedCompleteNetworkTrafficAnnotation( const char (&unique_id)[N1], const char (&group_id)[N2], const PartialNetworkTrafficAnnotationTag& partial_annotation, const char (&proto)[N3]) { … } // Example for joining N x 1 partial annotations: // N functions foo1(), ..., fooN() call one function bar(). Each // foo...() function defines part of a network traffic annotation. // These N partial annotations are combined with a second part in // bar(). // // void foo1() { // auto tag = DefinePartialNetworkTrafficAnnotation( // "call_by_foo1", "completion_by_bar", [partial_proto]); // bar(tag); // } // void foo2() { // auto tag = DefinePartialNetworkTrafficAnnotation( // "call_by_foo2", "completion_by_bar", [partial_proto]); // bar(tag); // } // void bar(PartialNetworkTrafficAnnotationTag tag) { // auto final_tag = CompleteNetworkTrafficAnnotation( // "completion_by_bar", tag, [rest_of_proto]); // // final_tag matches the value of tag (which is hash code of // // "call_by_fooX" where X can be 1 or 2). // net::URLFetcher::Create(..., final_tag); // } // Example for joining 1 x N partial annotations: // A function foo() calls a function bar(bool param), that sends // different network requests depending on param. Both functions // define parts of the network traffic annotation. // // void foo(bool param) { // auto tag = DefinePartialNetworkTrafficAnnotation( // "call_by_foo1", "completion_by_bar", [partial_proto]); // bar(param, tag); // } // void bar(bool param, PartialNetworkTrafficAnnotationTag tag) { // if (param) { // auto final_tag = BranchedCompleteNetworkTrafficAnnotation( // "call_bool_branch_1", "completion_by_bar", tag, [rest_of_proto]); // // final_tag is hash code of "call_bool_branch_1". // net::URLFetcher::Create(url1, ..., final_tag); // } else { // auto final_tag = BranchedCompleteNetworkTrafficAnnotation( // "call_bool_branch_2", "completion_by_bar", tag, [rest_of_proto]); // // final_tag is hash code of "call_bool_branch_2". // net::URLFetcher::Create(url2, ..., final_tag); // } // } // Please do not use this unless uninitialized annotations are required. // Mojo interfaces for this class and the next one are defined in // '/services/network/public/mojom'. struct MutableNetworkTrafficAnnotationTag { … }; inline MutableNetworkTrafficAnnotationTag CreateMutableNetworkTrafficAnnotationTag(int32_t unique_id_hash_code) { … } struct MutablePartialNetworkTrafficAnnotationTag { … }; } // namespace net // Placeholder for unannotated usages. #if !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) #define TRAFFIC_ANNOTATION_WITHOUT_PROTO … #endif // These annotations are unavailable on desktop Linux + Windows. They are // available on other platforms, since we only audit network annotations on // Linux & Windows. // // On Linux and Windows, use MISSING_TRAFFIC_ANNOTATION or // TRAFFIC_ANNOTATION_FOR_TESTS. // TODO(crbug.com/40118868): Revisit once build flag switch of lacros-chrome is // complete. #if !BUILDFLAG(IS_WIN) && \ !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) #define NO_TRAFFIC_ANNOTATION_YET … #endif #define MISSING_TRAFFIC_ANNOTATION … #endif // NET_TRAFFIC_ANNOTATION_NETWORK_TRAFFIC_ANNOTATION_H_