|  | @@ -22,6 +22,8 @@
 | 
	
		
			
				|  |  |  #include <cctype>
 | 
	
		
			
				|  |  |  #include <cstdlib>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#include "absl/strings/str_cat.h"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  #include <grpc/impl/codegen/log.h>
 | 
	
		
			
				|  |  |  #include <grpc/support/alloc.h>
 | 
	
		
			
				|  |  |  #include <grpc/support/string_util.h>
 | 
	
	
		
			
				|  | @@ -123,6 +125,10 @@ const char* XdsApi::kCdsTypeUrl = "type.googleapis.com/envoy.api.v2.Cluster";
 | 
	
		
			
				|  |  |  const char* XdsApi::kEdsTypeUrl =
 | 
	
		
			
				|  |  |      "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment";
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +XdsApi::XdsApi(const XdsBootstrap::Node* node)
 | 
	
		
			
				|  |  | +    : node_(node),
 | 
	
		
			
				|  |  | +      user_agent_name_(absl::StrCat("gRPC C-core ", GPR_PLATFORM_STRING)) {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  namespace {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void PopulateMetadataValue(upb_arena* arena, google_protobuf_Value* value_pb,
 | 
	
	
		
			
				|  | @@ -185,7 +191,8 @@ void PopulateMetadataValue(upb_arena* arena, google_protobuf_Value* value_pb,
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void PopulateNode(upb_arena* arena, const XdsBootstrap::Node* node,
 | 
	
		
			
				|  |  | -                  const char* build_version, const std::string& server_name,
 | 
	
		
			
				|  |  | +                  const std::string& user_agent_name,
 | 
	
		
			
				|  |  | +                  const std::string& server_name,
 | 
	
		
			
				|  |  |                    envoy_api_v2_core_Node* node_msg) {
 | 
	
		
			
				|  |  |    if (node != nullptr) {
 | 
	
		
			
				|  |  |      if (!node->id.empty()) {
 | 
	
	
		
			
				|  | @@ -231,8 +238,15 @@ void PopulateNode(upb_arena* arena, const XdsBootstrap::Node* node,
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  envoy_api_v2_core_Node_set_build_version(node_msg,
 | 
	
		
			
				|  |  | -                                           upb_strview_makez(build_version));
 | 
	
		
			
				|  |  | +  std::string build_version =
 | 
	
		
			
				|  |  | +      absl::StrCat(user_agent_name, " ", grpc_version_string());
 | 
	
		
			
				|  |  | +  envoy_api_v2_core_Node_set_build_version(
 | 
	
		
			
				|  |  | +      node_msg, upb_strview_make(build_version.data(), build_version.size()));
 | 
	
		
			
				|  |  | +  envoy_api_v2_core_Node_set_user_agent_name(
 | 
	
		
			
				|  |  | +      node_msg,
 | 
	
		
			
				|  |  | +      upb_strview_make(user_agent_name.data(), user_agent_name.size()));
 | 
	
		
			
				|  |  | +  envoy_api_v2_core_Node_set_user_agent_version(
 | 
	
		
			
				|  |  | +      node_msg, upb_strview_makez(grpc_version_string()));
 | 
	
		
			
				|  |  |    envoy_api_v2_core_Node_add_client_features(
 | 
	
		
			
				|  |  |        node_msg, upb_strview_makez("envoy.lb.does_not_support_overprovisioning"),
 | 
	
		
			
				|  |  |        arena);
 | 
	
	
		
			
				|  | @@ -241,7 +255,7 @@ void PopulateNode(upb_arena* arena, const XdsBootstrap::Node* node,
 | 
	
		
			
				|  |  |  envoy_api_v2_DiscoveryRequest* CreateDiscoveryRequest(
 | 
	
		
			
				|  |  |      upb_arena* arena, const char* type_url, const std::string& version,
 | 
	
		
			
				|  |  |      const std::string& nonce, grpc_error* error, const XdsBootstrap::Node* node,
 | 
	
		
			
				|  |  | -    const char* build_version) {
 | 
	
		
			
				|  |  | +    const std::string& user_agent_name) {
 | 
	
		
			
				|  |  |    // Create a request.
 | 
	
		
			
				|  |  |    envoy_api_v2_DiscoveryRequest* request =
 | 
	
		
			
				|  |  |        envoy_api_v2_DiscoveryRequest_new(arena);
 | 
	
	
		
			
				|  | @@ -273,10 +287,10 @@ envoy_api_v2_DiscoveryRequest* CreateDiscoveryRequest(
 | 
	
		
			
				|  |  |      GRPC_ERROR_UNREF(error);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    // Populate node.
 | 
	
		
			
				|  |  | -  if (build_version != nullptr) {
 | 
	
		
			
				|  |  | +  if (!user_agent_name.empty()) {
 | 
	
		
			
				|  |  |      envoy_api_v2_core_Node* node_msg =
 | 
	
		
			
				|  |  |          envoy_api_v2_DiscoveryRequest_mutable_node(request, arena);
 | 
	
		
			
				|  |  | -    PopulateNode(arena, node, build_version, "", node_msg);
 | 
	
		
			
				|  |  | +    PopulateNode(arena, node, user_agent_name, "", node_msg);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    return request;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -297,7 +311,7 @@ grpc_slice XdsApi::CreateUnsupportedTypeNackRequest(const std::string& type_url,
 | 
	
		
			
				|  |  |    upb::Arena arena;
 | 
	
		
			
				|  |  |    envoy_api_v2_DiscoveryRequest* request = CreateDiscoveryRequest(
 | 
	
		
			
				|  |  |        arena.ptr(), type_url.c_str(), /*version=*/"", nonce, error,
 | 
	
		
			
				|  |  | -      /*node=*/nullptr, /*build_version=*/nullptr);
 | 
	
		
			
				|  |  | +      /*node=*/nullptr, /*user_agent_name=*/"");
 | 
	
		
			
				|  |  |    return SerializeDiscoveryRequest(arena.ptr(), request);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -309,7 +323,7 @@ grpc_slice XdsApi::CreateLdsRequest(const std::string& server_name,
 | 
	
		
			
				|  |  |    envoy_api_v2_DiscoveryRequest* request =
 | 
	
		
			
				|  |  |        CreateDiscoveryRequest(arena.ptr(), kLdsTypeUrl, version, nonce, error,
 | 
	
		
			
				|  |  |                               populate_node ? node_ : nullptr,
 | 
	
		
			
				|  |  | -                             populate_node ? build_version_ : nullptr);
 | 
	
		
			
				|  |  | +                             populate_node ? user_agent_name_ : "");
 | 
	
		
			
				|  |  |    // Add resource_name.
 | 
	
		
			
				|  |  |    envoy_api_v2_DiscoveryRequest_add_resource_names(
 | 
	
		
			
				|  |  |        request, upb_strview_make(server_name.data(), server_name.size()),
 | 
	
	
		
			
				|  | @@ -325,7 +339,7 @@ grpc_slice XdsApi::CreateRdsRequest(const std::string& route_config_name,
 | 
	
		
			
				|  |  |    envoy_api_v2_DiscoveryRequest* request =
 | 
	
		
			
				|  |  |        CreateDiscoveryRequest(arena.ptr(), kRdsTypeUrl, version, nonce, error,
 | 
	
		
			
				|  |  |                               populate_node ? node_ : nullptr,
 | 
	
		
			
				|  |  | -                             populate_node ? build_version_ : nullptr);
 | 
	
		
			
				|  |  | +                             populate_node ? user_agent_name_ : "");
 | 
	
		
			
				|  |  |    // Add resource_name.
 | 
	
		
			
				|  |  |    envoy_api_v2_DiscoveryRequest_add_resource_names(
 | 
	
		
			
				|  |  |        request,
 | 
	
	
		
			
				|  | @@ -342,7 +356,7 @@ grpc_slice XdsApi::CreateCdsRequest(const std::set<StringView>& cluster_names,
 | 
	
		
			
				|  |  |    envoy_api_v2_DiscoveryRequest* request =
 | 
	
		
			
				|  |  |        CreateDiscoveryRequest(arena.ptr(), kCdsTypeUrl, version, nonce, error,
 | 
	
		
			
				|  |  |                               populate_node ? node_ : nullptr,
 | 
	
		
			
				|  |  | -                             populate_node ? build_version_ : nullptr);
 | 
	
		
			
				|  |  | +                             populate_node ? user_agent_name_ : "");
 | 
	
		
			
				|  |  |    // Add resource_names.
 | 
	
		
			
				|  |  |    for (const auto& cluster_name : cluster_names) {
 | 
	
		
			
				|  |  |      envoy_api_v2_DiscoveryRequest_add_resource_names(
 | 
	
	
		
			
				|  | @@ -359,7 +373,7 @@ grpc_slice XdsApi::CreateEdsRequest(
 | 
	
		
			
				|  |  |    envoy_api_v2_DiscoveryRequest* request =
 | 
	
		
			
				|  |  |        CreateDiscoveryRequest(arena.ptr(), kEdsTypeUrl, version, nonce, error,
 | 
	
		
			
				|  |  |                               populate_node ? node_ : nullptr,
 | 
	
		
			
				|  |  | -                             populate_node ? build_version_ : nullptr);
 | 
	
		
			
				|  |  | +                             populate_node ? user_agent_name_ : "");
 | 
	
		
			
				|  |  |    // Add resource_names.
 | 
	
		
			
				|  |  |    for (const auto& eds_service_name : eds_service_names) {
 | 
	
		
			
				|  |  |      envoy_api_v2_DiscoveryRequest_add_resource_names(
 | 
	
	
		
			
				|  | @@ -976,7 +990,7 @@ grpc_slice XdsApi::CreateLrsInitialRequest(const std::string& server_name) {
 | 
	
		
			
				|  |  |    envoy_api_v2_core_Node* node_msg =
 | 
	
		
			
				|  |  |        envoy_service_load_stats_v2_LoadStatsRequest_mutable_node(request,
 | 
	
		
			
				|  |  |                                                                  arena.ptr());
 | 
	
		
			
				|  |  | -  PopulateNode(arena.ptr(), node_, build_version_, server_name, node_msg);
 | 
	
		
			
				|  |  | +  PopulateNode(arena.ptr(), node_, user_agent_name_, server_name, node_msg);
 | 
	
		
			
				|  |  |    return SerializeLrsRequest(request, arena.ptr());
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 |