Copy disabled (too large)
Download .txt
Showing preview only (13,388K chars total). Download the full file to get everything.
Repository: grpc/grpc-go
Branch: master
Commit: 12e91ddb6df6
Files: 1307
Total size: 12.5 MB
Directory structure:
gitextract__6xnhcut/
├── .gemini/
│ └── config.yaml
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug.md
│ │ ├── feature.md
│ │ └── question.md
│ ├── codecov.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── codeql-analysis.yml
│ ├── coverage.yml
│ ├── deps.yml
│ ├── lock.yml
│ ├── pr-validation.yml
│ ├── release.yml
│ ├── stale.yml
│ └── testing.yml
├── AUTHORS
├── CODE-OF-CONDUCT.md
├── CONTRIBUTING.md
├── Documentation/
│ ├── anti-patterns.md
│ ├── benchmark.md
│ ├── compression.md
│ ├── concurrency.md
│ ├── encoding.md
│ ├── grpc-auth-support.md
│ ├── grpc-metadata.md
│ ├── keepalive.md
│ ├── log_levels.md
│ ├── proxy.md
│ ├── rpc-errors.md
│ ├── server-reflection-tutorial.md
│ └── versioning.md
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── Makefile
├── NOTICE.txt
├── README.md
├── SECURITY.md
├── admin/
│ ├── admin.go
│ ├── admin_test.go
│ └── test/
│ ├── admin_test.go
│ └── utils.go
├── attributes/
│ ├── attributes.go
│ └── attributes_test.go
├── authz/
│ ├── audit/
│ │ ├── audit_logger.go
│ │ ├── audit_logging_test.go
│ │ └── stdout/
│ │ ├── stdout_logger.go
│ │ └── stdout_logger_test.go
│ ├── grpc_authz_end2end_test.go
│ ├── grpc_authz_server_interceptors.go
│ ├── grpc_authz_server_interceptors_test.go
│ ├── rbac_translator.go
│ └── rbac_translator_test.go
├── backoff/
│ └── backoff.go
├── backoff.go
├── balancer/
│ ├── balancer.go
│ ├── base/
│ │ ├── balancer.go
│ │ ├── balancer_test.go
│ │ └── base.go
│ ├── conn_state_evaluator.go
│ ├── conn_state_evaluator_test.go
│ ├── endpointsharding/
│ │ ├── endpointsharding.go
│ │ ├── endpointsharding_ext_test.go
│ │ └── endpointsharding_test.go
│ ├── grpclb/
│ │ ├── grpc_lb_v1/
│ │ │ ├── load_balancer.pb.go
│ │ │ └── load_balancer_grpc.pb.go
│ │ ├── grpclb.go
│ │ ├── grpclb_config.go
│ │ ├── grpclb_config_test.go
│ │ ├── grpclb_picker.go
│ │ ├── grpclb_remote_balancer.go
│ │ ├── grpclb_test.go
│ │ ├── grpclb_util.go
│ │ ├── grpclb_util_test.go
│ │ └── state/
│ │ └── state.go
│ ├── lazy/
│ │ ├── lazy.go
│ │ └── lazy_ext_test.go
│ ├── leastrequest/
│ │ ├── leastrequest.go
│ │ └── leastrequest_test.go
│ ├── pickfirst/
│ │ ├── internal/
│ │ │ └── internal.go
│ │ ├── metrics_test.go
│ │ ├── pickfirst.go
│ │ ├── pickfirst_ext_test.go
│ │ ├── pickfirst_test.go
│ │ └── pickfirstleaf/
│ │ └── pickfirstleaf.go
│ ├── randomsubsetting/
│ │ ├── randomsubsetting.go
│ │ └── randomsubsetting_test.go
│ ├── ringhash/
│ │ ├── config.go
│ │ ├── config_test.go
│ │ ├── logging.go
│ │ ├── picker.go
│ │ ├── picker_test.go
│ │ ├── ring.go
│ │ ├── ring_test.go
│ │ ├── ringhash.go
│ │ ├── ringhash_e2e_test.go
│ │ └── ringhash_test.go
│ ├── rls/
│ │ ├── balancer.go
│ │ ├── balancer_test.go
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ ├── child_policy.go
│ │ ├── config.go
│ │ ├── config_test.go
│ │ ├── control_channel.go
│ │ ├── control_channel_test.go
│ │ ├── helpers_test.go
│ │ ├── internal/
│ │ │ ├── adaptive/
│ │ │ │ ├── adaptive.go
│ │ │ │ ├── adaptive_test.go
│ │ │ │ ├── lookback.go
│ │ │ │ └── lookback_test.go
│ │ │ ├── keys/
│ │ │ │ ├── builder.go
│ │ │ │ └── builder_test.go
│ │ │ └── test/
│ │ │ └── e2e/
│ │ │ ├── e2e.go
│ │ │ ├── rls_child_policy.go
│ │ │ └── rls_lb_config.go
│ │ ├── metrics_test.go
│ │ ├── picker.go
│ │ └── picker_test.go
│ ├── roundrobin/
│ │ └── roundrobin.go
│ ├── subconn.go
│ ├── weightedroundrobin/
│ │ ├── balancer.go
│ │ ├── balancer_test.go
│ │ ├── config.go
│ │ ├── internal/
│ │ │ └── internal.go
│ │ ├── logging.go
│ │ ├── metrics_test.go
│ │ └── scheduler.go
│ └── weightedtarget/
│ ├── logging.go
│ ├── weightedaggregator/
│ │ └── aggregator.go
│ ├── weightedtarget.go
│ ├── weightedtarget_config.go
│ ├── weightedtarget_config_test.go
│ └── weightedtarget_test.go
├── balancer_wrapper.go
├── balancer_wrapper_test.go
├── benchmark/
│ ├── benchmain/
│ │ └── main.go
│ ├── benchmark.go
│ ├── benchresult/
│ │ └── main.go
│ ├── client/
│ │ └── main.go
│ ├── flags/
│ │ ├── flags.go
│ │ └── flags_test.go
│ ├── latency/
│ │ ├── latency.go
│ │ └── latency_test.go
│ ├── primitives/
│ │ ├── code_string_test.go
│ │ ├── context_test.go
│ │ ├── primitives_test.go
│ │ ├── safe_config_selector_test.go
│ │ └── syncmap_test.go
│ ├── run_bench.sh
│ ├── server/
│ │ └── main.go
│ ├── stats/
│ │ ├── curve.go
│ │ ├── histogram.go
│ │ └── stats.go
│ └── worker/
│ ├── benchmark_client.go
│ ├── benchmark_server.go
│ └── main.go
├── binarylog/
│ ├── binarylog_end2end_test.go
│ ├── grpc_binarylog_v1/
│ │ └── binarylog.pb.go
│ └── sink.go
├── call.go
├── channelz/
│ ├── channelz.go
│ ├── grpc_channelz_v1/
│ │ ├── channelz.pb.go
│ │ └── channelz_grpc.pb.go
│ ├── internal/
│ │ └── protoconv/
│ │ ├── channel.go
│ │ ├── server.go
│ │ ├── socket.go
│ │ ├── sockopt_linux.go
│ │ ├── sockopt_nonlinux.go
│ │ ├── subchannel.go
│ │ └── util.go
│ └── service/
│ ├── service.go
│ ├── service_sktopt_test.go
│ └── service_test.go
├── clientconn.go
├── clientconn_authority_test.go
├── clientconn_parsed_target_test.go
├── clientconn_test.go
├── cmd/
│ └── protoc-gen-go-grpc/
│ ├── README.md
│ ├── go.mod
│ ├── go.sum
│ ├── grpc.go
│ ├── main.go
│ ├── protoc-gen-go-grpc_test.sh
│ └── unimpl_test.go
├── codec.go
├── codec_test.go
├── codes/
│ ├── code_string.go
│ ├── codes.go
│ └── codes_test.go
├── connectivity/
│ └── connectivity.go
├── credentials/
│ ├── alts/
│ │ ├── alts.go
│ │ ├── alts_test.go
│ │ ├── internal/
│ │ │ ├── authinfo/
│ │ │ │ ├── authinfo.go
│ │ │ │ └── authinfo_test.go
│ │ │ ├── common.go
│ │ │ ├── conn/
│ │ │ │ ├── aeadrekey.go
│ │ │ │ ├── aeadrekey_test.go
│ │ │ │ ├── aes128gcm.go
│ │ │ │ ├── aes128gcm_test.go
│ │ │ │ ├── aes128gcmrekey.go
│ │ │ │ ├── aes128gcmrekey_test.go
│ │ │ │ ├── common.go
│ │ │ │ ├── counter.go
│ │ │ │ ├── counter_test.go
│ │ │ │ ├── record.go
│ │ │ │ ├── record_test.go
│ │ │ │ └── utils.go
│ │ │ ├── handshaker/
│ │ │ │ ├── handshaker.go
│ │ │ │ ├── handshaker_test.go
│ │ │ │ └── service/
│ │ │ │ ├── service.go
│ │ │ │ └── service_test.go
│ │ │ ├── proto/
│ │ │ │ └── grpc_gcp/
│ │ │ │ ├── altscontext.pb.go
│ │ │ │ ├── handshaker.pb.go
│ │ │ │ ├── handshaker_grpc.pb.go
│ │ │ │ └── transport_security_common.pb.go
│ │ │ └── testutil/
│ │ │ └── testutil.go
│ │ ├── utils.go
│ │ └── utils_test.go
│ ├── credentials.go
│ ├── credentials_ext_test.go
│ ├── credentials_test.go
│ ├── google/
│ │ ├── google.go
│ │ ├── google_test.go
│ │ ├── xds.go
│ │ └── xds_test.go
│ ├── insecure/
│ │ └── insecure.go
│ ├── jwt/
│ │ ├── doc.go
│ │ ├── file_reader.go
│ │ ├── file_reader_test.go
│ │ ├── token_file_call_creds.go
│ │ ├── token_file_call_creds_ext_test.go
│ │ └── token_file_call_creds_test.go
│ ├── local/
│ │ ├── local.go
│ │ └── local_test.go
│ ├── oauth/
│ │ ├── oauth.go
│ │ └── oauth_test.go
│ ├── sts/
│ │ ├── sts.go
│ │ └── sts_test.go
│ ├── tls/
│ │ └── certprovider/
│ │ ├── distributor.go
│ │ ├── distributor_test.go
│ │ ├── pemfile/
│ │ │ ├── builder.go
│ │ │ ├── builder_test.go
│ │ │ ├── watcher.go
│ │ │ └── watcher_test.go
│ │ ├── provider.go
│ │ ├── store.go
│ │ └── store_test.go
│ ├── tls.go
│ ├── tls_ext_test.go
│ └── xds/
│ ├── xds.go
│ ├── xds_client_test.go
│ └── xds_server_test.go
├── default_dial_option_server_option_test.go
├── dial_test.go
├── dialoptions.go
├── doc.go
├── encoding/
│ ├── compressor_test.go
│ ├── encoding.go
│ ├── encoding_test.go
│ ├── encoding_v2.go
│ ├── gzip/
│ │ └── gzip.go
│ ├── internal/
│ │ └── internal.go
│ └── proto/
│ ├── proto.go
│ ├── proto_benchmark_test.go
│ └── proto_test.go
├── examples/
│ ├── README.md
│ ├── data/
│ │ ├── data.go
│ │ ├── rbac/
│ │ │ └── policy.json
│ │ └── x509/
│ │ ├── README.md
│ │ ├── ca_cert.pem
│ │ ├── ca_key.pem
│ │ ├── client_ca_cert.pem
│ │ ├── client_ca_key.pem
│ │ ├── client_cert.pem
│ │ ├── client_key.pem
│ │ ├── create.sh
│ │ ├── openssl.cnf
│ │ ├── server_cert.pem
│ │ └── server_key.pem
│ ├── examples_test.sh
│ ├── features/
│ │ ├── advancedtls/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ ├── creds/
│ │ │ │ ├── ca_cert.pem
│ │ │ │ ├── ca_key.pem
│ │ │ │ ├── client_cert.pem
│ │ │ │ ├── client_cert_revoked.pem
│ │ │ │ ├── client_key.pem
│ │ │ │ ├── crl/
│ │ │ │ │ └── client_revoked.crl
│ │ │ │ ├── localhost-openssl.cnf
│ │ │ │ ├── openssl-ca.cnf
│ │ │ │ ├── server_cert.pem
│ │ │ │ ├── server_cert_revoked.pem
│ │ │ │ ├── server_key.pem
│ │ │ │ └── server_revoked.crl
│ │ │ ├── generate.sh
│ │ │ ├── localhost-openssl.cnf
│ │ │ ├── openssl-ca.cnf
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── authentication/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── authz/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ ├── server/
│ │ │ │ └── main.go
│ │ │ └── token/
│ │ │ └── token.go
│ │ ├── cancellation/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── compression/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── csm_observability/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ ├── Dockerfile
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ ├── Dockerfile
│ │ │ └── main.go
│ │ ├── customloadbalancer/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ ├── customroundrobin/
│ │ │ │ │ └── customroundrobin.go
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── deadline/
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── debugging/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── dualstack/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── encryption/
│ │ │ ├── ALTS/
│ │ │ │ ├── client/
│ │ │ │ │ └── main.go
│ │ │ │ └── server/
│ │ │ │ └── main.go
│ │ │ ├── README.md
│ │ │ ├── TLS/
│ │ │ │ ├── client/
│ │ │ │ │ └── main.go
│ │ │ │ └── server/
│ │ │ │ └── main.go
│ │ │ └── mTLS/
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── error_details/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── error_handling/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── flow_control/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── gracefulstop/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── health/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── interceptor/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── keepalive/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── load_balancing/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── metadata/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── metadata_interceptor/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── multiplex/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── name_resolving/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── observability/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ ├── clientConfig.json
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ ├── main.go
│ │ │ └── serverConfig.json
│ │ ├── opentelemetry/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── orca/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── proto/
│ │ │ └── echo/
│ │ │ ├── echo.pb.go
│ │ │ ├── echo.proto
│ │ │ └── echo_grpc.pb.go
│ │ ├── reflection/
│ │ │ ├── README.md
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── retry/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── stats_monitoring/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ ├── server/
│ │ │ │ └── main.go
│ │ │ └── statshandler/
│ │ │ └── handler.go
│ │ ├── unix_abstract/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── wait_for_ready/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ └── xds/
│ │ ├── README.md
│ │ ├── client/
│ │ │ └── main.go
│ │ └── server/
│ │ └── main.go
│ ├── go.mod
│ ├── go.sum
│ ├── gotutorial.md
│ ├── helloworld/
│ │ ├── README.md
│ │ ├── greeter_client/
│ │ │ └── main.go
│ │ ├── greeter_server/
│ │ │ └── main.go
│ │ └── helloworld/
│ │ ├── helloworld.pb.go
│ │ ├── helloworld.proto
│ │ └── helloworld_grpc.pb.go
│ └── route_guide/
│ ├── README.md
│ ├── client/
│ │ └── client.go
│ ├── routeguide/
│ │ ├── route_guide.pb.go
│ │ ├── route_guide.proto
│ │ └── route_guide_grpc.pb.go
│ ├── server/
│ │ └── server.go
│ └── testdata/
│ └── route_guide_db.json
├── experimental/
│ ├── credentials/
│ │ ├── credentials_test.go
│ │ ├── internal/
│ │ │ ├── spiffe.go
│ │ │ ├── spiffe_test.go
│ │ │ ├── syscallconn.go
│ │ │ └── syscallconn_test.go
│ │ ├── tls.go
│ │ └── tls_ext_test.go
│ ├── experimental.go
│ ├── opentelemetry/
│ │ └── trace_options.go
│ ├── shared_buffer_pool_test.go
│ └── stats/
│ ├── metricregistry.go
│ ├── metricregistry_test.go
│ └── metrics.go
├── gcp/
│ └── observability/
│ ├── config.go
│ ├── exporting.go
│ ├── go.mod
│ ├── go.sum
│ ├── logging.go
│ ├── logging_test.go
│ ├── observability.go
│ ├── observability_test.go
│ └── opencensus.go
├── go.mod
├── go.sum
├── grpc_test.go
├── grpclog/
│ ├── component.go
│ ├── glogger/
│ │ └── glogger.go
│ ├── grpclog.go
│ ├── internal/
│ │ ├── grpclog.go
│ │ ├── logger.go
│ │ ├── loggerv2.go
│ │ └── loggerv2_test.go
│ ├── logger.go
│ └── loggerv2.go
├── health/
│ ├── client.go
│ ├── client_test.go
│ ├── grpc_health_v1/
│ │ ├── health.pb.go
│ │ └── health_grpc.pb.go
│ ├── logging.go
│ ├── producer.go
│ ├── server.go
│ ├── server_internal_test.go
│ └── server_test.go
├── interceptor.go
├── internal/
│ ├── admin/
│ │ └── admin.go
│ ├── backoff/
│ │ └── backoff.go
│ ├── balancer/
│ │ ├── gracefulswitch/
│ │ │ ├── config.go
│ │ │ ├── gracefulswitch.go
│ │ │ └── gracefulswitch_test.go
│ │ ├── nop/
│ │ │ └── nop.go
│ │ ├── stub/
│ │ │ └── stub.go
│ │ └── weight/
│ │ ├── weight.go
│ │ └── weight_test.go
│ ├── balancergroup/
│ │ ├── balancergroup.go
│ │ ├── balancergroup_test.go
│ │ └── balancerstateaggregator.go
│ ├── balancerload/
│ │ └── load.go
│ ├── binarylog/
│ │ ├── binarylog.go
│ │ ├── binarylog_test.go
│ │ ├── binarylog_testutil.go
│ │ ├── env_config.go
│ │ ├── env_config_test.go
│ │ ├── method_logger.go
│ │ ├── method_logger_test.go
│ │ ├── regexp_test.go
│ │ └── sink.go
│ ├── buffer/
│ │ ├── unbounded.go
│ │ └── unbounded_test.go
│ ├── cache/
│ │ ├── timeoutCache.go
│ │ └── timeoutCache_test.go
│ ├── channelz/
│ │ ├── channel.go
│ │ ├── channelmap.go
│ │ ├── funcs.go
│ │ ├── logging.go
│ │ ├── server.go
│ │ ├── socket.go
│ │ ├── subchannel.go
│ │ ├── syscall_linux.go
│ │ ├── syscall_nonlinux.go
│ │ ├── syscall_test.go
│ │ └── trace.go
│ ├── credentials/
│ │ ├── credentials.go
│ │ ├── spiffe/
│ │ │ ├── spiffe.go
│ │ │ └── spiffe_test.go
│ │ ├── spiffe.go
│ │ ├── spiffe_test.go
│ │ ├── syscallconn.go
│ │ ├── syscallconn_test.go
│ │ ├── util.go
│ │ ├── util_test.go
│ │ └── xds/
│ │ ├── handshake_info.go
│ │ └── handshake_info_test.go
│ ├── envconfig/
│ │ ├── envconfig.go
│ │ ├── envconfig_test.go
│ │ ├── observability.go
│ │ └── xds.go
│ ├── experimental.go
│ ├── googlecloud/
│ │ ├── googlecloud.go
│ │ ├── googlecloud_test.go
│ │ ├── manufacturer.go
│ │ ├── manufacturer_linux.go
│ │ └── manufacturer_windows.go
│ ├── grpclog/
│ │ └── prefix_logger.go
│ ├── grpcsync/
│ │ ├── callback_serializer.go
│ │ ├── callback_serializer_test.go
│ │ ├── event.go
│ │ ├── event_test.go
│ │ ├── pubsub.go
│ │ └── pubsub_test.go
│ ├── grpctest/
│ │ ├── example_test.go
│ │ ├── grpctest.go
│ │ ├── grpctest_test.go
│ │ ├── tlogger.go
│ │ └── tlogger_test.go
│ ├── grpcutil/
│ │ ├── compressor.go
│ │ ├── compressor_test.go
│ │ ├── encode_duration.go
│ │ ├── encode_duration_test.go
│ │ ├── grpcutil.go
│ │ ├── metadata.go
│ │ ├── method.go
│ │ ├── method_test.go
│ │ ├── regex.go
│ │ └── regex_test.go
│ ├── hierarchy/
│ │ ├── hierarchy.go
│ │ └── hierarchy_ext_test.go
│ ├── idle/
│ │ ├── idle.go
│ │ ├── idle_e2e_test.go
│ │ └── idle_test.go
│ ├── internal.go
│ ├── leakcheck/
│ │ ├── leakcheck.go
│ │ ├── leakcheck_enabled.go
│ │ └── leakcheck_test.go
│ ├── mem/
│ │ ├── buffer_pool.go
│ │ ├── buffer_pool_ext_test.go
│ │ └── buffer_pool_test.go
│ ├── metadata/
│ │ ├── metadata.go
│ │ └── metadata_test.go
│ ├── pretty/
│ │ └── pretty.go
│ ├── profiling/
│ │ ├── buffer/
│ │ │ ├── buffer.go
│ │ │ └── buffer_test.go
│ │ ├── goid_modified.go
│ │ ├── goid_regular.go
│ │ ├── profiling.go
│ │ └── profiling_test.go
│ ├── proto/
│ │ └── grpc_lookup_v1/
│ │ ├── rls.pb.go
│ │ ├── rls_config.pb.go
│ │ └── rls_grpc.pb.go
│ ├── proxyattributes/
│ │ ├── proxyattributes.go
│ │ └── proxyattributes_test.go
│ ├── resolver/
│ │ ├── config_selector.go
│ │ ├── config_selector_test.go
│ │ ├── delegatingresolver/
│ │ │ ├── delegatingresolver.go
│ │ │ ├── delegatingresolver_ext_test.go
│ │ │ └── delegatingresolver_test.go
│ │ ├── dns/
│ │ │ ├── dns_resolver.go
│ │ │ ├── dns_resolver_test.go
│ │ │ ├── fake_net_resolver_test.go
│ │ │ └── internal/
│ │ │ └── internal.go
│ │ ├── passthrough/
│ │ │ └── passthrough.go
│ │ └── unix/
│ │ └── unix.go
│ ├── ringhash/
│ │ └── ringhash.go
│ ├── serviceconfig/
│ │ ├── duration.go
│ │ ├── duration_test.go
│ │ ├── serviceconfig.go
│ │ └── serviceconfig_test.go
│ ├── stats/
│ │ ├── labels.go
│ │ ├── metrics_recorder_list.go
│ │ ├── metrics_recorder_list_test.go
│ │ └── stats.go
│ ├── status/
│ │ ├── status.go
│ │ └── status_test.go
│ ├── stubserver/
│ │ └── stubserver.go
│ ├── syscall/
│ │ ├── syscall_linux.go
│ │ └── syscall_nonlinux.go
│ ├── tcp_keepalive_others.go
│ ├── tcp_keepalive_unix.go
│ ├── tcp_keepalive_windows.go
│ ├── testutils/
│ │ ├── balancer.go
│ │ ├── blocking_context_dialer.go
│ │ ├── blocking_context_dialer_test.go
│ │ ├── channel.go
│ │ ├── envconfig.go
│ │ ├── fakegrpclb/
│ │ │ └── server.go
│ │ ├── http_client.go
│ │ ├── local_listener.go
│ │ ├── marshal_any.go
│ │ ├── parse_port.go
│ │ ├── parse_url.go
│ │ ├── pickfirst/
│ │ │ └── pickfirst.go
│ │ ├── pipe_listener.go
│ │ ├── pipe_listener_test.go
│ │ ├── proxyserver/
│ │ │ └── proxyserver.go
│ │ ├── resolver.go
│ │ ├── restartable_listener.go
│ │ ├── rls/
│ │ │ └── fake_rls_server.go
│ │ ├── roundrobin/
│ │ │ └── roundrobin.go
│ │ ├── state.go
│ │ ├── stats/
│ │ │ └── test_metrics_recorder.go
│ │ ├── status_equal.go
│ │ ├── status_equal_test.go
│ │ ├── stubstatshandler.go
│ │ ├── tls_creds.go
│ │ ├── wrappers.go
│ │ ├── wrr.go
│ │ ├── xds/
│ │ │ ├── e2e/
│ │ │ │ ├── bootstrap.go
│ │ │ │ ├── clientresources.go
│ │ │ │ ├── logging.go
│ │ │ │ ├── server.go
│ │ │ │ └── setup/
│ │ │ │ └── setup.go
│ │ │ └── fakeserver/
│ │ │ └── server.go
│ │ └── xds_bootstrap.go
│ ├── transport/
│ │ ├── bdp_estimator.go
│ │ ├── client_stream.go
│ │ ├── controlbuf.go
│ │ ├── defaults.go
│ │ ├── flowcontrol.go
│ │ ├── handler_server.go
│ │ ├── handler_server_test.go
│ │ ├── http2_client.go
│ │ ├── http2_server.go
│ │ ├── http_util.go
│ │ ├── http_util_test.go
│ │ ├── keepalive_test.go
│ │ ├── logging.go
│ │ ├── networktype/
│ │ │ └── networktype.go
│ │ ├── proxy.go
│ │ ├── proxy_ext_test.go
│ │ ├── proxy_test.go
│ │ ├── server_stream.go
│ │ ├── transport.go
│ │ └── transport_test.go
│ ├── wrr/
│ │ ├── edf.go
│ │ ├── edf_test.go
│ │ ├── random.go
│ │ ├── wrr.go
│ │ └── wrr_test.go
│ └── xds/
│ ├── balancer/
│ │ ├── balancer.go
│ │ ├── cdsbalancer/
│ │ │ ├── aggregate_cluster_test.go
│ │ │ ├── cdsbalancer.go
│ │ │ ├── cdsbalancer_test.go
│ │ │ ├── configbuilder.go
│ │ │ ├── configbuilder_childname.go
│ │ │ ├── configbuilder_childname_test.go
│ │ │ ├── configbuilder_test.go
│ │ │ ├── e2e_test/
│ │ │ │ ├── aggregate_cluster_test.go
│ │ │ │ ├── balancer_test.go
│ │ │ │ ├── dns_impl_test.go
│ │ │ │ └── eds_impl_test.go
│ │ │ └── logging.go
│ │ ├── clusterimpl/
│ │ │ ├── balancer_test.go
│ │ │ ├── clusterimpl.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── internal/
│ │ │ │ └── internal.go
│ │ │ ├── logging.go
│ │ │ ├── picker.go
│ │ │ └── tests/
│ │ │ ├── balancer_test.go
│ │ │ └── clusterimpl_security_test.go
│ │ ├── clustermanager/
│ │ │ ├── balancerstateaggregator.go
│ │ │ ├── clustermanager.go
│ │ │ ├── clustermanager_test.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── e2e_test/
│ │ │ │ └── clustermanager_test.go
│ │ │ └── picker.go
│ │ ├── loadstore/
│ │ │ └── load_store_wrapper.go
│ │ ├── outlierdetection/
│ │ │ ├── balancer.go
│ │ │ ├── balancer_ext_test.go
│ │ │ ├── balancer_test.go
│ │ │ ├── callcounter.go
│ │ │ ├── callcounter_test.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── e2e_test/
│ │ │ │ └── outlierdetection_test.go
│ │ │ ├── logging.go
│ │ │ └── subconn_wrapper.go
│ │ ├── priority/
│ │ │ ├── balancer.go
│ │ │ ├── balancer_child.go
│ │ │ ├── balancer_priority.go
│ │ │ ├── balancer_test.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── ignore_resolve_now.go
│ │ │ ├── ignore_resolve_now_test.go
│ │ │ └── logging.go
│ │ └── wrrlocality/
│ │ ├── balancer.go
│ │ ├── balancer_test.go
│ │ └── logging.go
│ ├── bootstrap/
│ │ ├── bootstrap.go
│ │ ├── bootstrap_test.go
│ │ ├── jwtcreds/
│ │ │ ├── call_creds.go
│ │ │ └── call_creds_test.go
│ │ ├── logging.go
│ │ ├── template.go
│ │ ├── template_test.go
│ │ └── tlscreds/
│ │ ├── bundle.go
│ │ ├── bundle_ext_test.go
│ │ └── bundle_test.go
│ ├── clients/
│ │ ├── config.go
│ │ ├── grpctransport/
│ │ │ ├── examples_test.go
│ │ │ ├── grpc_transport.go
│ │ │ ├── grpc_transport_ext_test.go
│ │ │ └── grpc_transport_test.go
│ │ ├── internal/
│ │ │ ├── backoff/
│ │ │ │ └── backoff.go
│ │ │ ├── buffer/
│ │ │ │ ├── unbounded.go
│ │ │ │ └── unbounded_test.go
│ │ │ ├── internal.go
│ │ │ ├── internal_test.go
│ │ │ ├── pretty/
│ │ │ │ └── pretty.go
│ │ │ ├── syncutil/
│ │ │ │ ├── callback_serializer.go
│ │ │ │ ├── callback_serializer_test.go
│ │ │ │ ├── event.go
│ │ │ │ └── event_test.go
│ │ │ └── testutils/
│ │ │ ├── channel.go
│ │ │ ├── e2e/
│ │ │ │ ├── clientresources.go
│ │ │ │ ├── logging.go
│ │ │ │ └── server.go
│ │ │ ├── fakeserver/
│ │ │ │ └── server.go
│ │ │ ├── faketransport/
│ │ │ │ └── xds_fake_transport.go
│ │ │ ├── marshal_any.go
│ │ │ ├── restartable_listener.go
│ │ │ └── wrappers.go
│ │ ├── lrsclient/
│ │ │ ├── internal/
│ │ │ │ └── internal.go
│ │ │ ├── load_store.go
│ │ │ ├── load_store_test.go
│ │ │ ├── loadreport_test.go
│ │ │ ├── logging.go
│ │ │ ├── lrs_stream.go
│ │ │ ├── lrsclient.go
│ │ │ └── lrsconfig.go
│ │ ├── transport_builder.go
│ │ └── xdsclient/
│ │ ├── ads_stream.go
│ │ ├── authority.go
│ │ ├── channel.go
│ │ ├── channel_test.go
│ │ ├── clientimpl_watchers.go
│ │ ├── helpers_test.go
│ │ ├── internal/
│ │ │ ├── internal.go
│ │ │ └── xdsresource/
│ │ │ ├── ads_stream.go
│ │ │ ├── errors.go
│ │ │ ├── name.go
│ │ │ ├── type.go
│ │ │ └── version.go
│ │ ├── logging.go
│ │ ├── metrics/
│ │ │ └── metrics.go
│ │ ├── resource_type.go
│ │ ├── resource_watcher.go
│ │ ├── test/
│ │ │ ├── ads_stream_ack_nack_test.go
│ │ │ ├── ads_stream_backoff_test.go
│ │ │ ├── ads_stream_flow_control_test.go
│ │ │ ├── ads_stream_restart_test.go
│ │ │ ├── ads_stream_watch_test.go
│ │ │ ├── authority_test.go
│ │ │ ├── custom_resource_watch_test.go
│ │ │ ├── dump_test.go
│ │ │ ├── helpers_test.go
│ │ │ ├── lds_watchers_test.go
│ │ │ ├── metrics_test.go
│ │ │ └── misc_watchers_test.go
│ │ ├── xdsclient.go
│ │ ├── xdsclient_test.go
│ │ └── xdsconfig.go
│ ├── clusterspecifier/
│ │ ├── cluster_specifier.go
│ │ └── rls/
│ │ ├── rls.go
│ │ └── rls_test.go
│ ├── httpfilter/
│ │ ├── fault/
│ │ │ ├── fault.go
│ │ │ └── fault_test.go
│ │ ├── httpfilter.go
│ │ ├── rbac/
│ │ │ └── rbac.go
│ │ └── router/
│ │ └── router.go
│ ├── matcher/
│ │ ├── matcher_header.go
│ │ ├── matcher_header_test.go
│ │ ├── string_matcher.go
│ │ └── string_matcher_test.go
│ ├── rbac/
│ │ ├── converter.go
│ │ ├── converter_test.go
│ │ ├── matchers.go
│ │ ├── rbac_engine.go
│ │ └── rbac_engine_test.go
│ ├── resolver/
│ │ ├── cluster_specifier_plugin_test.go
│ │ ├── helpers_test.go
│ │ ├── internal/
│ │ │ └── internal.go
│ │ ├── logging.go
│ │ ├── serviceconfig.go
│ │ ├── serviceconfig_test.go
│ │ ├── watch_service_test.go
│ │ ├── xds_http_filters_test.go
│ │ ├── xds_resolver.go
│ │ └── xds_resolver_test.go
│ ├── server/
│ │ ├── conn_wrapper.go
│ │ ├── filter_chain_manager.go
│ │ ├── filter_chain_manager_test.go
│ │ ├── listener_wrapper.go
│ │ ├── rds_handler.go
│ │ ├── rds_handler_test.go
│ │ ├── routing.go
│ │ └── routing_test.go
│ ├── test/
│ │ └── e2e/
│ │ ├── README.md
│ │ ├── controlplane.go
│ │ ├── e2e.go
│ │ ├── e2e_test.go
│ │ ├── e2e_utils.go
│ │ └── run.sh
│ ├── testutils/
│ │ ├── balancer_test.go
│ │ ├── fakeclient/
│ │ │ └── client.go
│ │ ├── resource_watcher.go
│ │ └── testutils.go
│ ├── xds.go
│ ├── xds_test.go
│ ├── xdsclient/
│ │ ├── attributes.go
│ │ ├── client.go
│ │ ├── client_refcounted_test.go
│ │ ├── client_test.go
│ │ ├── clientimpl.go
│ │ ├── clientimpl_loadreport.go
│ │ ├── clientimpl_test.go
│ │ ├── internal/
│ │ │ └── internal.go
│ │ ├── logging.go
│ │ ├── metrics_test.go
│ │ ├── pool/
│ │ │ └── pool_ext_test.go
│ │ ├── pool.go
│ │ ├── requests_counter.go
│ │ ├── requests_counter_test.go
│ │ ├── resource_types.go
│ │ ├── tests/
│ │ │ ├── ads_stream_ack_nack_test.go
│ │ │ ├── ads_stream_restart_test.go
│ │ │ ├── authority_test.go
│ │ │ ├── cds_watchers_test.go
│ │ │ ├── client_custom_dialopts_test.go
│ │ │ ├── dump_test.go
│ │ │ ├── eds_watchers_test.go
│ │ │ ├── fallback/
│ │ │ │ └── fallback_test.go
│ │ │ ├── federation_watchers_test.go
│ │ │ ├── helpers_test.go
│ │ │ ├── lds_watchers_test.go
│ │ │ ├── loadreport_test.go
│ │ │ ├── rds_watchers_test.go
│ │ │ └── resource_update_test.go
│ │ ├── xdsclient_test.go
│ │ ├── xdslbregistry/
│ │ │ ├── converter/
│ │ │ │ └── converter.go
│ │ │ ├── xdslbregistry.go
│ │ │ └── xdslbregistry_test.go
│ │ └── xdsresource/
│ │ ├── cluster_resource_type.go
│ │ ├── endpoints_resource_type.go
│ │ ├── errors.go
│ │ ├── filter_chain.go
│ │ ├── filter_chain_test.go
│ │ ├── listener_resource_type.go
│ │ ├── logging.go
│ │ ├── matcher.go
│ │ ├── matcher_path.go
│ │ ├── matcher_path_test.go
│ │ ├── matcher_test.go
│ │ ├── metadata.go
│ │ ├── metadata_test.go
│ │ ├── name.go
│ │ ├── name_test.go
│ │ ├── resource_type.go
│ │ ├── route_config_resource_type.go
│ │ ├── test_utils_test.go
│ │ ├── tests/
│ │ │ └── unmarshal_cds_test.go
│ │ ├── type.go
│ │ ├── type_cds.go
│ │ ├── type_eds.go
│ │ ├── type_lds.go
│ │ ├── type_rds.go
│ │ ├── unmarshal_cds.go
│ │ ├── unmarshal_cds_test.go
│ │ ├── unmarshal_eds.go
│ │ ├── unmarshal_eds_test.go
│ │ ├── unmarshal_lds.go
│ │ ├── unmarshal_lds_test.go
│ │ ├── unmarshal_rds.go
│ │ ├── unmarshal_rds_test.go
│ │ ├── version/
│ │ │ └── version.go
│ │ └── xdsconfig.go
│ └── xdsdepmgr/
│ ├── xds_dependency_manager.go
│ └── xds_dependency_manager_test.go
├── interop/
│ ├── alts/
│ │ ├── client/
│ │ │ └── client.go
│ │ └── server/
│ │ └── server.go
│ ├── client/
│ │ └── client.go
│ ├── fake_grpclb/
│ │ └── fake_grpclb.go
│ ├── grpc_testing/
│ │ ├── benchmark_service.pb.go
│ │ ├── benchmark_service_grpc.pb.go
│ │ ├── control.pb.go
│ │ ├── core/
│ │ │ └── stats.pb.go
│ │ ├── empty.pb.go
│ │ ├── messages.pb.go
│ │ ├── payloads.pb.go
│ │ ├── report_qps_scenario_service.pb.go
│ │ ├── report_qps_scenario_service_grpc.pb.go
│ │ ├── stats.pb.go
│ │ ├── test.pb.go
│ │ ├── test_grpc.pb.go
│ │ ├── worker_service.pb.go
│ │ └── worker_service_grpc.pb.go
│ ├── grpclb_fallback/
│ │ └── client_linux.go
│ ├── http2/
│ │ └── negative_http2_client.go
│ ├── interop_test.sh
│ ├── observability/
│ │ ├── Dockerfile
│ │ ├── build_docker.sh
│ │ ├── client/
│ │ │ └── client.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── run.sh
│ │ └── server/
│ │ └── server.go
│ ├── orcalb.go
│ ├── server/
│ │ └── server.go
│ ├── soak_tests.go
│ ├── stress/
│ │ ├── client/
│ │ │ └── main.go
│ │ ├── grpc_testing/
│ │ │ ├── metrics.pb.go
│ │ │ ├── metrics.proto
│ │ │ └── metrics_grpc.pb.go
│ │ └── metrics_client/
│ │ └── main.go
│ ├── test_utils.go
│ ├── xds/
│ │ ├── client/
│ │ │ ├── Dockerfile
│ │ │ └── client.go
│ │ ├── custom_lb.go
│ │ ├── custom_lb_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── server/
│ │ ├── Dockerfile
│ │ └── server.go
│ └── xds_federation/
│ └── client.go
├── keepalive/
│ └── keepalive.go
├── mem/
│ ├── buffer_pool.go
│ ├── buffer_pool_test.go
│ ├── buffer_slice.go
│ ├── buffer_slice_test.go
│ ├── buffers.go
│ └── buffers_test.go
├── metadata/
│ ├── metadata.go
│ └── metadata_test.go
├── orca/
│ ├── call_metrics.go
│ ├── call_metrics_test.go
│ ├── internal/
│ │ └── internal.go
│ ├── orca.go
│ ├── orca_test.go
│ ├── producer.go
│ ├── producer_test.go
│ ├── server_metrics.go
│ ├── server_metrics_test.go
│ ├── service.go
│ └── service_test.go
├── peer/
│ ├── peer.go
│ └── peer_test.go
├── picker_wrapper.go
├── picker_wrapper_test.go
├── preloader.go
├── producer_ext_test.go
├── profiling/
│ ├── cmd/
│ │ ├── catapult.go
│ │ ├── flags.go
│ │ ├── local.go
│ │ ├── main.go
│ │ └── remote.go
│ ├── profiling.go
│ ├── proto/
│ │ ├── service.pb.go
│ │ ├── service.proto
│ │ └── service_grpc.pb.go
│ └── service/
│ └── service.go
├── reflection/
│ ├── README.md
│ ├── adapt.go
│ ├── grpc_reflection_v1/
│ │ ├── reflection.pb.go
│ │ └── reflection_grpc.pb.go
│ ├── grpc_reflection_v1alpha/
│ │ ├── reflection.pb.go
│ │ └── reflection_grpc.pb.go
│ ├── grpc_testing/
│ │ ├── proto2.pb.go
│ │ ├── proto2.proto
│ │ ├── proto2_ext.pb.go
│ │ ├── proto2_ext.proto
│ │ ├── proto2_ext2.pb.go
│ │ ├── proto2_ext2.proto
│ │ ├── test.pb.go
│ │ ├── test.proto
│ │ └── test_grpc.pb.go
│ ├── internal/
│ │ └── internal.go
│ ├── serverreflection.go
│ └── test/
│ └── serverreflection_test.go
├── resolver/
│ ├── dns/
│ │ └── dns_resolver.go
│ ├── manual/
│ │ ├── manual.go
│ │ └── manual_test.go
│ ├── map.go
│ ├── map_test.go
│ ├── passthrough/
│ │ └── passthrough.go
│ ├── resolver.go
│ ├── resolver_test.go
│ └── ringhash/
│ └── attr.go
├── resolver_balancer_ext_test.go
├── resolver_test.go
├── resolver_wrapper.go
├── rpc_util.go
├── rpc_util_test.go
├── scripts/
│ ├── common.sh
│ ├── gen-deps.sh
│ ├── install-protoc.sh
│ ├── regenerate.sh
│ ├── revive.toml
│ ├── vet-proto.sh
│ └── vet.sh
├── security/
│ └── advancedtls/
│ ├── advancedtls.go
│ ├── advancedtls_integration_test.go
│ ├── advancedtls_test.go
│ ├── crl.go
│ ├── crl_provider.go
│ ├── crl_provider_test.go
│ ├── crl_test.go
│ ├── examples/
│ │ ├── credential_reloading_from_files/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── examples_test.sh
│ │ ├── go.mod
│ │ └── go.sum
│ ├── go.mod
│ ├── go.sum
│ ├── internal/
│ │ └── testutils/
│ │ └── testutils.go
│ ├── sni.go
│ └── testdata/
│ ├── README.md
│ ├── another_client_cert_1.pem
│ ├── another_client_key_1.pem
│ ├── client_cert_1.pem
│ ├── client_cert_2.pem
│ ├── client_key_1.pem
│ ├── client_key_2.pem
│ ├── client_trust_cert_1.pem
│ ├── client_trust_cert_2.pem
│ ├── client_trust_key_1.pem
│ ├── client_trust_key_2.pem
│ ├── crl/
│ │ ├── 1.crl
│ │ ├── 2.crl
│ │ ├── 2f11f022.r0
│ │ ├── 3.crl
│ │ ├── 4.crl
│ │ ├── 5.crl
│ │ ├── 6.crl
│ │ ├── README.md
│ │ ├── provider_ca.cnf
│ │ ├── provider_client_cert.key
│ │ ├── provider_client_cert.pem
│ │ ├── provider_client_trust_cert.pem
│ │ ├── provider_client_trust_key.pem
│ │ ├── provider_create.sh
│ │ ├── provider_crl.cnf
│ │ ├── provider_crl_empty.pem
│ │ ├── provider_crl_server_revoked.pem
│ │ ├── provider_extensions.conf
│ │ ├── provider_malicious_client_trust_cert.pem
│ │ ├── provider_malicious_client_trust_key.pem
│ │ ├── provider_malicious_crl_empty.pem
│ │ ├── provider_server_cert.key
│ │ ├── provider_server_cert.pem
│ │ ├── provider_server_trust_cert.pem
│ │ ├── provider_server_trust_key.pem
│ │ ├── revokedInt.pem
│ │ ├── revokedLeaf.pem
│ │ └── unrevoked.pem
│ ├── localhost-openssl.cnf
│ ├── openssl-ca.cnf
│ ├── server_cert_1.pem
│ ├── server_cert_1.txt
│ ├── server_cert_2.pem
│ ├── server_cert_2.txt
│ ├── server_cert_3.pem
│ ├── server_cert_3.txt
│ ├── server_cert_localhost_1.pem
│ ├── server_key_1.pem
│ ├── server_key_2.pem
│ ├── server_key_3.pem
│ ├── server_key_localhost_1.pem
│ ├── server_trust_cert_1.pem
│ ├── server_trust_cert_2.pem
│ ├── server_trust_key_1.pem
│ ├── server_trust_key_2.pem
│ └── testdata.go
├── server.go
├── server_ext_test.go
├── server_test.go
├── service_config.go
├── service_config_test.go
├── serviceconfig/
│ └── serviceconfig.go
├── stats/
│ ├── handlers.go
│ ├── metrics.go
│ ├── opencensus/
│ │ ├── client_metrics.go
│ │ ├── e2e_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── opencensus.go
│ │ ├── server_metrics.go
│ │ ├── stats.go
│ │ └── trace.go
│ ├── opentelemetry/
│ │ ├── client_metrics.go
│ │ ├── client_tracing.go
│ │ ├── csm/
│ │ │ ├── observability.go
│ │ │ ├── observability_test.go
│ │ │ ├── pluginoption.go
│ │ │ └── pluginoption_test.go
│ │ ├── e2e_test.go
│ │ ├── example_test.go
│ │ ├── grpc_trace_bin_propagator.go
│ │ ├── grpc_trace_bin_propagator_test.go
│ │ ├── internal/
│ │ │ ├── pluginoption.go
│ │ │ ├── testutils/
│ │ │ │ └── testutils.go
│ │ │ └── tracing/
│ │ │ ├── carrier.go
│ │ │ └── carrier_test.go
│ │ ├── metricsregistry_test.go
│ │ ├── opentelemetry.go
│ │ ├── server_metrics.go
│ │ ├── server_tracing.go
│ │ └── trace.go
│ ├── stats.go
│ └── stats_test.go
├── status/
│ ├── status.go
│ ├── status_ext_test.go
│ └── status_test.go
├── stream.go
├── stream_interfaces.go
├── stream_test.go
├── tap/
│ └── tap.go
├── test/
│ ├── authority_test.go
│ ├── balancer_switching_test.go
│ ├── balancer_test.go
│ ├── bufconn/
│ │ ├── bufconn.go
│ │ └── bufconn_test.go
│ ├── channelz_linux_test.go
│ ├── channelz_test.go
│ ├── clientconn_state_transition_test.go
│ ├── clientconn_test.go
│ ├── clienttester.go
│ ├── codec_perf/
│ │ ├── perf.pb.go
│ │ └── perf.proto
│ ├── compressor_test.go
│ ├── config_selector_test.go
│ ├── context_canceled_test.go
│ ├── control_plane_status_test.go
│ ├── creds_test.go
│ ├── end2end_test.go
│ ├── goaway_test.go
│ ├── gracefulstop_test.go
│ ├── healthcheck_test.go
│ ├── http_header_end2end_test.go
│ ├── insecure_creds_test.go
│ ├── interceptor_test.go
│ ├── invoke_test.go
│ ├── kokoro/
│ │ ├── README.md
│ │ ├── psm-csm.cfg
│ │ ├── psm-dualstack.cfg
│ │ ├── psm-interop-build-go.sh
│ │ ├── psm-interop-test-go.sh
│ │ ├── psm-light.cfg
│ │ ├── psm-security.cfg
│ │ ├── psm-spiffe.cfg
│ │ ├── xds.cfg
│ │ ├── xds.sh
│ │ ├── xds_k8s_lb.cfg
│ │ ├── xds_url_map.cfg
│ │ ├── xds_v3.cfg
│ │ └── xds_v3.sh
│ ├── local_creds_test.go
│ ├── logging.go
│ ├── malformed_method_test.go
│ ├── metadata_test.go
│ ├── parse_config.go
│ ├── race_test.go
│ ├── rawConnWrapper.go
│ ├── resolver_update_test.go
│ ├── retry_test.go
│ ├── roundrobin_test.go
│ ├── server_test.go
│ ├── servertester.go
│ ├── stats_test.go
│ ├── stream_cleanup_test.go
│ ├── subconn_test.go
│ ├── timeouts.go
│ ├── tools/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── tools.go
│ │ └── tools_vet.go
│ ├── transport_test.go
│ └── xds/
│ ├── xds_client_ack_nack_test.go
│ ├── xds_client_affinity_test.go
│ ├── xds_client_certificate_providers_test.go
│ ├── xds_client_custom_lb_test.go
│ ├── xds_client_federation_test.go
│ ├── xds_client_ignore_resource_deletion_test.go
│ ├── xds_client_integration_test.go
│ ├── xds_client_outlier_detection_test.go
│ ├── xds_client_priority_locality_test.go
│ ├── xds_client_retry_test.go
│ ├── xds_rls_clusterspecifier_plugin_test.go
│ ├── xds_security_config_nack_test.go
│ ├── xds_server_filter_state_retention_test.go
│ ├── xds_server_integration_test.go
│ ├── xds_server_rbac_test.go
│ └── xds_telemetry_labels_test.go
├── testdata/
│ ├── README.md
│ ├── ca.pem
│ ├── grpc_testing_not_regenerated/
│ │ ├── README.md
│ │ ├── dynamic.go
│ │ ├── dynamic.proto
│ │ ├── simple.proto
│ │ ├── simple_message_v1.go
│ │ ├── testv3.go
│ │ └── testv3.proto
│ ├── server1.key
│ ├── server1.pem
│ ├── spiffe/
│ │ ├── README.md
│ │ ├── client_spiffe.pem
│ │ ├── server1_spiffe.pem
│ │ ├── spiffe-openssl.cnf
│ │ ├── spiffe_cert.pem
│ │ ├── spiffe_multi_uri_san_cert.pem
│ │ ├── spiffe_test.json
│ │ ├── spiffebundle.json
│ │ ├── spiffebundle2.json
│ │ ├── spiffebundle_corrupted_cert.json
│ │ ├── spiffebundle_empty_keys.json
│ │ ├── spiffebundle_empty_string_key.json
│ │ ├── spiffebundle_invalid_trustdomain.json
│ │ ├── spiffebundle_malformed.json
│ │ ├── spiffebundle_match_client_spiffe.json
│ │ ├── spiffebundle_wrong_kid.json
│ │ ├── spiffebundle_wrong_kty.json
│ │ ├── spiffebundle_wrong_multi_certs.json
│ │ ├── spiffebundle_wrong_root.json
│ │ ├── spiffebundle_wrong_seq_type.json
│ │ └── spiffebundle_wrong_use.json
│ ├── spiffe_end2end/
│ │ ├── README.md
│ │ ├── ca.key
│ │ ├── ca.pem
│ │ ├── client.key
│ │ ├── client_spiffe.pem
│ │ ├── client_spiffebundle.json
│ │ ├── generate.sh
│ │ ├── intermediate.cnf
│ │ ├── intermediate_ca.key
│ │ ├── intermediate_ca.pem
│ │ ├── intermediate_gen.sh
│ │ ├── leaf_and_intermediate_chain.pem
│ │ ├── leaf_signed_by_intermediate.key
│ │ ├── leaf_signed_by_intermediate.pem
│ │ ├── server.key
│ │ ├── server_spiffe.pem
│ │ ├── server_spiffebundle.json
│ │ └── spiffe-openssl.cnf
│ ├── testdata.go
│ └── x509/
│ ├── README.md
│ ├── client1_cert.pem
│ ├── client1_key.pem
│ ├── client2_cert.pem
│ ├── client2_key.pem
│ ├── client_ca_cert.pem
│ ├── client_ca_key.pem
│ ├── client_with_spiffe_cert.pem
│ ├── client_with_spiffe_key.pem
│ ├── client_with_spiffe_openssl.cnf
│ ├── create.sh
│ ├── multiple_uri_cert.pem
│ ├── multiple_uri_key.pem
│ ├── openssl.cnf
│ ├── server1_cert.pem
│ ├── server1_key.pem
│ ├── server2_cert.pem
│ ├── server2_key.pem
│ ├── server_ca_cert.pem
│ ├── server_ca_key.pem
│ ├── spiffe_cert.pem
│ └── spiffe_key.pem
├── trace.go
├── trace_notrace.go
├── trace_test.go
├── trace_withtrace.go
├── version.go
└── xds/
├── bootstrap/
│ ├── bootstrap.go
│ ├── bootstrap_test.go
│ └── credentials.go
├── csds/
│ ├── csds.go
│ └── csds_e2e_test.go
├── googledirectpath/
│ ├── googlec2p.go
│ ├── googlec2p_test.go
│ └── utils.go
├── server.go
├── server_ext_test.go
├── server_options.go
├── server_resource_ext_test.go
├── server_security_ext_test.go
├── server_serving_mode_ext_test.go
├── server_test.go
├── test/
│ └── eds_resource_missing_test.go
└── xds.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .gemini/config.yaml
================================================
have_fun: false
memory_config:
disabled: false
code_review:
disable: false
comment_severity_threshold: MEDIUM
max_review_comments: -1
pull_request_opened:
help: false
summary: false
code_review: false
include_drafts: false
ignore_patterns: []
================================================
FILE: .github/ISSUE_TEMPLATE/bug.md
================================================
---
name: Bug Report
about: Report a non-security bug. For suspected security vulnerabilities or crashes, please use "Report a Security Vulnerability", below.
labels: 'Type: Bug'
---
NOTE: if you are reporting is a potential security vulnerability or a crash,
please follow our CVE process at
https://github.com/grpc/proposal/blob/master/P4-grpc-cve-process.md instead of
filing an issue here.
Please see the FAQ in our main README.md, then answer the questions below
before submitting your issue.
### What version of gRPC are you using?
### What version of Go are you using (`go version`)?
### What operating system (Linux, Windows, …) and version?
### What did you do?
If possible, provide a recipe for reproducing the error.
### What did you expect to see?
### What did you see instead?
================================================
FILE: .github/ISSUE_TEMPLATE/feature.md
================================================
---
name: Feature Request
about: Suggest an idea for gRPC-Go
labels: 'Type: Feature'
---
Please see the FAQ in our main README.md before submitting your issue.
### Use case(s) - what problem will this feature solve?
### Proposed Solution
### Alternatives Considered
### Additional Context
================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: Question
about: Ask a question about gRPC-Go
labels: 'Type: Question'
---
Please see the FAQ in our main README.md before submitting your issue.
================================================
FILE: .github/codecov.yml
================================================
coverage:
status:
project:
default:
informational: true
patch:
default:
informational: true
ignore:
# All 'pb.go's.
- "**/*.pb.go"
# Tests and test related files.
- "**/test"
- "**/testdata"
- "**/testutils"
- "benchmark"
- "interop"
# Other submodules.
- "cmd"
- "examples"
- "gcp"
- "security"
- "stats/opencensus"
comment:
layout: "header, diff, files"
================================================
FILE: .github/pull_request_template.md
================================================
Thank you for your PR. Please read and follow
https://github.com/grpc/grpc-go/blob/master/CONTRIBUTING.md, especially the
"Guidelines for Pull Requests" section, and then delete this text before
entering your PR description.
================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: "CodeQL"
on:
push:
branches: [ master ]
schedule:
- cron: '24 20 * * 3'
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
security-events: write
pull-requests: read
actions: read
strategy:
fail-fast: false
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: go
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
================================================
FILE: .github/workflows/coverage.yml
================================================
name: codecov
on: [push, pull_request]
permissions:
contents: read
jobs:
upload:
runs-on: ubuntu-latest
steps:
- name: Install checkout
uses: actions/checkout@v4
- name: Install checkout
uses: actions/setup-go@v5
with:
go-version: "stable"
- name: Run coverage
run: go test -coverprofile=coverage.out -coverpkg=./... ./...
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
================================================
FILE: .github/workflows/deps.yml
================================================
name: Dependency Changes
# Trigger on PRs.
on:
pull_request:
permissions:
contents: read
jobs:
# Compare dependencies before and after this PR.
dependencies:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: true
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: stable
cache-dependency-path: "**/*go.sum"
# Run the commands to generate dependencies before and after and compare.
- name: Compare dependencies
run: |
set -eu
TEMP_DIR="$(mktemp -d)"
# GITHUB_BASE_REF is set when the job is triggered by a PR.
TARGET_REF="${GITHUB_BASE_REF:-master}"
mkdir "${TEMP_DIR}/after"
scripts/gen-deps.sh "${TEMP_DIR}/after"
git checkout "origin/${TARGET_REF}"
mkdir "${TEMP_DIR}/before"
scripts/gen-deps.sh "${TEMP_DIR}/before"
echo -e " \nComparing dependencies..."
cd "${TEMP_DIR}"
# Run grep in a sub-shell since bash does not support ! in the middle of a pipe.
if diff -u0 -r "before" "after" | bash -c '! grep -v "@@"'; then
echo "No changes detected."
exit 0
fi
# Print packages in `after` but not `before`.
for x in $(ls -1 after | grep -vF "$(ls -1 before)"); do
echo -e " \nDependencies of new package $x:"
cat "after/$x"
done
echo -e " \nChanges detected; exiting with error."
exit 1
================================================
FILE: .github/workflows/lock.yml
================================================
name: 'Lock Threads'
on:
workflow_dispatch:
schedule:
- cron: '22 1 * * *'
permissions:
contents: read
jobs:
lock:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: dessant/lock-threads@v5
with:
github-token: ${{ github.token }}
issue-inactive-days: 180
pr-inactive-days: 180
================================================
FILE: .github/workflows/pr-validation.yml
================================================
name: PR Validation
on:
pull_request:
types: [opened, edited, synchronize, labeled, unlabeled, milestoned, demilestoned]
permissions:
contents: read
jobs:
validate:
name: Validate PR
runs-on: ubuntu-latest
steps:
- name: Validate Description
uses: actions/github-script@v6
with:
script: |
const body = context.payload.pull_request.body;
const requiredRegex = new RegExp('^RELEASE NOTES:\\s*([Nn][Oo][Nn][Ee]|[Nn]/[Aa]|\\n(\\*|-)\\s*.+)$', 'm');
if (!requiredRegex.test(body)) {
core.setFailed(`
The PR description must include a RELEASE NOTES section.
It should be in one of the following formats:
- "RELEASE NOTES: none" (case-insensitive)
- "RELEASE NOTES: N/A" (case-insensitive)
- A bulleted list under "RELEASE NOTES:", for example:
RELEASE NOTES:
* my_package: Fix bug causing crash...
`);
}
- name: Validate Label
uses: actions/github-script@v6
with:
script: |
const labels = context.payload.pull_request.labels.map(label => label.name);
const requiredRegex = new RegExp('^Type:');
const hasRequiredLabel = labels.some(label => requiredRegex.test(label));
if (!hasRequiredLabel) {
core.setFailed("This PR must have a label starting with 'Type:'.");
}
- name: Validate Milestone
uses: actions/github-script@v6
with:
script: |
const milestone = context.payload.pull_request.milestone;
if (!milestone) {
core.setFailed("This PR must be associated with a milestone.");
} else {
const requiredRegex = new RegExp('Release$');
if (!requiredRegex.test(milestone.title)) {
core.setFailed("The milestone for this PR must end with 'Release'.");
}
}
================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
release:
types: [published]
permissions:
contents: read
jobs:
release:
permissions:
contents: write # to upload release asset (actions/upload-release-asset)
name: Release cmd/protoc-gen-go-grpc
runs-on: ubuntu-latest
if: startsWith(github.event.release.tag_name, 'cmd/protoc-gen-go-grpc/')
strategy:
matrix:
goos: [linux, darwin, windows]
goarch: [386, amd64, arm64]
exclude:
- goos: darwin
goarch: 386
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
- name: Download dependencies
run: |
cd cmd/protoc-gen-go-grpc
go mod download
- name: Prepare build directory
run: |
mkdir -p build/
cp README.md build/
cp LICENSE build/
- name: Build
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: |
cd cmd/protoc-gen-go-grpc
go build -trimpath -o $GITHUB_WORKSPACE/build
- name: Create package
id: package
run: |
PACKAGE_NAME=protoc-gen-go-grpc.${GITHUB_REF#refs/tags/cmd/protoc-gen-go-grpc/}.${{ matrix.goos }}.${{ matrix.goarch }}.tar.gz
tar -czvf $PACKAGE_NAME -C build .
echo "name=${PACKAGE_NAME}" >> $GITHUB_OUTPUT
- name: Upload asset
run: |
gh release upload ${{ github.event.release.tag_name }} ./${{ steps.package.outputs.name }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/stale.yml
================================================
name: Stale bot
on:
workflow_dispatch:
schedule:
- cron: "44 */2 * * *"
permissions:
contents: read
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v8
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 6
days-before-close: 7
only-labels: 'Status: Requires Reporter Clarification'
stale-issue-label: 'stale'
stale-pr-label: 'stale'
operations-per-run: 999
stale-issue-message: >
This issue is labeled as requiring an update from the reporter, and no update has been received
after 6 days. If no update is provided in the next 7 days, this issue will be automatically closed.
stale-pr-message: >
This PR is labeled as requiring an update from the reporter, and no update has been received
after 6 days. If no update is provided in the next 7 days, this issue will be automatically closed.
================================================
FILE: .github/workflows/testing.yml
================================================
name: Testing
# Trigger on pushes, PRs (excluding documentation changes), and nightly.
on:
push:
pull_request:
schedule:
- cron: 0 0 * * * # daily at 00:00
permissions:
contents: read
# Always force the use of Go modules
env:
GO111MODULE: on
jobs:
# Check generated protos match their source repos (optional for PRs).
vet-proto:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout repo
uses: actions/checkout@v4
# Setup the environment.
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.26'
cache-dependency-path: "**/go.sum"
# Run the vet-proto checks.
- name: vet-proto
run: ./scripts/vet-proto.sh -install && ./scripts/vet-proto.sh
# Run the main gRPC-Go tests.
tests:
name: ${{ matrix.display_name }}
# Use the matrix variable to set the runner, with 'ubuntu-latest' as the
# default.
runs-on: ${{ matrix.runner || 'ubuntu-latest' }}
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
include:
- type: vet
goversion: '1.25'
display_name: 'static checks (latest-1)'
- type: extras
goversion: '1.26'
display_name: 'extras (latest)'
- type: tests
goversion: '1.26'
display_name: 'tests (latest)'
- type: tests
goversion: '1.26'
testflags: -race
display_name: 'tests (-race, latest)'
- type: tests
goversion: '1.26'
goarch: 386
display_name: 'tests (i386, latest)'
- type: tests
goversion: '1.26'
goarch: arm64
runner: ubuntu-24.04-arm
display_name: 'tests (arm, latest)'
- type: tests
goversion: '1.25'
display_name: 'tests (latest-1)'
steps:
# Setup the environment.
- name: Setup GOARCH
if: matrix.goarch != ''
run: echo "GOARCH=${{ matrix.goarch }}" >> $GITHUB_ENV
- name: Setup GRPC environment
if: matrix.grpcenv != ''
run: echo "${{ matrix.grpcenv }}" >> $GITHUB_ENV
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.goversion }}
cache-dependency-path: "**/*go.sum"
# Only run vet for 'vet' runs.
- name: Run vet.sh
if: matrix.type == 'vet'
run: ./scripts/vet.sh -install && ./scripts/vet.sh
# Main tests run for everything except when testing "extras"
# (where we run a reduced set of tests).
- name: Run tests
if: matrix.type == 'tests'
run: |
go version
go test ${{ matrix.testflags }} -cpu 1,4 -timeout 7m ./...
cd "${GITHUB_WORKSPACE}"
for MOD_FILE in $(find . -name 'go.mod' | grep -Ev '^\./go\.mod'); do
pushd "$(dirname ${MOD_FILE})"
go test ${{ matrix.testflags }} -cpu 1,4 -timeout 2m ./...
popd
done
# Non-core gRPC tests (examples, interop, etc)
- name: Run extras tests
if: matrix.type == 'extras'
run: |
export TERM=${TERM:-xterm}
go version
echo -e "\n-- Running Examples --"
examples/examples_test.sh
echo -e "\n-- Running AdvancedTLS Examples --"
security/advancedtls/examples/examples_test.sh
echo -e "\n-- Running Interop Test --"
interop/interop_test.sh
echo -e "\n-- Running xDS E2E Test --"
internal/xds/test/e2e/run.sh
echo -e "\n-- Running protoc-gen-go-grpc test --"
./scripts/vet-proto.sh -install
cmd/protoc-gen-go-grpc/protoc-gen-go-grpc_test.sh
================================================
FILE: AUTHORS
================================================
Google Inc.
================================================
FILE: CODE-OF-CONDUCT.md
================================================
## Community Code of Conduct
gRPC follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
================================================
FILE: CONTRIBUTING.md
================================================
# How to contribute
We welcome your patches and contributions to gRPC! Please read the gRPC
organization's [governance
rules](https://github.com/grpc/grpc-community/blob/master/governance.md) before
proceeding.
If you are new to GitHub, please start by reading [Pull Request howto](https://help.github.com/articles/about-pull-requests/)
## Legal requirements
In order to protect both you and ourselves, you will need to sign the
[Contributor License
Agreement](https://identity.linuxfoundation.org/projects/cncf). When you create
your first PR, a link will be added as a comment that contains the steps needed
to complete this process.
## Getting Started
A great way to start is by searching through our open issues. [Unassigned issues
labeled as "help
wanted"](https://github.com/grpc/grpc-go/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20label%3A%22Status%3A%20Help%20Wanted%22%20no%3Aassignee)
are especially nice for first-time contributors, as they should be well-defined
problems that already have agreed-upon solutions.
## Code Style
We follow [Google's published Go style
guide](https://google.github.io/styleguide/go/). Note that there are three
primary documents that make up this style guide; please follow them as closely
as possible. If a reviewer recommends something that contradicts those
guidelines, there may be valid reasons to do so, but it should be rare.
## Guidelines for Pull Requests
Please read the following carefully to ensure your contributions can be merged
smoothly and quickly.
### PR Contents
- Create **small PRs** that are narrowly focused on **addressing a single
concern**. We often receive PRs that attempt to fix several things at the same
time, and if one part of the PR has a problem, that will hold up the entire
PR.
- If your change does not address an **open issue** with an **agreed
resolution**, consider opening an issue and discussing it first. If you are
suggesting a behavioral or API change, consider starting with a [gRFC
proposal](https://github.com/grpc/proposal). Many new features that are not
bug fixes will require cross-language agreement.
- If you want to fix **formatting or style**, consider whether your changes are
an obvious improvement or might be considered a personal preference. If a
style change is based on preference, it likely will not be accepted. If it
corrects widely agreed-upon anti-patterns, then please do create a PR and
explain the benefits of the change.
- For correcting **misspellings**, please be aware that we use some terms that
are sometimes flagged by spell checkers. As an example, "if an only if" is
often written as "iff". Please do not make spelling correction changes unless
you are certain they are misspellings.
- **All tests need to be passing** before your change can be merged. We
recommend you run tests locally before creating your PR to catch breakages
early on:
- `./scripts/vet.sh` to catch vet errors.
- `go test -cpu 1,4 -timeout 7m ./...` to run the tests.
- `go test -race -cpu 1,4 -timeout 7m ./...` to run tests in race mode.
Note that we have a multi-module repo, so `go test` commands may need to be
run from the root of each module in order to cause all tests to run.
*Alternatively*, you may find it easier to push your changes to your fork on
GitHub, which will trigger a GitHub Actions run that you can use to verify
everything is passing.
- Note that there are two GitHub actions checks that need not be green:
1. We test the freshness of the generated proto code we maintain via the
`vet-proto` check. If the source proto files are updated, but our repo is
not updated, an optional checker will fail. This will be fixed by our team
in a separate PR and will not prevent the merge of your PR.
2. We run a checker that will fail if there is any change in dependencies of
an exported package via the `dependencies` check. If new dependencies are
added that are not appropriate, we may not accept your PR (see below).
- If you are adding a **new file**, make sure it has the **copyright message**
template at the top as a comment. You can copy the message from an existing
file and update the year.
- The grpc package should only depend on standard Go packages and a small number
of exceptions. **If your contribution introduces new dependencies**, you will
need a discussion with gRPC-Go maintainers.
### PR Descriptions
- **PR titles** should start with the name of the component being addressed, or
the type of change. Examples: transport, client, server, round_robin, xds,
cleanup, deps.
- Read and follow the **guidelines for PR titles and descriptions** here:
https://google.github.io/eng-practices/review/developer/cl-descriptions.html
*particularly* the sections "First Line" and "Body is Informative".
Note: your PR description will be used as the git commit message in a
squash-and-merge if your PR is approved. We may make changes to this as
necessary.
- **Does this PR relate to an open issue?** On the first line, please use the
tag `Fixes #<issue>` to ensure the issue is closed when the PR is merged. Or
use `Updates #<issue>` if the PR is related to an open issue, but does not fix
it. Consider filing an issue if one does not already exist.
- PR descriptions *must* conclude with **release notes** as follows:
```
RELEASE NOTES:
* <component>: <summary>
```
This need not match the PR title.
The summary must:
* be something that gRPC users will understand.
* clearly explain the feature being added, the issue being fixed, or the
behavior being changed, etc. If fixing a bug, be clear about how the bug
can be triggered by an end-user.
* begin with a capital letter and use complete sentences.
* be as short as possible to describe the change being made.
If a PR is *not* end-user visible -- e.g. a cleanup, testing change, or
GitHub-related, use `RELEASE NOTES: n/a`.
### PR Process
- Please **self-review** your code changes before sending your PR. This will
prevent simple, obvious errors from causing delays.
- Maintain a **clean commit history** and use **meaningful commit messages**.
PRs with messy commit histories are difficult to review and won't be merged.
Before sending your PR, ensure your changes are based on top of the latest
`upstream/master` commits, and avoid rebasing in the middle of a code review.
You should **never use `git push -f`** unless absolutely necessary during a
review, as it can interfere with GitHub's tracking of comments.
- Unless your PR is trivial, you should **expect reviewer comments** that you
will need to address before merging. We'll label the PR as `Status: Requires
Reporter Clarification` if we expect you to respond to these comments in a
timely manner. If the PR remains inactive for 6 days, it will be marked as
`stale`, and we will automatically close it after 7 days if we don't hear back
from you. Please feel free to ping issues or bugs if you do not get a response
within a week.
================================================
FILE: Documentation/anti-patterns.md
================================================
## Anti-Patterns of Client creation
### How to properly create a `ClientConn`: `grpc.NewClient`
[`grpc.NewClient`](https://pkg.go.dev/google.golang.org/grpc#NewClient) is the
function in the gRPC library that creates a virtual connection from a client
application to a gRPC server. It takes a target URI (which represents the name
of a logical backend service and resolves to one or more physical addresses) and
a list of options, and returns a
[`ClientConn`](https://pkg.go.dev/google.golang.org/grpc#ClientConn) object that
represents the virtual connection to the server. The `ClientConn` contains one
or more actual connections to real servers and attempts to maintain these
connections by automatically reconnecting to them when they break. `NewClient`
was introduced in gRPC-Go v1.63.
### The wrong way: `grpc.Dial`
[`grpc.Dial`](https://pkg.go.dev/google.golang.org/grpc#Dial) is a deprecated
function that also creates the same virtual connection pool as `grpc.NewClient`.
However, unlike `grpc.NewClient`, it immediately starts connecting and supports
a few additional `DialOption`s that control this initial connection attempt.
These are: `WithBlock`, `WithTimeout`, `WithReturnConnectionError`, and
`FailOnNonTempDialError`.
That `grpc.Dial` creates connections immediately is not a problem in and of
itself, but this behavior differs from how gRPC works in all other languages,
and it can be convenient to have a constructor that does not perform I/O. It
can also be confusing to users, as most people expect a function called `Dial`
to create _a_ connection which may need to be recreated if it is lost.
`grpc.Dial` uses "passthrough" as the default name resolver for backward
compatibility while `grpc.NewClient` uses "dns" as its default name resolver.
This subtle difference is important to legacy systems that also specified a
custom dialer and expected it to receive the target string directly.
For these reasons, using `grpc.Dial` is discouraged. Even though it is marked
as deprecated, we will continue to support it until a v2 is released (and no
plans for a v2 exist at the time this was written).
### Especially bad: using deprecated `DialOptions`
`FailOnNonTempDialError`, `WithBlock`, and `WithReturnConnectionError` are three
`DialOption`s that are only supported by `Dial` because they only affect the
behavior of `Dial` itself. `WithBlock` causes `Dial` to wait until the
`ClientConn` reports its `State` as `connectivity.Connected`. The other two deal
with returning connection errors before the timeout (`WithTimeout` or on the
context when using `DialContext`).
The reason these options can be a problem is that connections with a
`ClientConn` are dynamic -- they may come and go over time. If your client
successfully connects, the server could go down 1 second later, and your RPCs
will fail. "Knowing you are connected" does not tell you much in this regard.
Additionally, _all_ RPCs created on an "idle" or a "connecting" `ClientConn`
will wait until their deadline or until a connection is established before
failing. This means that you don't need to check that a `ClientConn` is "ready"
before starting your RPCs. By default, RPCs will fail if the `ClientConn`
enters the "transient failure" state, but setting `WaitForReady(true)` on a
call will cause it to queue even in the "transient failure" state, and it will
only ever fail due to a deadline, a server response, or a connection loss after
the RPC was sent to a server.
Some users of `Dial` use it as a way to validate the configuration of their
system. If you wish to maintain this behavior but migrate to `NewClient`, you
can call `GetState`, then `Connect` if the state is `Idle` and
`WaitForStateChange` until the channel is connected. However, if this fails,
it does not mean that your configuration was bad - it could also mean the
service is not reachable by the client due to connectivity reasons.
## Best practices for error handling in gRPC
Instead of relying on failures at dial time, we strongly encourage developers to
rely on errors from RPCs. When a client makes an RPC, it can receive an error
response from the server. These errors can provide valuable information about
what went wrong, including information about network issues, server-side errors,
and incorrect usage of the gRPC API.
By handling errors from RPCs correctly, developers can write more reliable and
robust gRPC applications. Here are some best practices for error handling in
gRPC:
- Always check for error responses from RPCs and handle them appropriately.
- Use the `status` field of the error response to determine the type of error
that occurred.
- When retrying failed RPCs, consider using the built-in retry mechanism
provided by gRPC-Go, if available, instead of manually implementing retries.
Refer to the [gRPC-Go retry example
documentation](https://github.com/grpc/grpc-go/blob/master/examples/features/retry/README.md)
for more information. Note that this is not a substitute for client-side
retries as errors that occur after an RPC starts on a server cannot be
retried through gRPC's built-in mechanism.
- If making an outgoing RPC from a server handler, be sure to translate the
status code before returning the error from your method handler. For example,
if the error is an `INVALID_ARGUMENT` status code, that probably means
your service has a bug (otherwise it shouldn't have triggered this error), in
which case `INTERNAL` is more appropriate to return back to your users.
### Example: Handling errors from an RPC
The following code snippet demonstrates how to handle errors from an RPC in
gRPC:
```go
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
res, err := client.MyRPC(ctx, &MyRequest{})
if err != nil {
// Handle the error appropriately,
// log it & return an error to the caller, etc.
log.Printf("Error calling MyRPC: %v", err)
return nil, err
}
// Use the response as appropriate
log.Printf("MyRPC response: %v", res)
```
To determine the type of error that occurred, you can use the status field of
the error response:
```go
resp, err := client.MakeRPC(context.TODO(), request)
if err != nil {
if status, ok := status.FromError(err); ok {
// Handle the error based on its status code
if status.Code() == codes.NotFound {
log.Println("Requested resource not found")
} else {
log.Printf("RPC error: %v", status.Message())
}
} else {
// Handle non-RPC errors
log.Printf("Non-RPC error: %v", err)
}
return
}
// Use the response as needed
log.Printf("Response received: %v", resp)
```
### Example: Using a backoff strategy
When retrying failed RPCs, use a backoff strategy to avoid overwhelming the
server or exacerbating network issues:
```go
var res *MyResponse
var err error
retryableStatusCodes := map[codes.Code]bool{
codes.Unavailable: true, // etc
}
// Retry the RPC a maximum number of times.
for i := 0; i < maxRetries; i++ {
// Make the RPC.
res, err = client.MyRPC(context.TODO(), &MyRequest{})
// Check if the RPC was successful.
if !retryableStatusCodes[status.Code(err)] {
// The RPC was successful or errored in a non-retryable way;
// do not retry.
break
}
// The RPC is retryable; wait for a backoff period before retrying.
backoff := time.Duration(i+1) * time.Second
log.Printf("Error calling MyRPC: %v; retrying in %v", err, backoff)
time.Sleep(backoff)
}
// Check if the RPC was successful after all retries.
if err != nil {
// All retries failed, so handle the error appropriately
log.Printf("Error calling MyRPC: %v", err)
return nil, err
}
// Use the response as appropriate.
log.Printf("MyRPC response: %v", res)
```
================================================
FILE: Documentation/benchmark.md
================================================
# Benchmark
gRPC-Go comes with a set of benchmarking utilities to measure performance.
These utilities can be found in the `benchmark` directory within the project's
root directory.
The main utility, aptly named `benchmain`, supports a host of configurable
parameters to simulate various environments and workloads. For example, if your
server's workload is primarily streaming RPCs with large messages with
compression turned on, invoking `benchmain` in the following way may closely
simulate your application:
```bash
$ go run google.golang.org/grpc/benchmark/benchmain/main.go \
-workloads=streaming \
-reqSizeBytes=1024 \
-respSizeBytes=1024 \
-compression=gzip
```
Pass the `-h` flag to the `benchmain` utility to see other flags and workloads
that are supported.
## Varying Payload Sizes (Weighted Random Distribution)
The `benchmain` utility supports two flags, `-reqPayloadCurveFiles` and
`-respPayloadCurveFiles`, that can be used to specify histograms representing
a weighted random distribution of request and response payload sizes,
respectively. This is useful to simulate workloads with arbitrary payload
sizes.
The options take a comma-separated list of file paths as value. Each file must
be a valid CSV file with three columns in each row. Each row represents a range
of payload sizes (first two columns) and the weight associated with that range
(third column). For example, consider the below file:
```csv
1,32,12.5
128,256,12.5
1024,2048,25.0
```
Assume that `benchmain` is invoked like so:
```bash
$ go run google.golang.org/grpc/benchmark/benchmain/main.go \
-workloads=unary \
-reqPayloadCurveFiles=/path/to/csv \
-respPayloadCurveFiles=/path/to/csv
```
This tells the `benchmain` utility to generate unary RPC requests with a 25%
probability of payload sizes in the ranges 1-32 bytes, 25% probability in the
128-256 bytes range, and 50% probability in the 1024-2048 bytes range. RPC
requests outside these ranges will not be generated.
You may specify multiple CSV files delimited by a comma. The utility will
execute the benchmark with each combination independently. That is, the
following command will execute four benchmarks:
```bash
$ go run google.golang.org/grpc/benchmark/benchmain/main.go \
-workloads=unary \
-reqPayloadCurveFiles=/path/to/csv1,/path/to/csv2 \
-respPayloadCurveFiles=/path/to/csv3,/path/to/csv4
```
You may also combine `PayloadCurveFiles` with `SizeBytes` options. For example:
```
$ go run google.golang.org/grpc/benchmark/benchmain/main.go \
-workloads=unary \
-reqPayloadCurveFiles=/path/to/csv \
-respSizeBytes=1
```
================================================
FILE: Documentation/compression.md
================================================
# Compression
The preferred method for configuring message compression on both clients and
servers is to use
[`encoding.RegisterCompressor`](https://godoc.org/google.golang.org/grpc/encoding#RegisterCompressor)
to register an implementation of a compression algorithm. See
`grpc/encoding/gzip/gzip.go` for an example of how to implement one.
Once a compressor has been registered on the client-side, RPCs may be sent using
it via the
[`UseCompressor`](https://godoc.org/google.golang.org/grpc#UseCompressor)
`CallOption`. Remember that `CallOption`s may be turned into defaults for all
calls from a `ClientConn` by using the
[`WithDefaultCallOptions`](https://godoc.org/google.golang.org/grpc#WithDefaultCallOptions)
`DialOption`. If `UseCompressor` is used and the corresponding compressor has
not been installed, an `Internal` error will be returned to the application
before the RPC is sent.
Server-side, registered compressors will be used automatically to decode request
messages and encode the responses. Servers currently always respond using the
same compression method specified by the client. If the corresponding
compressor has not been registered, an `Unimplemented` status will be returned
to the client.
## Deprecated API
There is a deprecated API for setting compression as well. It is not
recommended for use. However, if you were previously using it, the following
section may be helpful in understanding how it works in combination with the new
API.
### Client-Side
There are two legacy functions and one new function to configure compression:
```go
func WithCompressor(grpc.Compressor) DialOption {}
func WithDecompressor(grpc.Decompressor) DialOption {}
func UseCompressor(name) CallOption {}
```
For outgoing requests, the following rules are applied in order:
1. If `UseCompressor` is used, messages will be compressed using the compressor
named.
* If the compressor named is not registered, an Internal error is returned
back to the client before sending the RPC.
* If UseCompressor("identity"), no compressor will be used, but "identity"
will be sent in the header to the server.
1. If `WithCompressor` is used, messages will be compressed using that
compressor implementation.
1. Otherwise, outbound messages will be uncompressed.
For incoming responses, the following rules are applied in order:
1. If `WithDecompressor` is used and it matches the message's encoding, it will
be used.
1. If a registered compressor matches the response's encoding, it will be used.
1. Otherwise, the stream will be closed and an `Unimplemented` status error will
be returned to the application.
### Server-Side
There are two legacy functions to configure compression:
```go
func RPCCompressor(grpc.Compressor) ServerOption {}
func RPCDecompressor(grpc.Decompressor) ServerOption {}
```
For incoming requests, the following rules are applied in order:
1. If `RPCDecompressor` is used and that decompressor matches the request's
encoding: it will be used.
1. If a registered compressor matches the request's encoding, it will be used.
1. Otherwise, an `Unimplemented` status will be returned to the client.
For outgoing responses, the following rules are applied in order:
1. If `RPCCompressor` is used, that compressor will be used to compress all
response messages.
1. If compression was used for the incoming request and a registered compressor
supports it, that same compression method will be used for the outgoing
response.
1. Otherwise, no compression will be used for the outgoing response.
================================================
FILE: Documentation/concurrency.md
================================================
# Concurrency
In general, gRPC-go provides a concurrency-friendly API. What follows are some
guidelines.
## Clients
A [ClientConn][client-conn] can safely be accessed concurrently. Using
[helloworld][helloworld] as an example, one could share the `ClientConn` across
multiple goroutines to create multiple `GreeterClient` types. In this case,
RPCs would be sent in parallel. `GreeterClient`, generated from the proto
definitions and wrapping `ClientConn`, is also concurrency safe, and may be
directly shared in the same way. Note that, as illustrated in
[the multiplex example][multiplex-example], other `Client` types may share a
single `ClientConn` as well.
## Streams
When using streams, one must take care to avoid calling either `SendMsg` or
`RecvMsg` multiple times against the same [Stream][stream] from different
goroutines. In other words, it's safe to have a goroutine calling `SendMsg` and
another goroutine calling `RecvMsg` on the same stream at the same time. But it
is not safe to call `SendMsg` on the same stream in different goroutines, or to
call `RecvMsg` on the same stream in different goroutines.
## Servers
Each RPC handler attached to a registered server will be invoked in its own
goroutine. For example, [SayHello][say-hello] will be invoked in its own
goroutine. The same is true for service handlers for streaming RPCs, as seen
in the route guide example [here][route-guide-stream]. Similar to clients,
multiple services can be registered to the same server.
[helloworld]: https://github.com/grpc/grpc-go/blob/master/examples/helloworld/greeter_client/main.go#L43
[client-conn]: https://godoc.org/google.golang.org/grpc#ClientConn
[stream]: https://godoc.org/google.golang.org/grpc#Stream
[say-hello]: https://github.com/grpc/grpc-go/blob/master/examples/helloworld/greeter_server/main.go#L41
[route-guide-stream]: https://github.com/grpc/grpc-go/blob/master/examples/route_guide/server/server.go#L126
[multiplex-example]: https://github.com/grpc/grpc-go/tree/master/examples/features/multiplex
================================================
FILE: Documentation/encoding.md
================================================
# Encoding
The gRPC API for sending and receiving is based upon *messages*. However,
messages cannot be transmitted directly over a network; they must first be
converted into *bytes*. This document describes how gRPC-Go converts messages
into bytes and vice-versa for the purposes of network transmission.
## Codecs (Serialization and Deserialization)
A `Codec` contains code to serialize a message into a byte slice (`Marshal`) and
deserialize a byte slice back into a message (`Unmarshal`). `Codec`s are
registered by name into a global registry maintained in the `encoding` package.
### Implementing a `Codec`
A typical `Codec` will be implemented in its own package with an `init` function
that registers itself, and is imported anonymously. For example:
```go
package proto
import "google.golang.org/grpc/encoding"
func init() {
encoding.RegisterCodec(protoCodec{})
}
// ... implementation of protoCodec ...
```
For an example, gRPC's implementation of the `proto` codec can be found in
[`encoding/proto`](https://godoc.org/google.golang.org/grpc/encoding/proto).
### Using a `Codec`
By default, gRPC registers and uses the "proto" codec, so it is not necessary to
do this in your own code to send and receive proto messages. To use another
`Codec` from a client or server:
```go
package myclient
import _ "path/to/another/codec"
```
`Codec`s, by definition, must be symmetric, so the same desired `Codec` should
be registered in both client and server binaries.
On the client-side, to specify a `Codec` to use for message transmission, the
`CallOption` `CallContentSubtype` should be used as follows:
```go
response, err := myclient.MyCall(ctx, request, grpc.CallContentSubtype("mycodec"))
```
As a reminder, all `CallOption`s may be converted into `DialOption`s that become
the default for all RPCs sent through a client using `grpc.WithDefaultCallOptions`:
```go
myclient := grpc.NewClient(target, grpc.WithDefaultCallOptions(grpc.CallContentSubtype("mycodec")))
```
When specified in either of these ways, messages will be encoded using this
codec and sent along with headers indicating the codec (`content-type` set to
`application/grpc+<codec name>`).
On the server-side, using a `Codec` is as simple as registering it into the
global registry (i.e. `import`ing it). If a message is encoded with the content
sub-type supported by a registered `Codec`, it will be used automatically for
decoding the request and encoding the response. Otherwise, for
backward-compatibility reasons, gRPC will attempt to use the "proto" codec. In
an upcoming change (tracked in [this
issue](https://github.com/grpc/grpc-go/issues/1824)), such requests will be
rejected with status code `Unimplemented` instead.
## Compressors (Compression and Decompression)
Sometimes, the resulting serialization of a message is not space-efficient, and
it may be beneficial to compress this byte stream before transmitting it over
the network. To facilitate this operation, gRPC supports a mechanism for
performing compression and decompression.
A `Compressor` contains code to compress and decompress by wrapping `io.Writer`s
and `io.Reader`s, respectively. (The form of `Compress` and `Decompress` were
chosen to most closely match Go's standard package
[implementations](https://golang.org/pkg/compress/) of compressors). Like
`Codec`s, `Compressor`s are registered by name into a global registry maintained
in the `encoding` package.
### Implementing a `Compressor`
A typical `Compressor` will be implemented in its own package with an `init`
function that registers itself, and is imported anonymously. For example:
```go
package gzip
import "google.golang.org/grpc/encoding"
func init() {
encoding.RegisterCompressor(compressor{})
}
// ... implementation of compressor ...
```
An implementation of a `gzip` compressor can be found in
[`encoding/gzip`](https://godoc.org/google.golang.org/grpc/encoding/gzip).
### Using a `Compressor`
By default, gRPC does not register or use any compressors. To use a
`Compressor` from a client or server:
```go
package myclient
import _ "google.golang.org/grpc/encoding/gzip"
```
`Compressor`s, by definition, must be symmetric, so the same desired
`Compressor` should be registered in both client and server binaries.
On the client-side, to specify a `Compressor` to use for message transmission,
the `CallOption` `UseCompressor` should be used as follows:
```go
response, err := myclient.MyCall(ctx, request, grpc.UseCompressor("gzip"))
```
As a reminder, all `CallOption`s may be converted into `DialOption`s that become
the default for all RPCs sent through a client using `grpc.WithDefaultCallOptions`:
```go
myclient := grpc.NewClient(target, grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")))
```
When specified in either of these ways, messages will be compressed using this
compressor and sent along with headers indicating the compressor
(`content-coding` set to `<compressor name>`).
On the server-side, using a `Compressor` is as simple as registering it into the
global registry (i.e. `import`ing it). If a message is compressed with the
content coding supported by a registered `Compressor`, it will be used
automatically for decompressing the request and compressing the response.
Otherwise, the request will be rejected with status code `Unimplemented`.
================================================
FILE: Documentation/grpc-auth-support.md
================================================
# Authentication
As outlined in the
[gRPC authentication guide](https://grpc.io/docs/guides/auth.html), there are a
number of different mechanisms for asserting identity between a client and
server. We'll present some code-samples here demonstrating how to provide TLS
support encryption and identity assertions as well as passing OAuth2 tokens to
services that support it.
## Enabling TLS on a gRPC client
```go
conn, err := grpc.NewClient(serverAddr, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")))
```
## Enabling TLS on a gRPC server
```go
creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
if err != nil {
log.Fatalf("Failed to generate credentials %v", err)
}
lis, err := net.Listen("tcp", ":0")
server := grpc.NewServer(grpc.Creds(creds))
...
server.Serve(lis)
```
## OAuth2
For an example of how to configure client and server to use OAuth2 tokens, see
[here](https://github.com/grpc/grpc-go/tree/master/examples/features/authentication).
### Validating a token on the server
Clients may use
[metadata.MD](https://godoc.org/google.golang.org/grpc/metadata#MD) to store
tokens and other authentication-related data. To gain access to the
`metadata.MD` object, a server may use
[metadata.FromIncomingContext](https://godoc.org/google.golang.org/grpc/metadata#FromIncomingContext).
With a reference to `metadata.MD` on the server, one needs to simply look up the
`authorization` key. Note, all keys stored within `metadata.MD` are normalized
to lowercase. See [here](https://godoc.org/google.golang.org/grpc/metadata#New).
It is possible to configure token validation for all RPCs using an interceptor.
A server may configure either a
[grpc.UnaryInterceptor](https://godoc.org/google.golang.org/grpc#UnaryInterceptor)
or a
[grpc.StreamInterceptor](https://godoc.org/google.golang.org/grpc#StreamInterceptor).
### Adding a token to all outgoing client RPCs
To send an OAuth2 token with each RPC, a client may configure the
`grpc.DialOption`
[grpc.WithPerRPCCredentials](https://godoc.org/google.golang.org/grpc#WithPerRPCCredentials).
Alternatively, a client may also use the `grpc.CallOption`
[grpc.PerRPCCredentials](https://godoc.org/google.golang.org/grpc#PerRPCCredentials)
on each invocation of an RPC.
To create a `credentials.PerRPCCredentials`, use
[oauth.TokenSource](https://godoc.org/google.golang.org/grpc/credentials/oauth#TokenSource).
Note, the OAuth2 implementation of `grpc.PerRPCCredentials` requires a client to
use
[grpc.WithTransportCredentials](https://godoc.org/google.golang.org/grpc#WithTransportCredentials)
to prevent any insecure transmission of tokens.
## Authenticating with Google
### Google Compute Engine (GCE)
```go
conn, err := grpc.NewClient(serverAddr, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), grpc.WithPerRPCCredentials(oauth.NewComputeEngine()))
```
### JWT
```go
jwtCreds, err := oauth.NewServiceAccountFromFile(*serviceAccountKeyFile, *oauthScope)
if err != nil {
log.Fatalf("Failed to create JWT credentials: %v", err)
}
conn, err := grpc.NewClient(serverAddr, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), grpc.WithPerRPCCredentials(jwtCreds))
```
================================================
FILE: Documentation/grpc-metadata.md
================================================
# Metadata
gRPC supports sending metadata between client and server.
This doc shows how to send and receive metadata in gRPC-go.
## Background
Four kinds of service method:
- [Unary RPC](https://grpc.io/docs/guides/concepts.html#unary-rpc)
- [Server streaming RPC](https://grpc.io/docs/guides/concepts.html#server-streaming-rpc)
- [Client streaming RPC](https://grpc.io/docs/guides/concepts.html#client-streaming-rpc)
- [Bidirectional streaming RPC](https://grpc.io/docs/guides/concepts.html#bidirectional-streaming-rpc)
And concept of [metadata].
## Constructing metadata
A metadata can be created using package [metadata].
The type MD is actually a map from string to a list of strings:
```go
type MD map[string][]string
```
Metadata can be read like a normal map.
Note that the value type of this map is `[]string`,
so that users can attach multiple values using a single key.
### Creating a new metadata
A metadata can be created from a `map[string]string` using function `New`:
```go
md := metadata.New(map[string]string{"key1": "val1", "key2": "val2"})
```
Another way is to use `Pairs`.
Values with the same key will be merged into a list:
```go
md := metadata.Pairs(
"key1", "val1",
"key1", "val1-2", // "key1" will have map value []string{"val1", "val1-2"}
"key2", "val2",
)
```
__Note:__ all the keys will be automatically converted to lowercase,
so "key1" and "kEy1" will be the same key and their values will be merged into the same list.
This happens for both `New` and `Pairs`.
### Storing binary data in metadata
In metadata, keys are always strings. But values can be strings or binary data.
To store binary data value in metadata, simply add "-bin" suffix to the key.
The values with "-bin" suffixed keys will be encoded when creating the metadata:
```go
md := metadata.Pairs(
"key", "string value",
"key-bin", string([]byte{96, 102}), // this binary data will be encoded (base64) before sending
// and will be decoded after being transferred.
)
```
## Sending and receiving metadata - client side
Client side metadata sending and receiving examples are available
[here](../examples/features/metadata/client/main.go).
### Sending metadata
There are two ways to send metadata to the server. The recommended way is to append kv pairs to the context using
`AppendToOutgoingContext`. This can be used with or without existing metadata on the context. When there is no prior
metadata, metadata is added; when metadata already exists on the context, kv pairs are merged in.
```go
// create a new context with some metadata
ctx := metadata.AppendToOutgoingContext(ctx, "k1", "v1", "k1", "v2", "k2", "v3")
// later, add some more metadata to the context (e.g. in an interceptor)
ctx := metadata.AppendToOutgoingContext(ctx, "k3", "v4")
// make unary RPC
response, err := client.SomeRPC(ctx, someRequest)
// or make streaming RPC
stream, err := client.SomeStreamingRPC(ctx)
```
Alternatively, metadata may be attached to the context using `NewOutgoingContext`. However, this
replaces any existing metadata in the context, so care must be taken to preserve the existing
metadata if desired. This is slower than using `AppendToOutgoingContext`. An example of this
is below:
```go
// create a new context with some metadata
md := metadata.Pairs("k1", "v1", "k1", "v2", "k2", "v3")
ctx := metadata.NewOutgoingContext(context.Background(), md)
// later, add some more metadata to the context (e.g. in an interceptor)
send, _ := metadata.FromOutgoingContext(ctx)
newMD := metadata.Pairs("k3", "v3")
ctx = metadata.NewOutgoingContext(ctx, metadata.Join(send, newMD))
// make unary RPC
response, err := client.SomeRPC(ctx, someRequest)
// or make streaming RPC
stream, err := client.SomeStreamingRPC(ctx)
```
### Receiving metadata
Metadata that a client can receive includes header and trailer.
#### Unary call
Header and trailer sent along with a unary call can be retrieved using function
[Header] and [Trailer] in [CallOption]:
```go
var header, trailer metadata.MD // variable to store header and trailer
r, err := client.SomeRPC(
ctx,
someRequest,
grpc.Header(&header), // will retrieve header
grpc.Trailer(&trailer), // will retrieve trailer
)
// do something with header and trailer
```
#### Streaming call
For streaming calls including:
- Server streaming RPC
- Client streaming RPC
- Bidirectional streaming RPC
Header and trailer can be retrieved from the returned stream using function
`Header` and `Trailer` in interface [ClientStream]:
```go
stream, err := client.SomeStreamingRPC(ctx)
// retrieve header
header, err := stream.Header()
// retrieve trailer
trailer := stream.Trailer()
```
## Sending and receiving metadata - server side
Server side metadata sending and receiving examples are available
[here](../examples/features/metadata/server/main.go).
### Receiving metadata
To read metadata sent by the client, the server needs to retrieve it from RPC
context using [FromIncomingContext].
If it is a unary call, the RPC handler's context can be used.
For streaming calls, the server needs to get context from the stream.
#### Unary call
```go
func (s *server) SomeRPC(ctx context.Context, in *pb.someRequest) (*pb.someResponse, error) {
md, ok := metadata.FromIncomingContext(ctx)
// do something with metadata
}
```
#### Streaming call
```go
func (s *server) SomeStreamingRPC(stream pb.Service_SomeStreamingRPCServer) error {
md, ok := metadata.FromIncomingContext(stream.Context()) // get context from stream
// do something with metadata
}
```
### Sending metadata
#### Unary call
To send header and trailer to client in unary call, the server can call
[SetHeader] and [SetTrailer] functions in module [grpc].
These two functions take a context as the first parameter.
It should be the RPC handler's context or one derived from it:
```go
func (s *server) SomeRPC(ctx context.Context, in *pb.someRequest) (*pb.someResponse, error) {
// create and set header
header := metadata.Pairs("header-key", "val")
grpc.SetHeader(ctx, header)
// create and set trailer
trailer := metadata.Pairs("trailer-key", "val")
grpc.SetTrailer(ctx, trailer)
}
```
#### Streaming call
For streaming calls, header and trailer can be sent using function
[SetHeader] and [SetTrailer] in interface [ServerStream]:
```go
func (s *server) SomeStreamingRPC(stream pb.Service_SomeStreamingRPCServer) error {
// create and set header
header := metadata.Pairs("header-key", "val")
stream.SetHeader(header)
// create and set trailer
trailer := metadata.Pairs("trailer-key", "val")
stream.SetTrailer(trailer)
}
```
**Important**
Do not use
[FromOutgoingContext] on the server to write metadata to be sent to the client.
[FromOutgoingContext] is for client-side use only.
## Updating metadata from a server interceptor
An example for updating metadata from a server interceptor is
available [here](../examples/features/metadata_interceptor/server/main.go).
[FromIncomingContext]: <https://pkg.go.dev/google.golang.org/grpc/metadata#FromIncomingContext>
[SetHeader]: <https://godoc.org/google.golang.org/grpc#SetHeader>
[SetTrailer]: https://godoc.org/google.golang.org/grpc#SetTrailer
[FromOutgoingContext]: https://pkg.go.dev/google.golang.org/grpc/metadata#FromOutgoingContext
[ServerStream]: https://godoc.org/google.golang.org/grpc#ServerStream
[grpc]: https://godoc.org/google.golang.org/grpc
[ClientStream]: https://godoc.org/google.golang.org/grpc#ClientStream
[Header]: https://godoc.org/google.golang.org/grpc#Header
[Trailer]: https://godoc.org/google.golang.org/grpc#Trailer
[CallOption]: https://godoc.org/google.golang.org/grpc#CallOption
[metadata]: https://godoc.org/google.golang.org/grpc/metadata
================================================
FILE: Documentation/keepalive.md
================================================
# Keepalive
gRPC sends http2 pings on the transport to detect if the connection is down. If
the ping is not acknowledged by the other side within a certain period, the
connection will be closed. Note that pings are only necessary when there's no
activity on the connection.
For how to configure keepalive, see
https://godoc.org/google.golang.org/grpc/keepalive for the options.
## Why do I need this?
Keepalive can be useful to detect TCP level connection failures. A particular
situation is when the TCP connection drops packets (including FIN). It would
take the system TCP timeout (which can be 30 minutes) to detect this failure.
Keepalive would allow gRPC to detect this failure much sooner.
Another usage is (as the name suggests) to keep the connection alive. For
example in cases where the L4 proxies are configured to kill "idle" connections.
Sending pings would make the connections not "idle".
## What should I set?
It should be sufficient for most users to set [client
parameters](https://godoc.org/google.golang.org/grpc/keepalive) as a [dial
option](https://godoc.org/google.golang.org/grpc#WithKeepaliveParams).
## What will happen?
(The behavior described here is specific for gRPC-go, it might be slightly
different in other languages.)
When there's no activity on a connection (note that an ongoing stream results in
__no activity__ when there's no message being sent), after `Time`, a ping will
be sent by the client and the server will send a ping ack when it gets the ping.
Client will wait for `Timeout`, and check if there's any activity on the
connection during this period (a ping ack is an activity).
## What about server side?
Server has similar `Time` and `Timeout` settings as client. Server can also
configure connection max-age. See [server
parameters](https://godoc.org/google.golang.org/grpc/keepalive#ServerParameters)
for details.
### Enforcement policy
[Enforcement
policy](https://godoc.org/google.golang.org/grpc/keepalive#EnforcementPolicy) is
a special setting on server side to protect server from malicious or misbehaving
clients.
Server sends GOAWAY with ENHANCE_YOUR_CALM and close the connection when bad
behaviors are detected:
- Client sends too frequent pings
- Client sends pings when there's no stream and this is disallowed by server
config
================================================
FILE: Documentation/log_levels.md
================================================
# Log Levels
This document describes the different log levels supported by the grpc-go
library, and under what conditions they should be used.
### Info
Info messages are for informational purposes and may aid in the debugging of
applications or the gRPC library.
Examples:
- The name resolver received an update.
- The balancer updated its picker.
- Significant gRPC state is changing.
At verbosity of 0 (the default), any single info message should not be output
more than once every 5 minutes under normal operation.
### Warning
Warning messages indicate problems that are non-fatal for the application, but
could lead to unexpected behavior or subsequent errors.
Examples:
- Resolver could not resolve target name.
- Error received while connecting to a server.
- Lost or corrupt connection with remote endpoint.
### Error
Error messages represent errors in the usage of gRPC that cannot be returned to
the application as errors, or internal gRPC-Go errors that are recoverable.
Internal errors are detected during gRPC tests and will result in test failures.
Examples:
- Invalid arguments passed to a function that cannot return an error.
- An internal error that cannot be returned or would be inappropriate to return
to the user.
### Fatal
Fatal errors are severe internal errors that are unrecoverable. These lead
directly to panics, and are avoided as much as possible.
Example:
- Internal invariant was violated.
- User attempted an action that cannot return an error gracefully, but would
lead to an invalid state if performed.
================================================
FILE: Documentation/proxy.md
================================================
# Proxy
HTTP CONNECT proxies are supported by default in gRPC. The proxy address can be
specified by the environment variables `HTTPS_PROXY` and `NO_PROXY`. (Note that
these environment variables are case insensitive.)
**NOTE**: Using CONNECT proxies via https is not supported. gRPC performs a
plaintext CONNECT handshake to establish a tunnel and does not support the
additional encryption required to secure the initial connection to the proxy
itself.
When using TLS, the gRPC traffic is encrypted end-to-end between the client and
the destination server. Even when using a CONNECT proxy without https, the
security is not compromised, as the proxy only sees the destination address and
cannot intercept the encrypted gRPC data.
## Custom proxy
Currently, proxy support is implemented in the default dialer. It does one more
handshake (a CONNECT handshake in the case of HTTP CONNECT proxy) on the
connection before giving it to gRPC.
If the default proxy doesn't work for you, replace the default dialer with your
custom proxy dialer. This can be done using
[`WithContextDialer`](https://pkg.go.dev/google.golang.org/grpc#WithContextDialer).
================================================
FILE: Documentation/rpc-errors.md
================================================
# RPC Errors
All service method handlers should return `nil` or errors from the
`status.Status` type. Clients have direct access to the errors.
Upon encountering an error, a gRPC server method handler should create a
`status.Status`. In typical usage, one would use [status.New][new-status]
passing in an appropriate [codes.Code][code] as well as a description of the
error to produce a `status.Status`. Calling [status.Err][status-err] converts
the `status.Status` type into an `error`. As a convenience method, there is also
[status.Error][status-error] which obviates the conversion step. Compare:
```
st := status.New(codes.NotFound, "some description")
err := st.Err()
// vs.
err := status.Error(codes.NotFound, "some description")
```
## Adding additional details to errors
In some cases, it may be necessary to add details for a particular error on the
server side. The [status.WithDetails][with-details] method exists for this
purpose. Clients may then read those details by first converting the plain
`error` type back to a [status.Status][status] and then using
[status.Details][details].
## Example
The [example][example] demonstrates the API discussed above and shows how to add
information about rate limits to the error message using `status.Status`.
To run the example, first start the server:
```
$ go run examples/rpc_errors/server/main.go
```
In a separate session, run the client:
```
$ go run examples/rpc_errors/client/main.go
```
On the first run of the client, all is well:
```
2018/03/12 19:39:33 Greeting: Hello world
```
Upon running the client a second time, the client exceeds the rate limit and
receives an error with details:
```
2018/03/19 16:42:01 Quota failure: violations:<subject:"name:world" description:"Limit one greeting per person" >
exit status 1
```
[status]: https://godoc.org/google.golang.org/grpc/status#Status
[new-status]: https://godoc.org/google.golang.org/grpc/status#New
[code]: https://godoc.org/google.golang.org/grpc/codes#Code
[with-details]: https://godoc.org/google.golang.org/grpc/internal/status#Status.WithDetails
[details]: https://godoc.org/google.golang.org/grpc/internal/status#Status.Details
[status-err]: https://godoc.org/google.golang.org/grpc/internal/status#Status.Err
[status-error]: https://godoc.org/google.golang.org/grpc/status#Error
[example]: https://github.com/grpc/grpc-go/tree/master/examples/features/error_details
================================================
FILE: Documentation/server-reflection-tutorial.md
================================================
# gRPC Server Reflection Tutorial
gRPC Server Reflection provides information about publicly-accessible gRPC
services on a server, and assists clients at runtime to construct RPC requests
and responses without precompiled service information. It is used by
[gRPCurl](https://github.com/fullstorydev/grpcurl), which can be used to
introspect server protos and send/receive test RPCs.
## Enable Server Reflection
gRPC-go Server Reflection is implemented in package
[reflection](https://github.com/grpc/grpc-go/tree/master/reflection). To enable
server reflection, you need to import this package and register reflection
service on your gRPC server.
For example, to enable server reflection in `example/helloworld`, we need to
make the following changes:
```diff
--- a/examples/helloworld/greeter_server/main.go
+++ b/examples/helloworld/greeter_server/main.go
@@ -40,6 +40,7 @@ import (
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
+ "google.golang.org/grpc/reflection"
)
const (
@@ -61,6 +62,8 @@ func main() {
}
s := grpc.NewServer()
pb.RegisterGreeterService(s, &pb.GreeterService{SayHello: sayHello})
+ // Register reflection service on gRPC server.
+ reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
```
An example server with reflection registered can be found at
`examples/features/reflection/server`.
## gRPCurl
After enabling Server Reflection in a server application, you can use gRPCurl
to check its services. gRPCurl is built with Go and has packages available.
Instructions on how to install and use gRPCurl can be found at
[gRPCurl Installation](https://github.com/fullstorydev/grpcurl#installation).
## Use gRPCurl to check services
First, start the helloworld server in grpc-go directory:
```sh
$ cd <grpc-go-directory>/examples
$ go run features/reflection/server/main.go
```
output:
```sh
server listening at [::]:50051
```
After installing gRPCurl, open a new terminal and run the commands from the new
terminal.
**NOTE:** gRPCurl expects a TLS-encrypted connection by default. For all of
the commands below, use the `-plaintext` flag to use an unencrypted connection.
### List services and methods
The `list` command lists services exposed at a given port:
- List all the services exposed at a given port
```sh
$ grpcurl -plaintext localhost:50051 list
```
output:
```sh
grpc.examples.echo.Echo
grpc.reflection.v1alpha.ServerReflection
helloworld.Greeter
```
- List all the methods of a service
The `list` command lists methods given the full service name (in the format of
\<package\>.\<service\>).
```sh
$ grpcurl -plaintext localhost:50051 list helloworld.Greeter
```
output:
```sh
helloworld.Greeter.SayHello
```
### Describe services and methods
- Describe all services
The `describe` command inspects a service given its full name (in the format
of \<package\>.\<service\>).
```sh
$ grpcurl -plaintext localhost:50051 describe helloworld.Greeter
```
output:
```sh
helloworld.Greeter is a service:
service Greeter {
rpc SayHello ( .helloworld.HelloRequest ) returns ( .helloworld.HelloReply );
}
```
- Describe all methods of a service
The `describe` command inspects a method given its full name (in the format of
\<package\>.\<service\>.\<method\>).
```sh
$ grpcurl -plaintext localhost:50051 describe helloworld.Greeter.SayHello
```
output:
```sh
helloworld.Greeter.SayHello is a method:
rpc SayHello ( .helloworld.HelloRequest ) returns ( .helloworld.HelloReply );
```
### Inspect message types
We can use the `describe` command to inspect request/response types given the
full name of the type (in the format of \<package\>.\<type\>).
- Get information about the request type
```sh
$ grpcurl -plaintext localhost:50051 describe helloworld.HelloRequest
```
output:
```sh
helloworld.HelloRequest is a message:
message HelloRequest {
string name = 1;
}
```
### Call a remote method
We can send RPCs to a server and get responses using the full method name (in
the format of \<package\>.\<service\>.\<method\>). The `-d <string>` flag
represents the request data and the `-format text` flag indicates that the
request data is in text format.
- Call a unary method
```sh
$ grpcurl -plaintext -format text -d 'name: "gRPCurl"' \
localhost:50051 helloworld.Greeter.SayHello
```
output:
```sh
message: "Hello gRPCurl"
```
================================================
FILE: Documentation/versioning.md
================================================
# Versioning and Releases
Note: This document references terminology defined at http://semver.org.
## Release Frequency
Regular MINOR releases of gRPC-Go are performed every six weeks. Patch releases
to the previous two MINOR releases may be performed on demand or if serious
security problems are discovered.
## Versioning Policy
The gRPC-Go versioning policy follows the Semantic Versioning 2.0.0
specification, with the following exceptions:
- A MINOR version will not _necessarily_ add new functionality.
- MINOR releases will not break backward compatibility, except in the following
circumstances:
- An API was marked as EXPERIMENTAL upon its introduction.
- An API was marked as DEPRECATED in the initial MAJOR release.
- An API is inherently flawed and cannot provide correct or secure behavior.
In these cases, APIs MAY be changed or removed without a MAJOR release.
Otherwise, backward compatibility will be preserved by MINOR releases.
For an API marked as DEPRECATED, an alternative will be available (if
appropriate) for at least three months prior to its removal.
## Release History
Please see our release history on GitHub:
https://github.com/grpc/grpc-go/releases
================================================
FILE: GOVERNANCE.md
================================================
This repository is governed by the gRPC organization's [governance rules](https://github.com/grpc/grpc-community/blob/master/governance.md).
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: MAINTAINERS.md
================================================
This page lists all active maintainers of this repository. If you were a
maintainer and would like to add your name to the Emeritus list, please send us a
PR.
See [GOVERNANCE.md](https://github.com/grpc/grpc-community/blob/master/governance.md)
for governance guidelines and how to become a maintainer.
See [CONTRIBUTING.md](https://github.com/grpc/grpc-community/blob/master/CONTRIBUTING.md)
for general contribution guidelines.
## Maintainers (in alphabetical order)
- [arjan-bal](https://github.com/arjan-bal), Google LLC
- [arvindbr8](https://github.com/arvindbr8), Google LLC
- [atollena](https://github.com/atollena), Datadog, Inc.
- [dfawley](https://github.com/dfawley), Google LLC
- [easwars](https://github.com/easwars), Google LLC
- [gtcooke94](https://github.com/gtcooke94), Google LLC
## Emeritus Maintainers (in alphabetical order)
- [adelez](https://github.com/adelez)
- [aranjans](https://github.com/aranjans)
- [canguler](https://github.com/canguler)
- [cesarghali](https://github.com/cesarghali)
- [erm-g](https://github.com/erm-g)
- [iamqizhao](https://github.com/iamqizhao)
- [jeanbza](https://github.com/jeanbza)
- [jtattermusch](https://github.com/jtattermusch)
- [lyuxuan](https://github.com/lyuxuan)
- [makmukhi](https://github.com/makmukhi)
- [matt-kwong](https://github.com/matt-kwong)
- [menghanl](https://github.com/menghanl)
- [nicolasnoble](https://github.com/nicolasnoble)
- [purnesh42h](https://github.com/purnesh42h)
- [srini100](https://github.com/srini100)
- [yongni](https://github.com/yongni)
- [zasweq](https://github.com/zasweq)
================================================
FILE: Makefile
================================================
all: vet test testrace
build:
go build google.golang.org/grpc/...
clean:
go clean -i google.golang.org/grpc/...
deps:
GO111MODULE=on go get -d -v google.golang.org/grpc/...
proto:
@ if ! which protoc > /dev/null; then \
echo "error: protoc not installed" >&2; \
exit 1; \
fi
go generate google.golang.org/grpc/...
test:
go test -cpu 1,4 -timeout 7m google.golang.org/grpc/...
testsubmodule:
cd security/advancedtls && go test -cpu 1,4 -timeout 7m google.golang.org/grpc/security/advancedtls/...
cd security/authorization && go test -cpu 1,4 -timeout 7m google.golang.org/grpc/security/authorization/...
testrace:
go test -race -cpu 1,4 -timeout 7m google.golang.org/grpc/...
testdeps:
GO111MODULE=on go get -d -v -t google.golang.org/grpc/...
vet: vetdeps
./scripts/vet.sh
vetdeps:
./scripts/vet.sh -install
.PHONY: \
all \
build \
clean \
deps \
proto \
test \
testsubmodule \
testrace \
testdeps \
vet \
vetdeps
================================================
FILE: NOTICE.txt
================================================
Copyright 2014 gRPC authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# gRPC-Go
[][API]
[](https://goreportcard.com/report/github.com/grpc/grpc-go)
[](https://codecov.io/gh/grpc/grpc-go)
The [Go][] implementation of [gRPC][]: A high performance, open source, general
RPC framework that puts mobile and HTTP/2 first. For more information see the
[Go gRPC docs][], or jump directly into the [quick start][].
## Prerequisites
- **[Go][]**: any one of the **two latest major** [releases][go-releases].
## Installation
Simply add the following import to your code, and then `go [build|run|test]`
will automatically fetch the necessary dependencies:
```go
import "google.golang.org/grpc"
```
> **Note:** If you are trying to access `grpc-go` from **China**, see the
> [FAQ](#FAQ) below.
## Learn more
- [Go gRPC docs][], which include a [quick start][] and [API
reference][API] among other resources
- [Low-level technical docs](Documentation) from this repository
- [Performance benchmark][]
- [Examples](examples)
- [Contribution guidelines](CONTRIBUTING.md)
## FAQ
### I/O Timeout Errors
The `golang.org` domain may be blocked from some countries. `go get` usually
produces an error like the following when this happens:
```console
$ go get -u google.golang.org/grpc
package google.golang.org/grpc: unrecognized import path "google.golang.org/grpc" (https fetch: Get https://google.golang.org/grpc?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
```
To build Go code, there are several options:
- Set up a VPN and access google.golang.org through that.
- With Go module support: it is possible to use the `replace` feature of `go
mod` to create aliases for golang.org packages. In your project's directory:
```sh
go mod edit -replace=google.golang.org/grpc=github.com/grpc/grpc-go@latest
go mod tidy
go mod vendor
go build -mod=vendor
```
Again, this will need to be done for all transitive dependencies hosted on
golang.org as well. For details, refer to [golang/go issue
#28652](https://github.com/golang/go/issues/28652).
### Compiling error, undefined: grpc.SupportPackageIsVersion
Please update to the latest version of gRPC-Go using
`go get google.golang.org/grpc`.
### How to turn on logging
The default logger is controlled by environment variables. Turn everything on
like this:
```console
$ export GRPC_GO_LOG_VERBOSITY_LEVEL=99
$ export GRPC_GO_LOG_SEVERITY_LEVEL=info
```
### The RPC failed with error `"code = Unavailable desc = transport is closing"`
This error means the connection the RPC is using was closed, and there are many
possible reasons, including:
1. mis-configured transport credentials, connection failed on handshaking
1. bytes disrupted, possibly by a proxy in between
1. server shutdown
1. Keepalive parameters caused connection shutdown, for example if you have
configured your server to terminate connections regularly to [trigger DNS
lookups](https://github.com/grpc/grpc-go/issues/3170#issuecomment-552517779).
If this is the case, you may want to increase your
[MaxConnectionAgeGrace](https://pkg.go.dev/google.golang.org/grpc/keepalive?tab=doc#ServerParameters),
to allow longer RPC calls to finish.
It can be tricky to debug this because the error happens on the client side but
the root cause of the connection being closed is on the server side. Turn on
logging on __both client and server__, and see if there are any transport
errors.
[API]: https://pkg.go.dev/google.golang.org/grpc
[Go]: https://golang.org
[Go module]: https://github.com/golang/go/wiki/Modules
[gRPC]: https://grpc.io
[Go gRPC docs]: https://grpc.io/docs/languages/go
[Performance benchmark]: https://performance-dot-grpc-testing.appspot.com/explore?dashboard=5180705743044608
[quick start]: https://grpc.io/docs/languages/go/quickstart
[go-releases]: https://golang.org/doc/devel/release.html
================================================
FILE: SECURITY.md
================================================
# Security Policy
For information on gRPC Security Policy and reporting potential security issues, please see [gRPC CVE Process](https://github.com/grpc/proposal/blob/master/P4-grpc-cve-process.md).
================================================
FILE: admin/admin.go
================================================
/*
*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package admin provides a convenient method for registering a collection of
// administration services to a gRPC server. The services registered are:
//
// - Channelz: https://github.com/grpc/proposal/blob/master/A14-channelz.md
//
// - CSDS: https://github.com/grpc/proposal/blob/master/A40-csds-support.md
//
// # Experimental
//
// Notice: All APIs in this package are experimental and may be removed in a
// later release.
package admin
import (
"google.golang.org/grpc"
channelzservice "google.golang.org/grpc/channelz/service"
internaladmin "google.golang.org/grpc/internal/admin"
)
func init() {
// Add a list of default services to admin here. Optional services, like
// CSDS, will be added by other packages.
internaladmin.AddService(func(registrar grpc.ServiceRegistrar) (func(), error) {
channelzservice.RegisterChannelzServiceToServer(registrar)
return nil, nil
})
}
// Register registers the set of admin services to the given server.
//
// The returned cleanup function should be called to clean up the resources
// allocated for the service handlers after the server is stopped.
//
// Note that if `s` is not a *grpc.Server or a *xds.GRPCServer, CSDS will not be
// registered because CSDS generated code is old and doesn't support interface
// `grpc.ServiceRegistrar`.
// https://github.com/envoyproxy/go-control-plane/issues/403
func Register(s grpc.ServiceRegistrar) (cleanup func(), _ error) {
return internaladmin.Register(s)
}
================================================
FILE: admin/admin_test.go
================================================
/*
*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package admin_test
import (
"testing"
"google.golang.org/grpc/admin/test"
"google.golang.org/grpc/codes"
)
func TestRegisterNoCSDS(t *testing.T) {
test.RunRegisterTests(t, test.ExpectedStatusCodes{
ChannelzCode: codes.OK,
// CSDS is not registered because xDS isn't imported.
CSDSCode: codes.Unimplemented,
})
}
================================================
FILE: admin/test/admin_test.go
================================================
/*
*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// This file has the same content as admin_test.go, difference is that this is
// in another package, and it imports "xds", so we can test that csds is
// registered when xds is imported.
package test_test
import (
"testing"
"google.golang.org/grpc/admin/test"
"google.golang.org/grpc/codes"
_ "google.golang.org/grpc/xds"
)
func TestRegisterWithCSDS(t *testing.T) {
test.RunRegisterTests(t, test.ExpectedStatusCodes{
ChannelzCode: codes.OK,
CSDSCode: codes.OK,
})
}
================================================
FILE: admin/test/utils.go
================================================
/*
*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package test contains test only functions for package admin. It's used by
// admin/admin_test.go and admin/test/admin_test.go.
package test
import (
"context"
"net"
"testing"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/admin"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/status"
v3statusgrpc "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
v3statuspb "github.com/envoyproxy/go-control-plane/envoy/service/status/v3"
channelzgrpc "google.golang.org/grpc/channelz/grpc_channelz_v1"
channelzpb "google.golang.org/grpc/channelz/grpc_channelz_v1"
)
const (
defaultTestTimeout = 10 * time.Second
)
// ExpectedStatusCodes contains the expected status code for each RPC (can be
// OK).
type ExpectedStatusCodes struct {
ChannelzCode codes.Code
CSDSCode codes.Code
}
// RunRegisterTests makes a client, runs the RPCs, and compares the status
// codes.
func RunRegisterTests(t *testing.T, ec ExpectedStatusCodes) {
lis, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("cannot create listener: %v", err)
}
server := grpc.NewServer()
defer server.Stop()
cleanup, err := admin.Register(server)
if err != nil {
t.Fatalf("failed to register admin: %v", err)
}
defer cleanup()
go func() {
server.Serve(lis)
}()
conn, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("grpc.NewClient(%q) = %v", lis.Addr().String(), err)
}
t.Run("channelz", func(t *testing.T) {
if err := RunChannelz(conn); status.Code(err) != ec.ChannelzCode {
t.Fatalf("%s RPC failed with error %v, want code %v", "channelz", err, ec.ChannelzCode)
}
})
t.Run("csds", func(t *testing.T) {
if err := RunCSDS(conn); status.Code(err) != ec.CSDSCode {
t.Fatalf("%s RPC failed with error %v, want code %v", "CSDS", err, ec.CSDSCode)
}
})
}
// RunChannelz makes a channelz RPC.
func RunChannelz(conn *grpc.ClientConn) error {
c := channelzgrpc.NewChannelzClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()
_, err := c.GetTopChannels(ctx, &channelzpb.GetTopChannelsRequest{}, grpc.WaitForReady(true))
return err
}
// RunCSDS makes a CSDS RPC.
func RunCSDS(conn *grpc.ClientConn) error {
c := v3statusgrpc.NewClientStatusDiscoveryServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()
_, err := c.FetchClientStatus(ctx, &v3statuspb.ClientStatusRequest{}, grpc.WaitForReady(true))
return err
}
================================================
FILE: attributes/attributes.go
================================================
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package attributes defines a generic key/value store used in various gRPC
// components.
//
// # Experimental
//
// Notice: This package is EXPERIMENTAL and may be changed or removed in a
// later release.
package attributes
import (
"fmt"
"iter"
"maps"
"strings"
)
// Attributes is an immutable struct for storing and retrieving generic
// key/value pairs. Keys must be hashable, and users should define their own
// types for keys. Values should not be modified after they are added to an
// Attributes or if they were received from one. If values implement 'Equal(o
// any) bool', it will be called by (*Attributes).Equal to determine whether
// two values with the same key should be considered equal.
type Attributes struct {
parent *Attributes
key, value any
}
// New returns a new Attributes containing the key/value pair.
func New(key, value any) *Attributes {
return &Attributes{
key: key,
value: value,
}
}
// WithValue returns a new Attributes containing the previous keys and values
// and the new key/value pair. If the same key appears multiple times, the
// last value overwrites all previous values for that key. value should not be
// modified later.
//
// Note that Attributes do not support deletion. Avoid using untyped nil values.
// Since the Value method returns an untyped nil when a key is absent, it is
// impossible to distinguish between a missing key and a key explicitly set to
// an untyped nil. If you need to represent a value being unset, consider
// storing a specific sentinel type or a wrapper struct with a boolean field
// indicating presence.
func (a *Attributes) WithValue(key, value any) *Attributes {
return &Attributes{
parent: a,
key: key,
value: value,
}
}
// Value returns the value associated with these attributes for key, or nil if
// no value is associated with key. The returned value should not be modified.
func (a *Attributes) Value(key any) any {
for cur := a; cur != nil; cur = cur.parent {
if cur.key == key {
return cur.value
}
}
return nil
}
// Equal returns whether a and o are equivalent. If 'Equal(o any) bool' is
// implemented for a value in the attributes, it is called to determine if the
// value matches the one stored in the other attributes. If Equal is not
// implemented, standard equality is used to determine if the two values are
// equal. Note that some types (e.g. maps) aren't comparable by default, so
// they must be wrapped in a struct, or in an alias type, with Equal defined.
func (a *Attributes) Equal(o *Attributes) bool {
if a == nil && o == nil {
return true
}
if a == nil || o == nil {
return false
}
if a == o {
return true
}
m := maps.Collect(o.all())
lenA := 0
for k, v := range a.all() {
lenA++
ov, ok := m[k]
if !ok {
// o missing element of a
return false
}
if eq, ok := v.(interface{ Equal(o any) bool }); ok {
if !eq.Equal(ov) {
return false
}
} else if v != ov {
// Fallback to a standard equality check if Value is unimplemented.
return false
}
}
return lenA == len(m)
}
// String prints the attribute map. If any key or values throughout the map
// implement fmt.Stringer, it calls that method and appends.
func (a *Attributes) String() string {
var sb strings.Builder
sb.WriteString("{")
first := true
for k, v := range a.all() {
if !first {
sb.WriteString(", ")
}
fmt.Fprintf(&sb, "%q: %q ", str(k), str(v))
first = false
}
sb.WriteString("}")
return sb.String()
}
func str(x any) (s string) {
if v, ok := x.(fmt.Stringer); ok {
return fmt.Sprint(v)
} else if v, ok := x.(string); ok {
return v
}
return fmt.Sprintf("<%p>", x)
}
// MarshalJSON helps implement the json.Marshaler interface, thereby rendering
// the Attributes correctly when printing (via pretty.JSON) structs containing
// Attributes as fields.
//
// Is it impossible to unmarshal attributes from a JSON representation and this
// method is meant only for debugging purposes.
func (a *Attributes) MarshalJSON() ([]byte, error) {
return []byte(a.String()), nil
}
// all returns an iterator that yields all key-value pairs in the Attributes
// chain. If a key appears multiple times, only the most recently added value
// is yielded.
func (a *Attributes) all() iter.Seq2[any, any] {
return func(yield func(any, any) bool) {
seen := map[any]bool{}
for cur := a; cur != nil; cur = cur.parent {
if seen[cur.key] {
continue
}
if !yield(cur.key, cur.value) {
return
}
seen[cur.key] = true
}
}
}
================================================
FILE: attributes/attributes_test.go
================================================
/*
*
* Copyright 2019 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package attributes_test
import (
"fmt"
"testing"
"google.golang.org/grpc/attributes"
)
type stringVal struct {
s string
}
func (s stringVal) Equal(o any) bool {
os, ok := o.(stringVal)
return ok && s.s == os.s
}
type stringerVal struct {
s string
}
func (s stringerVal) String() string {
return s.s
}
func ExampleAttributes() {
type keyOne struct{}
type keyTwo struct{}
a := attributes.New(keyOne{}, 1).WithValue(keyTwo{}, stringVal{s: "two"})
fmt.Println("Key one:", a.Value(keyOne{}))
fmt.Println("Key two:", a.Value(keyTwo{}))
// Output:
// Key one: 1
// Key two: {two}
}
func ExampleAttributes_WithValue() {
type keyOne struct{}
type keyTwo struct{}
a := attributes.New(keyOne{}, 1)
a = a.WithValue(keyTwo{}, stringVal{s: "two"})
fmt.Println("Key one:", a.Value(keyOne{}))
fmt.Println("Key two:", a.Value(keyTwo{}))
// Output:
// Key one: 1
// Key two: {two}
}
func ExampleAttributes_String() {
type key struct{}
var typedNil *stringerVal
a1 := attributes.New(key{}, typedNil) // typed nil implements [fmt.Stringer]
a2 := attributes.New(key{}, (*stringerVal)(nil)) // typed nil implements [fmt.Stringer]
a3 := attributes.New(key{}, (*stringVal)(nil)) // typed nil not implements [fmt.Stringer]
a4 := attributes.New(key{}, nil) // untyped nil
a5 := attributes.New(key{}, 1)
a6 := attributes.New(key{}, stringerVal{s: "two"})
a7 := attributes.New(key{}, stringVal{s: "two"})
a8 := attributes.New(1, true)
fmt.Println("a1:", a1.String())
fmt.Println("a2:", a2.String())
fmt.Println("a3:", a3.String())
fmt.Println("a4:", a4.String())
fmt.Println("a5:", a5.String())
fmt.Println("a6:", a6.String())
fmt.Println("a7:", a7.String())
fmt.Println("a8:", a8.String())
// Output:
// a1: {"<%!p(attributes_test.key={})>": "<nil>" }
// a2: {"<%!p(attributes_test.key={})>": "<nil>" }
// a3: {"<%!p(attributes_test.key={})>": "<0x0>" }
// a4: {"<%!p(attributes_test.key={})>": "<%!p(<nil>)>" }
// a5: {"<%!p(attributes_test.key={})>": "<%!p(int=1)>" }
// a6: {"<%!p(attributes_test.key={})>": "two" }
// a7: {"<%!p(attributes_test.key={})>": "<%!p(attributes_test.stringVal={two})>" }
// a8: {"<%!p(int=1)>": "<%!p(bool=true)>" }
}
// Test that two attributes with different content are not Equal.
func TestEqual(t *testing.T) {
type keyOne struct{}
type keyTwo struct{}
tests := []struct {
name string
a *attributes.Attributes
b *attributes.Attributes
want bool
}{
{
name: "different_first_value",
a: attributes.New(keyOne{}, 1).WithValue(keyTwo{}, stringVal{s: "two"}),
b: attributes.New(keyOne{}, 2).WithValue(keyTwo{}, stringVal{s: "two"}),
want: false,
},
{
name: "different_second_value",
a: attributes.New(keyOne{}, 1).WithValue(keyTwo{}, stringVal{s: "one"}),
b: attributes.New(keyOne{}, 1).WithValue(keyTwo{}, stringVal{s: "two"}),
want: false,
},
{
name: "same",
a: attributes.New(keyOne{}, 1).WithValue(keyTwo{}, stringVal{s: "two"}),
b: attributes.New(keyOne{}, 1).WithValue(keyTwo{}, stringVal{s: "two"}),
want: true,
},
{
name: "subset",
a: attributes.New(keyOne{}, 1),
b: attributes.New(keyOne{}, 1).WithValue(keyTwo{}, stringVal{s: "two"}),
want: false,
},
{
name: "superset",
a: attributes.New(keyOne{}, 1).WithValue(keyTwo{}, stringVal{s: "two"}),
b: attributes.New(keyTwo{}, stringVal{s: "two"}),
want: false,
},
{
name: "a_nil",
a: nil,
b: attributes.New(keyOne{}, 1),
want: false,
},
{
name: "b_nil",
a: attributes.New(keyOne{}, 1),
b: nil,
want: false,
},
{
name: "both_nil",
a: nil,
b: nil,
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.a.Equal(tt.b); got != tt.want {
t.Errorf("%+v.Equal(%+v) = %v; want %v", tt.a, tt.b, got, tt.want)
}
// The Equal function should be symmetric, i.e. a.Equals(b) ==
// b.Equals(a).
if got := tt.b.Equal(tt.a); got != tt.want {
t.Errorf("%+v.Equal(%+v) = %v; want %v", tt.b, tt.a, got, tt.want)
}
})
}
}
func BenchmarkWithValue(b *testing.B) {
keys := make([]any, 10)
for i := range 10 {
keys[i] = i
}
b.ReportAllocs()
for b.Loop() {
// 50 endpoints
for range 50 {
a := attributes.New(keys[0], keys[0])
// 10 attributes each.
for j := 1; j < 10; j++ {
a = a.WithValue(keys[j], keys[j])
}
}
}
}
================================================
FILE: authz/audit/audit_logger.go
================================================
/*
*
* Copyright 2023 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package audit contains interfaces for audit logging during authorization.
package audit
import (
"encoding/json"
"sync"
)
// loggerBuilderRegistry holds a map of audit logger builders and a mutex
// to facilitate thread-safe reading/writing operations.
type loggerBuilderRegistry struct {
mu sync.Mutex
builders map[string]LoggerBuilder
}
var (
registry = loggerBuilderRegistry{
builders: make(map[string]LoggerBuilder),
}
)
// RegisterLoggerBuilder registers the builder in a global map
// using b.Name() as the key.
//
// This should only be called during initialization time (i.e. in an init()
// function). If multiple builders are registered with the same name,
// the one registered last will take effect.
func RegisterLoggerBuilder(b LoggerBuilder) {
registry.mu.Lock()
defer registry.mu.Unlock()
registry.builders[b.Name()] = b
}
// GetLoggerBuilder returns a builder with the given name.
// It returns nil if the builder is not found in the registry.
func GetLoggerBuilder(name string) LoggerBuilder {
registry.mu.Lock()
defer registry.mu.Unlock()
return registry.builders[name]
}
// Event contains information passed to the audit logger as part of an
// audit logging event.
type Event struct {
// FullMethodName is the full method name of the audited RPC, in the format
// of "/pkg.Service/Method". For example, "/helloworld.Greeter/SayHello".
FullMethodName string
// Principal is the identity of the caller. Currently it will only be
// available in certificate-based TLS authentication.
Principal string
// PolicyName is the authorization policy name or the xDS RBAC filter name.
PolicyName string
// MatchedRule is the matched rule or policy name in the xDS RBAC filter.
// It will be empty if there is no match.
MatchedRule string
// Authorized indicates whether the audited RPC is authorized or not.
Authorized bool
}
// LoggerConfig represents an opaque data structure holding an audit
// logger configuration. Concrete types representing configuration of specific
// audit loggers must embed this interface to implement it.
type LoggerConfig interface {
loggerConfig()
}
// Logger is the interface to be implemented by audit loggers.
//
// An audit logger is a logger instance that can be configured via the
// authorization policy API or xDS HTTP RBAC filters. When the authorization
// decision meets the condition for audit, all the configured audit loggers'
// Log() method will be invoked to log that event.
//
// Please refer to
// https://github.com/grpc/proposal/blob/master/A59-audit-logging.md for more
// details about audit logging.
type Logger interface {
// Log performs audit logging for the provided audit event.
//
// This method is invoked in the RPC path and therefore implementations
// must not block.
Log(*Event)
}
// LoggerBuilder is the interface to be implemented by audit logger
// builders that are used at runtime to configure and instantiate audit loggers.
//
// Users who want to implement their own audit logging logic should
// implement this interface, along with the Logger interface, and register
// it by calling RegisterLoggerBuilder() at init time.
//
// Please refer to
// https://github.com/grpc/proposal/blob/master/A59-audit-logging.md for more
// details about audit logging.
type LoggerBuilder interface {
// ParseLoggerConfig parses the given JSON bytes into a structured
// logger config this builder can use to build an audit logger.
ParseLoggerConfig(config json.RawMessage) (LoggerConfig, error)
// Build builds an audit logger with the given logger config.
// This will only be called with valid configs returned from
// ParseLoggerConfig() and any runtime issues such as failing to
// create a file should be handled by the logger implementation instead of
// failing the logger instantiation. So implementers need to make sure it
// can return a logger without error at this stage.
Build(LoggerConfig) Logger
// Name returns the name of logger built by this builder.
// This is used to register and pick the builder.
Name() string
}
================================================
FILE: authz/audit/audit_logging_test.go
================================================
/*
*
* Copyright 2023 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package audit_test
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"io"
"os"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"google.golang.org/grpc"
"google.golang.org/grpc/authz"
"google.golang.org/grpc/authz/audit"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/internal/grpctest"
"google.golang.org/grpc/internal/stubserver"
testgrpc "google.golang.org/grpc/interop/grpc_testing"
testpb "google.golang.org/grpc/interop/grpc_testing"
"google.golang.org/grpc/status"
"google.golang.org/grpc/testdata"
_ "google.golang.org/grpc/authz/audit/stdout"
)
type s struct {
grpctest.Tester
}
func Test(t *testing.T) {
grpctest.RunSubTests(t, s{})
}
type statAuditLogger struct {
authzDecisionStat map[bool]int // Map to hold the counts of authorization decisions
lastEvent *audit.Event // Field to store last received event
}
func (s *statAuditLogger) Log(event *audit.Event) {
s.authzDecisionStat[event.Authorized]++
*s.lastEvent = *event
}
type loggerBuilder struct {
authzDecisionStat map[bool]int
lastEvent *audit.Event
}
func (loggerBuilder) Name() string {
return "stat_logger"
}
func (lb *loggerBuilder) Build(audit.LoggerConfig) audit.Logger {
return &statAuditLogger{
authzDecisionStat: lb.authzDecisionStat,
lastEvent: lb.lastEvent,
}
}
func (*loggerBuilder) ParseLoggerConfig(json.RawMessage) (audit.LoggerConfig, error) {
return nil, nil
}
// TestAuditLogger examines audit logging invocations using four different
// authorization policies. It covers scenarios including a disabled audit,
// auditing both 'allow' and 'deny' outcomes, and separately auditing 'allow'
// and 'deny' outcomes. Additionally, it checks if SPIFFE ID from a certificate
// is propagated correctly.
func (s) TestAuditLogger(t *testing.T) {
// Each test data entry contains an authz policy for a grpc server,
// how many 'allow' and 'deny' outcomes we expect (each test case makes 2
// unary calls and one client-streaming call), and a structure to check if
// the audit.Event fields are properly populated. Additionally, we specify
// directly which authz outcome we expect from each type of call.
tests := []struct {
name string
authzPolicy string
wantAuthzOutcomes map[bool]int
eventContent *audit.Event
wantUnaryCallCode codes.Code
wantStreamingCallCode codes.Code
}{
{
name: "No audit",
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_UnaryCall",
"request": {
"paths": [
"/grpc.testing.TestService/UnaryCall"
]
}
}
],
"audit_logging_options": {
"audit_condition": "NONE",
"audit_loggers": [
{
"name": "stat_logger",
"config": {},
"is_optional": false
}
]
}
}`,
wantAuthzOutcomes: map[bool]int{true: 0, false: 0},
wantUnaryCallCode: codes.OK,
wantStreamingCallCode: codes.PermissionDenied,
},
{
name: "Allow All Deny Streaming - Audit All",
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_all",
"request": {
"paths": [
"*"
]
}
}
],
"deny_rules": [
{
"name": "deny_all",
"request": {
"paths": [
"/grpc.testing.TestService/StreamingInputCall"
]
}
}
],
"audit_logging_options": {
"audit_condition": "ON_DENY_AND_ALLOW",
"audit_loggers": [
{
"name": "stat_logger",
"config": {},
"is_optional": false
},
{
"name": "stdout_logger",
"is_optional": false
}
]
}
}`,
wantAuthzOutcomes: map[bool]int{true: 2, false: 1},
eventContent: &audit.Event{
FullMethodName: "/grpc.testing.TestService/StreamingInputCall",
Principal: "spiffe://foo.bar.com/client/workload/1",
PolicyName: "authz",
MatchedRule: "authz_deny_all",
Authorized: false,
},
wantUnaryCallCode: codes.OK,
wantStreamingCallCode: codes.PermissionDenied,
},
{
name: "Allow Unary - Audit Allow",
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_UnaryCall",
"request": {
"paths": [
"/grpc.testing.TestService/UnaryCall"
]
}
}
],
"audit_logging_options": {
"audit_condition": "ON_ALLOW",
"audit_loggers": [
{
"name": "stat_logger",
"config": {},
"is_optional": false
}
]
}
}`,
wantAuthzOutcomes: map[bool]int{true: 2, false: 0},
wantUnaryCallCode: codes.OK,
wantStreamingCallCode: codes.PermissionDenied,
},
{
name: "Allow Typo - Audit Deny",
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_UnaryCall",
"request": {
"paths": [
"/grpc.testing.TestService/UnaryCall_Z"
]
}
}
],
"audit_logging_options": {
"audit_condition": "ON_DENY",
"audit_loggers": [
{
"name": "stat_logger",
"config": {},
"is_optional": false
}
]
}
}`,
wantAuthzOutcomes: map[bool]int{true: 0, false: 3},
wantUnaryCallCode: codes.PermissionDenied,
wantStreamingCallCode: codes.PermissionDenied,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
// Construct the credentials for the tests and the stub server
serverCreds := loadServerCreds(t)
clientCreds := loadClientCreds(t)
ss := &stubserver.StubServer{
UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
},
FullDuplexCallF: func(stream testgrpc.TestService_FullDuplexCallServer) error {
_, err := stream.Recv()
if err != io.EOF {
return err
}
return nil
},
}
// Setup test statAuditLogger, gRPC test server with authzPolicy, unary
// and stream interceptors.
lb := &loggerBuilder{
authzDecisionStat: map[bool]int{true: 0, false: 0},
lastEvent: &audit.Event{},
}
audit.RegisterLoggerBuilder(lb)
i, _ := authz.NewStatic(test.authzPolicy)
s := grpc.NewServer(grpc.Creds(serverCreds), grpc.ChainUnaryInterceptor(i.UnaryInterceptor), grpc.ChainStreamInterceptor(i.StreamInterceptor))
defer s.Stop()
ss.S = s
stubserver.StartTestService(t, ss)
// Setup gRPC test client with certificates containing a SPIFFE Id.
cc, err := grpc.NewClient(ss.Address, grpc.WithTransportCredentials(clientCreds))
if err != nil {
t.Fatalf("grpc.NewClient(%v) failed: %v", ss.Address, err)
}
defer cc.Close()
client := testgrpc.NewTestServiceClient(cc)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if _, err := client.UnaryCall(ctx, &testpb.SimpleRequest{}); status.Code(err) != test.wantUnaryCallCode {
t.Errorf("Unexpected UnaryCall fail: got %v want %v", err, test.wantUnaryCallCode)
}
if _, err := client.UnaryCall(ctx, &testpb.SimpleRequest{}); status.Code(err) != test.wantUnaryCallCode {
t.Errorf("Unexpected UnaryCall fail: got %v want %v", err, test.wantUnaryCallCode)
}
stream, err := client.StreamingInputCall(ctx)
if err != nil {
t.Fatalf("StreamingInputCall failed: %v", err)
}
req := &testpb.StreamingInputCallRequest{
Payload: &testpb.Payload{
Body: []byte("hi"),
},
}
if err := stream.Send(req); err != nil && err != io.EOF {
t.Fatalf("stream.Send failed: %v", err)
}
if _, err := stream.CloseAndRecv(); status.Code(err) != test.wantStreamingCallCode {
t.Errorf("Unexpected stream.CloseAndRecv fail: got %v want %v", err, test.wantStreamingCallCode)
}
// Compare expected number of allows/denies with content of the internal
// map of statAuditLogger.
if diff := cmp.Diff(lb.authzDecisionStat, test.wantAuthzOutcomes); diff != "" {
t.Errorf("Authorization decisions do not match\ndiff (-got +want):\n%s", diff)
}
// Compare last event received by statAuditLogger with expected event.
if test.eventContent != nil {
if diff := cmp.Diff(lb.lastEvent, test.eventContent); diff != "" {
t.Errorf("Unexpected message\ndiff (-got +want):\n%s", diff)
}
}
})
}
}
// loadServerCreds constructs TLS containing server certs and CA
func loadServerCreds(t *testing.T) credentials.TransportCredentials {
t.Helper()
cert := loadKeys(t, "x509/server1_cert.pem", "x509/server1_key.pem")
certPool := loadCACerts(t, "x509/client_ca_cert.pem")
return credentials.NewTLS(&tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
Certificates: []tls.Certificate{cert},
ClientCAs: certPool,
})
}
// loadClientCreds constructs TLS containing client certs and CA
func loadClientCreds(t *testing.T) credentials.TransportCredentials {
t.Helper()
cert := loadKeys(t, "x509/client_with_spiffe_cert.pem", "x509/client_with_spiffe_key.pem")
roots := loadCACerts(t, "x509/server_ca_cert.pem")
return credentials.NewTLS(&tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: roots,
ServerName: "x.test.example.com",
})
}
// loadKeys loads X509 key pair from the provided file paths.
// It is used for loading both client and server certificates for the test
func loadKeys(t *testing.T, certPath, key string) tls.Certificate {
t.Helper()
cert, err := tls.LoadX509KeyPair(testdata.Path(certPath), testdata.Path(key))
if err != nil {
t.Fatalf("tls.LoadX509KeyPair(%q, %q) failed: %v", certPath, key, err)
}
return cert
}
// loadCACerts loads CA certificates and constructs x509.CertPool
// It is used for loading both client and server CAs for the test
func loadCACerts(t *testing.T, certPath string) *x509.CertPool {
t.Helper()
ca, err := os.ReadFile(testdata.Path(certPath))
if err != nil {
t.Fatalf("os.ReadFile(%q) failed: %v", certPath, err)
}
roots := x509.NewCertPool()
if !roots.AppendCertsFromPEM(ca) {
t.Fatal("Failed to append certificates")
}
return roots
}
================================================
FILE: authz/audit/stdout/stdout_logger.go
================================================
/*
*
* Copyright 2023 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
// Package stdout defines an stdout audit logger.
package stdout
import (
"encoding/json"
"log"
"os"
"time"
"google.golang.org/grpc/authz/audit"
"google.golang.org/grpc/grpclog"
)
var grpcLogger = grpclog.Component("authz-audit")
// Name is the string to identify this logger type in the registry
const Name = "stdout_logger"
func init() {
audit.RegisterLoggerBuilder(&loggerBuilder{
goLogger: log.New(os.Stdout, "", 0),
})
}
type event struct {
FullMethodName string `json:"rpc_method"`
Principal string `json:"principal"`
PolicyName string `json:"policy_name"`
MatchedRule string `json:"matched_rule"`
Authorized bool `json:"authorized"`
Timestamp string `json:"timestamp"` // Time when the audit event is logged via Log method
}
// logger implements the audit.logger interface by logging to standard output.
type logger struct {
goLogger *log.Logger
}
// Log marshals the audit.Event to json and prints it to standard output.
func (l *logger) Log(event *audit.Event) {
jsonContainer := map[string]any{
"grpc_audit_log": convertEvent(event),
}
jsonBytes, err := json.Marshal(jsonContainer)
if err != nil {
grpcLogger.Errorf("failed to marshal AuditEvent data to JSON: %v", err)
return
}
l.goLogger.Println(string(jsonBytes))
}
// loggerConfig represents the configuration for the stdout logger.
// It is currently empty and implements the audit.Logger interface by embedding it.
type loggerConfig struct {
audit.LoggerConfig
}
type loggerBuilder struct {
goLogger *log.Logger
}
func (loggerBuilder) Name() string {
return Name
}
// Build returns a new instance of the stdout logger.
// Passed in configuration is ignored as the stdout logger does not
// expect any configuration to be provided.
func (lb *loggerBuilder) Build(audit.LoggerConfig) audit.Logger {
return &logger{
goLogger: lb.goLogger,
}
}
// ParseLoggerConfig is a no-op since the stdout logger does not accept any configuration.
func (*loggerBuilder) ParseLoggerConfig(config json.RawMessage) (audit.LoggerConfig, error) {
if len(config) != 0 && string(config) != "{}" {
grpcLogger.Warningf("Stdout logger doesn't support custom configs. Ignoring:\n%s", string(config))
}
return &loggerConfig{}, nil
}
func convertEvent(auditEvent *audit.Event) *event {
return &event{
FullMethodName: auditEvent.FullMethodName,
Principal: auditEvent.Principal,
PolicyName: auditEvent.PolicyName,
MatchedRule: auditEvent.MatchedRule,
Authorized: auditEvent.Authorized,
Timestamp: time.Now().Format(time.RFC3339Nano),
}
}
================================================
FILE: authz/audit/stdout/stdout_logger_test.go
================================================
/*
*
* Copyright 2023 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package stdout
import (
"bytes"
"encoding/json"
"log"
"os"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"google.golang.org/grpc/authz/audit"
"google.golang.org/grpc/internal/grpctest"
)
type s struct {
grpctest.Tester
}
func Test(t *testing.T) {
grpctest.RunSubTests(t, s{})
}
func (s) TestStdoutLogger_Log(t *testing.T) {
tests := map[string]struct {
event *audit.Event
wantMessage string
wantErr string
}{
"few fields": {
event: &audit.Event{PolicyName: "test policy", Principal: "test principal"},
wantMessage: `{"fullMethodName":"","principal":"test principal","policyName":"test policy","matchedRule":"","authorized":false`,
},
"all fields": {
event: &audit.Event{
FullMethodName: "/helloworld.Greeter/SayHello",
Principal: "spiffe://example.org/ns/default/sa/default/backend",
PolicyName: "example-policy",
MatchedRule: "dev-access",
Authorized: true,
},
wantMessage: `{"fullMethodName":"/helloworld.Greeter/SayHello",` +
`"principal":"spiffe://example.org/ns/default/sa/default/backend","policyName":"example-policy",` +
`"matchedRule":"dev-access","authorized":true`,
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
before := time.Now().Unix()
var buf bytes.Buffer
builder := &loggerBuilder{goLogger: log.New(&buf, "", 0)}
auditLogger := builder.Build(nil)
auditLogger.Log(test.event)
var container map[string]any
if err := json.Unmarshal(buf.Bytes(), &container); err != nil {
t.Fatalf("Failed to unmarshal audit log event: %v", err)
}
innerEvent := extractEvent(container["grpc_audit_log"].(map[string]any))
if innerEvent.Timestamp == "" {
t.Fatalf("Resulted event has no timestamp: %v", innerEvent)
}
after := time.Now().Unix()
innerEventUnixTime, err := time.Parse(time.RFC3339Nano, innerEvent.Timestamp)
if err != nil {
t.Fatalf("Failed to convert event timestamp into Unix time format: %v", err)
}
if before > innerEventUnixTime.Unix() || after < innerEventUnixTime.Unix() {
t.Errorf("The audit event timestamp is outside of the test interval: test start %v, event timestamp %v, test end %v", before, innerEventUnixTime.Unix(), after)
}
if diff := cmp.Diff(trimEvent(innerEvent), test.event); diff != "" {
t.Fatalf("Unexpected message\ndiff (-got +want):\n%s", diff)
}
})
}
}
func (s) TestStdoutLoggerBuilder_NilConfig(t *testing.T) {
builder := &loggerBuilder{
goLogger: log.New(os.Stdout, "", log.LstdFlags),
}
config, err := builder.ParseLoggerConfig(nil)
if err != nil {
t.Fatalf("Failed to parse stdout logger configuration: %v", err)
}
if l := builder.Build(config); l == nil {
t.Fatal("Failed to build stdout audit logger")
}
}
func (s) TestStdoutLoggerBuilder_Registration(t *testing.T) {
if audit.GetLoggerBuilder("stdout_logger") == nil {
t.Fatal("stdout logger is not registered")
}
}
// extractEvent extracts an stdout.event from a map
// unmarshalled from a logged json message.
func extractEvent(container map[string]any) event {
return event{
FullMethodName: container["rpc_method"].(string),
Principal: container["principal"].(string),
PolicyName: container["policy_name"].(string),
MatchedRule: container["matched_rule"].(string),
Authorized: container["authorized"].(bool),
Timestamp: container["timestamp"].(string),
}
}
// trimEvent converts a logged stdout.event into an audit.Event
// by removing Timestamp field. It is used for comparing events during testing.
func trimEvent(testEvent event) *audit.Event {
return &audit.Event{
FullMethodName: testEvent.FullMethodName,
Principal: testEvent.Principal,
PolicyName: testEvent.PolicyName,
MatchedRule: testEvent.MatchedRule,
Authorized: testEvent.Authorized,
}
}
================================================
FILE: authz/grpc_authz_end2end_test.go
================================================
/*
*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package authz_test
import (
"context"
"crypto/tls"
"crypto/x509"
"io"
"os"
"testing"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/authz"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/internal/grpctest"
"google.golang.org/grpc/internal/stubserver"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/grpc/testdata"
testgrpc "google.golang.org/grpc/interop/grpc_testing"
testpb "google.golang.org/grpc/interop/grpc_testing"
)
type s struct {
grpctest.Tester
}
func Test(t *testing.T) {
grpctest.RunSubTests(t, s{})
}
var authzTests = map[string]struct {
authzPolicy string
md metadata.MD
wantStatus *status.Status
}{
"DeniesRPCMatchInDenyNoMatchInAllow": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_StreamingOutputCall",
"request": {
"paths":
[
"/grpc.testing.TestService/StreamingOutputCall"
]
}
}
],
"deny_rules":
[
{
"name": "deny_TestServiceCalls",
"request": {
"paths":
[
"/grpc.testing.TestService/*"
],
"headers":
[
{
"key": "key-abc",
"values":
[
"val-abc",
"val-def"
]
}
]
}
}
]
}`,
md: metadata.Pairs("key-abc", "val-abc"),
wantStatus: status.New(codes.PermissionDenied, "unauthorized RPC request rejected"),
},
"DeniesRPCMatchInDenyAndAllow": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_all",
"request": {
"paths":
[
"*"
]
}
}
],
"deny_rules":
[
{
"name": "deny_all",
"request": {
"paths":
[
"*"
]
}
}
]
}`,
wantStatus: status.New(codes.PermissionDenied, "unauthorized RPC request rejected"),
},
"AllowsRPCNoMatchInDenyMatchInAllow": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_all"
}
],
"deny_rules":
[
{
"name": "deny_TestServiceCalls",
"request": {
"paths":
[
"/grpc.testing.TestService/UnaryCall",
"/grpc.testing.TestService/StreamingInputCall"
],
"headers":
[
{
"key": "key-abc",
"values":
[
"val-abc",
"val-def"
]
}
]
}
}
]
}`,
md: metadata.Pairs("key-xyz", "val-xyz"),
wantStatus: status.New(codes.OK, ""),
},
"DeniesRPCNoMatchInDenyAndAllow": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_some_user",
"source": {
"principals":
[
"some_user"
]
}
}
],
"deny_rules":
[
{
"name": "deny_StreamingOutputCall",
"request": {
"paths":
[
"/grpc.testing.TestService/StreamingOutputCall"
]
}
}
]
}`,
wantStatus: status.New(codes.PermissionDenied, "unauthorized RPC request rejected"),
},
"AllowsRPCEmptyDenyMatchInAllow": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_UnaryCall",
"request":
{
"paths":
[
"/grpc.testing.TestService/UnaryCall"
]
}
},
{
"name": "allow_StreamingInputCall",
"request":
{
"paths":
[
"/grpc.testing.TestService/StreamingInputCall"
]
}
}
]
}`,
wantStatus: status.New(codes.OK, ""),
},
"DeniesRPCEmptyDenyNoMatchInAllow": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_StreamingOutputCall",
"request":
{
"paths":
[
"/grpc.testing.TestService/StreamingOutputCall"
]
}
}
]
}`,
wantStatus: status.New(codes.PermissionDenied, "unauthorized RPC request rejected"),
},
"DeniesRPCRequestWithPrincipalsFieldOnUnauthenticatedConnection": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_authenticated",
"source": {
"principals": ["*", ""]
}
}
]
}`,
wantStatus: status.New(codes.PermissionDenied, "unauthorized RPC request rejected"),
},
"DeniesRPCRequestNoMatchInAllowFailsPresenceMatch": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_TestServiceCalls",
"request": {
"paths":
[
"/grpc.testing.TestService/*"
],
"headers":
[
{
"key": "key-abc",
"values":
[
"*"
]
}
]
}
}
]
}`,
md: metadata.Pairs("key-abc", ""),
wantStatus: status.New(codes.PermissionDenied, "unauthorized RPC request rejected"),
},
}
func (s) TestStaticPolicyEnd2End(t *testing.T) {
for name, test := range authzTests {
t.Run(name, func(t *testing.T) {
// Start a gRPC server with gRPC authz unary and stream server interceptors.
i, _ := authz.NewStatic(test.authzPolicy)
stub := &stubserver.StubServer{
UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
},
StreamingInputCallF: func(stream testgrpc.TestService_StreamingInputCallServer) error {
for {
_, err := stream.Recv()
if err == io.EOF {
return stream.SendAndClose(&testpb.StreamingInputCallResponse{})
}
if err != nil {
return err
}
}
},
S: grpc.NewServer(grpc.ChainUnaryInterceptor(i.UnaryInterceptor), grpc.ChainStreamInterceptor(i.StreamInterceptor)),
}
stubserver.StartTestService(t, stub)
defer stub.Stop()
// Establish a connection to the server.
cc, err := grpc.NewClient(stub.Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("grpc.NewClient(%v) failed: %v", stub.Address, err)
}
defer cc.Close()
client := testgrpc.NewTestServiceClient(cc)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = metadata.NewOutgoingContext(ctx, test.md)
// Verifying authorization decision for Unary RPC.
_, err = client.UnaryCall(ctx, &testpb.SimpleRequest{})
if got := status.Convert(err); got.Code() != test.wantStatus.Code() || got.Message() != test.wantStatus.Message() {
t.Fatalf("[UnaryCall] error want:{%v} got:{%v}", test.wantStatus.Err(), got.Err())
}
// Verifying authorization decision for Streaming RPC.
stream, err := client.StreamingInputCall(ctx)
if err != nil {
t.Fatalf("failed StreamingInputCall err: %v", err)
}
req := &testpb.StreamingInputCallRequest{
Payload: &testpb.Payload{
Body: []byte("hi"),
},
}
if err := stream.Send(req); err != nil && err != io.EOF {
t.Fatalf("failed stream.Send err: %v", err)
}
_, err = stream.CloseAndRecv()
if got := status.Convert(err); got.Code() != test.wantStatus.Code() || got.Message() != test.wantStatus.Message() {
t.Fatalf("[StreamingCall] error want:{%v} got:{%v}", test.wantStatus.Err(), got.Err())
}
})
}
}
func (s) TestAllowsRPCRequestWithPrincipalsFieldOnTLSAuthenticatedConnection(t *testing.T) {
authzPolicy := `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_authenticated",
"source": {
"principals": ["*", ""]
}
}
]
}`
// Start a gRPC server with gRPC authz unary server interceptor.
i, _ := authz.NewStatic(authzPolicy)
creds, err := credentials.NewServerTLSFromFile(testdata.Path("x509/server1_cert.pem"), testdata.Path("x509/server1_key.pem"))
if err != nil {
t.Fatalf("failed to generate credentials: %v", err)
}
stub := &stubserver.StubServer{
UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
},
S: grpc.NewServer(grpc.Creds(creds), grpc.ChainUnaryInterceptor(i.UnaryInterceptor)),
}
stubserver.StartTestService(t, stub)
defer stub.S.Stop()
// Establish a connection to the server.
creds, err = credentials.NewClientTLSFromFile(testdata.Path("x509/server_ca_cert.pem"), "x.test.example.com")
if err != nil {
t.Fatalf("failed to load credentials: %v", err)
}
cc, err := grpc.NewClient(stub.Address, grpc.WithTransportCredentials(creds))
if err != nil {
t.Fatalf("grpc.NewClient(%v) failed: %v", stub.Address, err)
}
defer cc.Close()
client := testgrpc.NewTestServiceClient(cc)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Verifying authorization decision.
if _, err = client.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil {
t.Fatalf("client.UnaryCall(_, _) = %v; want nil", err)
}
}
func (s) TestAllowsRPCRequestWithPrincipalsFieldOnMTLSAuthenticatedConnection(t *testing.T) {
authzPolicy := `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_authenticated",
"source": {
"principals": ["*", ""]
}
}
]
}`
// Start a gRPC server with gRPC authz unary server interceptor.
i, _ := authz.NewStatic(authzPolicy)
cert, err := tls.LoadX509KeyPair(testdata.Path("x509/server1_cert.pem"), testdata.Path("x509/server1_key.pem"))
if err != nil {
t.Fatalf("tls.LoadX509KeyPair(x509/server1_cert.pem, x509/server1_key.pem) failed: %v", err)
}
ca, err := os.ReadFile(testdata.Path("x509/client_ca_cert.pem"))
if err != nil {
t.Fatalf("os.ReadFile(x509/client_ca_cert.pem) failed: %v", err)
}
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(ca) {
t.Fatal("failed to append certificates")
}
creds := credentials.NewTLS(&tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
Certificates: []tls.Certificate{cert},
ClientCAs: certPool,
})
stub := &stubserver.StubServer{
UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
},
S: grpc.NewServer(grpc.Creds(creds), grpc.ChainUnaryInterceptor(i.UnaryInterceptor)),
}
stubserver.StartTestService(t, stub)
defer stub.Stop()
// Establish a connection to the server.
cert, err = tls.LoadX509KeyPair(testdata.Path("x509/client1_cert.pem"), testdata.Path("x509/client1_key.pem"))
if err != nil {
t.Fatalf("tls.LoadX509KeyPair(x509/client1_cert.pem, x509/client1_key.pem) failed: %v", err)
}
ca, err = os.ReadFile(testdata.Path("x509/server_ca_cert.pem"))
if err != nil {
t.Fatalf("os.ReadFile(x509/server_ca_cert.pem) failed: %v", err)
}
roots := x509.NewCertPool()
if !roots.AppendCertsFromPEM(ca) {
t.Fatal("failed to append certificates")
}
creds = credentials.NewTLS(&tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: roots,
ServerName: "x.test.example.com",
})
cc, err := grpc.NewClient(stub.Address, grpc.WithTransportCredentials(creds))
if err != nil {
t.Fatalf("grpc.NewClient(%v) failed: %v", stub.Address, err)
}
defer cc.Close()
client := testgrpc.NewTestServiceClient(cc)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Verifying authorization decision.
if _, err = client.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil {
t.Fatalf("client.UnaryCall(_, _) = %v; want nil", err)
}
}
func (s) TestFileWatcherEnd2End(t *testing.T) {
for name, test := range authzTests {
t.Run(name, func(t *testing.T) {
file := createTmpPolicyFile(t, name, []byte(test.authzPolicy))
i, _ := authz.NewFileWatcher(file, 1*time.Second)
defer i.Close()
stub := &stubserver.StubServer{
UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
},
StreamingInputCallF: func(stream testgrpc.TestService_StreamingInputCallServer) error {
for {
_, err := stream.Recv()
if err == io.EOF {
return stream.SendAndClose(&testpb.StreamingInputCallResponse{})
}
if err != nil {
return err
}
}
},
// Start a gRPC server with gRPC authz unary and stream server interceptors.
S: grpc.NewServer(grpc.ChainUnaryInterceptor(i.UnaryInterceptor), grpc.ChainStreamInterceptor(i.StreamInterceptor)),
}
stubserver.StartTestService(t, stub)
defer stub.Stop()
// Establish a connection to the server.
cc, err := grpc.NewClient(stub.Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("grpc.NewClient(%v) failed: %v", stub.Address, err)
}
defer cc.Close()
client := testgrpc.NewTestServiceClient(cc)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ctx = metadata.NewOutgoingContext(ctx, test.md)
// Verifying authorization decision for Unary RPC.
_, err = client.UnaryCall(ctx, &testpb.SimpleRequest{})
if got := status.Convert(err); got.Code() != test.wantStatus.Code() || got.Message() != test.wantStatus.Message() {
t.Fatalf("[UnaryCall] error want:{%v} got:{%v}", test.wantStatus.Err(), got.Err())
}
// Verifying authorization decision for Streaming RPC.
stream, err := client.StreamingInputCall(ctx)
if err != nil {
t.Fatalf("failed StreamingInputCall : %v", err)
}
req := &testpb.StreamingInputCallRequest{
Payload: &testpb.Payload{
Body: []byte("hi"),
},
}
if err := stream.Send(req); err != nil && err != io.EOF {
t.Fatalf("failed stream.Send : %v", err)
}
_, err = stream.CloseAndRecv()
if got := status.Convert(err); got.Code() != test.wantStatus.Code() || got.Message() != test.wantStatus.Message() {
t.Fatalf("[StreamingCall] error want:{%v} got:{%v}", test.wantStatus.Err(), got.Err())
}
})
}
}
func retryUntil(ctx context.Context, tsc testgrpc.TestServiceClient, want *status.Status) (lastErr error) {
for ctx.Err() == nil {
_, lastErr = tsc.UnaryCall(ctx, &testpb.SimpleRequest{})
if s := status.Convert(lastErr); s.Code() == want.Code() && s.Message() == want.Message() {
return nil
}
time.Sleep(20 * time.Millisecond)
}
return lastErr
}
func (s) TestFileWatcher_ValidPolicyRefresh(t *testing.T) {
valid1 := authzTests["DeniesRPCMatchInDenyAndAllow"]
file := createTmpPolicyFile(t, "valid_policy_refresh", []byte(valid1.authzPolicy))
i, _ := authz.NewFileWatcher(file, 100*time.Millisecond)
defer i.Close()
stub := &stubserver.StubServer{
UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
},
// Start a gRPC server with gRPC authz unary server interceptor.
S: grpc.NewServer(grpc.ChainUnaryInterceptor(i.UnaryInterceptor)),
}
stubserver.StartTestService(t, stub)
defer stub.Stop()
// Establish a connection to the server.
cc, err := grpc.NewClient(stub.Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("grpc.NewClient(%v) failed: %v", stub.Address, err)
}
defer cc.Close()
client := testgrpc.NewTestServiceClient(cc)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Verifying authorization decision.
_, err = client.UnaryCall(ctx, &testpb.SimpleRequest{})
if got := status.Convert(err); got.Code() != valid1.wantStatus.Code() || got.Message() != valid1.wantStatus.Message() {
t.Fatalf("client.UnaryCall(_, _) = %v; want = %v", got.Err(), valid1.wantStatus.Err())
}
// Rewrite the file with a different valid authorization policy.
valid2 := authzTests["AllowsRPCEmptyDenyMatchInAllow"]
if err := os.WriteFile(file, []byte(valid2.authzPolicy), os.ModePerm); err != nil {
t.Fatalf("os.WriteFile(%q) failed: %v", file, err)
}
// Verifying authorization decision.
if got := retryUntil(ctx, client, valid2.wantStatus); got != nil {
t.Fatalf("client.UnaryCall(_, _) = %v; want = %v", got, valid2.wantStatus.Err())
}
}
func (s) TestFileWatcher_InvalidPolicySkipReload(t *testing.T) {
valid := authzTests["DeniesRPCMatchInDenyAndAllow"]
file := createTmpPolicyFile(t, "invalid_policy_skip_reload", []byte(valid.authzPolicy))
i, _ := authz.NewFileWatcher(file, 20*time.Millisecond)
defer i.Close()
stub := &stubserver.StubServer{
UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
},
// Start a gRPC server with gRPC authz unary server interceptors.
S: grpc.NewServer(grpc.ChainUnaryInterceptor(i.UnaryInterceptor)),
}
stubserver.StartTestService(t, stub)
defer stub.Stop()
// Establish a connection to the server.
cc, err := grpc.NewClient(stub.Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("grpc.NewClient(%v) failed: %v", stub.Address, err)
}
defer cc.Close()
client := testgrpc.NewTestServiceClient(cc)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Verifying authorization decision.
_, err = client.UnaryCall(ctx, &testpb.SimpleRequest{})
if got := status.Convert(err); got.Code() != valid.wantStatus.Code() || got.Message() != valid.wantStatus.Message() {
t.Fatalf("client.UnaryCall(_, _) = %v; want = %v", got.Err(), valid.wantStatus.Err())
}
// Skips the invalid policy update, and continues to use the valid policy.
if err := os.WriteFile(file, []byte("{}"), os.ModePerm); err != nil {
t.Fatalf("os.WriteFile(%q) failed: %v", file, err)
}
// Wait 40 ms for background go routine to read updated files.
time.Sleep(40 * time.Millisecond)
// Verifying authorization decision.
_, err = client.UnaryCall(ctx, &testpb.SimpleRequest{})
if got := status.Convert(err); got.Code() != valid.wantStatus.Code() || got.Message() != valid.wantStatus.Message() {
t.Fatalf("client.UnaryCall(_, _) = %v; want = %v", got.Err(), valid.wantStatus.Err())
}
}
func (s) TestFileWatcher_RecoversFromReloadFailure(t *testing.T) {
valid1 := authzTests["DeniesRPCMatchInDenyAndAllow"]
file := createTmpPolicyFile(t, "recovers_from_reload_failure", []byte(valid1.authzPolicy))
i, _ := authz.NewFileWatcher(file, 100*time.Millisecond)
defer i.Close()
stub := &stubserver.StubServer{
UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
return &testpb.SimpleResponse{}, nil
},
S: grpc.NewServer(grpc.ChainUnaryInterceptor(i.UnaryInterceptor)),
}
stubserver.StartTestService(t, stub)
defer stub.Stop()
// Establish a connection to the server.
cc, err := grpc.NewClient(stub.Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("grpc.NewClient(%v) failed: %v", stub.Address, err)
}
defer cc.Close()
client := testgrpc.NewTestServiceClient(cc)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Verifying authorization decision.
_, err = client.UnaryCall(ctx, &testpb.SimpleRequest{})
if got := status.Convert(err); got.Code() != valid1.wantStatus.Code() || got.Message() != valid1.wantStatus.Message() {
t.Fatalf("client.UnaryCall(_, _) = %v; want = %v", got.Err(), valid1.wantStatus.Err())
}
// Skips the invalid policy update, and continues to use the valid policy.
if err := os.WriteFile(file, []byte("{}"), os.ModePerm); err != nil {
t.Fatalf("os.WriteFile(%q) failed: %v", file, err)
}
// Wait 120 ms for background go routine to read updated files.
time.Sleep(120 * time.Millisecond)
// Verifying authorization decision.
_, err = client.UnaryCall(ctx, &testpb.SimpleRequest{})
if got := status.Convert(err); got.Code() != valid1.wantStatus.Code() || got.Message() != valid1.wantStatus.Message() {
t.Fatalf("client.UnaryCall(_, _) = %v; want = %v", got.Err(), valid1.wantStatus.Err())
}
// Rewrite the file with a different valid authorization policy.
valid2 := authzTests["AllowsRPCEmptyDenyMatchInAllow"]
if err := os.WriteFile(file, []byte(valid2.authzPolicy), os.ModePerm); err != nil {
t.Fatalf("os.WriteFile(%q) failed: %v", file, err)
}
// Verifying authorization decision.
if got := retryUntil(ctx, client, valid2.wantStatus); got != nil {
t.Fatalf("client.UnaryCall(_, _) = %v; want = %v", got, valid2.wantStatus.Err())
}
}
================================================
FILE: authz/grpc_authz_server_interceptors.go
================================================
/*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package authz
import (
"bytes"
"context"
"fmt"
"os"
"sync/atomic"
"time"
"unsafe"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/xds/rbac"
"google.golang.org/grpc/status"
)
var logger = grpclog.Component("authz")
// StaticInterceptor contains engines used to make authorization decisions. It
// either contains two engines deny engine followed by an allow engine or only
// one allow engine.
type StaticInterceptor struct {
engines rbac.ChainEngine
}
// NewStatic returns a new StaticInterceptor from a static authorization policy
// JSON string.
func NewStatic(authzPolicy string) (*StaticInterceptor, error) {
rbacs, policyName, err := translatePolicy(authzPolicy)
if err != nil {
return nil, err
}
chainEngine, err := rbac.NewChainEngine(rbacs, policyName)
if err != nil {
return nil, err
}
return &StaticInterceptor{*chainEngine}, nil
}
// UnaryInterceptor intercepts incoming Unary RPC requests.
// Only authorized requests are allowed to pass. Otherwise, an unauthorized
// error is returned to the client.
func (i *StaticInterceptor) UnaryInterceptor(ctx context.Context, req any, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
err := i.engines.IsAuthorized(ctx)
if err != nil {
if status.Code(err) == codes.PermissionDenied {
if logger.V(2) {
logger.Infof("unauthorized RPC request rejected: %v", err)
}
return nil, status.Errorf(codes.PermissionDenied, "unauthorized RPC request rejected")
}
return nil, err
}
return handler(ctx, req)
}
// StreamInterceptor intercepts incoming Stream RPC requests.
// Only authorized requests are allowed to pass. Otherwise, an unauthorized
// error is returned to the client.
func (i *StaticInterceptor) StreamInterceptor(srv any, ss grpc.ServerStream, _ *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
err := i.engines.IsAuthorized(ss.Context())
if err != nil {
if status.Code(err) == codes.PermissionDenied {
if logger.V(2) {
logger.Infof("unauthorized RPC request rejected: %v", err)
}
return status.Errorf(codes.PermissionDenied, "unauthorized RPC request rejected")
}
return err
}
return handler(srv, ss)
}
// FileWatcherInterceptor contains details used to make authorization decisions
// by watching a file path that contains authorization policy in JSON format.
type FileWatcherInterceptor struct {
internalInterceptor unsafe.Pointer // *StaticInterceptor
policyFile string
policyContents []byte
refreshDuration time.Duration
cancel context.CancelFunc
}
// NewFileWatcher returns a new FileWatcherInterceptor from a policy file
// that contains JSON string of authorization policy and a refresh duration to
// specify the amount of time between policy refreshes.
func NewFileWatcher(file string, duration time.Duration) (*FileWatcherInterceptor, error) {
if file == "" {
return nil, fmt.Errorf("authorization policy file path is empty")
}
if duration <= time.Duration(0) {
return nil, fmt.Errorf("requires refresh interval(%v) greater than 0s", duration)
}
i := &FileWatcherInterceptor{policyFile: file, refreshDuration: duration}
if err := i.updateInternalInterceptor(); err != nil {
return nil, err
}
ctx, cancel := context.WithCancel(context.Background())
i.cancel = cancel
// Create a background go routine for policy refresh.
go i.run(ctx)
return i, nil
}
func (i *FileWatcherInterceptor) run(ctx context.Context) {
ticker := time.NewTicker(i.refreshDuration)
for {
if err := i.updateInternalInterceptor(); err != nil {
logger.Warningf("authorization policy reload status err: %v", err)
}
select {
case <-ctx.Done():
ticker.Stop()
return
case <-ticker.C:
}
}
}
// updateInternalInterceptor checks if the policy file that is watching has changed,
// and if so, updates the internalInterceptor with the policy. Unlike the
// constructor, if there is an error in reading the file or parsing the policy, the
// previous internalInterceptors will not be replaced.
func (i *FileWatcherInterceptor) updateInternalInterceptor() error {
policyContents, err := os.ReadFile(i.policyFile)
if err != nil {
return fmt.Errorf("policyFile(%s) read failed: %v", i.policyFile, err)
}
if bytes.Equal(i.policyContents, policyContents) {
return nil
}
i.policyContents = policyContents
policyContentsString := string(policyContents)
interceptor, err := NewStatic(policyContentsString)
if err != nil {
return err
}
atomic.StorePointer(&i.internalInterceptor, unsafe.Pointer(interceptor))
logger.Infof("authorization policy reload status: successfully loaded new policy %v", policyContentsString)
return nil
}
// Close cleans up resources allocated by the interceptor.
func (i *FileWatcherInterceptor) Close() {
i.cancel()
}
// UnaryInterceptor intercepts incoming Unary RPC requests.
// Only authorized requests are allowed to pass. Otherwise, an unauthorized
// error is returned to the client.
func (i *FileWatcherInterceptor) UnaryInterceptor(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
return ((*StaticInterceptor)(atomic.LoadPointer(&i.internalInterceptor))).UnaryInterceptor(ctx, req, info, handler)
}
// StreamInterceptor intercepts incoming Stream RPC requests.
// Only authorized requests are allowed to pass. Otherwise, an unauthorized
// error is returned to the client.
func (i *FileWatcherInterceptor) StreamInterceptor(srv any, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
return ((*StaticInterceptor)(atomic.LoadPointer(&i.internalInterceptor))).StreamInterceptor(srv, ss, info, handler)
}
================================================
FILE: authz/grpc_authz_server_interceptors_test.go
================================================
/*
*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package authz_test
import (
"fmt"
"os"
"path"
"testing"
"time"
"google.golang.org/grpc/authz"
)
func createTmpPolicyFile(t *testing.T, dirSuffix string, policy []byte) string {
t.Helper()
// Create a temp directory. Passing an empty string for the first argument
// uses the system temp directory.
dir, err := os.MkdirTemp("", dirSuffix)
if err != nil {
t.Fatalf("os.MkdirTemp() failed: %v", err)
}
t.Logf("Using tmpdir: %s", dir)
// Write policy into file.
filename := path.Join(dir, "policy.json")
if err := os.WriteFile(filename, policy, os.ModePerm); err != nil {
t.Fatalf("os.WriteFile(%q) failed: %v", filename, err)
}
t.Logf("Wrote policy %s to file at %s", string(policy), filename)
return filename
}
func (s) TestNewStatic(t *testing.T) {
tests := map[string]struct {
authzPolicy string
wantErr error
}{
"InvalidPolicyFailsToCreateInterceptor": {
authzPolicy: `{}`,
wantErr: fmt.Errorf(`"name" is not present`),
},
"ValidPolicyCreatesInterceptor": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_all"
}
]
}`,
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
if _, err := authz.NewStatic(test.authzPolicy); fmt.Sprint(err) != fmt.Sprint(test.wantErr) {
t.Fatalf("NewStatic(%v) returned err: %v, want err: %v", test.authzPolicy, err, test.wantErr)
}
})
}
}
func (s) TestNewFileWatcher(t *testing.T) {
tests := map[string]struct {
authzPolicy string
refreshDuration time.Duration
wantErr error
}{
"InvalidRefreshDurationFailsToCreateInterceptor": {
refreshDuration: time.Duration(0),
wantErr: fmt.Errorf("requires refresh interval(0s) greater than 0s"),
},
"InvalidPolicyFailsToCreateInterceptor": {
authzPolicy: `{}`,
refreshDuration: time.Duration(1),
wantErr: fmt.Errorf(`"name" is not present`),
},
"ValidPolicyCreatesInterceptor": {
authzPolicy: `{
"name": "authz",
"allow_rules":
[
{
"name": "allow_all"
}
]
}`,
refreshDuration: time.Duration(1),
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
file := createTmpPolicyFile(t, name, []byte(test.authzPolicy))
i, err := authz.NewFileWatcher(file, test.refreshDuration)
if fmt.Sprint(err) != fmt.Sprint(test.wantErr) {
t.Fatalf("NewFileWatcher(%v) returned err: %v, want err: %v", test.authzPolicy, err, test.wantErr)
}
if i != nil {
i.Close()
}
})
}
}
================================================
FILE: authz/rbac_translator.go
================================================
/*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Package authz exposes methods to manage authorization within gRPC.
//
// # Experimental
//
// Notice: This package is EXPERIMENTAL and may be changed or removed
// in a later release.
package authz
import (
"bytes"
"encoding/json"
"fmt"
"strings"
v1xdsudpatypepb "github.com/cncf/xds/go/udpa/type/v1"
v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
v3rbacpb "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3"
v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
v3matcherpb "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/structpb"
)
// This is used when converting a custom config from raw JSON to a TypedStruct
// The TypeURL of the TypeStruct will be "grpc.authz.audit_logging/<name>"
const typeURLPrefix = "grpc.authz.audit_logging/"
type header struct {
Key string
Values []string
}
type peer struct {
Principals []string
}
type request struct {
Paths []string
Headers []header
}
type rule struct {
Name string
Source peer
Request request
}
type auditLogger struct {
Name string `json:"name"`
Config *structpb.Struct `json:"config"`
IsOptional bool `json:"is_optional"`
}
type auditLoggingOptions struct {
AuditCondition string `json:"audit_condition"`
AuditLoggers []*auditLogger `json:"audit_loggers"`
}
// Represents the SDK authorization policy provided by user.
type authorizationPolicy struct {
Name string
DenyRules []rule `json:"deny_rules"`
AllowRules []rule `json:"allow_rules"`
AuditLoggingOptions auditLoggingOptions `json:"audit_logging_options"`
}
func principalOr(principals []*v3rbacpb.Principal) *v3rbacpb.Principal {
return &v3rbacpb.Principal{
Identifier: &v3rbacpb.Principal_OrIds{
OrIds: &v3rbacpb.Principal_Set{
Ids: principals,
},
},
}
}
func permissionOr(permission []*v3rbacpb.Permission) *v3rbacpb.Permission {
return &v3rbacpb.Permission{
Rule: &v3rbacpb.Permission_OrRules{
OrRules: &v3rbacpb.Permission_Set{
Rules: permission,
},
},
}
}
func permissionAnd(permission []*v3rbacpb.Permission) *v3rbacpb.Permission {
return &v3rbacpb.Permission{
Rule: &v3rbacpb.Permission_AndRules{
AndRules: &v3rbacpb.Permission_Set{
Rules: permission,
},
},
}
}
func getStringMatcher(value string) *v3matcherpb.StringMatcher {
switch {
case value == "*":
return &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{
SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
}
case strings.HasSuffix(value, "*"):
prefix := strings.TrimSuffix(value, "*")
return &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Prefix{Prefix: prefix},
}
case strings.HasPrefix(value, "*"):
suffix := strings.TrimPrefix(value, "*")
return &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Suffix{Suffix: suffix},
}
default:
return &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: value},
}
}
}
func getHeaderMatcher(key, value string) *v3routepb.HeaderMatcher {
switch {
case value == "*":
return &v3routepb.HeaderMatcher{
Name: key,
HeaderMatchSpecifier: &v3routepb.HeaderMatcher_SafeRegexMatch{
SafeRegexMatch: &v3matcherpb.RegexMatcher{Regex: ".+"}},
}
case strings.HasSuffix(value, "*"):
prefix := strings.TrimSuffix(value, "*")
return &v3routepb.HeaderMatcher{
Name: key,
HeaderMatchSpecifier: &v3routepb.HeaderMatcher_PrefixMatch{PrefixMatch: prefix},
}
case strings.HasPrefix(value, "*"):
suffix := strings.TrimPrefix(value, "*")
return &v3routepb.HeaderMatcher{
Name: key,
HeaderMatchSpecifier: &v3routepb.HeaderMatcher_SuffixMatch{SuffixMatch: suffix},
}
default:
return &v3routepb.HeaderMatcher{
Name: key,
HeaderMatchSpecifier: &v3routepb.HeaderMatcher_ExactMatch{ExactMatch: value},
}
}
}
func parsePrincipalNames(principalNames []string) []*v3rbacpb.Principal {
ps := make([]*v3rbacpb.Principal, 0, len(principalNames))
for _, principalName := range principalNames {
newPrincipalName := &v3rbacpb.Principal{
Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{
PrincipalName: getStringMatcher(principalName),
},
}}
ps = append(ps, newPrincipalName)
}
return ps
}
func parsePeer(source peer) *v3rbacpb.Principal {
if len(source.Principals) == 0 {
return &v3rbacpb.Principal{
Identifier: &v3rbacpb.Principal_Any{
Any: true,
},
}
}
return principalOr(parsePrincipalNames(source.Principals))
}
func parsePaths(paths []string) []*v3rbacpb.Permission {
ps := make([]*v3rbacpb.Permission, 0, len(paths))
for _, path := range paths {
newPath := &v3rbacpb.Permission{
Rule: &v3rbacpb.Permission_UrlPath{
UrlPath: &v3matcherpb.PathMatcher{
Rule: &v3matcherpb.PathMatcher_Path{Path: getStringMatcher(path)}}}}
ps = append(ps, newPath)
}
return ps
}
func parseHeaderValues(key string, values []string) []*v3rbacpb.Permission {
vs := make([]*v3rbacpb.Permission, 0, len(values))
for _, value := range values {
newHeader := &v3rbacpb.Permission{
Rule: &v3rbacpb.Permission_Header{
Header: getHeaderMatcher(key, value)}}
vs = append(vs, newHeader)
}
return vs
}
var unsupportedHeaders = map[string]bool{
"host": true,
"connection": true,
"keep-alive": true,
"proxy-authenticate": true,
"proxy-authorization": true,
"te": true,
"trailer": true,
"transfer-encoding": true,
"upgrade": true,
}
func unsupportedHeader(key string) bool {
return key[0] == ':' || strings.HasPrefix(key, "grpc-") || unsupportedHeaders[key]
}
func parseHeaders(headers []header) ([]*v3rbacpb.Permission, error) {
hs := make([]*v3rbacpb.Permission, 0, len(headers))
for i, header := range headers {
if header.Key == "" {
return nil, fmt.Errorf(`"headers" %d: "key" is not present`, i)
}
header.Key = strings.ToLower(header.Key)
if unsupportedHeader(header.Key) {
return nil, fmt.Errorf(`"headers" %d: unsupported "key" %s`, i, header.Key)
}
if len(header.Values) == 0 {
return nil, fmt.Errorf(`"headers" %d: "values" is not present`, i)
}
values := parseHeaderValues(header.Key, header.Values)
hs = append(hs, permissionOr(values))
}
return hs, nil
}
func parseRequest(request request) (*v3rbacpb.Permission, error) {
var and []*v3rbacpb.Permission
if len(request.Paths) > 0 {
and = append(and, permissionOr(parsePaths(request.Paths)))
}
if len(request.Headers) > 0 {
headers, err := parseHeaders(request.Headers)
if err != nil {
return nil, err
}
and = append(and, permissionAnd(headers))
}
if len(and) > 0 {
return permissionAnd(and), nil
}
return &v3rbacpb.Permission{
Rule: &v3rbacpb.Permission_Any{
Any: true,
},
}, nil
}
func parseRules(rules []rule, prefixName string) (map[string]*v3rbacpb.Policy, error) {
policies := make(map[string]*v3rbacpb.Policy)
for i, rule := range rules {
if rule.Name == "" {
return policies, fmt.Errorf(`%d: "name" is not present`, i)
}
permission, err := parseRequest(rule.Request)
if err != nil {
return nil, fmt.Errorf("%d: %v", i, err)
}
policyName := prefixName + "_" + rule.Name
policies[policyName] = &v3rbacpb.Policy{
Principals: []*v3rbacpb.Principal{parsePeer(rule.Source)},
Permissions: []*v3rbacpb.Permission{permission},
}
}
return policies, nil
}
// Parse auditLoggingOptions to the associated RBAC protos. The single
// auditLoggingOptions results in two different parsed protos, one for the allow
// policy and one for the deny policy
func (options *auditLoggingOptions) toProtos() (allow *v3rbacpb.RBAC_AuditLoggingOptions, deny *v3rbacpb.RBAC_AuditLoggingOptions, err error) {
allow = &v3rbacpb.RBAC_AuditLoggingOptions{}
deny = &v3rbacpb.RBAC_AuditLoggingOptions{}
if options.AuditCondition != "" {
rbacCondition, ok := v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition_value[options.AuditCondition]
if !ok {
return nil, nil, fmt.Errorf("failed to parse AuditCondition %v. Allowed values {NONE, ON_DENY, ON_ALLOW, ON_DENY_AND_ALLOW}", options.AuditCondition)
}
allow.AuditCondition = v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition(rbacCondition)
deny.AuditCondition = toDenyCondition(v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition(rbacCondition))
}
for i, config := range options.AuditLoggers {
if config.Name == "" {
return nil, nil, fmt.Errorf("missing required field: name in audit_logging_options.audit_loggers[%v]", i)
}
if config.Config == nil {
config.Config = &structpb.Struct{}
}
typedStruct := &v1xdsudpatypepb.TypedStruct{
TypeUrl: typeURLPrefix + config.Name,
Value: config.Config,
}
customConfig, err := anypb.New(typedStruct)
if err != nil {
return nil, nil, fmt.Errorf("error parsing custom audit logger config: %v", err)
}
logger := &v3corepb.TypedExtensionConfig{Name: config.Name, TypedConfig: customConfig}
rbacConfig := v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
IsOptional: config.IsOptional,
AuditLogger: logger,
}
allow.LoggerConfigs = append(allow.LoggerConfigs, &rbacConfig)
deny.LoggerConfigs = append(deny.LoggerConfigs, &rbacConfig)
}
return allow, deny, nil
}
// Maps the AuditCondition coming from AuditLoggingOptions to the proper
// condition for the deny policy RBAC proto
func toDenyCondition(condition v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition) v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition {
// Mapping the overall policy AuditCondition to what it must be for the Deny and Allow RBAC
// See gRPC A59 for details - https://github.com/grpc/proposal/pull/346/files
// |Authorization Policy |DENY RBAC |ALLOW RBAC |
// |----------------------|-------------------|---------------------|
// |NONE |NONE |NONE |
// |ON_DENY |ON_DENY |ON_DENY |
// |ON_ALLOW |NONE |ON_ALLOW |
// |ON_DENY_AND_ALLOW |ON_DENY |ON_DENY_AND_ALLOW |
switch condition {
case v3rbacpb.RBAC_AuditLoggingOptions_NONE:
return v3rbacpb.RBAC_AuditLoggingOptions_NONE
case v3rbacpb.RBAC_AuditLoggingOptions_ON_DENY:
return v3rbacpb.RBAC_AuditLoggingOptions_ON_DENY
case v3rbacpb.RBAC_AuditLoggingOptions_ON_ALLOW:
return v3rbacpb.RBAC_AuditLoggingOptions_NONE
case v3rbacpb.RBAC_AuditLoggingOptions_ON_DENY_AND_ALLOW:
return v3rbacpb.RBAC_AuditLoggingOptions_ON_DENY
default:
return v3rbacpb.RBAC_AuditLoggingOptions_NONE
}
}
// translatePolicy translates SDK authorization policy in JSON format to two
// Envoy RBAC polices (deny followed by allow policy) or only one Envoy RBAC
// allow policy. Also returns the overall policy name. If the input policy
// cannot be parsed or is invalid, an error will be returned.
func translatePolicy(policyStr string) ([]*v3rbacpb.RBAC, string, error) {
policy := &authorizationPolicy{}
d := json.NewDecoder(bytes.NewReader([]byte(policyStr)))
d.DisallowUnknownFields()
if err := d.Decode(policy); err != nil {
return nil, "", fmt.Errorf("failed to unmarshal policy: %v", err)
}
if policy.Name == "" {
return nil, "", fmt.Errorf(`"name" is not present`)
}
if len(policy.AllowRules) == 0 {
return nil, "", fmt.Errorf(`"allow_rules" is not present`)
}
allowLogger, denyLogger, err := policy.AuditLoggingOptions.toProtos()
if err != nil {
return nil, "", err
}
rbacs := make([]*v3rbacpb.RBAC, 0, 2)
if len(policy.DenyRules) > 0 {
denyPolicies, err := parseRules(policy.DenyRules, policy.Name)
if err != nil {
return nil, "", fmt.Errorf(`"deny_rules" %v`, err)
}
denyRBAC := &v3rbacpb.RBAC{
Action: v3rbacpb.RBAC_DENY,
Policies: denyPolicies,
AuditLoggingOptions: denyLogger,
}
rbacs = append(rbacs, denyRBAC)
}
allowPolicies, err := parseRules(policy.AllowRules, policy.Name)
if err != nil {
return nil, "", fmt.Errorf(`"allow_rules" %v`, err)
}
allowRBAC := &v3rbacpb.RBAC{Action: v3rbacpb.RBAC_ALLOW, Policies: allowPolicies, AuditLoggingOptions: allowLogger}
return append(rbacs, allowRBAC), policy.Name, nil
}
================================================
FILE: authz/rbac_translator_test.go
================================================
/*
*
* Copyright 2021 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package authz
import (
"strings"
"testing"
v1xdsudpatypepb "github.com/cncf/xds/go/udpa/type/v1"
"github.com/google/go-cmp/cmp"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/structpb"
v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
v3rbacpb "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3"
v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
v3matcherpb "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
)
func TestTranslatePolicy(t *testing.T) {
tests := map[string]struct {
authzPolicy string
wantErr string
wantPolicies []*v3rbacpb.RBAC
wantPolicyName string
}{
"valid policy": {
authzPolicy: `{
"name": "authz",
"deny_rules": [
{
"name": "deny_policy_1",
"source": {
"principals":[
"spiffe://foo.abc",
"spiffe://bar*",
"*baz",
"spiffe://abc.*.com"
]
}
}],
"allow_rules": [
{
"name": "allow_policy_1",
"source": {
"principals":["*"]
},
"request": {
"paths": ["path-foo*"]
}
},
{
"name": "allow_policy_2",
"request": {
"paths": [
"path-bar",
"*baz"
],
"headers": [
{
"key": "key-1",
"values": ["foo", "*bar"]
},
{
"key": "key-2",
"values": ["baz*"]
}
]
}
}]
}`,
wantPolicies: []*v3rbacpb.RBAC{
{
Action: v3rbacpb.RBAC_DENY,
Policies: map[string]*v3rbacpb.Policy{
"authz_deny_policy_1": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: "spiffe://foo.abc"},
}},
}},
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Prefix{Prefix: "spiffe://bar"},
}},
}},
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Suffix{Suffix: "baz"},
}},
}},
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: "spiffe://abc.*.com"},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{},
},
{
Action: v3rbacpb.RBAC_ALLOW,
Policies: map[string]*v3rbacpb.Policy{
"authz_allow_policy_1": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_AndRules{AndRules: &v3rbacpb.Permission_Set{
Rules: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_OrRules{OrRules: &v3rbacpb.Permission_Set{
Rules: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_UrlPath{
UrlPath: &v3matcherpb.PathMatcher{Rule: &v3matcherpb.PathMatcher_Path{Path: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Prefix{Prefix: "path-foo"},
}}},
}},
},
}}},
},
}}},
},
},
"authz_allow_policy_2": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Any{Any: true}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_AndRules{AndRules: &v3rbacpb.Permission_Set{
Rules: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_OrRules{OrRules: &v3rbacpb.Permission_Set{
Rules: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_UrlPath{
UrlPath: &v3matcherpb.PathMatcher{Rule: &v3matcherpb.PathMatcher_Path{Path: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: "path-bar"},
}}},
}},
{Rule: &v3rbacpb.Permission_UrlPath{
UrlPath: &v3matcherpb.PathMatcher{Rule: &v3matcherpb.PathMatcher_Path{Path: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Suffix{Suffix: "baz"},
}}},
}},
},
}}},
{Rule: &v3rbacpb.Permission_AndRules{AndRules: &v3rbacpb.Permission_Set{
Rules: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_OrRules{OrRules: &v3rbacpb.Permission_Set{
Rules: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Header{
Header: &v3routepb.HeaderMatcher{
Name: "key-1", HeaderMatchSpecifier: &v3routepb.HeaderMatcher_ExactMatch{ExactMatch: "foo"},
},
}},
{Rule: &v3rbacpb.Permission_Header{
Header: &v3routepb.HeaderMatcher{
Name: "key-1", HeaderMatchSpecifier: &v3routepb.HeaderMatcher_SuffixMatch{SuffixMatch: "bar"},
},
}},
},
}}},
{Rule: &v3rbacpb.Permission_OrRules{OrRules: &v3rbacpb.Permission_Set{
Rules: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Header{
Header: &v3routepb.HeaderMatcher{
Name: "key-2", HeaderMatchSpecifier: &v3routepb.HeaderMatcher_PrefixMatch{PrefixMatch: "baz"},
},
}},
},
}}},
},
}}},
},
}}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{},
},
},
wantPolicyName: "authz",
},
"allow authenticated": {
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_authenticated",
"source": {
"principals":["*", ""]
}
}]
}`,
wantPolicies: []*v3rbacpb.RBAC{
{
Action: v3rbacpb.RBAC_ALLOW,
Policies: map[string]*v3rbacpb.Policy{
"authz_allow_authenticated": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
}},
}},
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: ""},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{},
},
},
},
"audit_logging_ALLOW empty config": {
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_authenticated",
"source": {
"principals":["*", ""]
}
}],
"deny_rules": [
{
"name": "deny_policy_1",
"source": {
"principals":[
"spiffe://foo.abc"
]
}
}],
"audit_logging_options": {
"audit_condition": "ON_ALLOW",
"audit_loggers": [
{
"name": "stdout_logger",
"config": {},
"is_optional": false
}
]
}
}`,
wantPolicies: []*v3rbacpb.RBAC{
{
Action: v3rbacpb.RBAC_DENY,
Policies: map[string]*v3rbacpb.Policy{
"authz_deny_policy_1": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: "spiffe://foo.abc"},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{
AuditCondition: v3rbacpb.RBAC_AuditLoggingOptions_NONE,
LoggerConfigs: []*v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
{AuditLogger: &v3corepb.TypedExtensionConfig{Name: "stdout_logger", TypedConfig: anyPbHelper(t, map[string]any{}, "stdout_logger")},
IsOptional: false,
},
},
},
},
{
Action: v3rbacpb.RBAC_ALLOW,
Policies: map[string]*v3rbacpb.Policy{
"authz_allow_authenticated": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
}},
}},
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: ""},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{
AuditCondition: v3rbacpb.RBAC_AuditLoggingOptions_ON_ALLOW,
LoggerConfigs: []*v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
{AuditLogger: &v3corepb.TypedExtensionConfig{Name: "stdout_logger", TypedConfig: anyPbHelper(t, map[string]any{}, "stdout_logger")},
IsOptional: false,
},
},
},
},
},
},
"audit_logging_DENY_AND_ALLOW": {
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_authenticated",
"source": {
"principals":["*", ""]
}
}],
"deny_rules": [
{
"name": "deny_policy_1",
"source": {
"principals":[
"spiffe://foo.abc"
]
}
}],
"audit_logging_options": {
"audit_condition": "ON_DENY_AND_ALLOW",
"audit_loggers": [
{
"name": "stdout_logger",
"config": {},
"is_optional": false
}
]
}
}`,
wantPolicies: []*v3rbacpb.RBAC{
{
Action: v3rbacpb.RBAC_DENY,
Policies: map[string]*v3rbacpb.Policy{
"authz_deny_policy_1": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: "spiffe://foo.abc"},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{
AuditCondition: v3rbacpb.RBAC_AuditLoggingOptions_ON_DENY,
LoggerConfigs: []*v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
{AuditLogger: &v3corepb.TypedExtensionConfig{Name: "stdout_logger", TypedConfig: anyPbHelper(t, map[string]any{}, "stdout_logger")},
IsOptional: false,
},
},
},
},
{
Action: v3rbacpb.RBAC_ALLOW,
Policies: map[string]*v3rbacpb.Policy{
"authz_allow_authenticated": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
}},
}},
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: ""},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{
AuditCondition: v3rbacpb.RBAC_AuditLoggingOptions_ON_DENY_AND_ALLOW,
LoggerConfigs: []*v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
{AuditLogger: &v3corepb.TypedExtensionConfig{Name: "stdout_logger", TypedConfig: anyPbHelper(t, map[string]any{}, "stdout_logger")},
IsOptional: false,
},
},
},
},
},
},
"audit_logging_NONE": {
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_authenticated",
"source": {
"principals":["*", ""]
}
}],
"deny_rules": [
{
"name": "deny_policy_1",
"source": {
"principals":[
"spiffe://foo.abc"
]
}
}],
"audit_logging_options": {
"audit_condition": "NONE",
"audit_loggers": [
{
"name": "stdout_logger",
"config": {},
"is_optional": false
}
]
}
}`,
wantPolicies: []*v3rbacpb.RBAC{
{
Action: v3rbacpb.RBAC_DENY,
Policies: map[string]*v3rbacpb.Policy{
"authz_deny_policy_1": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: "spiffe://foo.abc"},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{
AuditCondition: v3rbacpb.RBAC_AuditLoggingOptions_NONE,
LoggerConfigs: []*v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
{AuditLogger: &v3corepb.TypedExtensionConfig{Name: "stdout_logger", TypedConfig: anyPbHelper(t, map[string]any{}, "stdout_logger")},
IsOptional: false,
},
},
},
},
{
Action: v3rbacpb.RBAC_ALLOW,
Policies: map[string]*v3rbacpb.Policy{
"authz_allow_authenticated": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
}},
}},
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: ""},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{
AuditCondition: v3rbacpb.RBAC_AuditLoggingOptions_NONE,
LoggerConfigs: []*v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
{AuditLogger: &v3corepb.TypedExtensionConfig{Name: "stdout_logger", TypedConfig: anyPbHelper(t, map[string]any{}, "stdout_logger")},
IsOptional: false,
},
},
},
},
},
},
"audit_logging_custom_config simple": {
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_authenticated",
"source": {
"principals":["*", ""]
}
}],
"deny_rules": [
{
"name": "deny_policy_1",
"source": {
"principals":[
"spiffe://foo.abc"
]
}
}],
"audit_logging_options": {
"audit_condition": "NONE",
"audit_loggers": [
{
"name": "stdout_logger",
"config": {"abc":123, "xyz":"123"},
"is_optional": false
}
]
}
}`,
wantPolicies: []*v3rbacpb.RBAC{
{
Action: v3rbacpb.RBAC_DENY,
Policies: map[string]*v3rbacpb.Policy{
"authz_deny_policy_1": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: "spiffe://foo.abc"},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{
AuditCondition: v3rbacpb.RBAC_AuditLoggingOptions_NONE,
LoggerConfigs: []*v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
{AuditLogger: &v3corepb.TypedExtensionConfig{Name: "stdout_logger", TypedConfig: anyPbHelper(t, map[string]any{"abc": 123, "xyz": "123"}, "stdout_logger")},
IsOptional: false,
},
},
},
},
{
Action: v3rbacpb.RBAC_ALLOW,
Policies: map[string]*v3rbacpb.Policy{
"authz_allow_authenticated": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
}},
}},
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: ""},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{
AuditCondition: v3rbacpb.RBAC_AuditLoggingOptions_NONE,
LoggerConfigs: []*v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
{AuditLogger: &v3corepb.TypedExtensionConfig{Name: "stdout_logger", TypedConfig: anyPbHelper(t, map[string]any{"abc": 123, "xyz": "123"}, "stdout_logger")},
IsOptional: false,
},
},
},
},
},
},
"audit_logging_custom_config nested": {
authzPolicy: `{
"name": "authz",
"allow_rules": [
{
"name": "allow_authenticated",
"source": {
"principals":["*", ""]
}
}],
"audit_logging_options": {
"audit_condition": "NONE",
"audit_loggers": [
{
"name": "stdout_logger",
"config": {"abc":123, "xyz":{"abc":123}},
"is_optional": false
}
]
}
}`,
wantPolicies: []*v3rbacpb.RBAC{
{
Action: v3rbacpb.RBAC_ALLOW,
Policies: map[string]*v3rbacpb.Policy{
"authz_allow_authenticated": {
Principals: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_OrIds{OrIds: &v3rbacpb.Principal_Set{
Ids: []*v3rbacpb.Principal{
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_SafeRegex{SafeRegex: &v3matcherpb.RegexMatcher{Regex: ".+"}},
}},
}},
{Identifier: &v3rbacpb.Principal_Authenticated_{
Authenticated: &v3rbacpb.Principal_Authenticated{PrincipalName: &v3matcherpb.StringMatcher{
MatchPattern: &v3matcherpb.StringMatcher_Exact{Exact: ""},
}},
}},
},
}}},
},
Permissions: []*v3rbacpb.Permission{
{Rule: &v3rbacpb.Permission_Any{Any: true}},
},
},
},
AuditLoggingOptions: &v3rbacpb.RBAC_AuditLoggingOptions{
AuditCondition: v3rbacpb.RBAC_AuditLoggingOptions_NONE,
LoggerConfigs: []*v3rbacpb.RBAC_AuditLoggingOptions_AuditLoggerConfig{
{AuditLogger: &v3corepb.TypedExtensionConfig{Name: "stdout_logger", TypedConfig: anyPbHelper(t, map[string]any{"abc": 123, "xyz": map[string]any{"abc": 123}}, "stdout_logger")},
IsOptional: false,
},
},
},
},
},
},
"missing audit logger config": {
gitextract__6xnhcut/
├── .gemini/
│ └── config.yaml
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug.md
│ │ ├── feature.md
│ │ └── question.md
│ ├── codecov.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── codeql-analysis.yml
│ ├── coverage.yml
│ ├── deps.yml
│ ├── lock.yml
│ ├── pr-validation.yml
│ ├── release.yml
│ ├── stale.yml
│ └── testing.yml
├── AUTHORS
├── CODE-OF-CONDUCT.md
├── CONTRIBUTING.md
├── Documentation/
│ ├── anti-patterns.md
│ ├── benchmark.md
│ ├── compression.md
│ ├── concurrency.md
│ ├── encoding.md
│ ├── grpc-auth-support.md
│ ├── grpc-metadata.md
│ ├── keepalive.md
│ ├── log_levels.md
│ ├── proxy.md
│ ├── rpc-errors.md
│ ├── server-reflection-tutorial.md
│ └── versioning.md
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── Makefile
├── NOTICE.txt
├── README.md
├── SECURITY.md
├── admin/
│ ├── admin.go
│ ├── admin_test.go
│ └── test/
│ ├── admin_test.go
│ └── utils.go
├── attributes/
│ ├── attributes.go
│ └── attributes_test.go
├── authz/
│ ├── audit/
│ │ ├── audit_logger.go
│ │ ├── audit_logging_test.go
│ │ └── stdout/
│ │ ├── stdout_logger.go
│ │ └── stdout_logger_test.go
│ ├── grpc_authz_end2end_test.go
│ ├── grpc_authz_server_interceptors.go
│ ├── grpc_authz_server_interceptors_test.go
│ ├── rbac_translator.go
│ └── rbac_translator_test.go
├── backoff/
│ └── backoff.go
├── backoff.go
├── balancer/
│ ├── balancer.go
│ ├── base/
│ │ ├── balancer.go
│ │ ├── balancer_test.go
│ │ └── base.go
│ ├── conn_state_evaluator.go
│ ├── conn_state_evaluator_test.go
│ ├── endpointsharding/
│ │ ├── endpointsharding.go
│ │ ├── endpointsharding_ext_test.go
│ │ └── endpointsharding_test.go
│ ├── grpclb/
│ │ ├── grpc_lb_v1/
│ │ │ ├── load_balancer.pb.go
│ │ │ └── load_balancer_grpc.pb.go
│ │ ├── grpclb.go
│ │ ├── grpclb_config.go
│ │ ├── grpclb_config_test.go
│ │ ├── grpclb_picker.go
│ │ ├── grpclb_remote_balancer.go
│ │ ├── grpclb_test.go
│ │ ├── grpclb_util.go
│ │ ├── grpclb_util_test.go
│ │ └── state/
│ │ └── state.go
│ ├── lazy/
│ │ ├── lazy.go
│ │ └── lazy_ext_test.go
│ ├── leastrequest/
│ │ ├── leastrequest.go
│ │ └── leastrequest_test.go
│ ├── pickfirst/
│ │ ├── internal/
│ │ │ └── internal.go
│ │ ├── metrics_test.go
│ │ ├── pickfirst.go
│ │ ├── pickfirst_ext_test.go
│ │ ├── pickfirst_test.go
│ │ └── pickfirstleaf/
│ │ └── pickfirstleaf.go
│ ├── randomsubsetting/
│ │ ├── randomsubsetting.go
│ │ └── randomsubsetting_test.go
│ ├── ringhash/
│ │ ├── config.go
│ │ ├── config_test.go
│ │ ├── logging.go
│ │ ├── picker.go
│ │ ├── picker_test.go
│ │ ├── ring.go
│ │ ├── ring_test.go
│ │ ├── ringhash.go
│ │ ├── ringhash_e2e_test.go
│ │ └── ringhash_test.go
│ ├── rls/
│ │ ├── balancer.go
│ │ ├── balancer_test.go
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ ├── child_policy.go
│ │ ├── config.go
│ │ ├── config_test.go
│ │ ├── control_channel.go
│ │ ├── control_channel_test.go
│ │ ├── helpers_test.go
│ │ ├── internal/
│ │ │ ├── adaptive/
│ │ │ │ ├── adaptive.go
│ │ │ │ ├── adaptive_test.go
│ │ │ │ ├── lookback.go
│ │ │ │ └── lookback_test.go
│ │ │ ├── keys/
│ │ │ │ ├── builder.go
│ │ │ │ └── builder_test.go
│ │ │ └── test/
│ │ │ └── e2e/
│ │ │ ├── e2e.go
│ │ │ ├── rls_child_policy.go
│ │ │ └── rls_lb_config.go
│ │ ├── metrics_test.go
│ │ ├── picker.go
│ │ └── picker_test.go
│ ├── roundrobin/
│ │ └── roundrobin.go
│ ├── subconn.go
│ ├── weightedroundrobin/
│ │ ├── balancer.go
│ │ ├── balancer_test.go
│ │ ├── config.go
│ │ ├── internal/
│ │ │ └── internal.go
│ │ ├── logging.go
│ │ ├── metrics_test.go
│ │ └── scheduler.go
│ └── weightedtarget/
│ ├── logging.go
│ ├── weightedaggregator/
│ │ └── aggregator.go
│ ├── weightedtarget.go
│ ├── weightedtarget_config.go
│ ├── weightedtarget_config_test.go
│ └── weightedtarget_test.go
├── balancer_wrapper.go
├── balancer_wrapper_test.go
├── benchmark/
│ ├── benchmain/
│ │ └── main.go
│ ├── benchmark.go
│ ├── benchresult/
│ │ └── main.go
│ ├── client/
│ │ └── main.go
│ ├── flags/
│ │ ├── flags.go
│ │ └── flags_test.go
│ ├── latency/
│ │ ├── latency.go
│ │ └── latency_test.go
│ ├── primitives/
│ │ ├── code_string_test.go
│ │ ├── context_test.go
│ │ ├── primitives_test.go
│ │ ├── safe_config_selector_test.go
│ │ └── syncmap_test.go
│ ├── run_bench.sh
│ ├── server/
│ │ └── main.go
│ ├── stats/
│ │ ├── curve.go
│ │ ├── histogram.go
│ │ └── stats.go
│ └── worker/
│ ├── benchmark_client.go
│ ├── benchmark_server.go
│ └── main.go
├── binarylog/
│ ├── binarylog_end2end_test.go
│ ├── grpc_binarylog_v1/
│ │ └── binarylog.pb.go
│ └── sink.go
├── call.go
├── channelz/
│ ├── channelz.go
│ ├── grpc_channelz_v1/
│ │ ├── channelz.pb.go
│ │ └── channelz_grpc.pb.go
│ ├── internal/
│ │ └── protoconv/
│ │ ├── channel.go
│ │ ├── server.go
│ │ ├── socket.go
│ │ ├── sockopt_linux.go
│ │ ├── sockopt_nonlinux.go
│ │ ├── subchannel.go
│ │ └── util.go
│ └── service/
│ ├── service.go
│ ├── service_sktopt_test.go
│ └── service_test.go
├── clientconn.go
├── clientconn_authority_test.go
├── clientconn_parsed_target_test.go
├── clientconn_test.go
├── cmd/
│ └── protoc-gen-go-grpc/
│ ├── README.md
│ ├── go.mod
│ ├── go.sum
│ ├── grpc.go
│ ├── main.go
│ ├── protoc-gen-go-grpc_test.sh
│ └── unimpl_test.go
├── codec.go
├── codec_test.go
├── codes/
│ ├── code_string.go
│ ├── codes.go
│ └── codes_test.go
├── connectivity/
│ └── connectivity.go
├── credentials/
│ ├── alts/
│ │ ├── alts.go
│ │ ├── alts_test.go
│ │ ├── internal/
│ │ │ ├── authinfo/
│ │ │ │ ├── authinfo.go
│ │ │ │ └── authinfo_test.go
│ │ │ ├── common.go
│ │ │ ├── conn/
│ │ │ │ ├── aeadrekey.go
│ │ │ │ ├── aeadrekey_test.go
│ │ │ │ ├── aes128gcm.go
│ │ │ │ ├── aes128gcm_test.go
│ │ │ │ ├── aes128gcmrekey.go
│ │ │ │ ├── aes128gcmrekey_test.go
│ │ │ │ ├── common.go
│ │ │ │ ├── counter.go
│ │ │ │ ├── counter_test.go
│ │ │ │ ├── record.go
│ │ │ │ ├── record_test.go
│ │ │ │ └── utils.go
│ │ │ ├── handshaker/
│ │ │ │ ├── handshaker.go
│ │ │ │ ├── handshaker_test.go
│ │ │ │ └── service/
│ │ │ │ ├── service.go
│ │ │ │ └── service_test.go
│ │ │ ├── proto/
│ │ │ │ └── grpc_gcp/
│ │ │ │ ├── altscontext.pb.go
│ │ │ │ ├── handshaker.pb.go
│ │ │ │ ├── handshaker_grpc.pb.go
│ │ │ │ └── transport_security_common.pb.go
│ │ │ └── testutil/
│ │ │ └── testutil.go
│ │ ├── utils.go
│ │ └── utils_test.go
│ ├── credentials.go
│ ├── credentials_ext_test.go
│ ├── credentials_test.go
│ ├── google/
│ │ ├── google.go
│ │ ├── google_test.go
│ │ ├── xds.go
│ │ └── xds_test.go
│ ├── insecure/
│ │ └── insecure.go
│ ├── jwt/
│ │ ├── doc.go
│ │ ├── file_reader.go
│ │ ├── file_reader_test.go
│ │ ├── token_file_call_creds.go
│ │ ├── token_file_call_creds_ext_test.go
│ │ └── token_file_call_creds_test.go
│ ├── local/
│ │ ├── local.go
│ │ └── local_test.go
│ ├── oauth/
│ │ ├── oauth.go
│ │ └── oauth_test.go
│ ├── sts/
│ │ ├── sts.go
│ │ └── sts_test.go
│ ├── tls/
│ │ └── certprovider/
│ │ ├── distributor.go
│ │ ├── distributor_test.go
│ │ ├── pemfile/
│ │ │ ├── builder.go
│ │ │ ├── builder_test.go
│ │ │ ├── watcher.go
│ │ │ └── watcher_test.go
│ │ ├── provider.go
│ │ ├── store.go
│ │ └── store_test.go
│ ├── tls.go
│ ├── tls_ext_test.go
│ └── xds/
│ ├── xds.go
│ ├── xds_client_test.go
│ └── xds_server_test.go
├── default_dial_option_server_option_test.go
├── dial_test.go
├── dialoptions.go
├── doc.go
├── encoding/
│ ├── compressor_test.go
│ ├── encoding.go
│ ├── encoding_test.go
│ ├── encoding_v2.go
│ ├── gzip/
│ │ └── gzip.go
│ ├── internal/
│ │ └── internal.go
│ └── proto/
│ ├── proto.go
│ ├── proto_benchmark_test.go
│ └── proto_test.go
├── examples/
│ ├── README.md
│ ├── data/
│ │ ├── data.go
│ │ ├── rbac/
│ │ │ └── policy.json
│ │ └── x509/
│ │ ├── README.md
│ │ ├── ca_cert.pem
│ │ ├── ca_key.pem
│ │ ├── client_ca_cert.pem
│ │ ├── client_ca_key.pem
│ │ ├── client_cert.pem
│ │ ├── client_key.pem
│ │ ├── create.sh
│ │ ├── openssl.cnf
│ │ ├── server_cert.pem
│ │ └── server_key.pem
│ ├── examples_test.sh
│ ├── features/
│ │ ├── advancedtls/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ ├── creds/
│ │ │ │ ├── ca_cert.pem
│ │ │ │ ├── ca_key.pem
│ │ │ │ ├── client_cert.pem
│ │ │ │ ├── client_cert_revoked.pem
│ │ │ │ ├── client_key.pem
│ │ │ │ ├── crl/
│ │ │ │ │ └── client_revoked.crl
│ │ │ │ ├── localhost-openssl.cnf
│ │ │ │ ├── openssl-ca.cnf
│ │ │ │ ├── server_cert.pem
│ │ │ │ ├── server_cert_revoked.pem
│ │ │ │ ├── server_key.pem
│ │ │ │ └── server_revoked.crl
│ │ │ ├── generate.sh
│ │ │ ├── localhost-openssl.cnf
│ │ │ ├── openssl-ca.cnf
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── authentication/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── authz/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ ├── server/
│ │ │ │ └── main.go
│ │ │ └── token/
│ │ │ └── token.go
│ │ ├── cancellation/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── compression/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── csm_observability/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ ├── Dockerfile
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ ├── Dockerfile
│ │ │ └── main.go
│ │ ├── customloadbalancer/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ ├── customroundrobin/
│ │ │ │ │ └── customroundrobin.go
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── deadline/
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── debugging/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── dualstack/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── encryption/
│ │ │ ├── ALTS/
│ │ │ │ ├── client/
│ │ │ │ │ └── main.go
│ │ │ │ └── server/
│ │ │ │ └── main.go
│ │ │ ├── README.md
│ │ │ ├── TLS/
│ │ │ │ ├── client/
│ │ │ │ │ └── main.go
│ │ │ │ └── server/
│ │ │ │ └── main.go
│ │ │ └── mTLS/
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── error_details/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── error_handling/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── flow_control/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── gracefulstop/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── health/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── interceptor/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── keepalive/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── load_balancing/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── metadata/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── metadata_interceptor/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── multiplex/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── name_resolving/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── observability/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ ├── clientConfig.json
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ ├── main.go
│ │ │ └── serverConfig.json
│ │ ├── opentelemetry/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── orca/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── proto/
│ │ │ └── echo/
│ │ │ ├── echo.pb.go
│ │ │ ├── echo.proto
│ │ │ └── echo_grpc.pb.go
│ │ ├── reflection/
│ │ │ ├── README.md
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── retry/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── stats_monitoring/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ ├── server/
│ │ │ │ └── main.go
│ │ │ └── statshandler/
│ │ │ └── handler.go
│ │ ├── unix_abstract/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── wait_for_ready/
│ │ │ ├── README.md
│ │ │ └── main.go
│ │ └── xds/
│ │ ├── README.md
│ │ ├── client/
│ │ │ └── main.go
│ │ └── server/
│ │ └── main.go
│ ├── go.mod
│ ├── go.sum
│ ├── gotutorial.md
│ ├── helloworld/
│ │ ├── README.md
│ │ ├── greeter_client/
│ │ │ └── main.go
│ │ ├── greeter_server/
│ │ │ └── main.go
│ │ └── helloworld/
│ │ ├── helloworld.pb.go
│ │ ├── helloworld.proto
│ │ └── helloworld_grpc.pb.go
│ └── route_guide/
│ ├── README.md
│ ├── client/
│ │ └── client.go
│ ├── routeguide/
│ │ ├── route_guide.pb.go
│ │ ├── route_guide.proto
│ │ └── route_guide_grpc.pb.go
│ ├── server/
│ │ └── server.go
│ └── testdata/
│ └── route_guide_db.json
├── experimental/
│ ├── credentials/
│ │ ├── credentials_test.go
│ │ ├── internal/
│ │ │ ├── spiffe.go
│ │ │ ├── spiffe_test.go
│ │ │ ├── syscallconn.go
│ │ │ └── syscallconn_test.go
│ │ ├── tls.go
│ │ └── tls_ext_test.go
│ ├── experimental.go
│ ├── opentelemetry/
│ │ └── trace_options.go
│ ├── shared_buffer_pool_test.go
│ └── stats/
│ ├── metricregistry.go
│ ├── metricregistry_test.go
│ └── metrics.go
├── gcp/
│ └── observability/
│ ├── config.go
│ ├── exporting.go
│ ├── go.mod
│ ├── go.sum
│ ├── logging.go
│ ├── logging_test.go
│ ├── observability.go
│ ├── observability_test.go
│ └── opencensus.go
├── go.mod
├── go.sum
├── grpc_test.go
├── grpclog/
│ ├── component.go
│ ├── glogger/
│ │ └── glogger.go
│ ├── grpclog.go
│ ├── internal/
│ │ ├── grpclog.go
│ │ ├── logger.go
│ │ ├── loggerv2.go
│ │ └── loggerv2_test.go
│ ├── logger.go
│ └── loggerv2.go
├── health/
│ ├── client.go
│ ├── client_test.go
│ ├── grpc_health_v1/
│ │ ├── health.pb.go
│ │ └── health_grpc.pb.go
│ ├── logging.go
│ ├── producer.go
│ ├── server.go
│ ├── server_internal_test.go
│ └── server_test.go
├── interceptor.go
├── internal/
│ ├── admin/
│ │ └── admin.go
│ ├── backoff/
│ │ └── backoff.go
│ ├── balancer/
│ │ ├── gracefulswitch/
│ │ │ ├── config.go
│ │ │ ├── gracefulswitch.go
│ │ │ └── gracefulswitch_test.go
│ │ ├── nop/
│ │ │ └── nop.go
│ │ ├── stub/
│ │ │ └── stub.go
│ │ └── weight/
│ │ ├── weight.go
│ │ └── weight_test.go
│ ├── balancergroup/
│ │ ├── balancergroup.go
│ │ ├── balancergroup_test.go
│ │ └── balancerstateaggregator.go
│ ├── balancerload/
│ │ └── load.go
│ ├── binarylog/
│ │ ├── binarylog.go
│ │ ├── binarylog_test.go
│ │ ├── binarylog_testutil.go
│ │ ├── env_config.go
│ │ ├── env_config_test.go
│ │ ├── method_logger.go
│ │ ├── method_logger_test.go
│ │ ├── regexp_test.go
│ │ └── sink.go
│ ├── buffer/
│ │ ├── unbounded.go
│ │ └── unbounded_test.go
│ ├── cache/
│ │ ├── timeoutCache.go
│ │ └── timeoutCache_test.go
│ ├── channelz/
│ │ ├── channel.go
│ │ ├── channelmap.go
│ │ ├── funcs.go
│ │ ├── logging.go
│ │ ├── server.go
│ │ ├── socket.go
│ │ ├── subchannel.go
│ │ ├── syscall_linux.go
│ │ ├── syscall_nonlinux.go
│ │ ├── syscall_test.go
│ │ └── trace.go
│ ├── credentials/
│ │ ├── credentials.go
│ │ ├── spiffe/
│ │ │ ├── spiffe.go
│ │ │ └── spiffe_test.go
│ │ ├── spiffe.go
│ │ ├── spiffe_test.go
│ │ ├── syscallconn.go
│ │ ├── syscallconn_test.go
│ │ ├── util.go
│ │ ├── util_test.go
│ │ └── xds/
│ │ ├── handshake_info.go
│ │ └── handshake_info_test.go
│ ├── envconfig/
│ │ ├── envconfig.go
│ │ ├── envconfig_test.go
│ │ ├── observability.go
│ │ └── xds.go
│ ├── experimental.go
│ ├── googlecloud/
│ │ ├── googlecloud.go
│ │ ├── googlecloud_test.go
│ │ ├── manufacturer.go
│ │ ├── manufacturer_linux.go
│ │ └── manufacturer_windows.go
│ ├── grpclog/
│ │ └── prefix_logger.go
│ ├── grpcsync/
│ │ ├── callback_serializer.go
│ │ ├── callback_serializer_test.go
│ │ ├── event.go
│ │ ├── event_test.go
│ │ ├── pubsub.go
│ │ └── pubsub_test.go
│ ├── grpctest/
│ │ ├── example_test.go
│ │ ├── grpctest.go
│ │ ├── grpctest_test.go
│ │ ├── tlogger.go
│ │ └── tlogger_test.go
│ ├── grpcutil/
│ │ ├── compressor.go
│ │ ├── compressor_test.go
│ │ ├── encode_duration.go
│ │ ├── encode_duration_test.go
│ │ ├── grpcutil.go
│ │ ├── metadata.go
│ │ ├── method.go
│ │ ├── method_test.go
│ │ ├── regex.go
│ │ └── regex_test.go
│ ├── hierarchy/
│ │ ├── hierarchy.go
│ │ └── hierarchy_ext_test.go
│ ├── idle/
│ │ ├── idle.go
│ │ ├── idle_e2e_test.go
│ │ └── idle_test.go
│ ├── internal.go
│ ├── leakcheck/
│ │ ├── leakcheck.go
│ │ ├── leakcheck_enabled.go
│ │ └── leakcheck_test.go
│ ├── mem/
│ │ ├── buffer_pool.go
│ │ ├── buffer_pool_ext_test.go
│ │ └── buffer_pool_test.go
│ ├── metadata/
│ │ ├── metadata.go
│ │ └── metadata_test.go
│ ├── pretty/
│ │ └── pretty.go
│ ├── profiling/
│ │ ├── buffer/
│ │ │ ├── buffer.go
│ │ │ └── buffer_test.go
│ │ ├── goid_modified.go
│ │ ├── goid_regular.go
│ │ ├── profiling.go
│ │ └── profiling_test.go
│ ├── proto/
│ │ └── grpc_lookup_v1/
│ │ ├── rls.pb.go
│ │ ├── rls_config.pb.go
│ │ └── rls_grpc.pb.go
│ ├── proxyattributes/
│ │ ├── proxyattributes.go
│ │ └── proxyattributes_test.go
│ ├── resolver/
│ │ ├── config_selector.go
│ │ ├── config_selector_test.go
│ │ ├── delegatingresolver/
│ │ │ ├── delegatingresolver.go
│ │ │ ├── delegatingresolver_ext_test.go
│ │ │ └── delegatingresolver_test.go
│ │ ├── dns/
│ │ │ ├── dns_resolver.go
│ │ │ ├── dns_resolver_test.go
│ │ │ ├── fake_net_resolver_test.go
│ │ │ └── internal/
│ │ │ └── internal.go
│ │ ├── passthrough/
│ │ │ └── passthrough.go
│ │ └── unix/
│ │ └── unix.go
│ ├── ringhash/
│ │ └── ringhash.go
│ ├── serviceconfig/
│ │ ├── duration.go
│ │ ├── duration_test.go
│ │ ├── serviceconfig.go
│ │ └── serviceconfig_test.go
│ ├── stats/
│ │ ├── labels.go
│ │ ├── metrics_recorder_list.go
│ │ ├── metrics_recorder_list_test.go
│ │ └── stats.go
│ ├── status/
│ │ ├── status.go
│ │ └── status_test.go
│ ├── stubserver/
│ │ └── stubserver.go
│ ├── syscall/
│ │ ├── syscall_linux.go
│ │ └── syscall_nonlinux.go
│ ├── tcp_keepalive_others.go
│ ├── tcp_keepalive_unix.go
│ ├── tcp_keepalive_windows.go
│ ├── testutils/
│ │ ├── balancer.go
│ │ ├── blocking_context_dialer.go
│ │ ├── blocking_context_dialer_test.go
│ │ ├── channel.go
│ │ ├── envconfig.go
│ │ ├── fakegrpclb/
│ │ │ └── server.go
│ │ ├── http_client.go
│ │ ├── local_listener.go
│ │ ├── marshal_any.go
│ │ ├── parse_port.go
│ │ ├── parse_url.go
│ │ ├── pickfirst/
│ │ │ └── pickfirst.go
│ │ ├── pipe_listener.go
│ │ ├── pipe_listener_test.go
│ │ ├── proxyserver/
│ │ │ └── proxyserver.go
│ │ ├── resolver.go
│ │ ├── restartable_listener.go
│ │ ├── rls/
│ │ │ └── fake_rls_server.go
│ │ ├── roundrobin/
│ │ │ └── roundrobin.go
│ │ ├── state.go
│ │ ├── stats/
│ │ │ └── test_metrics_recorder.go
│ │ ├── status_equal.go
│ │ ├── status_equal_test.go
│ │ ├── stubstatshandler.go
│ │ ├── tls_creds.go
│ │ ├── wrappers.go
│ │ ├── wrr.go
│ │ ├── xds/
│ │ │ ├── e2e/
│ │ │ │ ├── bootstrap.go
│ │ │ │ ├── clientresources.go
│ │ │ │ ├── logging.go
│ │ │ │ ├── server.go
│ │ │ │ └── setup/
│ │ │ │ └── setup.go
│ │ │ └── fakeserver/
│ │ │ └── server.go
│ │ └── xds_bootstrap.go
│ ├── transport/
│ │ ├── bdp_estimator.go
│ │ ├── client_stream.go
│ │ ├── controlbuf.go
│ │ ├── defaults.go
│ │ ├── flowcontrol.go
│ │ ├── handler_server.go
│ │ ├── handler_server_test.go
│ │ ├── http2_client.go
│ │ ├── http2_server.go
│ │ ├── http_util.go
│ │ ├── http_util_test.go
│ │ ├── keepalive_test.go
│ │ ├── logging.go
│ │ ├── networktype/
│ │ │ └── networktype.go
│ │ ├── proxy.go
│ │ ├── proxy_ext_test.go
│ │ ├── proxy_test.go
│ │ ├── server_stream.go
│ │ ├── transport.go
│ │ └── transport_test.go
│ ├── wrr/
│ │ ├── edf.go
│ │ ├── edf_test.go
│ │ ├── random.go
│ │ ├── wrr.go
│ │ └── wrr_test.go
│ └── xds/
│ ├── balancer/
│ │ ├── balancer.go
│ │ ├── cdsbalancer/
│ │ │ ├── aggregate_cluster_test.go
│ │ │ ├── cdsbalancer.go
│ │ │ ├── cdsbalancer_test.go
│ │ │ ├── configbuilder.go
│ │ │ ├── configbuilder_childname.go
│ │ │ ├── configbuilder_childname_test.go
│ │ │ ├── configbuilder_test.go
│ │ │ ├── e2e_test/
│ │ │ │ ├── aggregate_cluster_test.go
│ │ │ │ ├── balancer_test.go
│ │ │ │ ├── dns_impl_test.go
│ │ │ │ └── eds_impl_test.go
│ │ │ └── logging.go
│ │ ├── clusterimpl/
│ │ │ ├── balancer_test.go
│ │ │ ├── clusterimpl.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── internal/
│ │ │ │ └── internal.go
│ │ │ ├── logging.go
│ │ │ ├── picker.go
│ │ │ └── tests/
│ │ │ ├── balancer_test.go
│ │ │ └── clusterimpl_security_test.go
│ │ ├── clustermanager/
│ │ │ ├── balancerstateaggregator.go
│ │ │ ├── clustermanager.go
│ │ │ ├── clustermanager_test.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── e2e_test/
│ │ │ │ └── clustermanager_test.go
│ │ │ └── picker.go
│ │ ├── loadstore/
│ │ │ └── load_store_wrapper.go
│ │ ├── outlierdetection/
│ │ │ ├── balancer.go
│ │ │ ├── balancer_ext_test.go
│ │ │ ├── balancer_test.go
│ │ │ ├── callcounter.go
│ │ │ ├── callcounter_test.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── e2e_test/
│ │ │ │ └── outlierdetection_test.go
│ │ │ ├── logging.go
│ │ │ └── subconn_wrapper.go
│ │ ├── priority/
│ │ │ ├── balancer.go
│ │ │ ├── balancer_child.go
│ │ │ ├── balancer_priority.go
│ │ │ ├── balancer_test.go
│ │ │ ├── config.go
│ │ │ ├── config_test.go
│ │ │ ├── ignore_resolve_now.go
│ │ │ ├── ignore_resolve_now_test.go
│ │ │ └── logging.go
│ │ └── wrrlocality/
│ │ ├── balancer.go
│ │ ├── balancer_test.go
│ │ └── logging.go
│ ├── bootstrap/
│ │ ├── bootstrap.go
│ │ ├── bootstrap_test.go
│ │ ├── jwtcreds/
│ │ │ ├── call_creds.go
│ │ │ └── call_creds_test.go
│ │ ├── logging.go
│ │ ├── template.go
│ │ ├── template_test.go
│ │ └── tlscreds/
│ │ ├── bundle.go
│ │ ├── bundle_ext_test.go
│ │ └── bundle_test.go
│ ├── clients/
│ │ ├── config.go
│ │ ├── grpctransport/
│ │ │ ├── examples_test.go
│ │ │ ├── grpc_transport.go
│ │ │ ├── grpc_transport_ext_test.go
│ │ │ └── grpc_transport_test.go
│ │ ├── internal/
│ │ │ ├── backoff/
│ │ │ │ └── backoff.go
│ │ │ ├── buffer/
│ │ │ │ ├── unbounded.go
│ │ │ │ └── unbounded_test.go
│ │ │ ├── internal.go
│ │ │ ├── internal_test.go
│ │ │ ├── pretty/
│ │ │ │ └── pretty.go
│ │ │ ├── syncutil/
│ │ │ │ ├── callback_serializer.go
│ │ │ │ ├── callback_serializer_test.go
│ │ │ │ ├── event.go
│ │ │ │ └── event_test.go
│ │ │ └── testutils/
│ │ │ ├── channel.go
│ │ │ ├── e2e/
│ │ │ │ ├── clientresources.go
│ │ │ │ ├── logging.go
│ │ │ │ └── server.go
│ │ │ ├── fakeserver/
│ │ │ │ └── server.go
│ │ │ ├── faketransport/
│ │ │ │ └── xds_fake_transport.go
│ │ │ ├── marshal_any.go
│ │ │ ├── restartable_listener.go
│ │ │ └── wrappers.go
│ │ ├── lrsclient/
│ │ │ ├── internal/
│ │ │ │ └── internal.go
│ │ │ ├── load_store.go
│ │ │ ├── load_store_test.go
│ │ │ ├── loadreport_test.go
│ │ │ ├── logging.go
│ │ │ ├── lrs_stream.go
│ │ │ ├── lrsclient.go
│ │ │ └── lrsconfig.go
│ │ ├── transport_builder.go
│ │ └── xdsclient/
│ │ ├── ads_stream.go
│ │ ├── authority.go
│ │ ├── channel.go
│ │ ├── channel_test.go
│ │ ├── clientimpl_watchers.go
│ │ ├── helpers_test.go
│ │ ├── internal/
│ │ │ ├── internal.go
│ │ │ └── xdsresource/
│ │ │ ├── ads_stream.go
│ │ │ ├── errors.go
│ │ │ ├── name.go
│ │ │ ├── type.go
│ │ │ └── version.go
│ │ ├── logging.go
│ │ ├── metrics/
│ │ │ └── metrics.go
│ │ ├── resource_type.go
│ │ ├── resource_watcher.go
│ │ ├── test/
│ │ │ ├── ads_stream_ack_nack_test.go
│ │ │ ├── ads_stream_backoff_test.go
│ │ │ ├── ads_stream_flow_control_test.go
│ │ │ ├── ads_stream_restart_test.go
│ │ │ ├── ads_stream_watch_test.go
│ │ │ ├── authority_test.go
│ │ │ ├── custom_resource_watch_test.go
│ │ │ ├── dump_test.go
│ │ │ ├── helpers_test.go
│ │ │ ├── lds_watchers_test.go
│ │ │ ├── metrics_test.go
│ │ │ └── misc_watchers_test.go
│ │ ├── xdsclient.go
│ │ ├── xdsclient_test.go
│ │ └── xdsconfig.go
│ ├── clusterspecifier/
│ │ ├── cluster_specifier.go
│ │ └── rls/
│ │ ├── rls.go
│ │ └── rls_test.go
│ ├── httpfilter/
│ │ ├── fault/
│ │ │ ├── fault.go
│ │ │ └── fault_test.go
│ │ ├── httpfilter.go
│ │ ├── rbac/
│ │ │ └── rbac.go
│ │ └── router/
│ │ └── router.go
│ ├── matcher/
│ │ ├── matcher_header.go
│ │ ├── matcher_header_test.go
│ │ ├── string_matcher.go
│ │ └── string_matcher_test.go
│ ├── rbac/
│ │ ├── converter.go
│ │ ├── converter_test.go
│ │ ├── matchers.go
│ │ ├── rbac_engine.go
│ │ └── rbac_engine_test.go
│ ├── resolver/
│ │ ├── cluster_specifier_plugin_test.go
│ │ ├── helpers_test.go
│ │ ├── internal/
│ │ │ └── internal.go
│ │ ├── logging.go
│ │ ├── serviceconfig.go
│ │ ├── serviceconfig_test.go
│ │ ├── watch_service_test.go
│ │ ├── xds_http_filters_test.go
│ │ ├── xds_resolver.go
│ │ └── xds_resolver_test.go
│ ├── server/
│ │ ├── conn_wrapper.go
│ │ ├── filter_chain_manager.go
│ │ ├── filter_chain_manager_test.go
│ │ ├── listener_wrapper.go
│ │ ├── rds_handler.go
│ │ ├── rds_handler_test.go
│ │ ├── routing.go
│ │ └── routing_test.go
│ ├── test/
│ │ └── e2e/
│ │ ├── README.md
│ │ ├── controlplane.go
│ │ ├── e2e.go
│ │ ├── e2e_test.go
│ │ ├── e2e_utils.go
│ │ └── run.sh
│ ├── testutils/
│ │ ├── balancer_test.go
│ │ ├── fakeclient/
│ │ │ └── client.go
│ │ ├── resource_watcher.go
│ │ └── testutils.go
│ ├── xds.go
│ ├── xds_test.go
│ ├── xdsclient/
│ │ ├── attributes.go
│ │ ├── client.go
│ │ ├── client_refcounted_test.go
│ │ ├── client_test.go
│ │ ├── clientimpl.go
│ │ ├── clientimpl_loadreport.go
│ │ ├── clientimpl_test.go
│ │ ├── internal/
│ │ │ └── internal.go
│ │ ├── logging.go
│ │ ├── metrics_test.go
│ │ ├── pool/
│ │ │ └── pool_ext_test.go
│ │ ├── pool.go
│ │ ├── requests_counter.go
│ │ ├── requests_counter_test.go
│ │ ├── resource_types.go
│ │ ├── tests/
│ │ │ ├── ads_stream_ack_nack_test.go
│ │ │ ├── ads_stream_restart_test.go
│ │ │ ├── authority_test.go
│ │ │ ├── cds_watchers_test.go
│ │ │ ├── client_custom_dialopts_test.go
│ │ │ ├── dump_test.go
│ │ │ ├── eds_watchers_test.go
│ │ │ ├── fallback/
│ │ │ │ └── fallback_test.go
│ │ │ ├── federation_watchers_test.go
│ │ │ ├── helpers_test.go
│ │ │ ├── lds_watchers_test.go
│ │ │ ├── loadreport_test.go
│ │ │ ├── rds_watchers_test.go
│ │ │ └── resource_update_test.go
│ │ ├── xdsclient_test.go
│ │ ├── xdslbregistry/
│ │ │ ├── converter/
│ │ │ │ └── converter.go
│ │ │ ├── xdslbregistry.go
│ │ │ └── xdslbregistry_test.go
│ │ └── xdsresource/
│ │ ├── cluster_resource_type.go
│ │ ├── endpoints_resource_type.go
│ │ ├── errors.go
│ │ ├── filter_chain.go
│ │ ├── filter_chain_test.go
│ │ ├── listener_resource_type.go
│ │ ├── logging.go
│ │ ├── matcher.go
│ │ ├── matcher_path.go
│ │ ├── matcher_path_test.go
│ │ ├── matcher_test.go
│ │ ├── metadata.go
│ │ ├── metadata_test.go
│ │ ├── name.go
│ │ ├── name_test.go
│ │ ├── resource_type.go
│ │ ├── route_config_resource_type.go
│ │ ├── test_utils_test.go
│ │ ├── tests/
│ │ │ └── unmarshal_cds_test.go
│ │ ├── type.go
│ │ ├── type_cds.go
│ │ ├── type_eds.go
│ │ ├── type_lds.go
│ │ ├── type_rds.go
│ │ ├── unmarshal_cds.go
│ │ ├── unmarshal_cds_test.go
│ │ ├── unmarshal_eds.go
│ │ ├── unmarshal_eds_test.go
│ │ ├── unmarshal_lds.go
│ │ ├── unmarshal_lds_test.go
│ │ ├── unmarshal_rds.go
│ │ ├── unmarshal_rds_test.go
│ │ ├── version/
│ │ │ └── version.go
│ │ └── xdsconfig.go
│ └── xdsdepmgr/
│ ├── xds_dependency_manager.go
│ └── xds_dependency_manager_test.go
├── interop/
│ ├── alts/
│ │ ├── client/
│ │ │ └── client.go
│ │ └── server/
│ │ └── server.go
│ ├── client/
│ │ └── client.go
│ ├── fake_grpclb/
│ │ └── fake_grpclb.go
│ ├── grpc_testing/
│ │ ├── benchmark_service.pb.go
│ │ ├── benchmark_service_grpc.pb.go
│ │ ├── control.pb.go
│ │ ├── core/
│ │ │ └── stats.pb.go
│ │ ├── empty.pb.go
│ │ ├── messages.pb.go
│ │ ├── payloads.pb.go
│ │ ├── report_qps_scenario_service.pb.go
│ │ ├── report_qps_scenario_service_grpc.pb.go
│ │ ├── stats.pb.go
│ │ ├── test.pb.go
│ │ ├── test_grpc.pb.go
│ │ ├── worker_service.pb.go
│ │ └── worker_service_grpc.pb.go
│ ├── grpclb_fallback/
│ │ └── client_linux.go
│ ├── http2/
│ │ └── negative_http2_client.go
│ ├── interop_test.sh
│ ├── observability/
│ │ ├── Dockerfile
│ │ ├── build_docker.sh
│ │ ├── client/
│ │ │ └── client.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── run.sh
│ │ └── server/
│ │ └── server.go
│ ├── orcalb.go
│ ├── server/
│ │ └── server.go
│ ├── soak_tests.go
│ ├── stress/
│ │ ├── client/
│ │ │ └── main.go
│ │ ├── grpc_testing/
│ │ │ ├── metrics.pb.go
│ │ │ ├── metrics.proto
│ │ │ └── metrics_grpc.pb.go
│ │ └── metrics_client/
│ │ └── main.go
│ ├── test_utils.go
│ ├── xds/
│ │ ├── client/
│ │ │ ├── Dockerfile
│ │ │ └── client.go
│ │ ├── custom_lb.go
│ │ ├── custom_lb_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── server/
│ │ ├── Dockerfile
│ │ └── server.go
│ └── xds_federation/
│ └── client.go
├── keepalive/
│ └── keepalive.go
├── mem/
│ ├── buffer_pool.go
│ ├── buffer_pool_test.go
│ ├── buffer_slice.go
│ ├── buffer_slice_test.go
│ ├── buffers.go
│ └── buffers_test.go
├── metadata/
│ ├── metadata.go
│ └── metadata_test.go
├── orca/
│ ├── call_metrics.go
│ ├── call_metrics_test.go
│ ├── internal/
│ │ └── internal.go
│ ├── orca.go
│ ├── orca_test.go
│ ├── producer.go
│ ├── producer_test.go
│ ├── server_metrics.go
│ ├── server_metrics_test.go
│ ├── service.go
│ └── service_test.go
├── peer/
│ ├── peer.go
│ └── peer_test.go
├── picker_wrapper.go
├── picker_wrapper_test.go
├── preloader.go
├── producer_ext_test.go
├── profiling/
│ ├── cmd/
│ │ ├── catapult.go
│ │ ├── flags.go
│ │ ├── local.go
│ │ ├── main.go
│ │ └── remote.go
│ ├── profiling.go
│ ├── proto/
│ │ ├── service.pb.go
│ │ ├── service.proto
│ │ └── service_grpc.pb.go
│ └── service/
│ └── service.go
├── reflection/
│ ├── README.md
│ ├── adapt.go
│ ├── grpc_reflection_v1/
│ │ ├── reflection.pb.go
│ │ └── reflection_grpc.pb.go
│ ├── grpc_reflection_v1alpha/
│ │ ├── reflection.pb.go
│ │ └── reflection_grpc.pb.go
│ ├── grpc_testing/
│ │ ├── proto2.pb.go
│ │ ├── proto2.proto
│ │ ├── proto2_ext.pb.go
│ │ ├── proto2_ext.proto
│ │ ├── proto2_ext2.pb.go
│ │ ├── proto2_ext2.proto
│ │ ├── test.pb.go
│ │ ├── test.proto
│ │ └── test_grpc.pb.go
│ ├── internal/
│ │ └── internal.go
│ ├── serverreflection.go
│ └── test/
│ └── serverreflection_test.go
├── resolver/
│ ├── dns/
│ │ └── dns_resolver.go
│ ├── manual/
│ │ ├── manual.go
│ │ └── manual_test.go
│ ├── map.go
│ ├── map_test.go
│ ├── passthrough/
│ │ └── passthrough.go
│ ├── resolver.go
│ ├── resolver_test.go
│ └── ringhash/
│ └── attr.go
├── resolver_balancer_ext_test.go
├── resolver_test.go
├── resolver_wrapper.go
├── rpc_util.go
├── rpc_util_test.go
├── scripts/
│ ├── common.sh
│ ├── gen-deps.sh
│ ├── install-protoc.sh
│ ├── regenerate.sh
│ ├── revive.toml
│ ├── vet-proto.sh
│ └── vet.sh
├── security/
│ └── advancedtls/
│ ├── advancedtls.go
│ ├── advancedtls_integration_test.go
│ ├── advancedtls_test.go
│ ├── crl.go
│ ├── crl_provider.go
│ ├── crl_provider_test.go
│ ├── crl_test.go
│ ├── examples/
│ │ ├── credential_reloading_from_files/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ └── main.go
│ │ │ └── server/
│ │ │ └── main.go
│ │ ├── examples_test.sh
│ │ ├── go.mod
│ │ └── go.sum
│ ├── go.mod
│ ├── go.sum
│ ├── internal/
│ │ └── testutils/
│ │ └── testutils.go
│ ├── sni.go
│ └── testdata/
│ ├── README.md
│ ├── another_client_cert_1.pem
│ ├── another_client_key_1.pem
│ ├── client_cert_1.pem
│ ├── client_cert_2.pem
│ ├── client_key_1.pem
│ ├── client_key_2.pem
│ ├── client_trust_cert_1.pem
│ ├── client_trust_cert_2.pem
│ ├── client_trust_key_1.pem
│ ├── client_trust_key_2.pem
│ ├── crl/
│ │ ├── 1.crl
│ │ ├── 2.crl
│ │ ├── 2f11f022.r0
│ │ ├── 3.crl
│ │ ├── 4.crl
│ │ ├── 5.crl
│ │ ├── 6.crl
│ │ ├── README.md
│ │ ├── provider_ca.cnf
│ │ ├── provider_client_cert.key
│ │ ├── provider_client_cert.pem
│ │ ├── provider_client_trust_cert.pem
│ │ ├── provider_client_trust_key.pem
│ │ ├── provider_create.sh
│ │ ├── provider_crl.cnf
│ │ ├── provider_crl_empty.pem
│ │ ├── provider_crl_server_revoked.pem
│ │ ├── provider_extensions.conf
│ │ ├── provider_malicious_client_trust_cert.pem
│ │ ├── provider_malicious_client_trust_key.pem
│ │ ├── provider_malicious_crl_empty.pem
│ │ ├── provider_server_cert.key
│ │ ├── provider_server_cert.pem
│ │ ├── provider_server_trust_cert.pem
│ │ ├── provider_server_trust_key.pem
│ │ ├── revokedInt.pem
│ │ ├── revokedLeaf.pem
│ │ └── unrevoked.pem
│ ├── localhost-openssl.cnf
│ ├── openssl-ca.cnf
│ ├── server_cert_1.pem
│ ├── server_cert_1.txt
│ ├── server_cert_2.pem
│ ├── server_cert_2.txt
│ ├── server_cert_3.pem
│ ├── server_cert_3.txt
│ ├── server_cert_localhost_1.pem
│ ├── server_key_1.pem
│ ├── server_key_2.pem
│ ├── server_key_3.pem
│ ├── server_key_localhost_1.pem
│ ├── server_trust_cert_1.pem
│ ├── server_trust_cert_2.pem
│ ├── server_trust_key_1.pem
│ ├── server_trust_key_2.pem
│ └── testdata.go
├── server.go
├── server_ext_test.go
├── server_test.go
├── service_config.go
├── service_config_test.go
├── serviceconfig/
│ └── serviceconfig.go
├── stats/
│ ├── handlers.go
│ ├── metrics.go
│ ├── opencensus/
│ │ ├── client_metrics.go
│ │ ├── e2e_test.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── opencensus.go
│ │ ├── server_metrics.go
│ │ ├── stats.go
│ │ └── trace.go
│ ├── opentelemetry/
│ │ ├── client_metrics.go
│ │ ├── client_tracing.go
│ │ ├── csm/
│ │ │ ├── observability.go
│ │ │ ├── observability_test.go
│ │ │ ├── pluginoption.go
│ │ │ └── pluginoption_test.go
│ │ ├── e2e_test.go
│ │ ├── example_test.go
│ │ ├── grpc_trace_bin_propagator.go
│ │ ├── grpc_trace_bin_propagator_test.go
│ │ ├── internal/
│ │ │ ├── pluginoption.go
│ │ │ ├── testutils/
│ │ │ │ └── testutils.go
│ │ │ └── tracing/
│ │ │ ├── carrier.go
│ │ │ └── carrier_test.go
│ │ ├── metricsregistry_test.go
│ │ ├── opentelemetry.go
│ │ ├── server_metrics.go
│ │ ├── server_tracing.go
│ │ └── trace.go
│ ├── stats.go
│ └── stats_test.go
├── status/
│ ├── status.go
│ ├── status_ext_test.go
│ └── status_test.go
├── stream.go
├── stream_interfaces.go
├── stream_test.go
├── tap/
│ └── tap.go
├── test/
│ ├── authority_test.go
│ ├── balancer_switching_test.go
│ ├── balancer_test.go
│ ├── bufconn/
│ │ ├── bufconn.go
│ │ └── bufconn_test.go
│ ├── channelz_linux_test.go
│ ├── channelz_test.go
│ ├── clientconn_state_transition_test.go
│ ├── clientconn_test.go
│ ├── clienttester.go
│ ├── codec_perf/
│ │ ├── perf.pb.go
│ │ └── perf.proto
│ ├── compressor_test.go
│ ├── config_selector_test.go
│ ├── context_canceled_test.go
│ ├── control_plane_status_test.go
│ ├── creds_test.go
│ ├── end2end_test.go
│ ├── goaway_test.go
│ ├── gracefulstop_test.go
│ ├── healthcheck_test.go
│ ├── http_header_end2end_test.go
│ ├── insecure_creds_test.go
│ ├── interceptor_test.go
│ ├── invoke_test.go
│ ├── kokoro/
│ │ ├── README.md
│ │ ├── psm-csm.cfg
│ │ ├── psm-dualstack.cfg
│ │ ├── psm-interop-build-go.sh
│ │ ├── psm-interop-test-go.sh
│ │ ├── psm-light.cfg
│ │ ├── psm-security.cfg
│ │ ├── psm-spiffe.cfg
│ │ ├── xds.cfg
│ │ ├── xds.sh
│ │ ├── xds_k8s_lb.cfg
│ │ ├── xds_url_map.cfg
│ │ ├── xds_v3.cfg
│ │ └── xds_v3.sh
│ ├── local_creds_test.go
│ ├── logging.go
│ ├── malformed_method_test.go
│ ├── metadata_test.go
│ ├── parse_config.go
│ ├── race_test.go
│ ├── rawConnWrapper.go
│ ├── resolver_update_test.go
│ ├── retry_test.go
│ ├── roundrobin_test.go
│ ├── server_test.go
│ ├── servertester.go
│ ├── stats_test.go
│ ├── stream_cleanup_test.go
│ ├── subconn_test.go
│ ├── timeouts.go
│ ├── tools/
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── tools.go
│ │ └── tools_vet.go
│ ├── transport_test.go
│ └── xds/
│ ├── xds_client_ack_nack_test.go
│ ├── xds_client_affinity_test.go
│ ├── xds_client_certificate_providers_test.go
│ ├── xds_client_custom_lb_test.go
│ ├── xds_client_federation_test.go
│ ├── xds_client_ignore_resource_deletion_test.go
│ ├── xds_client_integration_test.go
│ ├── xds_client_outlier_detection_test.go
│ ├── xds_client_priority_locality_test.go
│ ├── xds_client_retry_test.go
│ ├── xds_rls_clusterspecifier_plugin_test.go
│ ├── xds_security_config_nack_test.go
│ ├── xds_server_filter_state_retention_test.go
│ ├── xds_server_integration_test.go
│ ├── xds_server_rbac_test.go
│ └── xds_telemetry_labels_test.go
├── testdata/
│ ├── README.md
│ ├── ca.pem
│ ├── grpc_testing_not_regenerated/
│ │ ├── README.md
│ │ ├── dynamic.go
│ │ ├── dynamic.proto
│ │ ├── simple.proto
│ │ ├── simple_message_v1.go
│ │ ├── testv3.go
│ │ └── testv3.proto
│ ├── server1.key
│ ├── server1.pem
│ ├── spiffe/
│ │ ├── README.md
│ │ ├── client_spiffe.pem
│ │ ├── server1_spiffe.pem
│ │ ├── spiffe-openssl.cnf
│ │ ├── spiffe_cert.pem
│ │ ├── spiffe_multi_uri_san_cert.pem
│ │ ├── spiffe_test.json
│ │ ├── spiffebundle.json
│ │ ├── spiffebundle2.json
│ │ ├── spiffebundle_corrupted_cert.json
│ │ ├── spiffebundle_empty_keys.json
│ │ ├── spiffebundle_empty_string_key.json
│ │ ├── spiffebundle_invalid_trustdomain.json
│ │ ├── spiffebundle_malformed.json
│ │ ├── spiffebundle_match_client_spiffe.json
│ │ ├── spiffebundle_wrong_kid.json
│ │ ├── spiffebundle_wrong_kty.json
│ │ ├── spiffebundle_wrong_multi_certs.json
│ │ ├── spiffebundle_wrong_root.json
│ │ ├── spiffebundle_wrong_seq_type.json
│ │ └── spiffebundle_wrong_use.json
│ ├── spiffe_end2end/
│ │ ├── README.md
│ │ ├── ca.key
│ │ ├── ca.pem
│ │ ├── client.key
│ │ ├── client_spiffe.pem
│ │ ├── client_spiffebundle.json
│ │ ├── generate.sh
│ │ ├── intermediate.cnf
│ │ ├── intermediate_ca.key
│ │ ├── intermediate_ca.pem
│ │ ├── intermediate_gen.sh
│ │ ├── leaf_and_intermediate_chain.pem
│ │ ├── leaf_signed_by_intermediate.key
│ │ ├── leaf_signed_by_intermediate.pem
│ │ ├── server.key
│ │ ├── server_spiffe.pem
│ │ ├── server_spiffebundle.json
│ │ └── spiffe-openssl.cnf
│ ├── testdata.go
│ └── x509/
│ ├── README.md
│ ├── client1_cert.pem
│ ├── client1_key.pem
│ ├── client2_cert.pem
│ ├── client2_key.pem
│ ├── client_ca_cert.pem
│ ├── client_ca_key.pem
│ ├── client_with_spiffe_cert.pem
│ ├── client_with_spiffe_key.pem
│ ├── client_with_spiffe_openssl.cnf
│ ├── create.sh
│ ├── multiple_uri_cert.pem
│ ├── multiple_uri_key.pem
│ ├── openssl.cnf
│ ├── server1_cert.pem
│ ├── server1_key.pem
│ ├── server2_cert.pem
│ ├── server2_key.pem
│ ├── server_ca_cert.pem
│ ├── server_ca_key.pem
│ ├── spiffe_cert.pem
│ └── spiffe_key.pem
├── trace.go
├── trace_notrace.go
├── trace_test.go
├── trace_withtrace.go
├── version.go
└── xds/
├── bootstrap/
│ ├── bootstrap.go
│ ├── bootstrap_test.go
│ └── credentials.go
├── csds/
│ ├── csds.go
│ └── csds_e2e_test.go
├── googledirectpath/
│ ├── googlec2p.go
│ ├── googlec2p_test.go
│ └── utils.go
├── server.go
├── server_ext_test.go
├── server_options.go
├── server_resource_ext_test.go
├── server_security_ext_test.go
├── server_serving_mode_ext_test.go
├── server_test.go
├── test/
│ └── eds_resource_missing_test.go
└── xds.go
Showing preview only (1,281K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (13673 symbols across 988 files)
FILE: admin/admin.go
function init (line 38) | func init() {
function Register (line 56) | func Register(s grpc.ServiceRegistrar) (cleanup func(), _ error) {
FILE: admin/admin_test.go
function TestRegisterNoCSDS (line 28) | func TestRegisterNoCSDS(t *testing.T) {
FILE: admin/test/admin_test.go
function TestRegisterWithCSDS (line 33) | func TestRegisterWithCSDS(t *testing.T) {
FILE: admin/test/utils.go
constant defaultTestTimeout (line 42) | defaultTestTimeout = 10 * time.Second
type ExpectedStatusCodes (line 47) | type ExpectedStatusCodes struct
function RunRegisterTests (line 54) | func RunRegisterTests(t *testing.T, ec ExpectedStatusCodes) {
function RunChannelz (line 89) | func RunChannelz(conn *grpc.ClientConn) error {
function RunCSDS (line 98) | func RunCSDS(conn *grpc.ClientConn) error {
FILE: attributes/attributes.go
type Attributes (line 41) | type Attributes struct
method WithValue (line 65) | func (a *Attributes) WithValue(key, value any) *Attributes {
method Value (line 75) | func (a *Attributes) Value(key any) any {
method Equal (line 90) | func (a *Attributes) Equal(o *Attributes) bool {
method String (line 124) | func (a *Attributes) String() string {
method MarshalJSON (line 154) | func (a *Attributes) MarshalJSON() ([]byte, error) {
method all (line 161) | func (a *Attributes) all() iter.Seq2[any, any] {
function New (line 47) | func New(key, value any) *Attributes {
function str (line 139) | func str(x any) (s string) {
FILE: attributes/attributes_test.go
type stringVal (line 28) | type stringVal struct
method Equal (line 32) | func (s stringVal) Equal(o any) bool {
type stringerVal (line 37) | type stringerVal struct
method String (line 41) | func (s stringerVal) String() string {
function ExampleAttributes (line 45) | func ExampleAttributes() {
function ExampleAttributes_WithValue (line 56) | func ExampleAttributes_WithValue() {
function ExampleAttributes_String (line 68) | func ExampleAttributes_String() {
function TestEqual (line 99) | func TestEqual(t *testing.T) {
function BenchmarkWithValue (line 172) | func BenchmarkWithValue(b *testing.B) {
FILE: authz/audit/audit_logger.go
type loggerBuilderRegistry (line 29) | type loggerBuilderRegistry struct
function RegisterLoggerBuilder (line 46) | func RegisterLoggerBuilder(b LoggerBuilder) {
function GetLoggerBuilder (line 54) | func GetLoggerBuilder(name string) LoggerBuilder {
type Event (line 62) | type Event struct
type LoggerConfig (line 81) | type LoggerConfig interface
type Logger (line 95) | type Logger interface
type LoggerBuilder (line 113) | type LoggerBuilder interface
FILE: authz/audit/audit_logging_test.go
type s (line 47) | type s struct
method TestAuditLogger (line 90) | func (s) TestAuditLogger(t *testing.T) {
function Test (line 51) | func Test(t *testing.T) {
type statAuditLogger (line 55) | type statAuditLogger struct
method Log (line 60) | func (s *statAuditLogger) Log(event *audit.Event) {
type loggerBuilder (line 65) | type loggerBuilder struct
method Name (line 70) | func (loggerBuilder) Name() string {
method Build (line 74) | func (lb *loggerBuilder) Build(audit.LoggerConfig) audit.Logger {
method ParseLoggerConfig (line 81) | func (*loggerBuilder) ParseLoggerConfig(json.RawMessage) (audit.Logger...
function loadServerCreds (line 322) | func loadServerCreds(t *testing.T) credentials.TransportCredentials {
function loadClientCreds (line 334) | func loadClientCreds(t *testing.T) credentials.TransportCredentials {
function loadKeys (line 348) | func loadKeys(t *testing.T, certPath, key string) tls.Certificate {
function loadCACerts (line 359) | func loadCACerts(t *testing.T, certPath string) *x509.CertPool {
FILE: authz/audit/stdout/stdout_logger.go
constant Name (line 35) | Name = "stdout_logger"
function init (line 37) | func init() {
type event (line 43) | type event struct
type logger (line 53) | type logger struct
method Log (line 58) | func (l *logger) Log(event *audit.Event) {
type loggerConfig (line 72) | type loggerConfig struct
type loggerBuilder (line 76) | type loggerBuilder struct
method Name (line 80) | func (loggerBuilder) Name() string {
method Build (line 87) | func (lb *loggerBuilder) Build(audit.LoggerConfig) audit.Logger {
method ParseLoggerConfig (line 94) | func (*loggerBuilder) ParseLoggerConfig(config json.RawMessage) (audit...
function convertEvent (line 101) | func convertEvent(auditEvent *audit.Event) *event {
FILE: authz/audit/stdout/stdout_logger_test.go
type s (line 34) | type s struct
method TestStdoutLogger_Log (line 42) | func (s) TestStdoutLogger_Log(t *testing.T) {
method TestStdoutLoggerBuilder_NilConfig (line 98) | func (s) TestStdoutLoggerBuilder_NilConfig(t *testing.T) {
method TestStdoutLoggerBuilder_Registration (line 111) | func (s) TestStdoutLoggerBuilder_Registration(t *testing.T) {
function Test (line 38) | func Test(t *testing.T) {
function extractEvent (line 119) | func extractEvent(container map[string]any) event {
function trimEvent (line 132) | func trimEvent(testEvent event) *audit.Event {
FILE: authz/grpc_authz_end2end_test.go
type s (line 45) | type s struct
method TestStaticPolicyEnd2End (line 291) | func (s) TestStaticPolicyEnd2End(t *testing.T) {
method TestAllowsRPCRequestWithPrincipalsFieldOnTLSAuthenticatedConnection (line 356) | func (s) TestAllowsRPCRequestWithPrincipalsFieldOnTLSAuthenticatedConn...
method TestAllowsRPCRequestWithPrincipalsFieldOnMTLSAuthenticatedConnection (line 406) | func (s) TestAllowsRPCRequestWithPrincipalsFieldOnMTLSAuthenticatedCon...
method TestFileWatcherEnd2End (line 481) | func (s) TestFileWatcherEnd2End(t *testing.T) {
method TestFileWatcher_ValidPolicyRefresh (line 559) | func (s) TestFileWatcher_ValidPolicyRefresh(t *testing.T) {
method TestFileWatcher_InvalidPolicySkipReload (line 604) | func (s) TestFileWatcher_InvalidPolicySkipReload(t *testing.T) {
method TestFileWatcher_RecoversFromReloadFailure (line 652) | func (s) TestFileWatcher_RecoversFromReloadFailure(t *testing.T) {
function Test (line 49) | func Test(t *testing.T) {
function retryUntil (line 548) | func retryUntil(ctx context.Context, tsc testgrpc.TestServiceClient, wan...
FILE: authz/grpc_authz_server_interceptors.go
type StaticInterceptor (line 40) | type StaticInterceptor struct
method UnaryInterceptor (line 61) | func (i *StaticInterceptor) UnaryInterceptor(ctx context.Context, req ...
method StreamInterceptor (line 78) | func (i *StaticInterceptor) StreamInterceptor(srv any, ss grpc.ServerS...
function NewStatic (line 46) | func NewStatic(authzPolicy string) (*StaticInterceptor, error) {
type FileWatcherInterceptor (line 94) | type FileWatcherInterceptor struct
method run (line 123) | func (i *FileWatcherInterceptor) run(ctx context.Context) {
method updateInternalInterceptor (line 142) | func (i *FileWatcherInterceptor) updateInternalInterceptor() error {
method Close (line 162) | func (i *FileWatcherInterceptor) Close() {
method UnaryInterceptor (line 169) | func (i *FileWatcherInterceptor) UnaryInterceptor(ctx context.Context,...
method StreamInterceptor (line 176) | func (i *FileWatcherInterceptor) StreamInterceptor(srv any, ss grpc.Se...
function NewFileWatcher (line 105) | func NewFileWatcher(file string, duration time.Duration) (*FileWatcherIn...
FILE: authz/grpc_authz_server_interceptors_test.go
function createTmpPolicyFile (line 31) | func createTmpPolicyFile(t *testing.T, dirSuffix string, policy []byte) ...
method TestNewStatic (line 50) | func (s) TestNewStatic(t *testing.T) {
method TestNewFileWatcher (line 80) | func (s) TestNewFileWatcher(t *testing.T) {
FILE: authz/rbac_translator.go
constant typeURLPrefix (line 42) | typeURLPrefix = "grpc.authz.audit_logging/"
type header (line 44) | type header struct
type peer (line 49) | type peer struct
type request (line 53) | type request struct
type rule (line 58) | type rule struct
type auditLogger (line 64) | type auditLogger struct
type auditLoggingOptions (line 70) | type auditLoggingOptions struct
method toProtos (line 292) | func (options *auditLoggingOptions) toProtos() (allow *v3rbacpb.RBAC_A...
type authorizationPolicy (line 76) | type authorizationPolicy struct
function principalOr (line 83) | func principalOr(principals []*v3rbacpb.Principal) *v3rbacpb.Principal {
function permissionOr (line 93) | func permissionOr(permission []*v3rbacpb.Permission) *v3rbacpb.Permission {
function permissionAnd (line 103) | func permissionAnd(permission []*v3rbacpb.Permission) *v3rbacpb.Permissi...
function getStringMatcher (line 113) | func getStringMatcher(value string) *v3matcherpb.StringMatcher {
function getHeaderMatcher (line 137) | func getHeaderMatcher(key, value string) *v3routepb.HeaderMatcher {
function parsePrincipalNames (line 165) | func parsePrincipalNames(principalNames []string) []*v3rbacpb.Principal {
function parsePeer (line 179) | func parsePeer(source peer) *v3rbacpb.Principal {
function parsePaths (line 190) | func parsePaths(paths []string) []*v3rbacpb.Permission {
function parseHeaderValues (line 202) | func parseHeaderValues(key string, values []string) []*v3rbacpb.Permissi...
function unsupportedHeader (line 225) | func unsupportedHeader(key string) bool {
function parseHeaders (line 229) | func parseHeaders(headers []header) ([]*v3rbacpb.Permission, error) {
function parseRequest (line 248) | func parseRequest(request request) (*v3rbacpb.Permission, error) {
function parseRules (line 270) | func parseRules(rules []rule, prefixName string) (map[string]*v3rbacpb.P...
function toDenyCondition (line 335) | func toDenyCondition(condition v3rbacpb.RBAC_AuditLoggingOptions_AuditCo...
function translatePolicy (line 362) | func translatePolicy(policyStr string) ([]*v3rbacpb.RBAC, string, error) {
FILE: authz/rbac_translator_test.go
function TestTranslatePolicy (line 37) | func TestTranslatePolicy(t *testing.T) {
function anyPbHelper (line 1037) | func anyPbHelper(t *testing.T, in map[string]any, name string) *anypb.Any {
FILE: backoff.go
type BackoffConfig (line 41) | type BackoffConfig struct
type ConnectParams (line 55) | type ConnectParams struct
FILE: backoff/backoff.go
type Config (line 30) | type Config struct
FILE: balancer/balancer.go
function Register (line 58) | func Register(b Builder) {
function unregisterForTesting (line 73) | func unregisterForTesting(name string) {
function init (line 77) | func init() {
function Get (line 84) | func Get(name string) Builder {
type NewSubConnOptions (line 99) | type NewSubConnOptions struct
type State (line 118) | type State struct
type ClientConn (line 139) | type ClientConn interface
type BuildOptions (line 191) | type BuildOptions struct
type Builder (line 222) | type Builder interface
type ConfigParser (line 231) | type ConfigParser interface
type PickInfo (line 239) | type PickInfo struct
type DoneInfo (line 249) | type DoneInfo struct
type PickResult (line 279) | type PickResult struct
function TransientFailureError (line 306) | func TransientFailureError(e error) error { return e }
type Picker (line 313) | type Picker interface
type Balancer (line 344) | type Balancer interface
type ExitIdler (line 376) | type ExitIdler interface
type ClientConnState (line 385) | type ClientConnState struct
FILE: balancer/base/balancer.go
type baseBuilder (line 33) | type baseBuilder struct
method Build (line 39) | func (bb *baseBuilder) Build(cc balancer.ClientConn, _ balancer.BuildO...
method Name (line 57) | func (bb *baseBuilder) Name() string {
type baseBalancer (line 61) | type baseBalancer struct
method ResolverError (line 77) | func (b *baseBalancer) ResolverError(err error) {
method UpdateClientConnState (line 95) | func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnStat...
method mergeErrors (line 149) | func (b *baseBalancer) mergeErrors() error {
method regeneratePicker (line 165) | func (b *baseBalancer) regeneratePicker() {
method UpdateSubConnState (line 182) | func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state b...
method updateSubConnState (line 186) | func (b *baseBalancer) updateSubConnState(sc balancer.SubConn, state b...
method Close (line 236) | func (b *baseBalancer) Close() {
method ExitIdle (line 241) | func (b *baseBalancer) ExitIdle() {
function NewErrPicker (line 245) | func NewErrPicker(err error) balancer.Picker {
type errPicker (line 254) | type errPicker struct
method Pick (line 258) | func (p *errPicker) Pick(balancer.PickInfo) (balancer.PickResult, erro...
FILE: balancer/base/balancer_test.go
type testClientConn (line 32) | type testClientConn struct
method NewSubConn (line 37) | func (c *testClientConn) NewSubConn(addrs []resolver.Address, opts bal...
method UpdateState (line 41) | func (c *testClientConn) UpdateState(balancer.State) {}
type testSubConn (line 43) | type testSubConn struct
method UpdateAddresses (line 48) | func (sc *testSubConn) UpdateAddresses([]resolver.Address) {}
method Connect (line 50) | func (sc *testSubConn) Connect() {}
method Shutdown (line 52) | func (sc *testSubConn) Shutdown() {}
method GetOrBuildProducer (line 54) | func (sc *testSubConn) GetOrBuildProducer(balancer.ProducerBuilder) (b...
method RegisterHealthListener (line 59) | func (*testSubConn) RegisterHealthListener(func(balancer.SubConnState)...
type testPickBuilder (line 62) | type testPickBuilder struct
method Build (line 66) | func (p *testPickBuilder) Build(info PickerBuildInfo) balancer.Picker {
function TestBaseBalancerReserveAttributes (line 71) | func TestBaseBalancerReserveAttributes(t *testing.T) {
FILE: balancer/base/base.go
type PickerBuilder (line 39) | type PickerBuilder interface
type PickerBuildInfo (line 46) | type PickerBuildInfo struct
type SubConnInfo (line 54) | type SubConnInfo struct
type Config (line 59) | type Config struct
function NewBalancerBuilder (line 65) | func NewBalancerBuilder(name string, pb PickerBuilder, config Config) ba...
FILE: balancer/conn_state_evaluator.go
type ConnectivityStateEvaluator (line 27) | type ConnectivityStateEvaluator struct
method RecordTransition (line 43) | func (cse *ConnectivityStateEvaluator) RecordTransition(oldState, newS...
method CurrentState (line 62) | func (cse *ConnectivityStateEvaluator) CurrentState() connectivity.Sta...
FILE: balancer/conn_state_evaluator_test.go
type s (line 28) | type s struct
method TestRecordTransition_FirstStateChange (line 39) | func (s) TestRecordTransition_FirstStateChange(t *testing.T) {
method TestRecordTransition_SameState (line 75) | func (s) TestRecordTransition_SameState(t *testing.T) {
method TestRecordTransition_SingleSubConn_DifferentStates (line 118) | func (s) TestRecordTransition_SingleSubConn_DifferentStates(t *testing...
method TestRecordTransition_MultipleSubConns_DifferentStates (line 184) | func (s) TestRecordTransition_MultipleSubConns_DifferentStates(t *test...
function Test (line 32) | func Test(t *testing.T) {
FILE: balancer/endpointsharding/endpointsharding.go
type ChildState (line 44) | type ChildState struct
type ExitIdler (line 54) | type ExitIdler interface
type Options (line 63) | type Options struct
type ChildBuilderFunc (line 74) | type ChildBuilderFunc
function NewBalancer (line 79) | func NewBalancer(cc balancer.ClientConn, opts balancer.BuildOptions, chi...
type endpointSharding (line 93) | type endpointSharding struct
method UpdateClientConnState (line 138) | func (es *endpointSharding) UpdateClientConnState(state balancer.Clien...
method ResolverError (line 205) | func (es *endpointSharding) ResolverError(err error) {
method UpdateSubConnState (line 219) | func (es *endpointSharding) UpdateSubConnState(balancer.SubConn, balan...
method Close (line 223) | func (es *endpointSharding) Close() {
method ExitIdle (line 232) | func (es *endpointSharding) ExitIdle() {
method updateState (line 245) | func (es *endpointSharding) updateState() {
function rotateEndpoints (line 119) | func rotateEndpoints(es []resolver.Endpoint) []resolver.Endpoint {
type pickerWithChildStates (line 309) | type pickerWithChildStates struct
method Pick (line 315) | func (p *pickerWithChildStates) Pick(info balancer.PickInfo) (balancer...
function ChildStatesFromPicker (line 323) | func ChildStatesFromPicker(picker balancer.Picker) []ChildState {
type balancerWrapper (line 333) | type balancerWrapper struct
method UpdateState (line 350) | func (bw *balancerWrapper) UpdateState(state balancer.State) {
method ExitIdle (line 362) | func (bw *balancerWrapper) ExitIdle() {
method updateClientConnStateLocked (line 375) | func (bw *balancerWrapper) updateClientConnStateLocked(ccs balancer.Cl...
method closeLocked (line 381) | func (bw *balancerWrapper) closeLocked() {
method resolverErrorLocked (line 386) | func (bw *balancerWrapper) resolverErrorLocked(err error) {
FILE: balancer/endpointsharding/endpointsharding_ext_test.go
type s (line 60) | type s struct
method TestEndpointShardingBasic (line 134) | func (s) TestEndpointShardingBasic(t *testing.T) {
method TestEndpointShardingReconnectDisabled (line 210) | func (s) TestEndpointShardingReconnectDisabled(t *testing.T) {
method TestEndpointShardingExitIdle (line 295) | func (s) TestEndpointShardingExitIdle(t *testing.T) {
function Test (line 64) | func Test(t *testing.T) {
function init (line 70) | func init() {
constant fakePetioleName (line 74) | fakePetioleName = "fake_petiole"
type fakePetioleBuilder (line 76) | type fakePetioleBuilder struct
method Name (line 78) | func (fakePetioleBuilder) Name() string {
method Build (line 82) | func (fakePetioleBuilder) Build(cc balancer.ClientConn, opts balancer....
method ParseConfig (line 91) | func (fakePetioleBuilder) ParseConfig(json.RawMessage) (serviceconfig....
type fakePetiole (line 99) | type fakePetiole struct
method UpdateClientConnState (line 105) | func (fp *fakePetiole) UpdateClientConnState(state balancer.ClientConn...
method UpdateState (line 113) | func (fp *fakePetiole) UpdateState(state balancer.State) {
FILE: balancer/endpointsharding/endpointsharding_test.go
type s (line 29) | type s struct
method TestRotateEndpoints (line 37) | func (s) TestRotateEndpoints(t *testing.T) {
function Test (line 33) | func Test(t *testing.T) {
FILE: balancer/grpclb/grpc_lb_v1/load_balancer.pb.go
constant _ (line 40) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 42) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type LoadBalanceRequest (line 45) | type LoadBalanceRequest struct
method Reset (line 56) | func (x *LoadBalanceRequest) Reset() {
method String (line 63) | func (x *LoadBalanceRequest) String() string {
method ProtoMessage (line 67) | func (*LoadBalanceRequest) ProtoMessage() {}
method ProtoReflect (line 69) | func (x *LoadBalanceRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 82) | func (*LoadBalanceRequest) Descriptor() ([]byte, []int) {
method GetLoadBalanceRequestType (line 86) | func (x *LoadBalanceRequest) GetLoadBalanceRequestType() isLoadBalance...
method GetInitialRequest (line 93) | func (x *LoadBalanceRequest) GetInitialRequest() *InitialLoadBalanceRe...
method GetClientStats (line 102) | func (x *LoadBalanceRequest) GetClientStats() *ClientStats {
type isLoadBalanceRequest_LoadBalanceRequestType (line 111) | type isLoadBalanceRequest_LoadBalanceRequestType interface
type LoadBalanceRequest_InitialRequest (line 115) | type LoadBalanceRequest_InitialRequest struct
method isLoadBalanceRequest_LoadBalanceRequestType (line 126) | func (*LoadBalanceRequest_InitialRequest) isLoadBalanceRequest_LoadBal...
type LoadBalanceRequest_ClientStats (line 120) | type LoadBalanceRequest_ClientStats struct
method isLoadBalanceRequest_LoadBalanceRequestType (line 128) | func (*LoadBalanceRequest_ClientStats) isLoadBalanceRequest_LoadBalanc...
type InitialLoadBalanceRequest (line 130) | type InitialLoadBalanceRequest struct
method Reset (line 141) | func (x *InitialLoadBalanceRequest) Reset() {
method String (line 148) | func (x *InitialLoadBalanceRequest) String() string {
method ProtoMessage (line 152) | func (*InitialLoadBalanceRequest) ProtoMessage() {}
method ProtoReflect (line 154) | func (x *InitialLoadBalanceRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 167) | func (*InitialLoadBalanceRequest) Descriptor() ([]byte, []int) {
method GetName (line 171) | func (x *InitialLoadBalanceRequest) GetName() string {
type ClientStatsPerToken (line 179) | type ClientStatsPerToken struct
method Reset (line 189) | func (x *ClientStatsPerToken) Reset() {
method String (line 196) | func (x *ClientStatsPerToken) String() string {
method ProtoMessage (line 200) | func (*ClientStatsPerToken) ProtoMessage() {}
method ProtoReflect (line 202) | func (x *ClientStatsPerToken) ProtoReflect() protoreflect.Message {
method Descriptor (line 215) | func (*ClientStatsPerToken) Descriptor() ([]byte, []int) {
method GetLoadBalanceToken (line 219) | func (x *ClientStatsPerToken) GetLoadBalanceToken() string {
method GetNumCalls (line 226) | func (x *ClientStatsPerToken) GetNumCalls() int64 {
type ClientStats (line 235) | type ClientStats struct
method Reset (line 254) | func (x *ClientStats) Reset() {
method String (line 261) | func (x *ClientStats) String() string {
method ProtoMessage (line 265) | func (*ClientStats) ProtoMessage() {}
method ProtoReflect (line 267) | func (x *ClientStats) ProtoReflect() protoreflect.Message {
method Descriptor (line 280) | func (*ClientStats) Descriptor() ([]byte, []int) {
method GetTimestamp (line 284) | func (x *ClientStats) GetTimestamp() *timestamppb.Timestamp {
method GetNumCallsStarted (line 291) | func (x *ClientStats) GetNumCallsStarted() int64 {
method GetNumCallsFinished (line 298) | func (x *ClientStats) GetNumCallsFinished() int64 {
method GetNumCallsFinishedWithClientFailedToSend (line 305) | func (x *ClientStats) GetNumCallsFinishedWithClientFailedToSend() int64 {
method GetNumCallsFinishedKnownReceived (line 312) | func (x *ClientStats) GetNumCallsFinishedKnownReceived() int64 {
method GetCallsFinishedWithDrop (line 319) | func (x *ClientStats) GetCallsFinishedWithDrop() []*ClientStatsPerToken {
type LoadBalanceResponse (line 326) | type LoadBalanceResponse struct
method Reset (line 338) | func (x *LoadBalanceResponse) Reset() {
method String (line 345) | func (x *LoadBalanceResponse) String() string {
method ProtoMessage (line 349) | func (*LoadBalanceResponse) ProtoMessage() {}
method ProtoReflect (line 351) | func (x *LoadBalanceResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 364) | func (*LoadBalanceResponse) Descriptor() ([]byte, []int) {
method GetLoadBalanceResponseType (line 368) | func (x *LoadBalanceResponse) GetLoadBalanceResponseType() isLoadBalan...
method GetInitialResponse (line 375) | func (x *LoadBalanceResponse) GetInitialResponse() *InitialLoadBalance...
method GetServerList (line 384) | func (x *LoadBalanceResponse) GetServerList() *ServerList {
method GetFallbackResponse (line 393) | func (x *LoadBalanceResponse) GetFallbackResponse() *FallbackResponse {
type isLoadBalanceResponse_LoadBalanceResponseType (line 402) | type isLoadBalanceResponse_LoadBalanceResponseType interface
type LoadBalanceResponse_InitialResponse (line 406) | type LoadBalanceResponse_InitialResponse struct
method isLoadBalanceResponse_LoadBalanceResponseType (line 423) | func (*LoadBalanceResponse_InitialResponse) isLoadBalanceResponse_Load...
type LoadBalanceResponse_ServerList (line 411) | type LoadBalanceResponse_ServerList struct
method isLoadBalanceResponse_LoadBalanceResponseType (line 425) | func (*LoadBalanceResponse_ServerList) isLoadBalanceResponse_LoadBalan...
type LoadBalanceResponse_FallbackResponse (line 417) | type LoadBalanceResponse_FallbackResponse struct
method isLoadBalanceResponse_LoadBalanceResponseType (line 427) | func (*LoadBalanceResponse_FallbackResponse) isLoadBalanceResponse_Loa...
type FallbackResponse (line 429) | type FallbackResponse struct
method Reset (line 435) | func (x *FallbackResponse) Reset() {
method String (line 442) | func (x *FallbackResponse) String() string {
method ProtoMessage (line 446) | func (*FallbackResponse) ProtoMessage() {}
method ProtoReflect (line 448) | func (x *FallbackResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 461) | func (*FallbackResponse) Descriptor() ([]byte, []int) {
type InitialLoadBalanceResponse (line 465) | type InitialLoadBalanceResponse struct
method Reset (line 475) | func (x *InitialLoadBalanceResponse) Reset() {
method String (line 482) | func (x *InitialLoadBalanceResponse) String() string {
method ProtoMessage (line 486) | func (*InitialLoadBalanceResponse) ProtoMessage() {}
method ProtoReflect (line 488) | func (x *InitialLoadBalanceResponse) ProtoReflect() protoreflect.Messa...
method Descriptor (line 501) | func (*InitialLoadBalanceResponse) Descriptor() ([]byte, []int) {
method GetClientStatsReportInterval (line 505) | func (x *InitialLoadBalanceResponse) GetClientStatsReportInterval() *d...
type ServerList (line 512) | type ServerList struct
method Reset (line 523) | func (x *ServerList) Reset() {
method String (line 530) | func (x *ServerList) String() string {
method ProtoMessage (line 534) | func (*ServerList) ProtoMessage() {}
method ProtoReflect (line 536) | func (x *ServerList) ProtoReflect() protoreflect.Message {
method Descriptor (line 549) | func (*ServerList) Descriptor() ([]byte, []int) {
method GetServers (line 553) | func (x *ServerList) GetServers() []*Server {
type Server (line 562) | type Server struct
method Reset (line 585) | func (x *Server) Reset() {
method String (line 592) | func (x *Server) String() string {
method ProtoMessage (line 596) | func (*Server) ProtoMessage() {}
method ProtoReflect (line 598) | func (x *Server) ProtoReflect() protoreflect.Message {
method Descriptor (line 611) | func (*Server) Descriptor() ([]byte, []int) {
method GetIpAddress (line 615) | func (x *Server) GetIpAddress() []byte {
method GetPort (line 622) | func (x *Server) GetPort() int32 {
method GetLoadBalanceToken (line 629) | func (x *Server) GetLoadBalanceToken() string {
method GetDrop (line 636) | func (x *Server) GetDrop() bool {
constant file_grpc_lb_v1_load_balancer_proto_rawDesc (line 645) | file_grpc_lb_v1_load_balancer_proto_rawDesc = "" +
function file_grpc_lb_v1_load_balancer_proto_rawDescGZIP (line 692) | func file_grpc_lb_v1_load_balancer_proto_rawDescGZIP() []byte {
function init (line 732) | func init() { file_grpc_lb_v1_load_balancer_proto_init() }
function file_grpc_lb_v1_load_balancer_proto_init (line 733) | func file_grpc_lb_v1_load_balancer_proto_init() {
FILE: balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go
constant _ (line 38) | _ = grpc.SupportPackageIsVersion9
constant LoadBalancer_BalanceLoad_FullMethodName (line 41) | LoadBalancer_BalanceLoad_FullMethodName = "/grpc.lb.v1.LoadBalancer/Bala...
type LoadBalancerClient (line 47) | type LoadBalancerClient interface
type loadBalancerClient (line 52) | type loadBalancerClient struct
method BalanceLoad (line 60) | func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ......
function NewLoadBalancerClient (line 56) | func NewLoadBalancerClient(cc grpc.ClientConnInterface) LoadBalancerClie...
type LoadBalancerServer (line 76) | type LoadBalancerServer interface
type UnimplementedLoadBalancerServer (line 86) | type UnimplementedLoadBalancerServer struct
method BalanceLoad (line 88) | func (UnimplementedLoadBalancerServer) BalanceLoad(grpc.BidiStreamingS...
method testEmbeddedByValue (line 91) | func (UnimplementedLoadBalancerServer) testEmbeddedByValue() {}
type UnsafeLoadBalancerServer (line 96) | type UnsafeLoadBalancerServer interface
function RegisterLoadBalancerServer (line 100) | func RegisterLoadBalancerServer(s grpc.ServiceRegistrar, srv LoadBalance...
function _LoadBalancer_BalanceLoad_Handler (line 111) | func _LoadBalancer_BalanceLoad_Handler(srv interface{}, stream grpc.Serv...
FILE: balancer/grpclb/grpclb.go
constant lbTokenKey (line 53) | lbTokenKey = "lb-token"
constant defaultFallbackTimeout (line 54) | defaultFallbackTimeout = 10 * time.Second
constant grpclbName (line 55) | grpclbName = "grpclb"
function convertDuration (line 61) | func convertDuration(d *durationpb.Duration) time.Duration {
type loadBalancerClient (line 71) | type loadBalancerClient struct
method BalanceLoad (line 75) | func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ......
type balanceLoadClientStream (line 89) | type balanceLoadClientStream struct
method Send (line 93) | func (x *balanceLoadClientStream) Send(m *lbpb.LoadBalanceRequest) err...
method Recv (line 97) | func (x *balanceLoadClientStream) Recv() (*lbpb.LoadBalanceResponse, e...
function init (line 105) | func init() {
function newLBBuilder (line 111) | func newLBBuilder() balancer.Builder {
function newLBBuilderWithFallbackTimeout (line 121) | func newLBBuilderWithFallbackTimeout(fallbackTimeout time.Duration) bala...
type lbBuilder (line 127) | type lbBuilder struct
method Name (line 131) | func (b *lbBuilder) Name() string {
method Build (line 135) | func (b *lbBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOp...
type lbBalancer (line 177) | type lbBalancer struct
method regeneratePicker (line 247) | func (lb *lbBalancer) regeneratePicker(resetDrop bool) {
method aggregateSubConnStates (line 313) | func (lb *lbBalancer) aggregateSubConnStates() connectivity.State {
method UpdateSubConnState (line 334) | func (lb *lbBalancer) UpdateSubConnState(sc balancer.SubConn, scs bala...
method updateSubConnState (line 338) | func (lb *lbBalancer) updateSubConnState(sc balancer.SubConn, scs bala...
method updateStateAndPicker (line 383) | func (lb *lbBalancer) updateStateAndPicker(forceRegeneratePicker bool,...
method fallbackToBackendsAfter (line 404) | func (lb *lbBalancer) fallbackToBackendsAfter(fallbackTimeout time.Dur...
method handleServiceConfig (line 422) | func (lb *lbBalancer) handleServiceConfig(gc *grpclbServiceConfig) {
method ResolverError (line 460) | func (lb *lbBalancer) ResolverError(error) {
method UpdateClientConnState (line 465) | func (lb *lbBalancer) UpdateClientConnState(ccs balancer.ClientConnSta...
method Close (line 522) | func (lb *lbBalancer) Close() {
method ExitIdle (line 535) | func (lb *lbBalancer) ExitIdle() {}
FILE: balancer/grpclb/grpclb_config.go
constant roundRobinName (line 30) | roundRobinName = roundrobin.Name
constant pickFirstName (line 31) | pickFirstName = pickfirst.Name
type grpclbServiceConfig (line 34) | type grpclbServiceConfig struct
method ParseConfig (line 40) | func (b *lbBuilder) ParseConfig(lbConfig json.RawMessage) (serviceconfig...
function childIsPickFirst (line 48) | func childIsPickFirst(sc *grpclbServiceConfig) bool {
FILE: balancer/grpclb/grpclb_config_test.go
method TestParse (line 29) | func (s) TestParse(t *testing.T) {
method TestChildIsPickFirst (line 90) | func (s) TestChildIsPickFirst(t *testing.T) {
FILE: balancer/grpclb/grpclb_picker.go
type rpcStats (line 34) | type rpcStats struct
method toClientStats (line 61) | func (s *rpcStats) toClientStats() *lbpb.ClientStats {
method drop (line 81) | func (s *rpcStats) drop(token string) {
method failedToSend (line 89) | func (s *rpcStats) failedToSend() {
method knownReceived (line 95) | func (s *rpcStats) knownReceived() {
function newRPCStats (line 46) | func newRPCStats() *rpcStats {
function isZeroStats (line 52) | func isZeroStats(stats *lbpb.ClientStats) bool {
type rrPicker (line 106) | type rrPicker struct
method Pick (line 119) | func (p *rrPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
function newRRPicker (line 112) | func newRRPicker(readySCs []balancer.SubConn) *rrPicker {
type lbPicker (line 136) | type lbPicker struct
method Pick (line 155) | func (p *lbPicker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
method updateReadySCs (line 187) | func (p *lbPicker) updateReadySCs(readySCs []balancer.SubConn) {
function newLBPicker (line 146) | func newLBPicker(serverList []*lbpb.Server, readySCs []balancer.SubConn,...
FILE: balancer/grpclb/grpclb_remote_balancer.go
function serverListEqual (line 45) | func serverListEqual(a, b []*lbpb.Server) bool {
method processServerList (line 59) | func (lb *lbBalancer) processServerList(l *lbpb.ServerList) {
method refreshSubConns (line 108) | func (lb *lbBalancer) refreshSubConns(backendAddrs []resolver.Address, f...
type remoteBalancerCCWrapper (line 218) | type remoteBalancerCCWrapper struct
method close (line 282) | func (ccw *remoteBalancerCCWrapper) close() {
method readServerList (line 288) | func (ccw *remoteBalancerCCWrapper) readServerList(s *balanceLoadClien...
method sendLoadReport (line 309) | func (ccw *remoteBalancerCCWrapper) sendLoadReport(s *balanceLoadClien...
method callRemoteBalancer (line 341) | func (ccw *remoteBalancerCCWrapper) callRemoteBalancer(ctx context.Con...
method cancelRemoteBalancerCall (line 385) | func (ccw *remoteBalancerCCWrapper) cancelRemoteBalancerCall() {
method watchRemoteBalancer (line 394) | func (ccw *remoteBalancerCCWrapper) watchRemoteBalancer() {
method newRemoteBalancerCCWrapper (line 231) | func (lb *lbBalancer) newRemoteBalancerCCWrapper() error {
FILE: balancer/grpclb/grpclb_test.go
constant defaultTestTimeout (line 73) | defaultTestTimeout = 10 * time.Second
constant defaultTestShortTimeout (line 74) | defaultTestShortTimeout = 10 * time.Millisecond
constant testUserAgent (line 75) | testUserAgent = "test-user-agent"
constant grpclbConfig (line 76) | grpclbConfig = `{"loadBalancingConfig": [{"grpclb": {}}]}`
type s (line 79) | type s struct
method TestGRPCLB_Basic (line 421) | func (s) TestGRPCLB_Basic(t *testing.T) {
method TestGRPCLB_Weighted (line 480) | func (s) TestGRPCLB_Weighted(t *testing.T) {
method TestGRPCLB_DropRequest (line 555) | func (s) TestGRPCLB_DropRequest(t *testing.T) {
method TestGRPCLB_BalancerDisconnects (line 720) | func (s) TestGRPCLB_BalancerDisconnects(t *testing.T) {
method TestGRPCLB_Fallback (line 799) | func (s) TestGRPCLB_Fallback(t *testing.T) {
method TestGRPCLB_ExplicitFallback (line 897) | func (s) TestGRPCLB_ExplicitFallback(t *testing.T) {
method TestGRPCLB_FallBackWithNoServerAddress (line 969) | func (s) TestGRPCLB_FallBackWithNoServerAddress(t *testing.T) {
method TestGRPCLB_PickFirst (line 1074) | func (s) TestGRPCLB_PickFirst(t *testing.T) {
method TestGRPCLB_BackendConnectionErrorPropagation (line 1171) | func (s) TestGRPCLB_BackendConnectionErrorPropagation(t *testing.T) {
method TestGRPCLBEmptyServerListRoundRobin (line 1289) | func (s) TestGRPCLBEmptyServerListRoundRobin(t *testing.T) {
method TestGRPCLBEmptyServerListPickFirst (line 1293) | func (s) TestGRPCLBEmptyServerListPickFirst(t *testing.T) {
method TestGRPCLBWithTargetNameFieldInConfig (line 1297) | func (s) TestGRPCLBWithTargetNameFieldInConfig(t *testing.T) {
method TestGRPCLBStatsUnarySuccess (line 1457) | func (s) TestGRPCLBStatsUnarySuccess(t *testing.T) {
method TestGRPCLBStatsUnaryDrop (line 1478) | func (s) TestGRPCLBStatsUnaryDrop(t *testing.T) {
method TestGRPCLBStatsUnaryFailedToSend (line 1500) | func (s) TestGRPCLBStatsUnaryFailedToSend(t *testing.T) {
method TestGRPCLBStatsStreamingSuccess (line 1522) | func (s) TestGRPCLBStatsStreamingSuccess(t *testing.T) {
method TestGRPCLBStatsStreamingDrop (line 1557) | func (s) TestGRPCLBStatsStreamingDrop(t *testing.T) {
method TestGRPCLBStatsStreamingFailedToSend (line 1593) | func (s) TestGRPCLBStatsStreamingFailedToSend(t *testing.T) {
method TestGRPCLBStatsQuashEmpty (line 1621) | func (s) TestGRPCLBStatsQuashEmpty(t *testing.T) {
function Test (line 83) | func Test(t *testing.T) {
type serverNameCheckCreds (line 87) | type serverNameCheckCreds struct
method ServerHandshake (line 92) | func (c *serverNameCheckCreds) ServerHandshake(rawConn net.Conn) (net....
method ClientHandshake (line 99) | func (c *serverNameCheckCreds) ClientHandshake(ctx context.Context, au...
method Info (line 123) | func (c *serverNameCheckCreds) Info() credentials.ProtocolInfo {
method Clone (line 126) | func (c *serverNameCheckCreds) Clone() credentials.TransportCredentials {
method OverrideServerName (line 129) | func (c *serverNameCheckCreds) OverrideServerName(string) error {
function fakeNameDialer (line 135) | func fakeNameDialer(ctx context.Context, addr string) (net.Conn, error) {
method merge (line 143) | func (s *rpcStats) merge(cs *lbpb.ClientStats) {
function atomicEqual (line 155) | func atomicEqual(a, b *int64) bool {
method equal (line 162) | func (s *rpcStats) equal(o *rpcStats) bool {
method String (line 182) | func (s *rpcStats) String() string {
type remoteBalancer (line 193) | type remoteBalancer struct
method stop (line 220) | func (b *remoteBalancer) stop() {
method fallbackNow (line 225) | func (b *remoteBalancer) fallbackNow() {
method updateServerName (line 229) | func (b *remoteBalancer) updateServerName(name string) {
method BalanceLoad (line 233) | func (b *remoteBalancer) BalanceLoad(stream lbgrpc.LoadBalancer_Balanc...
function newRemoteBalancer (line 207) | func newRemoteBalancer(wantUserAgent, wantServerName string, statsChan c...
type testServer (line 301) | type testServer struct
method EmptyCall (line 310) | func (s *testServer) EmptyCall(ctx context.Context, _ *testpb.Empty) (...
method FullDuplexCall (line 322) | func (s *testServer) FullDuplexCall(testgrpc.TestService_FullDuplexCal...
constant testmdkey (line 308) | testmdkey = "testmd"
function startBackends (line 326) | func startBackends(t *testing.T, sn string, fallback bool, lis ...net.Li...
function stopBackends (line 342) | func stopBackends(servers []*grpc.Server) {
type testServers (line 348) | type testServers struct
function startBackendsAndRemoteLoadBalancer (line 360) | func startBackendsAndRemoteLoadBalancer(t *testing.T, numberOfBackends i...
function testGRPCLBEmptyServerList (line 1225) | func testGRPCLBEmptyServerList(t *testing.T, svcfg string) {
type failPreRPCCred (line 1382) | type failPreRPCCred struct
method GetRequestMetadata (line 1384) | func (failPreRPCCred) GetRequestMetadata(_ context.Context, uri ...str...
method RequireTransportSecurity (line 1391) | func (failPreRPCCred) RequireTransportSecurity() bool {
function checkStats (line 1395) | func checkStats(stats, expected *rpcStats) error {
function runAndCheckStats (line 1402) | func runAndCheckStats(t *testing.T, drop bool, statsChan chan *lbpb.Clie...
constant countRPC (line 1453) | countRPC = 40
constant failtosendURI (line 1454) | failtosendURI = "failtosend"
FILE: balancer/grpclb/grpclb_util.go
constant subConnCacheTime (line 30) | subConnCacheTime = time.Second * 10
type lbCacheClientConn (line 36) | type lbCacheClientConn struct
method NewSubConn (line 63) | func (ccc *lbCacheClientConn) NewSubConn(addrs []resolver.Address, opt...
method RemoveSubConn (line 90) | func (ccc *lbCacheClientConn) RemoveSubConn(sc balancer.SubConn) {
method UpdateState (line 148) | func (ccc *lbCacheClientConn) UpdateState(s balancer.State) {
method close (line 153) | func (ccc *lbCacheClientConn) close() {
type subConnCacheEntry (line 47) | type subConnCacheEntry struct
function newLBCacheClientConn (line 54) | func newLBCacheClientConn(cc balancer.ClientConn) *lbCacheClientConn {
type lbCacheSubConn (line 94) | type lbCacheSubConn struct
method Shutdown (line 99) | func (sc *lbCacheSubConn) Shutdown() {
type lbCachePicker (line 162) | type lbCachePicker struct
method Pick (line 166) | func (cp *lbCachePicker) Pick(i balancer.PickInfo) (balancer.PickResul...
FILE: balancer/grpclb/grpclb_util_test.go
type mockSubConn (line 31) | type mockSubConn struct
method Shutdown (line 36) | func (msc *mockSubConn) Shutdown() {
type mockClientConn (line 42) | type mockClientConn struct
method NewSubConn (line 55) | func (mcc *mockClientConn) NewSubConn(addrs []resolver.Address, _ bala...
method RemoveSubConn (line 63) | func (mcc *mockClientConn) RemoveSubConn(sc balancer.SubConn) {
function newMockClientConn (line 49) | func newMockClientConn() *mockClientConn {
constant testCacheTimeout (line 67) | testCacheTimeout = 100 * time.Millisecond
function checkMockCC (line 69) | func checkMockCC(mcc *mockClientConn, scLen int) error {
function checkCacheCC (line 78) | func checkCacheCC(ccc *lbCacheClientConn, sccLen, sctaLen int) error {
method TestLBCacheClientConnExpire (line 91) | func (s) TestLBCacheClientConnExpire(t *testing.T) {
method TestLBCacheClientConnReuse (line 143) | func (s) TestLBCacheClientConnReuse(t *testing.T) {
method TestLBCache_ShutdownTimer_New_Race (line 228) | func (s) TestLBCache_ShutdownTimer_New_Race(t *testing.T) {
FILE: balancer/grpclb/state/state.go
type keyType (line 28) | type keyType
constant key (line 30) | key = keyType("grpc.grpclb.state")
type State (line 33) | type State struct
function Set (line 41) | func Set(state resolver.State, s *State) resolver.State {
function Get (line 48) | func Get(state resolver.State) *State {
FILE: balancer/lazy/lazy.go
constant logPrefix (line 45) | logPrefix = "[lazy-lb %p] "
type ChildBuilderFunc (line 50) | type ChildBuilderFunc
function NewBalancer (line 53) | func NewBalancer(cc balancer.ClientConn, bOpts balancer.BuildOptions, ch...
type lazyBalancer (line 71) | type lazyBalancer struct
method Close (line 88) | func (lb *lazyBalancer) Close() {
method ResolverError (line 97) | func (lb *lazyBalancer) ResolverError(err error) {
method UpdateClientConnState (line 107) | func (lb *lazyBalancer) UpdateClientConnState(ccs balancer.ClientConnS...
method UpdateSubConnState (line 120) | func (lb *lazyBalancer) UpdateSubConnState(balancer.SubConn, balancer....
method ExitIdle (line 124) | func (lb *lazyBalancer) ExitIdle() {
type idlePicker (line 150) | type idlePicker struct
method Pick (line 154) | func (i *idlePicker) Pick(balancer.PickInfo) (balancer.PickResult, err...
FILE: balancer/lazy/lazy_ext_test.go
constant defaultTestTimeout (line 50) | defaultTestTimeout = 10 * time.Second
constant defaultTestShortTimeout (line 53) | defaultTestShortTimeout = 100 * time.Millisecond
type s (line 56) | type s struct
method TestExitIdle (line 67) | func (s) TestExitIdle(t *testing.T) {
method TestPicker (line 139) | func (s) TestPicker(t *testing.T) {
method TestGoodUpdateThenResolverError (line 193) | func (s) TestGoodUpdateThenResolverError(t *testing.T) {
method TestResolverErrorThenGoodUpdate (line 300) | func (s) TestResolverErrorThenGoodUpdate(t *testing.T) {
method TestExitIdlePassthrough (line 395) | func (s) TestExitIdlePassthrough(t *testing.T) {
function Test (line 60) | func Test(t *testing.T) {
FILE: balancer/leastrequest/leastrequest.go
constant Name (line 40) | Name = "least_request_experimental"
function init (line 48) | func init() {
type LBConfig (line 53) | type LBConfig struct
type bb (line 62) | type bb struct
method ParseConfig (line 64) | func (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingC...
method Name (line 84) | func (bb) Name() string {
method Build (line 88) | func (bb) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) b...
type leastRequestBalancer (line 99) | type leastRequestBalancer struct
method Close (line 113) | func (lrb *leastRequestBalancer) Close() {
method UpdateSubConnState (line 118) | func (lrb *leastRequestBalancer) UpdateSubConnState(sc balancer.SubCon...
method ResolverError (line 122) | func (lrb *leastRequestBalancer) ResolverError(err error) {
method ExitIdle (line 127) | func (lrb *leastRequestBalancer) ExitIdle() {
method UpdateClientConnState (line 131) | func (lrb *leastRequestBalancer) UpdateClientConnState(ccs balancer.Cl...
method UpdateState (line 153) | func (lrb *leastRequestBalancer) UpdateState(state balancer.State) {
type endpointState (line 148) | type endpointState struct
type picker (line 213) | type picker struct
method Pick (line 220) | func (p *picker) Pick(pInfo balancer.PickInfo) (balancer.PickResult, e...
FILE: balancer/leastrequest/leastrequest_test.go
constant defaultTestTimeout (line 46) | defaultTestTimeout = 5 * time.Second
constant defaultTestShortTimeout (line 47) | defaultTestShortTimeout = 10 * time.Millisecond
type s (line 50) | type s struct
method TestParseConfig (line 58) | func (s) TestParseConfig(t *testing.T) {
method TestLeastRequestE2E (line 206) | func (s) TestLeastRequestE2E(t *testing.T) {
method TestLeastRequestPersistsCounts (line 322) | func (s) TestLeastRequestPersistsCounts(t *testing.T) {
method TestConcurrentRPCs (line 475) | func (s) TestConcurrentRPCs(t *testing.T) {
method TestLeastRequestEndpoints_MultipleAddresses (line 535) | func (s) TestLeastRequestEndpoints_MultipleAddresses(t *testing.T) {
method TestLeastRequestEndpoints_ResolverError (line 714) | func (s) TestLeastRequestEndpoints_ResolverError(t *testing.T) {
function Test (line 54) | func Test(t *testing.T) {
function startBackends (line 122) | func startBackends(t *testing.T, numBackends int) []*stubserver.StubServ...
function setupBackends (line 148) | func setupBackends(t *testing.T, numBackends int) []string {
function checkRoundRobinRPCs (line 165) | func checkRoundRobinRPCs(ctx context.Context, client testgrpc.TestServic...
FILE: balancer/pickfirst/metrics_test.go
function init (line 49) | func init() {
method TestPickFirstMetrics (line 63) | func (s) TestPickFirstMetrics(t *testing.T) {
method TestPickFirstMetricsFailure (line 135) | func (s) TestPickFirstMetricsFailure(t *testing.T) {
method TestPickFirstMetricsE2E (line 173) | func (s) TestPickFirstMetricsE2E(t *testing.T) {
function metricsDataFromReader (line 283) | func metricsDataFromReader(ctx context.Context, reader *metric.ManualRea...
FILE: balancer/pickfirst/pickfirst.go
function init (line 48) | func init() {
constant Name (line 53) | Name = "pick_first"
type enableHealthListenerKeyType (line 57) | type enableHealthListenerKeyType struct
constant logPrefix (line 86) | logPrefix = "[pick-first-leaf-lb %p] "
constant connectionDelayInterval (line 89) | connectionDelayInterval = 250 * time.Millisecond
type ipAddrFamily (line 92) | type ipAddrFamily
constant ipAddrFamilyUnknown (line 97) | ipAddrFamilyUnknown ipAddrFamily = iota
constant ipAddrFamilyV4 (line 98) | ipAddrFamilyV4
constant ipAddrFamilyV6 (line 99) | ipAddrFamilyV6
type pickfirstBuilder (line 102) | type pickfirstBuilder struct
method Build (line 104) | func (pickfirstBuilder) Build(cc balancer.ClientConn, bo balancer.Buil...
method Name (line 118) | func (b pickfirstBuilder) Name() string {
method ParseConfig (line 122) | func (pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig...
function EnableHealthListener (line 137) | func EnableHealthListener(state resolver.State) resolver.State {
type pfConfig (line 142) | type pfConfig struct
type scData (line 153) | type scData struct
type pickfirstBalancer (line 185) | type pickfirstBalancer struct
method newSCData (line 167) | func (b *pickfirstBalancer) newSCData(addr resolver.Address) (*scData,...
method ResolverError (line 211) | func (b *pickfirstBalancer) ResolverError(err error) {
method resolverErrorLocked (line 217) | func (b *pickfirstBalancer) resolverErrorLocked(err error) {
method UpdateClientConnState (line 238) | func (b *pickfirstBalancer) UpdateClientConnState(state balancer.Clien...
method UpdateSubConnState (line 368) | func (b *pickfirstBalancer) UpdateSubConnState(subConn balancer.SubCon...
method Close (line 372) | func (b *pickfirstBalancer) Close() {
method ExitIdle (line 383) | func (b *pickfirstBalancer) ExitIdle() {
method startFirstPassLocked (line 398) | func (b *pickfirstBalancer) startFirstPassLocked() {
method closeSubConnsLocked (line 408) | func (b *pickfirstBalancer) closeSubConnsLocked() {
method reconcileSubConnsLocked (line 503) | func (b *pickfirstBalancer) reconcileSubConnsLocked(newAddrs []resolve...
method shutdownRemainingLocked (line 521) | func (b *pickfirstBalancer) shutdownRemainingLocked(selected *scData) {
method requestConnectionLocked (line 536) | func (b *pickfirstBalancer) requestConnectionLocked() {
method scheduleNextConnectionLocked (line 590) | func (b *pickfirstBalancer) scheduleNextConnectionLocked() {
method updateSubConnState (line 619) | func (b *pickfirstBalancer) updateSubConnState(sd *scData, newState ba...
method endFirstPassIfPossibleLocked (line 767) | func (b *pickfirstBalancer) endFirstPassIfPossibleLocked(lastErr error) {
method isActiveSCData (line 792) | func (b *pickfirstBalancer) isActiveSCData(sd *scData) bool {
method updateSubConnHealthState (line 797) | func (b *pickfirstBalancer) updateSubConnHealthState(sd *scData, state...
method updateBalancerState (line 832) | func (b *pickfirstBalancer) updateBalancerState(newState balancer.Stat...
method forceUpdateConcludedStateLocked (line 847) | func (b *pickfirstBalancer) forceUpdateConcludedStateLocked(newState b...
function deDupAddresses (line 416) | func deDupAddresses(addrs []resolver.Address) []resolver.Address {
function interleaveAddresses (line 441) | func interleaveAddresses(addrs []resolver.Address) []resolver.Address {
function addressFamily (line 474) | func addressFamily(address string) ipAddrFamily {
type picker (line 852) | type picker struct
method Pick (line 857) | func (p *picker) Pick(balancer.PickInfo) (balancer.PickResult, error) {
type idlePicker (line 863) | type idlePicker struct
method Pick (line 867) | func (i *idlePicker) Pick(balancer.PickInfo) (balancer.PickResult, err...
type addressList (line 876) | type addressList struct
method isValid (line 881) | func (al *addressList) isValid() bool {
method size (line 885) | func (al *addressList) size() int {
method increment (line 891) | func (al *addressList) increment() bool {
method currentAddress (line 901) | func (al *addressList) currentAddress() resolver.Address {
method reset (line 908) | func (al *addressList) reset() {
method updateAddrs (line 912) | func (al *addressList) updateAddrs(addrs []resolver.Address) {
method seekTo (line 919) | func (al *addressList) seekTo(needle resolver.Address) bool {
method hasNext (line 933) | func (al *addressList) hasNext() bool {
function equalAddressIgnoringBalAttributes (line 944) | func equalAddressIgnoringBalAttributes(a, b *resolver.Address) bool {
function weightAttribute (line 955) | func weightAttribute(e resolver.Endpoint) uint32 {
FILE: balancer/pickfirst/pickfirst_ext_test.go
constant pickFirstServiceConfig (line 62) | pickFirstServiceConfig = `{"loadBalancingConfig": [{"pick_first":{}}]}`
constant defaultTestTimeout (line 64) | defaultTestTimeout = 10 * time.Second
constant defaultTestShortTimeout (line 67) | defaultTestShortTimeout = 100 * time.Millisecond
constant stateStoringBalancerName (line 68) | stateStoringBalancerName = "state_storing"
type s (line 79) | type s struct
method TestPickFirst_OneBackend (line 164) | func (s) TestPickFirst_OneBackend(t *testing.T) {
method TestPickFirst_MultipleBackends (line 179) | func (s) TestPickFirst_MultipleBackends(t *testing.T) {
method TestPickFirst_OneServerDown (line 195) | func (s) TestPickFirst_OneServerDown(t *testing.T) {
method TestPickFirst_AllServersDown (line 218) | func (s) TestPickFirst_AllServersDown(t *testing.T) {
method TestPickFirst_AddressesRemoved (line 249) | func (s) TestPickFirst_AddressesRemoved(t *testing.T) {
method TestPickFirst_NewAddressWhileBlocking (line 295) | func (s) TestPickFirst_NewAddressWhileBlocking(t *testing.T) {
method TestPickFirst_StickyTransientFailure (line 358) | func (s) TestPickFirst_StickyTransientFailure(t *testing.T) {
method TestPickFirst_ShuffleAddressList (line 429) | func (s) TestPickFirst_ShuffleAddressList(t *testing.T) {
method TestPickFirst_ShuffleAddressListNoEndpoints (line 491) | func (s) TestPickFirst_ShuffleAddressListNoEndpoints(t *testing.T) {
method TestPickFirst_ShuffleAddressList_WeightedShuffling (line 570) | func (s) TestPickFirst_ShuffleAddressList_WeightedShuffling(t *testing...
method TestPickFirst_ParseConfig_Success (line 633) | func (s) TestPickFirst_ParseConfig_Success(t *testing.T) {
method TestPickFirst_ParseConfig_Failure (line 694) | func (s) TestPickFirst_ParseConfig_Failure(t *testing.T) {
method TestPickFirst_AddressUpdateWithAttributes (line 761) | func (s) TestPickFirst_AddressUpdateWithAttributes(t *testing.T) {
method TestPickFirst_AddressUpdateWithBalancerAttributes (line 839) | func (s) TestPickFirst_AddressUpdateWithBalancerAttributes(t *testing....
method TestPickFirst_ResolverError_NoPreviousUpdate (line 923) | func (s) TestPickFirst_ResolverError_NoPreviousUpdate(t *testing.T) {
method TestPickFirst_ResolverError_WithPreviousUpdate_Ready (line 947) | func (s) TestPickFirst_ResolverError_WithPreviousUpdate_Ready(t *testi...
method TestPickFirst_ResolverError_WithPreviousUpdate_Connecting (line 976) | func (s) TestPickFirst_ResolverError_WithPreviousUpdate_Connecting(t *...
method TestPickFirst_ResolverError_WithPreviousUpdate_TransientFailure (line 1041) | func (s) TestPickFirst_ResolverError_WithPreviousUpdate_TransientFailu...
method TestPickFirst_ResolverError_ZeroAddresses_WithPreviousUpdate (line 1110) | func (s) TestPickFirst_ResolverError_ZeroAddresses_WithPreviousUpdate(...
method TestPickFirstLeaf_SimpleResolverUpdate_FirstServerReady (line 1217) | func (s) TestPickFirstLeaf_SimpleResolverUpdate_FirstServerReady(t *te...
method TestPickFirstLeaf_SimpleResolverUpdate_FirstServerUnReady (line 1257) | func (s) TestPickFirstLeaf_SimpleResolverUpdate_FirstServerUnReady(t *...
method TestPickFirstLeaf_SimpleResolverUpdate_DuplicateAddrs (line 1299) | func (s) TestPickFirstLeaf_SimpleResolverUpdate_DuplicateAddrs(t *test...
method TestPickFirstLeaf_ResolverUpdates_DisjointLists (line 1355) | func (s) TestPickFirstLeaf_ResolverUpdates_DisjointLists(t *testing.T) {
method TestPickFirstLeaf_ResolverUpdates_ActiveBackendInUpdatedList (line 1416) | func (s) TestPickFirstLeaf_ResolverUpdates_ActiveBackendInUpdatedList(...
method TestPickFirstLeaf_ResolverUpdates_InActiveBackendInUpdatedList (line 1478) | func (s) TestPickFirstLeaf_ResolverUpdates_InActiveBackendInUpdatedLis...
method TestPickFirstLeaf_ResolverUpdates_IdenticalLists (line 1540) | func (s) TestPickFirstLeaf_ResolverUpdates_IdenticalLists(t *testing.T) {
method TestPickFirstLeaf_StopConnectedServer_FirstServerRestart (line 1612) | func (s) TestPickFirstLeaf_StopConnectedServer_FirstServerRestart(t *t...
method TestPickFirstLeaf_StopConnectedServer_SecondServerRestart (line 1674) | func (s) TestPickFirstLeaf_StopConnectedServer_SecondServerRestart(t *...
method TestPickFirstLeaf_StopConnectedServer_SecondServerToFirst (line 1743) | func (s) TestPickFirstLeaf_StopConnectedServer_SecondServerToFirst(t *...
method TestPickFirstLeaf_StopConnectedServer_FirstServerToSecond (line 1812) | func (s) TestPickFirstLeaf_StopConnectedServer_FirstServerToSecond(t *...
method TestPickFirstLeaf_EmptyAddressList (line 1884) | func (s) TestPickFirstLeaf_EmptyAddressList(t *testing.T) {
method TestPickFirstLeaf_HappyEyeballs_TF_AfterEndOfList (line 1935) | func (s) TestPickFirstLeaf_HappyEyeballs_TF_AfterEndOfList(t *testing....
method TestPickFirstLeaf_HappyEyeballs_TriggerConnectionDelay (line 2031) | func (s) TestPickFirstLeaf_HappyEyeballs_TriggerConnectionDelay(t *tes...
method TestPickFirstLeaf_HappyEyeballs_TF_ThenTimerFires (line 2112) | func (s) TestPickFirstLeaf_HappyEyeballs_TF_ThenTimerFires(t *testing....
method TestPickFirstLeaf_HappyEyeballs_Ignore_Inflight_Cancellations (line 2193) | func (s) TestPickFirstLeaf_HappyEyeballs_Ignore_Inflight_Cancellations...
method TestPickFirstLeaf_InterleavingIPV4Preferred (line 2268) | func (s) TestPickFirstLeaf_InterleavingIPV4Preferred(t *testing.T) {
method TestPickFirstLeaf_InterleavingIPv6Preferred (line 2314) | func (s) TestPickFirstLeaf_InterleavingIPv6Preferred(t *testing.T) {
method TestPickFirstLeaf_InterleavingUnknownPreferred (line 2359) | func (s) TestPickFirstLeaf_InterleavingUnknownPreferred(t *testing.T) {
method TestPickFirstLeaf_HealthListenerEnabled (line 2409) | func (s) TestPickFirstLeaf_HealthListenerEnabled(t *testing.T) {
method TestPickFirstLeaf_HealthListenerNotEnabled (line 2447) | func (s) TestPickFirstLeaf_HealthListenerNotEnabled(t *testing.T) {
method TestPickFirstLeaf_HealthUpdates (line 2502) | func (s) TestPickFirstLeaf_HealthUpdates(t *testing.T) {
method TestPickFirstLeaf_AddressUpdateWithMetadata (line 2602) | func (s) TestPickFirstLeaf_AddressUpdateWithMetadata(t *testing.T) {
method TestPickFirstLeaf_Reconnection (line 2682) | func (s) TestPickFirstLeaf_Reconnection(t *testing.T) {
function Test (line 83) | func Test(t *testing.T) {
function init (line 87) | func init() {
function parseServiceConfig (line 93) | func parseServiceConfig(t *testing.T, r *manual.Resolver, sc string) *se...
function setupPickFirst (line 106) | func setupPickFirst(t *testing.T, backendCount int, opts ...grpc.DialOpt...
function stubBackendsToResolverAddrs (line 154) | func stubBackendsToResolverAddrs(backends []*stubserver.StubServer) []re...
function setupPickFirstWithListenerWrapper (line 707) | func setupPickFirstWithListenerWrapper(t *testing.T, backendCount int, o...
function checkForConnectionError (line 1092) | func checkForConnectionError(ctx context.Context, t *testing.T, cc *grpc...
type testServer (line 1139) | type testServer struct
method stop (line 1144) | func (s *testServer) stop() {
method resume (line 1148) | func (s *testServer) resume() {
function newTestServer (line 1152) | func newTestServer(t *testing.T) *testServer {
function setupPickFirstLeaf (line 1170) | func setupPickFirstLeaf(t *testing.T, backendCount int, opts ...grpc.Dia...
function waitForMetric (line 2096) | func waitForMetric(ctx context.Context, t *testing.T, tmr *stats.TestMet...
type healthListenerCapturingCCWrapper (line 2775) | type healthListenerCapturingCCWrapper struct
method NewSubConn (line 2781) | func (ccw *healthListenerCapturingCCWrapper) NewSubConn(addrs []resolv...
method UpdateState (line 2799) | func (ccw *healthListenerCapturingCCWrapper) UpdateState(state balance...
type healthListenerCapturingSCWrapper (line 2804) | type healthListenerCapturingSCWrapper struct
method RegisterHealthListener (line 2809) | func (scw *healthListenerCapturingSCWrapper) RegisterHealthListener(li...
type unwrappingPicker (line 2815) | type unwrappingPicker struct
method Pick (line 2819) | func (pw *unwrappingPicker) Pick(info balancer.PickInfo) (balancer.Pic...
function subConnAddresses (line 2830) | func subConnAddresses(ctx context.Context, cc *testutils.BalancerClientC...
type stateStoringBalancer (line 2851) | type stateStoringBalancer struct
method Close (line 2857) | func (b *stateStoringBalancer) Close() {
method subConnStates (line 2876) | func (b *stateStoringBalancer) subConnStates() []scState {
method addSCState (line 2886) | func (b *stateStoringBalancer) addSCState(state *scState) {
type stateStoringBalancerBuilder (line 2861) | type stateStoringBalancerBuilder struct
method Name (line 2865) | func (b *stateStoringBalancerBuilder) Name() string {
method Build (line 2869) | func (b *stateStoringBalancerBuilder) Build(cc balancer.ClientConn, op...
type stateStoringCCWrapper (line 2892) | type stateStoringCCWrapper struct
method NewSubConn (line 2897) | func (ccw *stateStoringCCWrapper) NewSubConn(addrs []resolver.Address,...
type scState (line 2913) | type scState struct
type backendManager (line 2918) | type backendManager struct
method stopAllExcept (line 2922) | func (b *backendManager) stopAllExcept(index int) {
method resolverAddrs (line 2932) | func (b *backendManager) resolverAddrs() []resolver.Address {
method holds (line 2940) | func (b *backendManager) holds(dialer *testutils.BlockingDialer) []*te...
type ccStateSubscriber (line 2948) | type ccStateSubscriber struct
method transitions (line 2956) | func (c *ccStateSubscriber) transitions() []connectivity.State {
method OnMessage (line 2962) | func (c *ccStateSubscriber) OnMessage(msg any) {
function mockTimer (line 2971) | func mockTimer() (triggerFunc func(), timerFunc func(_ time.Duration, f ...
FILE: balancer/pickfirst/pickfirst_test.go
constant defaultTestTimeout (line 38) | defaultTestTimeout = 10 * time.Second
constant defaultTestShortTimeout (line 41) | defaultTestShortTimeout = 100 * time.Millisecond
type s (line 44) | type s struct
method TestPickFirst_InitialResolverError (line 55) | func (s) TestPickFirst_InitialResolverError(t *testing.T) {
method TestPickFirst_ResolverErrorinTF (line 88) | func (s) TestPickFirst_ResolverErrorinTF(t *testing.T) {
method TestAddressList_Iteration (line 137) | func (s) TestAddressList_Iteration(t *testing.T) {
method TestAddressList_SeekTo (line 202) | func (s) TestAddressList_SeekTo(t *testing.T) {
method TestPickFirstLeaf_TFPickerUpdate (line 278) | func (s) TestPickFirstLeaf_TFPickerUpdate(t *testing.T) {
function Test (line 48) | func Test(t *testing.T) {
FILE: balancer/pickfirst/pickfirstleaf/pickfirstleaf.go
constant Name (line 33) | Name = "pick_first"
function EnableHealthListener (line 39) | func EnableHealthListener(state resolver.State) resolver.State {
FILE: balancer/randomsubsetting/randomsubsetting.go
constant Name (line 50) | Name = "random_subsetting_experimental"
function prefixLogger (line 57) | func prefixLogger(p *subsettingBalancer) *internalgrpclog.PrefixLogger {
function init (line 61) | func init() {
type bb (line 65) | type bb struct
method Build (line 67) | func (bb) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) b...
method ParseConfig (line 85) | func (bb) ParseConfig(s json.RawMessage) (serviceconfig.LoadBalancingC...
method Name (line 103) | func (bb) Name() string {
type lbConfig (line 78) | type lbConfig struct
type subsettingBalancer (line 107) | type subsettingBalancer struct
method UpdateClientConnState (line 116) | func (b *subsettingBalancer) UpdateClientConnState(s balancer.ClientCo...
method calculateSubset (line 147) | func (b *subsettingBalancer) calculateSubset(endpoints []resolver.Endp...
FILE: balancer/randomsubsetting/randomsubsetting_test.go
type s (line 44) | type s struct
method TestParseConfig (line 52) | func (s) TestParseConfig(t *testing.T) {
method TestCalculateSubset_Simple (line 128) | func (s) TestCalculateSubset_Simple(t *testing.T) {
method TestCalculateSubset_EndpointsRetainHashValues (line 170) | func (s) TestCalculateSubset_EndpointsRetainHashValues(t *testing.T) {
method TestSubsettingBalancer_DeterministicSubset (line 196) | func (s) TestSubsettingBalancer_DeterministicSubset(t *testing.T) {
function Test (line 48) | func Test(t *testing.T) {
function makeEndpoints (line 118) | func makeEndpoints(n int) []resolver.Endpoint {
FILE: balancer/ringhash/config.go
constant defaultMinSize (line 32) | defaultMinSize = 1024
constant defaultMaxSize (line 33) | defaultMaxSize = 4096
constant ringHashSizeUpperBound (line 34) | ringHashSizeUpperBound = 8 * 1024 * 1024
function parseConfig (line 37) | func parseConfig(c json.RawMessage) (*iringhash.LBConfig, error) {
FILE: balancer/ringhash/config_test.go
method TestParseConfig (line 32) | func (s) TestParseConfig(t *testing.T) {
FILE: balancer/ringhash/logging.go
constant prefix (line 28) | prefix = "[ring-hash-lb %p] "
function prefixLogger (line 32) | func prefixLogger(p *ringhashBalancer) *internalgrpclog.PrefixLogger {
FILE: balancer/ringhash/picker.go
type picker (line 33) | type picker struct
method Pick (line 55) | func (p *picker) Pick(info balancer.PickInfo) (balancer.PickResult, er...
method endpointState (line 122) | func (p *picker) endpointState(e *ringEntry) endpointState {
FILE: balancer/ringhash/picker_test.go
function init (line 41) | func init() {
type fakeChildPicker (line 48) | type fakeChildPicker struct
method Pick (line 54) | func (p *fakeChildPicker) Pick(balancer.PickInfo) (balancer.PickResult...
type fakeExitIdler (line 68) | type fakeExitIdler struct
method ExitIdle (line 72) | func (ei *fakeExitIdler) ExitIdle() {
function testRingAndEndpointStates (line 76) | func testRingAndEndpointStates(states []connectivity.State) (*ring, map[...
method TestPickerPickFirstTwo (line 104) | func (s) TestPickerPickFirstTwo(t *testing.T) {
method TestPickerNoRequestHash (line 180) | func (s) TestPickerNoRequestHash(t *testing.T) {
method TestPickerRequestHashKey (line 194) | func (s) TestPickerRequestHashKey(t *testing.T) {
method TestPickerRandomHash (line 250) | func (s) TestPickerRandomHash(t *testing.T) {
FILE: balancer/ringhash/ring.go
type ring (line 31) | type ring struct
method pick (line 176) | func (r *ring) pick(h uint64) *ringEntry {
method next (line 187) | func (r *ring) next(e *ringEntry) *ringEntry {
type endpointInfo (line 35) | type endpointInfo struct
type ringEntry (line 41) | type ringEntry struct
function newRing (line 71) | func newRing(endpoints *resolver.EndpointMap[*endpointState], minRingSiz...
function normalizeWeights (line 139) | func normalizeWeights(endpoints *resolver.EndpointMap[*endpointState]) (...
FILE: balancer/ringhash/ring_test.go
function init (line 34) | func init() {
function testEndpoint (line 46) | func testEndpoint(addr string, endpointWeight uint32) resolver.Endpoint {
method TestRingNew (line 51) | func (s) TestRingNew(t *testing.T) {
function equalApproximately (line 79) | func equalApproximately(x, y float64) bool {
method TestRingPick (line 85) | func (s) TestRingPick(t *testing.T) {
method TestRingNext (line 103) | func (s) TestRingNext(t *testing.T) {
FILE: balancer/ringhash/ringhash.go
constant Name (line 55) | Name = "ring_hash_experimental"
function lazyPickFirstBuilder (line 57) | func lazyPickFirstBuilder(cc balancer.ClientConn, opts balancer.BuildOpt...
function init (line 61) | func init() {
type bb (line 65) | type bb struct
method Build (line 67) | func (bb) Build(cc balancer.ClientConn, opts balancer.BuildOptions) ba...
method Name (line 79) | func (bb) Name() string {
method ParseConfig (line 83) | func (bb) ParseConfig(c json.RawMessage) (serviceconfig.LoadBalancingC...
type ringhashBalancer (line 87) | type ringhashBalancer struct
method UpdateState (line 130) | func (b *ringhashBalancer) UpdateState(state balancer.State) {
method UpdateClientConnState (line 181) | func (b *ringhashBalancer) UpdateClientConnState(ccs balancer.ClientCo...
method ResolverError (line 231) | func (b *ringhashBalancer) ResolverError(err error) {
method UpdateSubConnState (line 235) | func (b *ringhashBalancer) UpdateSubConnState(sc balancer.SubConn, sta...
method updatePickerLocked (line 239) | func (b *ringhashBalancer) updatePickerLocked() {
method Close (line 309) | func (b *ringhashBalancer) Close() {
method ExitIdle (line 314) | func (b *ringhashBalancer) ExitIdle() {
method newPickerLocked (line 322) | func (b *ringhashBalancer) newPickerLocked() *picker {
method aggregatedStateLocked (line 357) | func (b *ringhashBalancer) aggregatedStateLocked() connectivity.State {
function hashKey (line 112) | func hashKey(endpoint resolver.Endpoint) string {
function getWeightAttribute (line 387) | func getWeightAttribute(e resolver.Endpoint) uint32 {
type endpointState (line 395) | type endpointState struct
FILE: balancer/ringhash/ringhash_e2e_test.go
type s (line 69) | type s struct
method TestRingHash_ReconnectToMoveOutOfTransientFailure (line 103) | func (s) TestRingHash_ReconnectToMoveOutOfTransientFailure(t *testing....
method TestRingHash_AggregateClusterFallBackFromRingHashAtStartup (line 324) | func (s) TestRingHash_AggregateClusterFallBackFromRingHashAtStartup(t ...
method TestRingHash_AggregateClusterFallBackFromRingHashToLogicalDnsAtStartup (line 425) | func (s) TestRingHash_AggregateClusterFallBackFromRingHashToLogicalDns...
method TestRingHash_AggregateClusterFallBackFromRingHashToLogicalDnsAtStartupNoFailedRPCs (line 505) | func (s) TestRingHash_AggregateClusterFallBackFromRingHashToLogicalDns...
method TestRingHash_ChannelIdHashing (line 672) | func (s) TestRingHash_ChannelIdHashing(t *testing.T) {
method TestRingHash_HeaderHashing (line 732) | func (s) TestRingHash_HeaderHashing(t *testing.T) {
method TestRingHash_HeaderHashingWithRegexRewrite (line 776) | func (s) TestRingHash_HeaderHashingWithRegexRewrite(t *testing.T) {
method TestRingHash_NoHashPolicy (line 872) | func (s) TestRingHash_NoHashPolicy(t *testing.T) {
method TestRingHash_EndpointWeights (line 913) | func (s) TestRingHash_EndpointWeights(t *testing.T) {
method TestRingHash_ContinuesPastTerminalPolicyThatDoesNotProduceResult (line 979) | func (s) TestRingHash_ContinuesPastTerminalPolicyThatDoesNotProduceRes...
method TestRingHash_HashOnHeaderThatIsNotPresent (line 1048) | func (s) TestRingHash_HashOnHeaderThatIsNotPresent(t *testing.T) {
method TestRingHash_UnsupportedHashPolicyDefaultToRandomHashing (line 1099) | func (s) TestRingHash_UnsupportedHashPolicyDefaultToRandomHashing(t *t...
method TestRingHash_UnsupportedHashPolicyUntilChannelIdHashing (line 1166) | func (s) TestRingHash_UnsupportedHashPolicyUntilChannelIdHashing(t *te...
method TestRingHash_RandomHashingDistributionAccordingToLocalityAndEndpointWeight (line 1242) | func (s) TestRingHash_RandomHashingDistributionAccordingToLocalityAndE...
method TestRingHash_FixedHashingTerminalPolicy (line 1319) | func (s) TestRingHash_FixedHashingTerminalPolicy(t *testing.T) {
method TestRingHash_IdleToReady (line 1396) | func (s) TestRingHash_IdleToReady(t *testing.T) {
method TestRingHash_ContinuesConnectingWithoutPicks (line 1431) | func (s) TestRingHash_ContinuesConnectingWithoutPicks(t *testing.T) {
method TestRingHash_TransientFailureCheckNextOne (line 1504) | func (s) TestRingHash_TransientFailureCheckNextOne(t *testing.T) {
method TestRingHash_ReattemptWhenGoingFromTransientFailureToIdle (line 1550) | func (s) TestRingHash_ReattemptWhenGoingFromTransientFailureToIdle(t *...
method TestRingHash_TransientFailureSkipToAvailableReady (line 1609) | func (s) TestRingHash_TransientFailureSkipToAvailableReady(t *testing....
method TestRingHash_ReattemptWhenAllEndpointsUnreachable (line 1724) | func (s) TestRingHash_ReattemptWhenAllEndpointsUnreachable(t *testing....
method TestRingHash_SwitchToLowerPriorityAndThenBack (line 1790) | func (s) TestRingHash_SwitchToLowerPriorityAndThenBack(t *testing.T) {
method TestRingHash_ContinuesConnectingWithoutPicksToMultipleSubConnsConcurrently (line 1899) | func (s) TestRingHash_ContinuesConnectingWithoutPicksToMultipleSubConn...
method TestRingHash_ReorderAddressessWithinEndpoint (line 2027) | func (s) TestRingHash_ReorderAddressessWithinEndpoint(t *testing.T) {
method TestRingHash_FallBackWithinEndpoint (line 2147) | func (s) TestRingHash_FallBackWithinEndpoint(t *testing.T) {
method TestRingHash_RecoverWhenEndpointEntersIdle (line 2235) | func (s) TestRingHash_RecoverWhenEndpointEntersIdle(t *testing.T) {
method TestRingHash_RecoverWhenResolverRemovesEndpoint (line 2397) | func (s) TestRingHash_RecoverWhenResolverRemovesEndpoint(t *testing.T) {
method TestRingHash_EndpointHashKey (line 2560) | func (s) TestRingHash_EndpointHashKey(t *testing.T) {
method TestRingHash_RequestHashKey (line 2667) | func (s) TestRingHash_RequestHashKey(t *testing.T) {
method TestRingHash_RequestHashKeyRandom (line 2748) | func (s) TestRingHash_RequestHashKeyRandom(t *testing.T) {
method TestRingHash_RequestHashKeyConnecting (line 2813) | func (s) TestRingHash_RequestHashKeyConnecting(t *testing.T) {
function Test (line 73) | func Test(t *testing.T) {
constant defaultTestTimeout (line 78) | defaultTestTimeout = 10 * time.Second
constant defaultTestShortTimeout (line 79) | defaultTestShortTimeout = 10 * time.Millisecond
constant errorTolerance (line 81) | errorTolerance = .05
constant virtualHostName (line 83) | virtualHostName = "test.server"
constant minRingSize (line 88) | minRingSize = 10000
function startTestServiceBackends (line 176) | func startTestServiceBackends(t *testing.T, num int) []*stubserver.StubS...
function backendAddrs (line 189) | func backendAddrs(servers []*stubserver.StubServer) []string {
function backendOptions (line 199) | func backendOptions(t *testing.T, serverAddrs []string) []e2e.BackendOpt...
function backendOptionsForEndpointsWithMultipleAddrs (line 210) | func backendOptionsForEndpointsWithMultipleAddrs(t *testing.T, backendAd...
function channelIDHashRoute (line 226) | func channelIDHashRoute(routeName, virtualHostDomain, clusterName string...
function checkRPCSendOK (line 243) | func checkRPCSendOK(ctx context.Context, t *testing.T, client testgrpc.T...
function makeUnreachableBackends (line 260) | func makeUnreachableBackends(t *testing.T, num int) []string {
function setupManagementServerAndResolver (line 291) | func setupManagementServerAndResolver(t *testing.T) (*e2e.ManagementServ...
function xdsUpdateOpts (line 311) | func xdsUpdateOpts(nodeID string, endpoints *v3endpointpb.ClusterLoadAss...
function replaceDNSResolver (line 411) | func replaceDNSResolver(t *testing.T) *manual.Resolver {
function endpointResource (line 639) | func endpointResource(t *testing.T, clusterName string, addrs []string) ...
function endpointResourceForBackendsWithMultipleAddrs (line 650) | func endpointResourceForBackendsWithMultipleAddrs(t *testing.T, clusterN...
function headerHashRoute (line 716) | func headerHashRoute(routeName, virtualHostName, clusterName, header str...
function computeIdealNumberOfRPCs (line 842) | func computeIdealNumberOfRPCs(t *testing.T, p, errorTolerance float64) i...
function setRingHashLBPolicyWithHighMinRingSize (line 853) | func setRingHashLBPolicyWithHighMinRingSize(t *testing.T, cluster *v3clu...
function highRingSizeServiceConfig (line 2732) | func highRingSizeServiceConfig(t *testing.T) string {
FILE: balancer/ringhash/ringhash_test.go
constant defaultTestTimeout (line 37) | defaultTestTimeout = 10 * time.Second
constant defaultTestShortTimeout (line 38) | defaultTestShortTimeout = 10 * time.Millisecond
constant testBackendAddrsCount (line 40) | testBackendAddrsCount = 12
function init (line 48) | func init() {
function setupTest (line 55) | func setupTest(t *testing.T, endpoints []resolver.Endpoint) (*testutils....
type s (line 93) | type s struct
method TestUpdateClientConnState_NewRingSize (line 105) | func (s) TestUpdateClientConnState_NewRingSize(t *testing.T) {
method TestOneEndpoint (line 138) | func (s) TestOneEndpoint(t *testing.T) {
method TestThreeSubConnsAffinity (line 188) | func (s) TestThreeSubConnsAffinity(t *testing.T) {
method TestThreeBackendsAffinityMultiple (line 334) | func (s) TestThreeBackendsAffinityMultiple(t *testing.T) {
method TestAddrWeightChange (line 435) | func (s) TestAddrWeightChange(t *testing.T) {
method TestAutoConnectEndpointOnTransientFailure (line 526) | func (s) TestAutoConnectEndpointOnTransientFailure(t *testing.T) {
method TestAggregatedConnectivityState (line 629) | func (s) TestAggregatedConnectivityState(t *testing.T) {
method TestAddrBalancerAttributesChange (line 701) | func (s) TestAddrBalancerAttributesChange(t *testing.T) {
function Test (line 97) | func Test(t *testing.T) {
type testKeyType (line 678) | type testKeyType
constant testKey (line 680) | testKey testKeyType = "grpc.lb.ringhash.testKey"
type testAttribute (line 682) | type testAttribute struct
function setTestAttrAddr (line 686) | func setTestAttrAddr(addr resolver.Address, content string) resolver.Add...
function setTestAttrEndpoint (line 691) | func setTestAttrEndpoint(endpoint resolver.Endpoint, content string) res...
FILE: balancer/rls/balancer.go
constant Name (line 50) | Name = internal.RLSLoadBalancingPolicyName
constant periodicCachePurgeFreq (line 52) | periodicCachePurgeFreq = time.Minute
function init (line 119) | func init() {
type rlsBB (line 123) | type rlsBB struct
method Name (line 125) | func (rlsBB) Name() string {
method Build (line 129) | func (rlsBB) Build(cc balancer.ClientConn, opts balancer.BuildOptions)...
type rlsBalancer (line 158) | type rlsBalancer struct
method run (line 223) | func (b *rlsBalancer) run() {
method purgeDataCache (line 274) | func (b *rlsBalancer) purgeDataCache(doneCh chan struct{}) {
method UpdateClientConnState (line 293) | func (b *rlsBalancer) UpdateClientConnState(ccs balancer.ClientConnSta...
method handleControlChannelUpdate (line 357) | func (b *rlsBalancer) handleControlChannelUpdate(newCfg *lbConfig) {
method handleChildPolicyConfigUpdate (line 385) | func (b *rlsBalancer) handleChildPolicyConfigUpdate(newCfg *lbConfig, ...
method buildAndPushChildPolicyConfigs (line 453) | func (b *rlsBalancer) buildAndPushChildPolicyConfigs(target string, ne...
method ResolverError (line 481) | func (b *rlsBalancer) ResolverError(err error) {
method UpdateSubConnState (line 485) | func (b *rlsBalancer) UpdateSubConnState(sc balancer.SubConn, state ba...
method Close (line 489) | func (b *rlsBalancer) Close() {
method ExitIdle (line 509) | func (b *rlsBalancer) ExitIdle() {
method sendNewPickerLocked (line 524) | func (b *rlsBalancer) sendNewPickerLocked() {
method sendNewPicker (line 570) | func (b *rlsBalancer) sendNewPicker() {
method aggregatedConnectivityState (line 593) | func (b *rlsBalancer) aggregatedConnectivityState() connectivity.State {
method UpdateState (line 627) | func (b *rlsBalancer) UpdateState(id string, state balancer.State) {
method handleChildPolicyStateUpdate (line 640) | func (b *rlsBalancer) handleChildPolicyStateUpdate(id string, newState...
method acquireChildPolicyReferences (line 669) | func (b *rlsBalancer) acquireChildPolicyReferences(targets []string) [...
method releaseChildPolicyReferences (line 701) | func (b *rlsBalancer) releaseChildPolicyReferences(targets []string) {
method Report (line 713) | func (b *rlsBalancer) Report(r estats.AsyncMetricsRecorder) error {
type resumePickerUpdates (line 207) | type resumePickerUpdates struct
type childPolicyIDAndState (line 212) | type childPolicyIDAndState struct
type controlChannelReady (line 217) | type controlChannelReady struct
FILE: balancer/rls/balancer_test.go
method TestConfigUpdate_ControlChannel (line 58) | func (s) TestConfigUpdate_ControlChannel(t *testing.T) {
method TestConfigUpdate_ControlChannelWithCreds (line 137) | func (s) TestConfigUpdate_ControlChannelWithCreds(t *testing.T) {
method TestConfigUpdate_ControlChannelServiceConfig (line 194) | func (s) TestConfigUpdate_ControlChannelServiceConfig(t *testing.T) {
method TestConfigUpdate_DefaultTarget (line 254) | func (s) TestConfigUpdate_DefaultTarget(t *testing.T) {
method TestConfigUpdate_ChildPolicyConfigs (line 294) | func (s) TestConfigUpdate_ChildPolicyConfigs(t *testing.T) {
method TestConfigUpdate_ChildPolicyChange (line 422) | func (s) TestConfigUpdate_ChildPolicyChange(t *testing.T) {
method TestConfigUpdate_BadChildPolicyConfigs (line 519) | func (s) TestConfigUpdate_BadChildPolicyConfigs(t *testing.T) {
method TestConfigUpdate_DataCacheSizeDecrease (line 561) | func (s) TestConfigUpdate_DataCacheSizeDecrease(t *testing.T) {
type stateCapturingCC (line 661) | type stateCapturingCC struct
method UpdateState (line 666) | func (cc *stateCapturingCC) UpdateState(bs balancer.State) {
function newStateCapturingCC (line 671) | func newStateCapturingCC(cc balancer.ClientConn) *stateCapturingCC {
method TestPickerUpdateOnDataCacheSizeDecrease (line 680) | func (s) TestPickerUpdateOnDataCacheSizeDecrease(t *testing.T) {
method TestDataCachePurging (line 897) | func (s) TestDataCachePurging(t *testing.T) {
method TestControlChannelConnectivityStateMonitoring (line 981) | func (s) TestControlChannelConnectivityStateMonitoring(t *testing.T) {
type testCCWrapper (line 1086) | type testCCWrapper struct
method UpdateState (line 1093) | func (t *testCCWrapper) UpdateState(bs balancer.State) {
method getStates (line 1100) | func (t *testCCWrapper) getStates() []balancer.State {
method TestUpdateStatePauses (line 1123) | func (s) TestUpdateStatePauses(t *testing.T) {
function waitForStateTransitions (line 1329) | func waitForStateTransitions(ctx context.Context, t *testing.T, stateCh ...
FILE: balancer/rls/cache.go
type cacheKey (line 33) | type cacheKey struct
type cacheEntry (line 44) | type cacheEntry struct
type backoffState (line 98) | type backoffState struct
type lru (line 116) | type lru struct
method addEntry (line 134) | func (l *lru) addEntry(key cacheKey) {
method makeRecent (line 139) | func (l *lru) makeRecent(key cacheKey) {
method removeEntry (line 144) | func (l *lru) removeEntry(key cacheKey) {
method getLeastRecentlyUsed (line 150) | func (l *lru) getLeastRecentlyUsed() cacheKey {
function newLRU (line 127) | func newLRU() *lru {
type dataCache (line 166) | type dataCache struct
method updateRLSServerTarget (line 194) | func (dc *dataCache) updateRLSServerTarget(rlsServerTarget string) {
method resize (line 204) | func (dc *dataCache) resize(size int64) (backoffCancelled bool) {
method evictExpiredEntries (line 253) | func (dc *dataCache) evictExpiredEntries() bool {
method resetBackoffState (line 279) | func (dc *dataCache) resetBackoffState(newBackoffState *backoffState) ...
method addEntry (line 309) | func (dc *dataCache) addEntry(key cacheKey, entry *cacheEntry) (backof...
method updateEntrySize (line 333) | func (dc *dataCache) updateEntrySize(entry *cacheEntry, newSize int64) {
method getEntry (line 340) | func (dc *dataCache) getEntry(key cacheKey) *cacheEntry {
method removeEntryForTesting (line 353) | func (dc *dataCache) removeEntryForTesting(key cacheKey) {
method deleteAndCleanup (line 366) | func (dc *dataCache) deleteAndCleanup(key cacheKey, entry *cacheEntry) {
method stop (line 373) | func (dc *dataCache) stop() {
function newDataCache (line 180) | func newDataCache(size int64, logger *internalgrpclog.PrefixLogger, grpc...
FILE: balancer/rls/cache_test.go
function initCacheEntries (line 44) | func initCacheEntries() {
method TestLRU_BasicOperations (line 79) | func (s) TestLRU_BasicOperations(t *testing.T) {
method TestDataCache_BasicOperations (line 120) | func (s) TestDataCache_BasicOperations(t *testing.T) {
method TestDataCache_AddForcesResize (line 134) | func (s) TestDataCache_AddForcesResize(t *testing.T) {
method TestDataCache_Resize (line 163) | func (s) TestDataCache_Resize(t *testing.T) {
method TestDataCache_EvictExpiredEntries (line 194) | func (s) TestDataCache_EvictExpiredEntries(t *testing.T) {
method TestDataCache_ResetBackoffState (line 217) | func (s) TestDataCache_ResetBackoffState(t *testing.T) {
FILE: balancer/rls/child_policy.go
type childPolicyWrapper (line 55) | type childPolicyWrapper struct
method acquireRef (line 89) | func (c *childPolicyWrapper) acquireRef() {
method releaseRef (line 95) | func (c *childPolicyWrapper) releaseRef() bool {
method lamify (line 103) | func (c *childPolicyWrapper) lamify(err error) {
function newChildPolicyWrapper (line 74) | func newChildPolicyWrapper(target string) *childPolicyWrapper {
FILE: balancer/rls/config.go
constant maxMaxAge (line 42) | maxMaxAge = 5 * time.Minute
constant maxCacheSize (line 44) | maxCacheSize = 5 * 1024 * 1024 * 8
constant defaultLookupServiceTimeout (line 46) | defaultLookupServiceTimeout = 10 * time.Second
constant dummyChildPolicyTarget (line 49) | dummyChildPolicyTarget = "target_name_to_be_filled_in_later"
type lbConfig (line 53) | type lbConfig struct
method Equal (line 70) | func (lbCfg *lbConfig) Equal(other *lbConfig) bool {
function childPolicyConfigEqual (line 84) | func childPolicyConfigEqual(a, b map[string]json.RawMessage) bool {
type lbConfigJSON (line 105) | type lbConfigJSON struct
method ParseConfig (line 145) | func (rlsBB) ParseConfig(c json.RawMessage) (serviceconfig.LoadBalancing...
function parseRLSProto (line 186) | func parseRLSProto(rlsProto *rlspb.RouteLookupConfig) (*lbConfig, error) {
function parseChildPolicyConfigs (line 284) | func parseChildPolicyConfigs(childPolicies []map[string]json.RawMessage,...
function convertDuration (line 325) | func convertDuration(d *durationpb.Duration) (time.Duration, error) {
FILE: balancer/rls/config_test.go
function testEqual (line 37) | func testEqual(a, b *lbConfig) bool {
method TestParseConfig (line 51) | func (s) TestParseConfig(t *testing.T) {
method TestParseConfigErrors (line 215) | func (s) TestParseConfigErrors(t *testing.T) {
FILE: balancer/rls/control_channel.go
type adaptiveThrottler (line 42) | type adaptiveThrottler interface
type controlChannel (line 49) | type controlChannel struct
method OnMessage (line 99) | func (cc *controlChannel) OnMessage(msg any) {
method dialOpts (line 108) | func (cc *controlChannel) dialOpts(bOpts balancer.BuildOptions, servic...
method monitorConnectivityState (line 151) | func (cc *controlChannel) monitorConnectivityState() {
method close (line 209) | func (cc *controlChannel) close() {
method lookup (line 225) | func (cc *controlChannel) lookup(reqKeys map[string]string, reason rls...
function newControlChannel (line 71) | func newControlChannel(rlsServerName, serviceConfig string, rpcTimeout t...
type lookupCallback (line 217) | type lookupCallback
FILE: balancer/rls/control_channel_test.go
method TestControlChannelThrottled (line 48) | func (s) TestControlChannelThrottled(t *testing.T) {
method TestLookupFailure (line 71) | func (s) TestLookupFailure(t *testing.T) {
method TestLookupDeadlineExceeded (line 110) | func (s) TestLookupDeadlineExceeded(t *testing.T) {
type testCredsBundle (line 148) | type testCredsBundle struct
method TransportCredentials (line 153) | func (f *testCredsBundle) TransportCredentials() credentials.Transport...
method PerRPCCredentials (line 157) | func (f *testCredsBundle) PerRPCCredentials() credentials.PerRPCCreden...
method NewWithMode (line 161) | func (f *testCredsBundle) NewWithMode(mode string) (credentials.Bundle...
type testPerRPCCredentials (line 180) | type testPerRPCCredentials struct
method GetRequestMetadata (line 184) | func (f *testPerRPCCredentials) GetRequestMetadata(context.Context, .....
method RequireTransportSecurity (line 188) | func (f *testPerRPCCredentials) RequireTransportSecurity() bool {
function callCredsValidatingServerInterceptor (line 194) | func callCredsValidatingServerInterceptor(ctx context.Context, req any, ...
function makeTLSCreds (line 213) | func makeTLSCreds(t *testing.T, certPath, keyPath, rootsPath string) cre...
constant wantHeaderData (line 233) | wantHeaderData = "headerData"
constant staleHeaderData (line 234) | staleHeaderData = "staleHeaderData"
function testControlChannelCredsSuccess (line 257) | func testControlChannelCredsSuccess(t *testing.T, sopts []grpc.ServerOpt...
method TestControlChannelCredsSuccess (line 309) | func (s) TestControlChannelCredsSuccess(t *testing.T) {
function testControlChannelCredsFailure (line 353) | func testControlChannelCredsFailure(t *testing.T, sopts []grpc.ServerOpt...
method TestControlChannelCredsFailure (line 391) | func (s) TestControlChannelCredsFailure(t *testing.T) {
type unsupportedCredsBundle (line 446) | type unsupportedCredsBundle struct
method NewWithMode (line 450) | func (*unsupportedCredsBundle) NewWithMode(mode string) (credentials.B...
method TestNewControlChannelUnsupportedCredsBundle (line 456) | func (s) TestNewControlChannelUnsupportedCredsBundle(t *testing.T) {
FILE: balancer/rls/helpers_test.go
constant defaultTestTimeout (line 46) | defaultTestTimeout = 5 * time.Second
constant defaultTestShortTimeout (line 47) | defaultTestShortTimeout = 100 * time.Millisecond
type s (line 50) | type s struct
function Test (line 54) | func Test(t *testing.T) {
type fakeBackoffStrategy (line 60) | type fakeBackoffStrategy struct
method Backoff (line 64) | func (f *fakeBackoffStrategy) Backoff(int) time.Duration {
type fakeThrottler (line 69) | type fakeThrottler struct
method ShouldThrottle (line 74) | func (f *fakeThrottler) ShouldThrottle() bool {
method RegisterBackendResponse (line 84) | func (f *fakeThrottler) RegisterBackendResponse(bool) {}
function alwaysThrottlingThrottler (line 87) | func alwaysThrottlingThrottler() *fakeThrottler {
function neverThrottlingThrottler (line 95) | func neverThrottlingThrottler() *fakeThrottler {
function oneTimeAllowingThrottler (line 106) | func oneTimeAllowingThrottler(firstRPCDone *grpcsync.Event) *fakeThrottl...
function overrideAdaptiveThrottler (line 113) | func overrideAdaptiveThrottler(t *testing.T, f *fakeThrottler) {
function buildBasicRLSConfig (line 122) | func buildBasicRLSConfig(childPolicyName, rlsServerAddress string) *e2e....
function buildBasicRLSConfigWithChildPolicy (line 147) | func buildBasicRLSConfigWithChildPolicy(t *testing.T, childPolicyName, r...
function startBackend (line 169) | func startBackend(t *testing.T, sopts ...grpc.ServerOption) (rpcCh chan ...
function startManualResolverWithConfig (line 192) | func startManualResolverWithConfig(t *testing.T, rlsConfig *e2e.RLSConfi...
function makeTestRPCAndExpectItToReachBackend (line 223) | func makeTestRPCAndExpectItToReachBackend(ctx context.Context, t *testin...
function makeTestRPCAndVerifyError (line 256) | func makeTestRPCAndVerifyError(ctx context.Context, t *testing.T, cc *gr...
function verifyRLSRequest (line 283) | func verifyRLSRequest(t *testing.T, ch chan struct{}, wantRequest bool) {
FILE: balancer/rls/internal/adaptive/adaptive.go
constant defaultDuration (line 35) | defaultDuration = 30 * time.Second
constant defaultBins (line 36) | defaultBins = 100
constant defaultRatioForAccepts (line 37) | defaultRatioForAccepts = 2.0
constant defaultRequestsPadding (line 38) | defaultRequestsPadding = 8.0
type Throttler (line 69) | type Throttler struct
method ShouldThrottle (line 99) | func (t *Throttler) ShouldThrottle() bool {
method RegisterBackendResponse (line 121) | func (t *Throttler) RegisterBackendResponse(throttled bool) {
function New (line 80) | func New() *Throttler {
function newWithArgs (line 86) | func newWithArgs(duration time.Duration, bins int64, ratioForAccepts, re...
FILE: balancer/rls/internal/adaptive/adaptive_test.go
method stats (line 28) | func (t *Throttler) stats() (int64, int64) {
constant E (line 39) | E = iota
constant A (line 40) | A
constant T (line 41) | T
function TestRegisterBackendResponse (line 44) | func TestRegisterBackendResponse(t *testing.T) {
function TestShouldThrottleOptions (line 110) | func TestShouldThrottleOptions(t *testing.T) {
function TestParallel (line 172) | func TestParallel(t *testing.T) {
type mockClock (line 221) | type mockClock struct
method Now (line 225) | func (m *mockClock) Now() time.Time {
method SetNanos (line 229) | func (m *mockClock) SetNanos(n int64) {
FILE: balancer/rls/internal/adaptive/lookback.go
type lookback (line 24) | type lookback struct
method add (line 44) | func (l *lookback) add(t time.Time, v int64) {
method sum (line 57) | func (l *lookback) sum(t time.Time) int64 {
method advance (line 66) | func (l *lookback) advance(t time.Time) int64 {
function newLookback (line 35) | func newLookback(bins int64, duration time.Duration) *lookback {
FILE: balancer/rls/internal/adaptive/lookback_test.go
function TestLookback (line 26) | func TestLookback(t *testing.T) {
FILE: balancer/rls/internal/keys/builder.go
type BuilderMap (line 33) | type BuilderMap
method RLSKey (line 122) | func (bm BuilderMap) RLSKey(md metadata.MD, host, path string) KeyMap {
method Equal (line 154) | func (bm BuilderMap) Equal(am BuilderMap) bool {
function MakeBuilderMap (line 37) | func MakeBuilderMap(cfg *rlspb.RouteLookupConfig) (BuilderMap, error) {
type KeyMap (line 107) | type KeyMap struct
type builder (line 175) | type builder struct
method Equal (line 185) | func (b builder) Equal(a builder) bool {
method buildHeaderKeys (line 237) | func (b builder) buildHeaderKeys(md metadata.MD) map[string]string {
type matcher (line 214) | type matcher struct
method Equal (line 222) | func (m matcher) Equal(a matcher) bool {
function mapToString (line 253) | func mapToString(kv map[string]string) string {
FILE: balancer/rls/internal/keys/builder_test.go
function TestMakeBuilderMap (line 61) | func TestMakeBuilderMap(t *testing.T) {
function TestMakeBuilderMapErrors (line 110) | func TestMakeBuilderMapErrors(t *testing.T) {
function TestRLSKey (line 260) | func TestRLSKey(t *testing.T) {
function TestMapToString (line 371) | func TestMapToString(t *testing.T) {
function TestBuilderMapEqual (line 418) | func TestBuilderMapEqual(t *testing.T) {
function TestBuilderEqual (line 505) | func TestBuilderEqual(t *testing.T) {
function TestMatcherEqual (line 604) | func TestMatcherEqual(t *testing.T) {
FILE: balancer/rls/internal/test/e2e/rls_child_policy.go
constant RLSChildPolicyTargetNameField (line 36) | RLSChildPolicyTargetNameField = "Backend"
constant RLSChildPolicyBadTarget (line 39) | RLSChildPolicyBadTarget = "bad-target"
type BalancerFuncs (line 48) | type BalancerFuncs struct
function RegisterRLSChildPolicy (line 59) | func RegisterRLSChildPolicy(name string, bf *BalancerFuncs) {
type bb (line 63) | type bb struct
method Name (line 68) | func (bb bb) Name() string { return bb.name }
method Build (line 70) | func (bb bb) Build(cc balancer.ClientConn, opts balancer.BuildOptions)...
method ParseConfig (line 81) | func (bb bb) ParseConfig(c json.RawMessage) (serviceconfig.LoadBalanci...
type bal (line 92) | type bal struct
method UpdateClientConnState (line 105) | func (b *bal) UpdateClientConnState(c balancer.ClientConnState) error {
method Close (line 118) | func (b *bal) Close() {
method run (line 129) | func (b *bal) run() {
type RLSChildPolicyConfig (line 99) | type RLSChildPolicyConfig struct
FILE: balancer/rls/internal/test/e2e/rls_lb_config.go
type RLSConfig (line 34) | type RLSConfig struct
method ServiceConfigJSON (line 43) | func (c *RLSConfig) ServiceConfigJSON() (string, error) {
method LoadBalancingConfig (line 75) | func (c *RLSConfig) LoadBalancingConfig() (serviceconfig.LoadBalancing...
FILE: balancer/rls/metrics_test.go
function metricsDataFromReader (line 39) | func metricsDataFromReader(ctx context.Context, reader *metric.ManualRea...
method TestRLSTargetPickMetric (line 55) | func (s) TestRLSTargetPickMetric(t *testing.T) {
method TestRLSDefaultTargetPickMetric (line 166) | func (s) TestRLSDefaultTargetPickMetric(t *testing.T) {
method TestRLSFailedRPCMetric (line 275) | func (s) TestRLSFailedRPCMetric(t *testing.T) {
FILE: balancer/rls/picker.go
type exitIdler (line 47) | type exitIdler interface
type rlsPicker (line 53) | type rlsPicker struct
method Pick (line 82) | func (p *rlsPicker) Pick(info balancer.PickInfo) (balancer.PickResult,...
method delegateToChildPoliciesLocked (line 187) | func (p *rlsPicker) delegateToChildPoliciesLocked(dcEntry *cacheEntry,...
method useDefaultPickIfPossible (line 229) | func (p *rlsPicker) useDefaultPickIfPossible(info balancer.PickInfo, e...
method sendRouteLookupRequestLocked (line 252) | func (p *rlsPicker) sendRouteLookupRequestLocked(cacheKey cacheKey, bs...
method handleRouteLookupResponse (line 272) | func (p *rlsPicker) handleRouteLookupResponse(cacheKey cacheKey, targe...
method setChildPolicyWrappersInCacheEntry (line 362) | func (p *rlsPicker) setChildPolicyWrappersInCacheEntry(dcEntry *cacheE...
function isFullMethodNameValid (line 77) | func isFullMethodNameValid(name string) bool {
function errToPickResult (line 169) | func errToPickResult(err error) string {
function dcEntrySize (line 395) | func dcEntrySize(key cacheKey, entry *cacheEntry) int64 {
FILE: balancer/rls/picker_test.go
method TestNoNonEmptyTargetsReturnsError (line 50) | func (s) TestNoNonEmptyTargetsReturnsError(t *testing.T) {
method TestPick_DataCacheMiss_NoPendingEntry_ThrottledWithDefaultTarget (line 81) | func (s) TestPick_DataCacheMiss_NoPendingEntry_ThrottledWithDefaultTarge...
method TestPick_DataCacheMiss_NoPendingEntry_ThrottledWithoutDefaultTarget (line 113) | func (s) TestPick_DataCacheMiss_NoPendingEntry_ThrottledWithoutDefaultTa...
method TestPick_DataCacheMiss_NoPendingEntry_NotThrottled (line 144) | func (s) TestPick_DataCacheMiss_NoPendingEntry_NotThrottled(t *testing.T) {
method TestPick_DataCacheMiss_PendingEntryExists (line 175) | func (s) TestPick_DataCacheMiss_PendingEntryExists(t *testing.T) {
method Test_RLSDefaultTargetPicksMetric (line 256) | func (s) Test_RLSDefaultTargetPicksMetric(t *testing.T) {
method Test_RLSTargetPicksMetric (line 297) | func (s) Test_RLSTargetPicksMetric(t *testing.T) {
method Test_RLSFailedPicksMetric (line 342) | func (s) Test_RLSFailedPicksMetric(t *testing.T) {
method TestPick_DataCacheHit_NoPendingEntry_ValidEntry (line 381) | func (s) TestPick_DataCacheHit_NoPendingEntry_ValidEntry(t *testing.T) {
method TestPick_DataCacheHit_NoPendingEntry_ValidEntry_WithHeaderData (line 423) | func (s) TestPick_DataCacheHit_NoPendingEntry_ValidEntry_WithHeaderData(...
method TestPick_DataCacheHit_NoPendingEntry_StaleEntry (line 480) | func (s) TestPick_DataCacheHit_NoPendingEntry_StaleEntry(t *testing.T) {
method TestPick_DataCacheHit_NoPendingEntry_ExpiredEntry (line 577) | func (s) TestPick_DataCacheHit_NoPendingEntry_ExpiredEntry(t *testing.T) {
method TestPick_DataCacheHit_NoPendingEntry_ExpiredEntryInBackoff (line 684) | func (s) TestPick_DataCacheHit_NoPendingEntry_ExpiredEntryInBackoff(t *t...
method TestPick_DataCacheHit_PendingEntryExists_StaleEntry (line 772) | func (s) TestPick_DataCacheHit_PendingEntryExists_StaleEntry(t *testing....
method TestPick_DataCacheHit_PendingEntryExists_ExpiredEntry (line 872) | func (s) TestPick_DataCacheHit_PendingEntryExists_ExpiredEntry(t *testin...
function TestIsFullMethodNameValid (line 976) | func TestIsFullMethodNameValid(t *testing.T) {
method TestChildPickResultError (line 1014) | func (s) TestChildPickResultError(t *testing.T) {
FILE: balancer/roundrobin/roundrobin.go
constant Name (line 35) | Name = "round_robin"
function init (line 39) | func init() {
type builder (line 43) | type builder struct
method Name (line 45) | func (bb builder) Name() string {
method Build (line 49) | func (bb builder) Build(cc balancer.ClientConn, opts balancer.BuildOpt...
type rrBalancer (line 60) | type rrBalancer struct
method UpdateClientConnState (line 66) | func (b *rrBalancer) UpdateClientConnState(ccs balancer.ClientConnStat...
FILE: balancer/subconn.go
type SubConn (line 51) | type SubConn interface
type ProducerBuilder (line 96) | type ProducerBuilder interface
type SubConnState (line 108) | type SubConnState struct
type Producer (line 120) | type Producer
FILE: balancer/weightedroundrobin/balancer.go
constant Name (line 57) | Name = "weighted_round_robin"
function init (line 96) | func init() {
type bb (line 100) | type bb struct
method Build (line 102) | func (bb) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) b...
method ParseConfig (line 120) | func (bb) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancing...
method Name (line 151) | func (bb) Name() string {
type wrrBalancer (line 205) | type wrrBalancer struct
method updateEndpointsLocked (line 159) | func (b *wrrBalancer) updateEndpointsLocked(endpoints []resolver.Endpo...
method UpdateClientConnState (line 224) | func (b *wrrBalancer) UpdateClientConnState(ccs balancer.ClientConnSta...
method UpdateState (line 251) | func (b *wrrBalancer) UpdateState(state balancer.State) {
method NewSubConn (line 317) | func (b *wrrBalancer) NewSubConn(addrs []resolver.Address, opts balanc...
method ResolverError (line 343) | func (b *wrrBalancer) ResolverError(err error) {
method UpdateSubConnState (line 351) | func (b *wrrBalancer) UpdateSubConnState(sc balancer.SubConn, state ba...
method updateSubConnState (line 355) | func (b *wrrBalancer) updateSubConnState(sc balancer.SubConn, state ba...
method Close (line 406) | func (b *wrrBalancer) Close() {
method ExitIdle (line 426) | func (b *wrrBalancer) ExitIdle() {
type pickerWeightedEndpoint (line 312) | type pickerWeightedEndpoint struct
type picker (line 433) | type picker struct
method endpointWeights (line 447) | func (p *picker) endpointWeights(recordMetrics bool) []float64 {
method Pick (line 456) | func (p *picker) Pick(info balancer.PickInfo) (balancer.PickResult, er...
method inc (line 481) | func (p *picker) inc() uint32 {
method regenerateScheduler (line 485) | func (p *picker) regenerateScheduler() {
method start (line 490) | func (p *picker) start(stopPicker *grpcsync.Event) {
type endpointWeight (line 516) | type endpointWeight struct
method OnLoadReport (line 546) | func (w *endpointWeight) OnLoadReport(load *v3orcapb.OrcaLoadReport) {
method updateConfig (line 579) | func (w *endpointWeight) updateConfig(cfg *lbConfig) {
method updateORCAListener (line 597) | func (w *endpointWeight) updateORCAListener(cfg *lbConfig) {
method weight (line 620) | func (w *endpointWeight) weight(now time.Time, weightExpirationPeriod,...
type backendServiceKey (line 659) | type backendServiceKey struct
function SetBackendService (line 663) | func SetBackendService(state resolver.State, backendService string) reso...
function backendServiceFromState (line 670) | func backendServiceFromState(state resolver.State) string {
FILE: balancer/weightedroundrobin/balancer_test.go
type s (line 47) | type s struct
method TestBalancer_OneAddress (line 173) | func (s) TestBalancer_OneAddress(t *testing.T) {
method TestWRRMetricsBasic (line 220) | func (s) TestWRRMetricsBasic(t *testing.T) {
method TestBalancer_TwoAddresses_ReportingDisabled (line 255) | func (s) TestBalancer_TwoAddresses_ReportingDisabled(t *testing.T) {
method TestBalancer_TwoAddresses_ReportingEnabledPerCall (line 277) | func (s) TestBalancer_TwoAddresses_ReportingEnabledPerCall(t *testing....
method TestBalancer_TwoAddresses_ReportingEnabledOOB (line 309) | func (s) TestBalancer_TwoAddresses_ReportingEnabledOOB(t *testing.T) {
method TestBalancer_TwoAddresses_UpdateLoads (line 367) | func (s) TestBalancer_TwoAddresses_UpdateLoads(t *testing.T) {
method TestBalancer_TwoAddresses_OOBThenPerCall (line 412) | func (s) TestBalancer_TwoAddresses_OOBThenPerCall(t *testing.T) {
method TestEndpoints_SharedAddress (line 466) | func (s) TestEndpoints_SharedAddress(t *testing.T) {
method TestEndpoints_MultipleAddresses (line 495) | func (s) TestEndpoints_MultipleAddresses(t *testing.T) {
method TestBalancer_TwoAddresses_ErrorPenalty (line 524) | func (s) TestBalancer_TwoAddresses_ErrorPenalty(t *testing.T) {
method TestBalancer_TwoAddresses_BlackoutPeriod (line 579) | func (s) TestBalancer_TwoAddresses_BlackoutPeriod(t *testing.T) {
method TestBalancer_TwoAddresses_WeightExpiration (line 658) | func (s) TestBalancer_TwoAddresses_WeightExpiration(t *testing.T) {
method TestBalancer_AddressesChanging (line 724) | func (s) TestBalancer_AddressesChanging(t *testing.T) {
function Test (line 51) | func Test(t *testing.T) {
constant defaultTestTimeout (line 55) | defaultTestTimeout = 10 * time.Second
constant weightUpdatePeriod (line 56) | weightUpdatePeriod = 50 * time.Millisecond
constant weightExpirationPeriod (line 57) | weightExpirationPeriod = time.Minute
constant oobReportingInterval (line 58) | oobReportingInterval = 10 * time.Millisecond
function init (line 60) | func init() {
function boolp (line 64) | func boolp(b bool) *bool { return &b }
function float64p (line 65) | func float64p(f float64) *float64 { return &f }
function stringp (line 66) | func stringp(s string) *string { return &s }
type testServer (line 95) | type testServer struct
type reportType (line 102) | type reportType
constant reportNone (line 105) | reportNone reportType = iota
constant reportOOB (line 106) | reportOOB
constant reportCall (line 107) | reportCall
constant reportBoth (line 108) | reportBoth
function startServer (line 111) | func startServer(t *testing.T, r reportType) *testServer {
function svcConfig (line 160) | func svcConfig(t *testing.T, wrrCfg iwrr.LBConfig) string {
function ensureReached (line 789) | func ensureReached(ctx context.Context, t *testing.T, c testgrpc.TestSer...
type srvWeight (line 801) | type srvWeight struct
constant rrIterations (line 806) | rrIterations = 100
function checkWeights (line 811) | func checkWeights(ctx context.Context, t *testing.T, sws ...srvWeight) {
function init (line 856) | func init() {
function timeNow (line 863) | func timeNow() time.Time {
function setTimeNow (line 867) | func setTimeNow(f func() time.Time) {
FILE: balancer/weightedroundrobin/config.go
type lbConfig (line 26) | type lbConfig struct
FILE: balancer/weightedroundrobin/internal/internal.go
type LBConfig (line 33) | type LBConfig struct
FILE: balancer/weightedroundrobin/logging.go
constant prefix (line 28) | prefix = "[%p] "
function prefixLogger (line 32) | func prefixLogger(p *wrrBalancer) *internalgrpclog.PrefixLogger {
FILE: balancer/weightedroundrobin/metrics_test.go
type s (line 30) | type s struct
method TestWRR_Metrics_SubConnWeight (line 41) | func (s) TestWRR_Metrics_SubConnWeight(t *testing.T) {
method TestWRR_Metrics_Scheduler_RR_Fallback (line 138) | func (s) TestWRR_Metrics_Scheduler_RR_Fallback(t *testing.T) {
function Test (line 34) | func Test(t *testing.T) {
FILE: balancer/weightedroundrobin/scheduler.go
type scheduler (line 25) | type scheduler interface
method newScheduler (line 34) | func (p *picker) newScheduler(recordMetrics bool) scheduler {
constant maxWeight (line 92) | maxWeight = math.MaxUint16
type edfScheduler (line 97) | type edfScheduler struct
method nextIndex (line 103) | func (s *edfScheduler) nextIndex() int {
type rrScheduler (line 138) | type rrScheduler struct
method nextIndex (line 143) | func (s *rrScheduler) nextIndex() int {
FILE: balancer/weightedtarget/logging.go
constant prefix (line 28) | prefix = "[weighted-target-lb %p] "
function prefixLogger (line 32) | func prefixLogger(p *weightedTargetBalancer) *internalgrpclog.PrefixLogg...
FILE: balancer/weightedtarget/weightedaggregator/aggregator.go
type weightedPickerState (line 40) | type weightedPickerState struct
method String (line 51) | func (s *weightedPickerState) String() string {
type Aggregator (line 56) | type Aggregator struct
method Start (line 94) | func (wbsa *Aggregator) Start() {
method Stop (line 102) | func (wbsa *Aggregator) Stop() {
method Add (line 111) | func (wbsa *Aggregator) Add(id string, weight uint32) {
method Remove (line 132) | func (wbsa *Aggregator) Remove(id string) {
method UpdateWeight (line 151) | func (wbsa *Aggregator) UpdateWeight(id string, newWeight uint32) {
method PauseStateUpdates (line 164) | func (wbsa *Aggregator) PauseStateUpdates() {
method ResumeStateUpdates (line 173) | func (wbsa *Aggregator) ResumeStateUpdates() {
method NeedUpdateStateOnResume (line 184) | func (wbsa *Aggregator) NeedUpdateStateOnResume() {
method UpdateState (line 194) | func (wbsa *Aggregator) UpdateState(id string, newState balancer.State) {
method clearStates (line 221) | func (wbsa *Aggregator) clearStates() {
method buildAndUpdateLocked (line 235) | func (wbsa *Aggregator) buildAndUpdateLocked() {
method build (line 252) | func (wbsa *Aggregator) build() balancer.State {
function New (line 82) | func New(cc balancer.ClientConn, logger *grpclog.PrefixLogger, newWRR fu...
type weightedPickerGroup (line 292) | type weightedPickerGroup struct
method Pick (line 312) | func (pg *weightedPickerGroup) Pick(info balancer.PickInfo) (balancer....
function newWeightedPickerGroup (line 301) | func newWeightedPickerGroup(readyWeightedPickers []weightedPickerState, ...
FILE: balancer/weightedtarget/weightedtarget.go
constant Name (line 41) | Name = "weighted_target_experimental"
function init (line 47) | func init() {
type bb (line 51) | type bb struct
method Build (line 53) | func (bb) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) b...
method Name (line 69) | func (bb) Name() string {
method ParseConfig (line 73) | func (bb) ParseConfig(c json.RawMessage) (serviceconfig.LoadBalancingC...
type weightedTargetBalancer (line 77) | type weightedTargetBalancer struct
method UpdateClientConnState (line 100) | func (b *weightedTargetBalancer) UpdateClientConnState(s balancer.Clie...
method ResolverError (line 181) | func (b *weightedTargetBalancer) ResolverError(err error) {
method UpdateSubConnState (line 185) | func (b *weightedTargetBalancer) UpdateSubConnState(sc balancer.SubCon...
method Close (line 189) | func (b *weightedTargetBalancer) Close() {
method ExitIdle (line 194) | func (b *weightedTargetBalancer) ExitIdle() {
type localityKeyType (line 86) | type localityKeyType
constant localityKey (line 88) | localityKey = localityKeyType("locality")
function LocalityFromResolverState (line 92) | func LocalityFromResolverState(state resolver.State) string {
FILE: balancer/weightedtarget/weightedtarget_config.go
type Target (line 29) | type Target struct
type LBConfig (line 37) | type LBConfig struct
function parseConfig (line 43) | func parseConfig(c json.RawMessage) (*LBConfig, error) {
FILE: balancer/weightedtarget/weightedtarget_config_test.go
constant testJSONConfig (line 32) | testJSONConfig = `{
method TestParseConfig (line 57) | func (s) TestParseConfig(t *testing.T) {
FILE: balancer/weightedtarget/weightedtarget_test.go
constant defaultTestTimeout (line 52) | defaultTestTimeout = 5 * time.Second
type s (line 55) | type s struct
method TestWeightedTarget_NoTargets (line 177) | func (s) TestWeightedTarget_NoTargets(t *testing.T) {
method TestWeightedTarget (line 212) | func (s) TestWeightedTarget(t *testing.T) {
method TestWeightedTarget_OneSubBalancer_AddRemoveBackend (line 399) | func (s) TestWeightedTarget_OneSubBalancer_AddRemoveBackend(t *testing...
method TestWeightedTarget_TwoSubBalancers_OneBackend (line 501) | func (s) TestWeightedTarget_TwoSubBalancers_OneBackend(t *testing.T) {
method TestWeightedTarget_TwoSubBalancers_MoreBackends (line 570) | func (s) TestWeightedTarget_TwoSubBalancers_MoreBackends(t *testing.T) {
method TestWeightedTarget_TwoSubBalancers_DifferentWeight_MoreBackends (line 732) | func (s) TestWeightedTarget_TwoSubBalancers_DifferentWeight_MoreBacken...
method TestWeightedTarget_ThreeSubBalancers_RemoveBalancer (line 815) | func (s) TestWeightedTarget_ThreeSubBalancers_RemoveBalancer(t *testin...
method TestWeightedTarget_TwoSubBalancers_ChangeWeight_MoreBackends (line 991) | func (s) TestWeightedTarget_TwoSubBalancers_ChangeWeight_MoreBackends(...
method TestWeightedTarget_InitOneSubBalancerTransientFailure (line 1111) | func (s) TestWeightedTarget_InitOneSubBalancerTransientFailure(t *test...
method TestBalancerGroup_SubBalancerTurnsConnectingFromTransientFailure (line 1175) | func (s) TestBalancerGroup_SubBalancerTurnsConnectingFromTransientFail...
method TestInitialIdle (line 1381) | func (s) TestInitialIdle(t *testing.T) {
method TestIgnoreSubBalancerStateTransitions (line 1424) | func (s) TestIgnoreSubBalancerStateTransitions(t *testing.T) {
method TestUpdateStatePauses (line 1476) | func (s) TestUpdateStatePauses(t *testing.T) {
function Test (line 59) | func Test(t *testing.T) {
type testConfigBalancerBuilder (line 63) | type testConfigBalancerBuilder struct
method Build (line 87) | func (t *testConfigBalancerBuilder) Build(cc balancer.ClientConn, opts...
method Name (line 96) | func (t *testConfigBalancerBuilder) Name() string {
method ParseConfig (line 105) | func (t *testConfigBalancerBuilder) ParseConfig(c json.RawMessage) (se...
function newTestConfigBalancerBuilder (line 67) | func newTestConfigBalancerBuilder() *testConfigBalancerBuilder {
function pickAndCheckError (line 75) | func pickAndCheckError(want error) func(balancer.Picker) error {
constant testConfigBalancerName (line 94) | testConfigBalancerName = "test_config_balancer"
type stringBalancerConfig (line 100) | type stringBalancerConfig struct
type testConfigBalancer (line 115) | type testConfigBalancer struct
method UpdateClientConnState (line 134) | func (b *testConfigBalancer) UpdateClientConnState(s balancer.ClientCo...
method Close (line 151) | func (b *testConfigBalancer) Close() {
type configKey (line 121) | type configKey struct
function setConfigKey (line 123) | func setConfigKey(addr resolver.Address, config string) resolver.Address {
function getConfigKey (line 128) | func getConfigKey(attr *attributes.Attributes) (string, bool) {
constant testBackendAddrsCount (line 161) | testBackendAddrsCount = 12
function init (line 163) | func init() {
function verifyAddressInNewSubConn (line 1261) | func verifyAddressInNewSubConn(t *testing.T, cc *testutils.BalancerClien...
type subConnWithAddr (line 1273) | type subConnWithAddr struct
function waitForNewSubConns (line 1284) | func waitForNewSubConns(ctx context.Context, t *testing.T, cc *testutils...
function verifySubConnAddrs (line 1314) | func verifySubConnAddrs(t *testing.T, scs map[string][]subConnWithAddr, ...
function scwasToAddrs (line 1335) | func scwasToAddrs(ss []subConnWithAddr) []string {
function addressesToAddrs (line 1343) | func addressesToAddrs(as []resolver.Address) []string {
constant initIdleBalancerName (line 1351) | initIdleBalancerName = "test-init-Idle-balancer"
function init (line 1355) | func init() {
type tcc (line 1466) | type tcc struct
method UpdateState (line 1471) | func (t *tcc) UpdateState(bs balancer.State) {
FILE: balancer_wrapper.go
type ccBalancerWrapper (line 61) | type ccBalancerWrapper struct
method MetricsRecorder (line 104) | func (ccb *ccBalancerWrapper) MetricsRecorder() stats.MetricsRecorder {
method updateClientConnState (line 111) | func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.Clie...
method resolverError (line 143) | func (ccb *ccBalancerWrapper) resolverError(err error) {
method close (line 155) | func (ccb *ccBalancerWrapper) close() {
method exitIdle (line 171) | func (ccb *ccBalancerWrapper) exitIdle() {
method NewSubConn (line 180) | func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opt...
method RemoveSubConn (line 210) | func (ccb *ccBalancerWrapper) RemoveSubConn(balancer.SubConn) {
method UpdateAddresses (line 215) | func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, add...
method UpdateState (line 223) | func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) {
method ResolveNow (line 250) | func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOptions) {
method Target (line 263) | func (ccb *ccBalancerWrapper) Target() string {
function newCCBalancerWrapper (line 84) | func newCCBalancerWrapper(cc *ClientConn) *ccBalancerWrapper {
type acBalancerWrapper (line 269) | type acBalancerWrapper struct
method updateState (line 307) | func (acbw *acBalancerWrapper) updateState(s connectivity.State, err e...
method String (line 341) | func (acbw *acBalancerWrapper) String() string {
method UpdateAddresses (line 345) | func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Addres...
method Connect (line 349) | func (acbw *acBalancerWrapper) Connect() {
method Shutdown (line 353) | func (acbw *acBalancerWrapper) Shutdown() {
method NewStream (line 361) | func (acbw *acBalancerWrapper) NewStream(ctx context.Context, desc *St...
method Invoke (line 372) | func (acbw *acBalancerWrapper) Invoke(ctx context.Context, method stri...
method GetOrBuildProducer (line 389) | func (acbw *acBalancerWrapper) GetOrBuildProducer(pb balancer.Producer...
method closeProducers (line 422) | func (acbw *acBalancerWrapper) closeProducers() {
method healthListenerRegFn (line 445) | func (acbw *acBalancerWrapper) healthListenerRegFn() func(context.Cont...
method RegisterHealthListener (line 469) | func (acbw *acBalancerWrapper) RegisterHealthListener(listener func(ba...
type healthData (line 287) | type healthData struct
function newHealthData (line 298) | func newHealthData(s connectivity.State) *healthData {
type refCountedProducer (line 383) | type refCountedProducer struct
FILE: balancer_wrapper_test.go
method TestBalancer_StateListenerBeforeConnect (line 36) | func (s) TestBalancer_StateListenerBeforeConnect(t *testing.T) {
FILE: benchmark/benchmain/main.go
constant workloadsUnary (line 127) | workloadsUnary = "unary"
constant workloadsStreaming (line 128) | workloadsStreaming = "streaming"
constant workloadsUnconstrained (line 129) | workloadsUnconstrained = "unconstrained"
constant workloadsAll (line 130) | workloadsAll = "all"
constant compModeOff (line 132) | compModeOff = "off"
constant compModeGzip (line 133) | compModeGzip = "gzip"
constant compModeNop (line 134) | compModeNop = "nop"
constant compModeAll (line 135) | compModeAll = "all"
constant toggleModeOff (line 137) | toggleModeOff = "off"
constant toggleModeOn (line 138) | toggleModeOn = "on"
constant toggleModeBoth (line 139) | toggleModeBoth = "both"
constant networkModeNone (line 141) | networkModeNone = "none"
constant networkModeLocal (line 142) | networkModeLocal = "Local"
constant networkModeLAN (line 143) | networkModeLAN = "LAN"
constant networkModeWAN (line 144) | networkModeWAN = "WAN"
constant networkLongHaul (line 145) | networkLongHaul = "Longhaul"
constant recvBufferPoolNil (line 147) | recvBufferPoolNil = "nil"
constant recvBufferPoolSimple (line 148) | recvBufferPoolSimple = "simple"
constant recvBufferPoolAll (line 149) | recvBufferPoolAll = "all"
constant numStatsBuckets (line 151) | numStatsBuckets = 10
constant warmupCallCount (line 152) | warmupCallCount = 10
constant warmuptime (line 153) | warmuptime = time.Second
type swappableBufferPool (line 158) | type swappableBufferPool struct
method Get (line 162) | func (p swappableBufferPool) Get(length int) *[]byte {
method Put (line 172) | func (p swappableBufferPool) Put(i *[]byte) {
function init (line 179) | func init() {
type runModes (line 210) | type runModes struct
function runModesFromWorkloads (line 216) | func runModesFromWorkloads(workload string) runModes {
type startFunc (line 236) | type startFunc
type stopFunc (line 237) | type stopFunc
type ucStopFunc (line 238) | type ucStopFunc
type rpcCallFunc (line 239) | type rpcCallFunc
type rpcSendFunc (line 240) | type rpcSendFunc
type rpcRecvFunc (line 241) | type rpcRecvFunc
type rpcCleanupFunc (line 242) | type rpcCleanupFunc
function unaryBenchmark (line 244) | func unaryBenchmark(start startFunc, stop stopFunc, bf stats.Features, s...
function streamBenchmark (line 250) | func streamBenchmark(start startFunc, stop stopFunc, bf stats.Features, ...
function unconstrainedStreamBenchmark (line 256) | func unconstrainedStreamBenchmark(start startFunc, stop ucStopFunc, bf s...
function makeClients (line 317) | func makeClients(bf stats.Features) ([]testgrpc.BenchmarkServiceClient, ...
function makeFuncUnary (line 419) | func makeFuncUnary(bf stats.Features) (rpcCallFunc, rpcCleanupFunc) {
function makeFuncStream (line 434) | func makeFuncStream(bf stats.Features) (rpcCallFunc, rpcCleanupFunc) {
function makeFuncUnconstrainedStreamPreloaded (line 466) | func makeFuncUnconstrainedStreamPreloaded(bf stats.Features) (rpcSendFun...
function makeFuncUnconstrainedStream (line 478) | func makeFuncUnconstrainedStream(bf stats.Features) (rpcSendFunc, rpcRec...
function setupStream (line 488) | func setupStream(bf stats.Features, unconstrained bool) ([][]testgrpc.Be...
function prepareMessages (line 523) | func prepareMessages(streams [][]testgrpc.BenchmarkService_StreamingCall...
function unaryCaller (line 539) | func unaryCaller(client testgrpc.BenchmarkServiceClient, reqSize, respSi...
function streamCaller (line 545) | func streamCaller(stream testgrpc.BenchmarkService_StreamingCallClient, ...
function runBenchmark (line 551) | func runBenchmark(caller rpcCallFunc, start startFunc, stop stopFunc, bf...
type benchOpts (line 598) | type benchOpts struct
method generateFeatures (line 720) | func (b *benchOpts) generateFeatures(featuresNum []int) []stats.Featur...
type featureOpts (line 616) | type featureOpts struct
function makeFeaturesNum (line 644) | func makeFeaturesNum(b *benchOpts) []int {
function sharedFeatures (line 697) | func sharedFeatures(featuresNum []int) []bool {
function addOne (line 777) | func addOne(features []int, featuresMaxPosition []int) {
function processFlags (line 795) | func processFlags() *benchOpts {
function setToggleMode (line 883) | func setToggleMode(val string) []bool {
function setCompressorMode (line 898) | func setCompressorMode(val string) []string {
function setRecvBufferPool (line 911) | func setRecvBufferPool(val string) []string {
function main (line 924) | func main() {
function before (line 956) | func before(opts *benchOpts) {
function after (line 974) | func after(opts *benchOpts, data []stats.BenchResults) {
type nopCompressor (line 1003) | type nopCompressor struct
method Do (line 1005) | func (nopCompressor) Do(w io.Writer, p []byte) error {
method Type (line 1016) | func (nopCompressor) Type() string { return compModeNop }
type nopDecompressor (line 1019) | type nopDecompressor struct
method Do (line 1021) | func (nopDecompressor) Do(r io.Reader) ([]byte, error) { return io.Rea...
method Type (line 1022) | func (nopDecompressor) Type() string { return compMo...
FILE: benchmark/benchmark.go
function setPayload (line 47) | func setPayload(p *testpb.Payload, t testpb.PayloadType, size int) {
function NewPayload (line 62) | func NewPayload(t testpb.PayloadType, size int) *testpb.Payload {
type testServer (line 68) | type testServer struct
method UnaryCall (line 72) | func (s *testServer) UnaryCall(_ context.Context, in *testpb.SimpleReq...
method StreamingCall (line 92) | func (s *testServer) StreamingCall(stream testgrpc.BenchmarkService_St...
method UnconstrainedStreamingCall (line 139) | func (s *testServer) UnconstrainedStreamingCall(stream testgrpc.Benchm...
constant UnconstrainedStreamingHeader (line 81) | UnconstrainedStreamingHeader = "unconstrained-streaming"
constant UnconstrainedStreamingDelayHeader (line 85) | UnconstrainedStreamingDelayHeader = "unconstrained-streaming-delay"
constant PreloadMsgSizeHeader (line 90) | PreloadMsgSizeHeader = "preload-msg-size"
type byteBufServer (line 214) | type byteBufServer struct
method UnaryCall (line 221) | func (s *byteBufServer) UnaryCall(context.Context, *testpb.SimpleReque...
method StreamingCall (line 225) | func (s *byteBufServer) StreamingCall(stream testgrpc.BenchmarkService...
type ServerInfo (line 243) | type ServerInfo struct
function StartServer (line 259) | func StartServer(info ServerInfo, opts ...grpc.ServerOption) func() {
function DoUnaryCall (line 280) | func DoUnaryCall(tc testgrpc.BenchmarkServiceClient, reqSize, respSize i...
function DoStreamingRoundTrip (line 294) | func DoStreamingRoundTrip(stream testgrpc.BenchmarkService_StreamingCall...
function DoStreamingRoundTripPreloaded (line 305) | func DoStreamingRoundTripPreloaded(stream testgrpc.BenchmarkService_Stre...
function DoByteBufStreamingRoundTrip (line 321) | func DoByteBufStreamingRoundTrip(stream testgrpc.BenchmarkService_Stream...
function NewClientConn (line 338) | func NewClientConn(addr string, opts ...grpc.DialOption) *grpc.ClientConn {
function NewClientConnWithContext (line 343) | func NewClientConnWithContext(_ context.Context, addr string, opts ...gr...
FILE: benchmark/benchresult/main.go
function createMap (line 43) | func createMap(fileName string) map[string]stats.BenchResults {
function intChange (line 61) | func intChange(title string, val1, val2 uint64) string {
function floatChange (line 65) | func floatChange(title string, val1, val2 float64) string {
function timeChange (line 68) | func timeChange(title string, val1, val2 time.Duration) string {
function strDiff (line 73) | func strDiff(title, val1, val2 string) string {
function compareTwoMap (line 77) | func compareTwoMap(m1, m2 map[string]stats.BenchResults) {
function compareBenchmark (line 100) | func compareBenchmark(file1, file2 string) {
function printHeader (line 104) | func printHeader() {
function printline (line 110) | func printline(benchName string, d stats.RunData) {
function formatBenchmark (line 116) | func formatBenchmark(fileName string) {
function main (line 146) | func main() {
FILE: benchmark/client/main.go
function main (line 86) | func main() {
function buildConnections (line 136) | func buildConnections(ctx context.Context) []*grpc.ClientConn {
function runWithConn (line 149) | func runWithConn(cc *grpc.ClientConn, req *testpb.SimpleRequest, warmDea...
function makeCaller (line 174) | func makeCaller(cc *grpc.ClientConn, req *testpb.SimpleRequest) func() {
function parseHist (line 197) | func parseHist(hist *stats.Histogram) {
function median (line 205) | func median(percentile float64, h *stats.Histogram) int64 {
FILE: benchmark/flags/flags.go
type stringFlagWithAllowedValues (line 37) | type stringFlagWithAllowedValues struct
method String (line 52) | func (as *stringFlagWithAllowedValues) String() string {
method Set (line 57) | func (as *stringFlagWithAllowedValues) Set(val string) error {
function StringWithAllowedValues (line 45) | func StringWithAllowedValues(name, defaultVal, usage string, allowed []s...
type durationSliceValue (line 67) | type durationSliceValue
method Set (line 79) | func (dsv *durationSliceValue) Set(s string) error {
method String (line 94) | func (dsv *durationSliceValue) String() string {
function DurationSlice (line 70) | func DurationSlice(name string, defaultVal []time.Duration, usage string...
type intSliceValue (line 105) | type intSliceValue
method Set (line 117) | func (isv *intSliceValue) Set(s string) error {
method String (line 132) | func (isv *intSliceValue) String() string {
function IntSlice (line 108) | func IntSlice(name string, defaultVal []int, usage string) *[]int {
type stringSliceValue (line 143) | type stringSliceValue
method Set (line 166) | func (ss *stringSliceValue) Set(str string) error {
method String (line 176) | func (ss *stringSliceValue) String() string {
function StringSlice (line 146) | func StringSlice(name string, defaultVal []string, usage string) *[]stri...
function escapedCommaSplit (line 156) | func escapedCommaSplit(str string) ([]string, error) {
FILE: benchmark/flags/flags_test.go
type s (line 30) | type s struct
method TestStringWithAllowedValues (line 38) | func (s) TestStringWithAllowedValues(t *testing.T) {
method TestDurationSlice (line 67) | func (s) TestDurationSlice(t *testing.T) {
method TestIntSlice (line 96) | func (s) TestIntSlice(t *testing.T) {
method TestStringSlice (line 125) | func (s) TestStringSlice(t *testing.T) {
function Test (line 34) | func Test(t *testing.T) {
FILE: benchmark/latency/latency.go
type Dialer (line 35) | type Dialer
type TimeoutDialer (line 38) | type TimeoutDialer
type ContextDialer (line 42) | type ContextDialer
type Network (line 59) | type Network struct
method isLocal (line 76) | func (n *Network) isLocal() bool {
method Conn (line 84) | func (n *Network) Conn(c net.Conn) (net.Conn, error) {
method Listener (line 255) | func (n *Network) Listener(l net.Listener) net.Listener {
method Dialer (line 277) | func (n *Network) Dialer(d Dialer) Dialer {
method TimeoutDialer (line 293) | func (n *Network) TimeoutDialer(d TimeoutDialer) TimeoutDialer {
method ContextDialer (line 309) | func (n *Network) ContextDialer(d ContextDialer) ContextDialer {
method pktTime (line 324) | func (n *Network) pktTime(b int) time.Duration {
type conn (line 97) | type conn struct
method Write (line 112) | func (c *conn) Write(p []byte) (n int, err error) {
method Read (line 146) | func (c *conn) Read(p []byte) (n int, err error) {
method sync (line 164) | func (c *conn) sync() error {
type header (line 107) | type header struct
type listener (line 262) | type listener struct
method Accept (line 267) | func (l *listener) Accept() (net.Conn, error) {
FILE: benchmark/latency/latency_test.go
type s (line 33) | type s struct
method TestConn (line 62) | func (s) TestConn(t *testing.T) {
method TestSync (line 135) | func (s) TestSync(t *testing.T) {
method TestSyncTooSlow (line 158) | func (s) TestSyncTooSlow(t *testing.T) {
method TestListenerAndDialer (line 179) | func (s) TestListenerAndDialer(t *testing.T) {
method TestBufferBloat (line 305) | func (s) TestBufferBloat(t *testing.T) {
function Test (line 37) | func Test(t *testing.T) {
type bufConn (line 42) | type bufConn struct
method Close (line 46) | func (bufConn) Close() error { panic("unimplemente...
method LocalAddr (line 47) | func (bufConn) LocalAddr() net.Addr { panic("unimplemente...
method RemoteAddr (line 48) | func (bufConn) RemoteAddr() net.Addr { panic("unimplemente...
method SetDeadline (line 49) | func (bufConn) SetDeadline(time.Time) error { panic("unimplemente...
method SetReadDeadline (line 50) | func (bufConn) SetReadDeadline(time.Time) error { panic("unimplemente...
method SetWriteDeadline (line 51) | func (bufConn) SetWriteDeadline(time.Time) error { panic("unimplemente...
function restoreHooks (line 53) | func restoreHooks() func() {
FILE: benchmark/primitives/code_string_test.go
type codeBench (line 28) | type codeBench
method String (line 55) | func (i codeBench) String() string {
method StringUsingMap (line 82) | func (i codeBench) StringUsingMap() string {
constant OK (line 31) | OK codeBench = iota
constant Canceled (line 32) | Canceled
constant Unknown (line 33) | Unknown
constant InvalidArgument (line 34) | InvalidArgument
constant DeadlineExceeded (line 35) | DeadlineExceeded
constant NotFound (line 36) | NotFound
constant AlreadyExists (line 37) | AlreadyExists
constant PermissionDenied (line 38) | PermissionDenied
constant ResourceExhausted (line 39) | ResourceExhausted
constant FailedPrecondition (line 40) | FailedPrecondition
constant Aborted (line 41) | Aborted
constant OutOfRange (line 42) | OutOfRange
constant Unimplemented (line 43) | Unimplemented
constant Internal (line 44) | Internal
constant Unavailable (line 45) | Unavailable
constant DataLoss (line 46) | DataLoss
constant Unauthenticated (line 47) | Unauthenticated
constant codeName (line 51) | codeName = "OKCanceledUnknownInvalidArgumentDeadlineExceededNotFoundAlre...
function BenchmarkCodeStringStringer (line 89) | func BenchmarkCodeStringStringer(b *testing.B) {
function BenchmarkCodeStringMap (line 96) | func BenchmarkCodeStringMap(b *testing.B) {
function BenchmarkCodeStringSwitch (line 104) | func BenchmarkCodeStringSwitch(b *testing.B) {
function BenchmarkCodeStringStringerWithOverflow (line 112) | func BenchmarkCodeStringStringerWithOverflow(b *testing.B) {
function BenchmarkCodeStringSwitchWithOverflow (line 120) | func BenchmarkCodeStringSwitchWithOverflow(b *testing.B) {
FILE: benchmark/primitives/context_test.go
constant defaultTestTimeout (line 27) | defaultTestTimeout = 10 * time.Second
function BenchmarkCancelContextErrNoErr (line 29) | func BenchmarkCancelContextErrNoErr(b *testing.B) {
function BenchmarkCancelContextErrGotErr (line 39) | func BenchmarkCancelContextErrGotErr(b *testing.B) {
function BenchmarkCancelContextChannelNoErr (line 49) | func BenchmarkCancelContextChannelNoErr(b *testing.B) {
function BenchmarkCancelContextChannelGotErr (line 61) | func BenchmarkCancelContextChannelGotErr(b *testing.B) {
function BenchmarkTimerContextErrNoErr (line 76) | func BenchmarkTimerContextErrNoErr(b *testing.B) {
function BenchmarkTimerContextErrGotErr (line 86) | func BenchmarkTimerContextErrGotErr(b *testing.B) {
function BenchmarkTimerContextChannelNoErr (line 96) | func BenchmarkTimerContextChannelNoErr(b *testing.B) {
function BenchmarkTimerContextChannelGotErr (line 108) | func BenchmarkTimerContextChannelGotErr(b *testing.B) {
type ctxKey (line 123) | type ctxKey struct
function newContextWithLocalKey (line 125) | func newContextWithLocalKey(parent context.Context) context.Context {
function newContextWithGlobalKey (line 131) | func newContextWithGlobalKey(parent context.Context) context.Context {
function BenchmarkContextWithValue (line 135) | func BenchmarkContextWithValue(b *testing.B) {
FILE: benchmark/primitives/primitives_test.go
function BenchmarkSelectClosed (line 32) | func BenchmarkSelectClosed(b *testing.B) {
function BenchmarkSelectOpen (line 50) | func BenchmarkSelectOpen(b *testing.B) {
function BenchmarkAtomicBool (line 67) | func BenchmarkAtomicBool(b *testing.B) {
function BenchmarkAtomicValueLoad (line 82) | func BenchmarkAtomicValueLoad(b *testing.B) {
function BenchmarkAtomicValueStore (line 98) | func BenchmarkAtomicValueStore(b *testing.B) {
function BenchmarkMutex (line 108) | func BenchmarkMutex(b *testing.B) {
function BenchmarkRWMutex (line 123) | func BenchmarkRWMutex(b *testing.B) {
function BenchmarkRWMutexW (line 138) | func BenchmarkRWMutexW(b *testing.B) {
function BenchmarkMutexWithDefer (line 153) | func BenchmarkMutexWithDefer(b *testing.B) {
function BenchmarkMutexWithClosureDefer (line 170) | func BenchmarkMutexWithClosureDefer(b *testing.B) {
function BenchmarkMutexWithoutDefer (line 187) | func BenchmarkMutexWithoutDefer(b *testing.B) {
function BenchmarkAtomicAddInt64 (line 204) | func BenchmarkAtomicAddInt64(b *testing.B) {
function BenchmarkAtomicTimeValueStore (line 216) | func BenchmarkAtomicTimeValueStore(b *testing.B) {
function BenchmarkAtomic16BValueStore (line 226) | func BenchmarkAtomic16BValueStore(b *testing.B) {
function BenchmarkAtomic32BValueStore (line 241) | func BenchmarkAtomic32BValueStore(b *testing.B) {
function BenchmarkAtomicPointerStore (line 258) | func BenchmarkAtomicPointerStore(b *testing.B) {
function BenchmarkAtomicTimePointerStore (line 268) | func BenchmarkAtomicTimePointerStore(b *testing.B) {
function BenchmarkStoreContentionWithAtomic (line 278) | func BenchmarkStoreContentionWithAtomic(b *testing.B) {
function BenchmarkStoreContentionWithMutex (line 288) | func BenchmarkStoreContentionWithMutex(b *testing.B) {
type dummyStruct (line 303) | type dummyStruct struct
function BenchmarkStructStoreContention (line 308) | func BenchmarkStructStoreContention(b *testing.B) {
type myFooer (line 357) | type myFooer struct
method Foo (line 359) | func (myFooer) Foo() {}
type fooer (line 361) | type fooer interface
function BenchmarkInterfaceTypeAssertion (line 365) | func BenchmarkInterfaceTypeAssertion(b *testing.B) {
function runInterfaceTypeAssertion (line 370) | func runInterfaceTypeAssertion(b *testing.B, fer any) {
function BenchmarkStructTypeAssertion (line 384) | func BenchmarkStructTypeAssertion(b *testing.B) {
function runStructTypeAssertion (line 389) | func runStructTypeAssertion(b *testing.B, fer any) {
function BenchmarkWaitGroupAddDone (line 403) | func BenchmarkWaitGroupAddDone(b *testing.B) {
function BenchmarkRLockUnlock (line 416) | func BenchmarkRLockUnlock(b *testing.B) {
type ifNop (line 429) | type ifNop interface
type alwaysNop (line 433) | type alwaysNop struct
method nop (line 435) | func (alwaysNop) nop() {}
type concreteNop (line 437) | type concreteNop struct
method nop (line 442) | func (c *concreteNop) nop() {
function BenchmarkInterfaceNop (line 449) | func BenchmarkInterfaceNop(b *testing.B) {
function BenchmarkConcreteNop (line 458) | func BenchmarkConcreteNop(b *testing.B) {
FILE: benchmark/primitives/safe_config_selector_test.go
type safeUpdaterAtomicAndCounter (line 31) | type safeUpdaterAtomicAndCounter struct
method call (line 40) | func (s *safeUpdaterAtomicAndCounter) call() {
method update (line 60) | func (s *safeUpdaterAtomicAndCounter) update(f func()) {
type countingFunc (line 35) | type countingFunc struct
type safeUpdaterRWMutex (line 70) | type safeUpdaterRWMutex struct
method call (line 75) | func (s *safeUpdaterRWMutex) call() {
method update (line 81) | func (s *safeUpdaterRWMutex) update(f func()) {
type updater (line 87) | type updater interface
function benchmarkSafeUpdater (line 92) | func benchmarkSafeUpdater(b *testing.B, u updater) {
function BenchmarkSafeUpdaterAtomicAndCounter (line 108) | func BenchmarkSafeUpdaterAtomicAndCounter(b *testing.B) {
function BenchmarkSafeUpdaterRWMutex (line 112) | func BenchmarkSafeUpdaterRWMutex(b *testing.B) {
FILE: benchmark/primitives/syncmap_test.go
type incrementUint64Map (line 26) | type incrementUint64Map interface
type mapWithLock (line 31) | type mapWithLock struct
method increment (line 42) | func (mwl *mapWithLock) increment(c string) {
method result (line 48) | func (mwl *mapWithLock) result(c string) uint64 {
function newMapWithLock (line 36) | func newMapWithLock() incrementUint64Map {
type mapWithAtomicFastpath (line 52) | type mapWithAtomicFastpath struct
method increment (line 63) | func (mwaf *mapWithAtomicFastpath) increment(c string) {
method result (line 83) | func (mwaf *mapWithAtomicFastpath) result(c string) uint64 {
function newMapWithAtomicFastpath (line 57) | func newMapWithAtomicFastpath() incrementUint64Map {
type mapWithSyncMap (line 87) | type mapWithSyncMap struct
method increment (line 95) | func (mwsm *mapWithSyncMap) increment(c string) {
method result (line 104) | func (mwsm *mapWithSyncMap) result(c string) uint64 {
function newMapWithSyncMap (line 91) | func newMapWithSyncMap() incrementUint64Map {
function benchmarkIncrementUint64Map (line 109) | func benchmarkIncrementUint64Map(b *testing.B, f func() incrementUint64M...
function BenchmarkMapWithSyncMutexContention (line 155) | func BenchmarkMapWithSyncMutexContention(b *testing.B) {
function BenchmarkMapWithAtomicFastpath (line 159) | func BenchmarkMapWithAtomicFastpath(b *testing.B) {
function BenchmarkMapWithSyncMap (line 163) | func BenchmarkMapWithSyncMap(b *testing.B) {
FILE: benchmark/server/main.go
function main (line 55) | func main() {
FILE: benchmark/stats/curve.go
type payloadCurveRange (line 34) | type payloadCurveRange struct
method chooseRandom (line 72) | func (pcr *payloadCurveRange) chooseRandom() int {
function newPayloadCurveRange (line 41) | func newPayloadCurveRange(line []string) (*payloadCurveRange, error) {
function sha256file (line 82) | func sha256file(file string) (string, error) {
type PayloadCurve (line 94) | type PayloadCurve struct
method ChooseRandom (line 156) | func (pc *PayloadCurve) ChooseRandom() int {
method Hash (line 172) | func (pc *PayloadCurve) Hash() string {
method ShortHash (line 177) | func (pc *PayloadCurve) ShortHash() string {
function NewPayloadCurve (line 103) | func NewPayloadCurve(file string) (*PayloadCurve, error) {
FILE: benchmark/stats/histogram.go
type Histogram (line 33) | type Histogram struct
method Print (line 106) | func (h *Histogram) Print(w io.Writer) {
method PrintWithUnit (line 112) | func (h *Histogram) PrintWithUnit(w io.Writer, unit float64) {
method String (line 143) | func (h *Histogram) String() string {
method Clear (line 150) | func (h *Histogram) Clear() {
method Opts (line 162) | func (h *Histogram) Opts() HistogramOptions {
method Add (line 167) | func (h *Histogram) Add(value int64) error {
method findBucket (line 185) | func (h *Histogram) findBucket(value int64) (int, error) {
method Merge (line 205) | func (h *Histogram) Merge(h2 *Histogram) {
type HistogramOptions (line 57) | type HistogramOptions struct
type HistogramBucket (line 70) | type HistogramBucket struct
function NewHistogram (line 79) | func NewHistogram(opts HistogramOptions) *Histogram {
FILE: benchmark/stats/stats.go
type FeatureIndex (line 39) | type FeatureIndex
constant EnableTraceIndex (line 43) | EnableTraceIndex FeatureIndex = iota
constant ReadLatenciesIndex (line 44) | ReadLatenciesIndex
constant ReadKbpsIndex (line 45) | ReadKbpsIndex
constant ReadMTUIndex (line 46) | ReadMTUIndex
constant MaxConcurrentCallsIndex (line 47) | MaxConcurrentCallsIndex
constant ReqSizeBytesIndex (line 48) | ReqSizeBytesIndex
constant RespSizeBytesIndex (line 49) | RespSizeBytesIndex
constant ReqPayloadCurveIndex (line 50) | ReqPayloadCurveIndex
constant RespPayloadCurveIndex (line 51) | RespPayloadCurveIndex
constant CompModesIndex (line 52) | CompModesIndex
constant EnableChannelzIndex (line 53) | EnableChannelzIndex
constant EnablePreloaderIndex (line 54) | EnablePreloaderIndex
constant ClientReadBufferSize (line 55) | ClientReadBufferSize
constant ClientWriteBufferSize (line 56) | ClientWriteBufferSize
constant ServerReadBufferSize (line 57) | ServerReadBufferSize
constant ServerWriteBufferSize (line 58) | ServerWriteBufferSize
constant SleepBetweenRPCs (line 59) | SleepBetweenRPCs
constant RecvBufferPool (line 60) | RecvBufferPool
constant SharedWriteBuffer (line 61) | SharedWriteBuffer
constant MaxFeatureIndex (line 65) | MaxFeatureIndex
type Features (line 72) | type Features struct
method String (line 138) | func (f Features) String() string {
method SharedFeatures (line 165) | func (f Features) SharedFeatures(wantFeatures []bool) string {
method PrintableName (line 184) | func (f Features) PrintableName(wantFeatures []bool) string {
method partialString (line 192) | func (f Features) partialString(b *bytes.Buffer, wantFeatures []bool, ...
type BenchResults (line 249) | type BenchResults struct
type RunData (line 269) | type RunData struct
type durationSlice (line 302) | type durationSlice
method Len (line 304) | func (a durationSlice) Len() int { return len(a) }
method Swap (line 305) | func (a durationSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
method Less (line 306) | func (a durationSlice) Less(i, j int) bool { return a[i] < a[j] }
type Stats (line 309) | type Stats struct
method StartRun (line 337) | func (s *Stats) StartRun(mode string, f Features, sf []bool) {
method EndRun (line 353) | func (s *Stats) EndRun(count uint64) {
method EndUnconstrainedRun (line 373) | func (s *Stats) EndUnconstrainedRun(req uint64, resp uint64) {
method AddDuration (line 394) | func (s *Stats) AddDuration(d time.Duration) {
method GetResults (line 402) | func (s *Stats) GetResults() []BenchResults {
method computeLatencies (line 411) | func (s *Stats) computeLatencies(result *BenchResults) {
method dump (line 449) | func (s *Stats) dump(result *BenchResults) {
type histWrapper (line 318) | type histWrapper struct
function NewStats (line 326) | func NewStats(numBuckets int) *Stats {
FILE: benchmark/worker/benchmark_client.go
type lockingHistogram (line 48) | type lockingHistogram struct
method add (line 53) | func (h *lockingHistogram) add(value int64) {
method swap (line 60) | func (h *lockingHistogram) swap(o *stats.Histogram) *stats.Histogram {
method mergeInto (line 68) | func (h *lockingHistogram) mergeInto(merged *stats.Histogram) {
type benchmarkClient (line 74) | type benchmarkClient struct
method unaryLoop (line 259) | func (bc *benchmarkClient) unaryLoop(ctx context.Context, conns []*grp...
method streamingLoop (line 296) | func (bc *benchmarkClient) streamingLoop(ctx context.Context, conns []...
method poissonUnary (line 342) | func (bc *benchmarkClient) poissonUnary(client testgrpc.BenchmarkServi...
method poissonStreaming (line 357) | func (bc *benchmarkClient) poissonStreaming(stream testgrpc.BenchmarkS...
method getStats (line 375) | func (bc *benchmarkClient) getStats(reset bool) *testpb.ClientStats {
method shutdown (line 426) | func (bc *benchmarkClient) shutdown() {
function printClientConfig (line 82) | func printClientConfig(config *testpb.ClientConfig) {
function setupClientEnv (line 104) | func setupClientEnv(config *testpb.ClientConfig) {
function createConns (line 117) | func createConns(config *testpb.ClientConfig) ([]*grpc.ClientConn, func(...
function performRPCs (line 170) | func performRPCs(ctx context.Context, config *testpb.ClientConfig, conns...
function startBenchmarkClient (line 224) | func startBenchmarkClient(ctx context.Context, config *testpb.ClientConf...
FILE: benchmark/worker/benchmark_server.go
type benchmarkServer (line 46) | type benchmarkServer struct
method getStats (line 171) | func (bs *benchmarkServer) getStats(reset bool) *testpb.ServerStats {
function printServerConfig (line 56) | func printServerConfig(config *testpb.ServerConfig) {
function startBenchmarkServer (line 73) | func startBenchmarkServer(config *testpb.ServerConfig, serverPort int) (...
FILE: benchmark/worker/main.go
type byteBufCodec (line 53) | type byteBufCodec struct
method Marshal (line 56) | func (byteBufCodec) Marshal(v any) ([]byte, error) {
method Unmarshal (line 64) | func (byteBufCodec) Unmarshal(data []byte, v any) error {
method String (line 73) | func (byteBufCodec) String() string {
type workerServer (line 79) | type workerServer struct
method RunServer (line 85) | func (s *workerServer) RunServer(stream testgrpc.WorkerService_RunServ...
method RunClient (line 140) | func (s *workerServer) RunClient(stream testgrpc.WorkerService_RunClie...
method CoreCount (line 193) | func (s *workerServer) CoreCount(context.Context, *testpb.CoreRequest)...
method QuitWorker (line 198) | func (s *workerServer) QuitWorker(context.Context, *testpb.Void) (*tes...
function main (line 204) | func main() {
FILE: binarylog/binarylog_end2end_test.go
type s (line 50) | type s struct
method TestClientBinaryLogUnaryRPC (line 909) | func (s) TestClientBinaryLogUnaryRPC(t *testing.T) {
method TestClientBinaryLogUnaryRPCError (line 915) | func (s) TestClientBinaryLogUnaryRPCError(t *testing.T) {
method TestClientBinaryLogClientStreamRPC (line 921) | func (s) TestClientBinaryLogClientStreamRPC(t *testing.T) {
method TestClientBinaryLogClientStreamRPCError (line 928) | func (s) TestClientBinaryLogClientStreamRPCError(t *testing.T) {
method TestClientBinaryLogServerStreamRPC (line 935) | func (s) TestClientBinaryLogServerStreamRPC(t *testing.T) {
method TestClientBinaryLogServerStreamRPCError (line 942) | func (s) TestClientBinaryLogServerStreamRPCError(t *testing.T) {
method TestClientBinaryLogFullDuplexRPC (line 949) | func (s) TestClientBinaryLogFullDuplexRPC(t *testing.T) {
method TestClientBinaryLogFullDuplexRPCError (line 956) | func (s) TestClientBinaryLogFullDuplexRPCError(t *testing.T) {
method TestClientBinaryLogCancel (line 963) | func (s) TestClientBinaryLogCancel(t *testing.T) {
method TestServerBinaryLogUnaryRPC (line 1011) | func (s) TestServerBinaryLogUnaryRPC(t *testing.T) {
method TestServerBinaryLogUnaryRPCError (line 1017) | func (s) TestServerBinaryLogUnaryRPCError(t *testing.T) {
method TestServerBinaryLogClientStreamRPC (line 1023) | func (s) TestServerBinaryLogClientStreamRPC(t *testing.T) {
method TestServerBinaryLogClientStreamRPCError (line 1030) | func (s) TestServerBinaryLogClientStreamRPCError(t *testing.T) {
method TestServerBinaryLogServerStreamRPC (line 1037) | func (s) TestServerBinaryLogServerStreamRPC(t *testing.T) {
method TestServerBinaryLogServerStreamRPCError (line 1044) | func (s) TestServerBinaryLogServerStreamRPCError(t *testing.T) {
method TestServerBinaryLogFullDuplex (line 1051) | func (s) TestServerBinaryLogFullDuplex(t *testing.T) {
method TestServerBinaryLogFullDuplexError (line 1058) | func (s) TestServerBinaryLogFullDuplexError(t *testing.T) {
method TestCanceledStatus (line 1067) | func (s) TestCanceledStatus(t *testing.T) {
function Test (line 54) | func Test(t *testing.T) {
function init (line 58) | func init() {
type testBinLogSink (line 67) | type testBinLogSink struct
method Write (line 72) | func (s *testBinLogSink) Write(e *binlogpb.GrpcLogEntry) error {
method Close (line 79) | func (s *testBinLogSink) Close() error { return nil }
method logEntries (line 83) | func (s *testBinLogSink) logEntries(client bool) []*binlogpb.GrpcLogEn...
method clear (line 99) | func (s *testBinLogSink) clear() {
function idToPayload (line 122) | func idToPayload(id int32) *testpb.Payload {
function payloadToID (line 126) | func payloadToID(p *testpb.Payload) int32 {
type testServer (line 133) | type testServer struct
method UnaryCall (line 138) | func (s *testServer) UnaryCall(ctx context.Context, in *testpb.SimpleR...
method FullDuplexCall (line 156) | func (s *testServer) FullDuplexCall(stream testgrpc.TestService_FullDu...
method StreamingInputCall (line 184) | func (s *testServer) StreamingInputCall(stream testgrpc.TestService_St...
method StreamingOutputCall (line 208) | func (s *testServer) StreamingOutputCall(in *testpb.StreamingOutputCal...
type test (line 232) | type test struct
method tearDown (line 250) | func (te *test) tearDown() {
method startServer (line 287) | func (te *test) startServer(ts testgrpc.TestServiceServer) {
method clientConn (line 312) | func (te *test) clientConn() *grpc.ClientConn {
method doUnaryCall (line 342) | func (te *test) doUnaryCall(c *rpcConfig) (*testpb.SimpleRequest, *tes...
method doFullDuplexCallRoundtrip (line 362) | func (te *test) doFullDuplexCallRoundtrip(c *rpcConfig) ([]proto.Messa...
method doClientStreamCall (line 411) | func (te *test) doClientStreamCall(c *rpcConfig) ([]proto.Message, pro...
method doServerStreamCall (line 443) | func (te *test) doServerStreamCall(c *rpcConfig) (proto.Message, []pro...
function newTest (line 261) | func newTest(t *testing.T) *test {
type listenerWrapper (line 268) | type listenerWrapper struct
method Accept (line 273) | func (lw *listenerWrapper) Accept() (net.Conn, error) {
type rpcType (line 326) | type rpcType
constant unaryRPC (line 329) | unaryRPC rpcType = iota
constant clientStreamRPC (line 330) | clientStreamRPC
constant serverStreamRPC (line 331) | serverStreamRPC
constant fullDuplexStreamRPC (line 332) | fullDuplexStreamRPC
constant cancelRPC (line 333) | cancelRPC
type rpcConfig (line 336) | type rpcConfig struct
type expectedData (line 476) | type expectedData struct
method newClientHeaderEntry (line 486) | func (ed *expectedData) newClientHeaderEntry(client bool, rpcID, inRPC...
method newServerHeaderEntry (line 520) | func (ed *expectedData) newServerHeaderEntry(client bool, rpcID, inRPC...
method newClientMessageEntry (line 550) | func (ed *expectedData) newClientMessageEntry(client bool, rpcID, inRP...
method newServerMessageEntry (line 574) | func (ed *expectedData) newServerMessageEntry(client bool, rpcID, inRP...
method newHalfCloseEntry (line 598) | func (ed *expectedData) newHalfCloseEntry(client bool, rpcID, inRPCID ...
method newServerTrailerEntry (line 613) | func (ed *expectedData) newServerTrailerEntry(client bool, rpcID, inRP...
method newCancelEntry (line 662) | func (ed *expectedData) newCancelEntry(rpcID, inRPCID uint64) *binlogp...
method toClientLogEntries (line 673) | func (ed *expectedData) toClientLogEntries() []*binlogpb.GrpcLogEntry {
method toServerLogEntries (line 731) | func (ed *expectedData) toServerLogEntries() []*binlogpb.GrpcLogEntry {
function runRPCs (line 797) | func runRPCs(t *testing.T, cc *rpcConfig) *expectedData {
function equalLogEntry (line 843) | func equalLogEntry(entries ...*binlogpb.GrpcLogEntry) (equal bool) {
function testClientBinaryLog (line 870) | func testClientBinaryLog(t *testing.T, c *rpcConfig) error {
function testServerBinaryLog (line 970) | func testServerBinaryLog(t *testing.T, c *rpcConfig) error {
FILE: binarylog/grpc_binarylog_v1/binarylog.pb.go
constant _ (line 39) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 41) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type GrpcLogEntry_EventType (line 47) | type GrpcLogEntry_EventType
method Enum (line 102) | func (x GrpcLogEntry_EventType) Enum() *GrpcLogEntry_EventType {
method String (line 108) | func (x GrpcLogEntry_EventType) String() string {
method Descriptor (line 112) | func (GrpcLogEntry_EventType) Descriptor() protoreflect.EnumDescriptor {
method Type (line 116) | func (GrpcLogEntry_EventType) Type() protoreflect.EnumType {
method Number (line 120) | func (x GrpcLogEntry_EventType) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 125) | func (GrpcLogEntry_EventType) EnumDescriptor() ([]byte, []int) {
constant GrpcLogEntry_EVENT_TYPE_UNKNOWN (line 50) | GrpcLogEntry_EVENT_TYPE_UNKNOWN GrpcLogEntry_EventType = 0
constant GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER (line 52) | GrpcLogEntry_EVENT_TYPE_CLIENT_HEADER GrpcLogEntry_EventType = 1
constant GrpcLogEntry_EVENT_TYPE_SERVER_HEADER (line 54) | GrpcLogEntry_EVENT_TYPE_SERVER_HEADER GrpcLogEntry_EventType = 2
constant GrpcLogEntry_EVENT_TYPE_CLIENT_MESSAGE (line 56) | GrpcLogEntry_EVENT_TYPE_CLIENT_MESSAGE GrpcLogEntry_EventType = 3
constant GrpcLogEntry_EVENT_TYPE_SERVER_MESSAGE (line 58) | GrpcLogEntry_EVENT_TYPE_SERVER_MESSAGE GrpcLogEntry_EventType = 4
constant GrpcLogEntry_EVENT_TYPE_CLIENT_HALF_CLOSE (line 60) | GrpcLogEntry_EVENT_TYPE_CLIENT_HALF_CLOSE GrpcLogEntry_EventType = 5
constant GrpcLogEntry_EVENT_TYPE_SERVER_TRAILER (line 68) | GrpcLogEntry_EVENT_TYPE_SERVER_TRAILER GrpcLogEntry_EventType = 6
constant GrpcLogEntry_EVENT_TYPE_CANCEL (line 75) | GrpcLogEntry_EVENT_TYPE_CANCEL GrpcLogEntry_EventType = 7
type GrpcLogEntry_Logger (line 130) | type GrpcLogEntry_Logger
method Enum (line 152) | func (x GrpcLogEntry_Logger) Enum() *GrpcLogEntry_Logger {
method String (line 158) | func (x GrpcLogEntry_Logger) String() string {
method Descriptor (line 162) | func (GrpcLogEntry_Logger) Descriptor() protoreflect.EnumDescriptor {
method Type (line 166) | func (GrpcLogEntry_Logger) Type() protoreflect.EnumType {
method Number (line 170) | func (x GrpcLogEntry_Logger) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 175) | func (GrpcLogEntry_Logger) EnumDescriptor() ([]byte, []int) {
constant GrpcLogEntry_LOGGER_UNKNOWN (line 133) | GrpcLogEntry_LOGGER_UNKNOWN GrpcLogEntry_Logger = 0
constant GrpcLogEntry_LOGGER_CLIENT (line 134) | GrpcLogEntry_LOGGER_CLIENT GrpcLogEntry_Logger = 1
constant GrpcLogEntry_LOGGER_SERVER (line 135) | GrpcLogEntry_LOGGER_SERVER GrpcLogEntry_Logger = 2
type Address_Type (line 179) | type Address_Type
method Enum (line 208) | func (x Address_Type) Enum() *Address_Type {
method String (line 214) | func (x Address_Type) String() string {
method Descriptor (line 218) | func (Address_Type) Descriptor() protoreflect.EnumDescriptor {
method Type (line 222) | func (Address_Type) Type() protoreflect.EnumType {
method Number (line 226) | func (x Address_Type) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 231) | func (Address_Type) EnumDescriptor() ([]byte, []int) {
constant Address_TYPE_UNKNOWN (line 182) | Address_TYPE_UNKNOWN Address_Type = 0
constant Address_TYPE_IPV4 (line 184) | Address_TYPE_IPV4 Address_Type = 1
constant Address_TYPE_IPV6 (line 187) | Address_TYPE_IPV6 Address_Type = 2
constant Address_TYPE_UNIX (line 189) | Address_TYPE_UNIX Address_Type = 3
type GrpcLogEntry (line 236) | type GrpcLogEntry struct
method Reset (line 275) | func (x *GrpcLogEntry) Reset() {
method String (line 282) | func (x *GrpcLogEntry) String() string {
method ProtoMessage (line 286) | func (*GrpcLogEntry) ProtoMessage() {}
method ProtoReflect (line 288) | func (x *GrpcLogEntry) ProtoReflect() protoreflect.Message {
method Descriptor (line 301) | func (*GrpcLogEntry) Descriptor() ([]byte, []int) {
method GetTimestamp (line 305) | func (x *GrpcLogEntry) GetTimestamp() *timestamppb.Timestamp {
method GetCallId (line 312) | func (x *GrpcLogEntry) GetCallId() uint64 {
method GetSequenceIdWithinCall (line 319) | func (x *GrpcLogEntry) GetSequenceIdWithinCall() uint64 {
method GetType (line 326) | func (x *GrpcLogEntry) GetType() GrpcLogEntry_EventType {
method GetLogger (line 333) | func (x *GrpcLogEntry) GetLogger() GrpcLogEntry_Logger {
method GetPayload (line 340) | func (x *GrpcLogEntry) GetPayload() isGrpcLogEntry_Payload {
method GetClientHeader (line 347) | func (x *GrpcLogEntry) GetClientHeader() *ClientHeader {
method GetServerHeader (line 356) | func (x *GrpcLogEntry) GetServerHeader() *ServerHeader {
method GetMessage (line 365) | func (x *GrpcLogEntry) GetMessage() *Message {
method GetTrailer (line 374) | func (x *GrpcLogEntry) GetTrailer() *Trailer {
method GetPayloadTruncated (line 383) | func (x *GrpcLogEntry) GetPayloadTruncated() bool {
method GetPeer (line 390) | func (x *GrpcLogEntry) GetPeer() *Address {
type isGrpcLogEntry_Payload (line 397) | type isGrpcLogEntry_Payload interface
type GrpcLogEntry_ClientHeader (line 401) | type GrpcLogEntry_ClientHeader struct
method isGrpcLogEntry_Payload (line 418) | func (*GrpcLogEntry_ClientHeader) isGrpcLogEntry_Payload() {}
type GrpcLogEntry_ServerHeader (line 405) | type GrpcLogEntry_ServerHeader struct
method isGrpcLogEntry_Payload (line 420) | func (*GrpcLogEntry_ServerHeader) isGrpcLogEntry_Payload() {}
type GrpcLogEntry_Message (line 409) | type GrpcLogEntry_Message struct
method isGrpcLogEntry_Payload (line 422) | func (*GrpcLogEntry_Message) isGrpcLogEntry_Payload() {}
type GrpcLogEntry_Trailer (line 414) | type GrpcLogEntry_Trailer struct
method isGrpcLogEntry_Payload (line 424) | func (*GrpcLogEntry_Trailer) isGrpcLogEntry_Payload() {}
type ClientHeader (line 426) | type ClientHeader struct
method Reset (line 446) | func (x *ClientHeader) Reset() {
method String (line 453) | func (x *ClientHeader) String() string {
method ProtoMessage (line 457) | func (*ClientHeader) ProtoMessage() {}
method ProtoReflect (line 459) | func (x *ClientHeader) ProtoReflect() protoreflect.Message {
method Descriptor (line 472) | func (*ClientHeader) Descriptor() ([]byte, []int) {
method GetMetadata (line 476) | func (x *ClientHeader) GetMetadata() *Metadata {
method GetMethodName (line 483) | func (x *ClientHeader) GetMethodName() string {
method GetAuthority (line 490) | func (x *ClientHeader) GetAuthority() string {
method GetTimeout (line 497) | func (x *ClientHeader) GetTimeout() *durationpb.Duration {
type ServerHeader (line 504) | type ServerHeader struct
method Reset (line 512) | func (x *ServerHeader) Reset() {
method String (line 519) | func (x *ServerHeader) String() string {
method ProtoMessage (line 523) | func (*ServerHeader) ProtoMessage() {}
method ProtoReflect (line 525) | func (x *ServerHeader) ProtoReflect() protoreflect.Message {
method Descriptor (line 538) | func (*ServerHeader) Descriptor() ([]byte, []int) {
method GetMetadata (line 542) | func (x *ServerHeader) GetMetadata() *Metadata {
type Trailer (line 549) | type Trailer struct
method Reset (line 565) | func (x *Trailer) Reset() {
method String (line 572) | func (x *Trailer) String() string {
method ProtoMessage (line 576) | func (*Trailer) ProtoMessage() {}
method ProtoReflect (line 578) | func (x *Trailer) ProtoReflect() protoreflect.Message {
method Descriptor (line 591) | func (*Trailer) Descriptor() ([]byte, []int) {
method GetMetadata (line 595) | func (x *Trailer) GetMetadata() *Metadata {
method GetStatusCode (line 602) | func (x *Trailer) GetStatusCode() uint32 {
method GetStatusMessage (line 609) | func (x *Trailer) GetStatusMessage() string {
method GetStatusDetails (line 616) | func (x *Trailer) GetStatusDetails() []byte {
type Message (line 624) | type Message struct
method Reset (line 635) | func (x *Message) Reset() {
method String (line 642) | func (x *Message) String() string {
method ProtoMessage (line 646) | func (*Message) ProtoMessage() {}
method ProtoReflect (line 648) | func (x *Message) ProtoReflect() protoreflect.Message {
method Descriptor (line 661) | func (*Message) Descriptor() ([]byte, []int) {
method GetLength (line 665) | func (x *Message) GetLength() uint32 {
method GetData (line 672) | func (x *Message) GetData() []byte {
type Metadata (line 700) | type Metadata struct
method Reset (line 707) | func (x *Metadata) Reset() {
method String (line 714) | func (x *Metadata) String() string {
method ProtoMessage (line 718) | func (*Metadata) ProtoMessage() {}
method ProtoReflect (line 720) | func (x *Metadata) ProtoReflect() protoreflect.Message {
method Descriptor (line 733) | func (*Metadata) Descriptor() ([]byte, []int) {
method GetEntry (line 737) | func (x *Metadata) GetEntry() []*MetadataEntry {
type MetadataEntry (line 745) | type MetadataEntry struct
method Reset (line 753) | func (x *MetadataEntry) Reset() {
method String (line 760) | func (x *MetadataEntry) String() string {
method ProtoMessage (line 764) | func (*MetadataEntry) ProtoMessage() {}
method ProtoReflect (line 766) | func (x *MetadataEntry) ProtoReflect() protoreflect.Message {
method Descriptor (line 779) | func (*MetadataEntry) Descriptor() ([]byte, []int) {
method GetKey (line 783) | func (x *MetadataEntry) GetKey() string {
method GetValue (line 790) | func (x *MetadataEntry) GetValue() []byte {
type Address (line 798) | type Address struct
method Reset (line 808) | func (x *Address) Reset() {
method String (line 815) | func (x *Address) String() string {
method ProtoMessage (line 819) | func (*Address) ProtoMessage() {}
method ProtoReflect (line 821) | func (x *Address) ProtoReflect() protoreflect.Message {
method Descriptor (line 834) | func (*Address) Descriptor() ([]byte, []int) {
method GetType (line 838) | func (x *Address) GetType() Address_Type {
method GetAddress (line 845) | func (x *Address) GetAddress() string {
method GetIpPort (line 852) | func (x *Address) GetIpPort() uint32 {
constant file_grpc_binlog_v1_binarylog_proto_rawDesc (line 861) | file_grpc_binlog_v1_binarylog_proto_rawDesc = "" +
function file_grpc_binlog_v1_binarylog_proto_rawDescGZIP (line 929) | func file_grpc_binlog_v1_binarylog_proto_rawDescGZIP() []byte {
function init (line 975) | func init() { file_grpc_binlog_v1_binarylog_proto_init() }
function file_grpc_binlog_v1_binarylog_proto_init (line 976) | func file_grpc_binlog_v1_binarylog_proto_init() {
FILE: binarylog/sink.go
function SetSink (line 37) | func SetSink(s Sink) {
type Sink (line 45) | type Sink interface
function NewTempFileSink (line 59) | func NewTempFileSink() (Sink, error) {
FILE: call.go
method Invoke (line 29) | func (cc *ClientConn) Invoke(ctx context.Context, method string, args, r...
function combine (line 40) | func combine(o1 []CallOption, o2 []CallOption) []CallOption {
function Invoke (line 59) | func Invoke(ctx context.Context, method string, args, reply any, cc *Cli...
function invoke (line 65) | func invoke(ctx context.Context, method string, req, reply any, cc *Clie...
FILE: channelz/grpc_channelz_v1/channelz.pb.go
constant _ (line 44) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
constant _ (line 46) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
type ChannelConnectivityState_State (line 49) | type ChannelConnectivityState_State
method Enum (line 80) | func (x ChannelConnectivityState_State) Enum() *ChannelConnectivitySta...
method String (line 86) | func (x ChannelConnectivityState_State) String() string {
method Descriptor (line 90) | func (ChannelConnectivityState_State) Descriptor() protoreflect.EnumDe...
method Type (line 94) | func (ChannelConnectivityState_State) Type() protoreflect.EnumType {
method Number (line 98) | func (x ChannelConnectivityState_State) Number() protoreflect.EnumNumb...
method EnumDescriptor (line 103) | func (ChannelConnectivityState_State) EnumDescriptor() ([]byte, []int) {
constant ChannelConnectivityState_UNKNOWN (line 52) | ChannelConnectivityState_UNKNOWN ChannelConnectivityState_Stat...
constant ChannelConnectivityState_IDLE (line 53) | ChannelConnectivityState_IDLE ChannelConnectivityState_Stat...
constant ChannelConnectivityState_CONNECTING (line 54) | ChannelConnectivityState_CONNECTING ChannelConnectivityState_Stat...
constant ChannelConnectivityState_READY (line 55) | ChannelConnectivityState_READY ChannelConnectivityState_Stat...
constant ChannelConnectivityState_TRANSIENT_FAILURE (line 56) | ChannelConnectivityState_TRANSIENT_FAILURE ChannelConnectivityState_Stat...
constant ChannelConnectivityState_SHUTDOWN (line 57) | ChannelConnectivityState_SHUTDOWN ChannelConnectivityState_Stat...
type ChannelTraceEvent_Severity (line 108) | type ChannelTraceEvent_Severity
method Enum (line 133) | func (x ChannelTraceEvent_Severity) Enum() *ChannelTraceEvent_Severity {
method String (line 139) | func (x ChannelTraceEvent_Severity) String() string {
method Descriptor (line 143) | func (ChannelTraceEvent_Severity) Descriptor() protoreflect.EnumDescri...
method Type (line 147) | func (ChannelTraceEvent_Severity) Type() protoreflect.EnumType {
method Number (line 151) | func (x ChannelTraceEvent_Severity) Number() protoreflect.EnumNumber {
method EnumDescriptor (line 156) | func (ChannelTraceEvent_Severity) EnumDescriptor() ([]byte, []int) {
constant ChannelTraceEvent_CT_UNKNOWN (line 111) | ChannelTraceEvent_CT_UNKNOWN ChannelTraceEvent_Severity = 0
constant ChannelTraceEvent_CT_INFO (line 112) | ChannelTraceEvent_CT_INFO ChannelTraceEvent_Severity = 1
constant ChannelTraceEvent_CT_WARNING (line 113) | ChannelTraceEvent_CT_WARNING ChannelTraceEvent_Severity = 2
constant ChannelTraceEvent_CT_ERROR (line 114) | ChannelTraceEvent_CT_ERROR ChannelTraceEvent_Severity = 3
type Channel (line 161) | type Channel struct
method Reset (line 182) | func (x *Channel) Reset() {
method String (line 189) | func (x *Channel) String() string {
method ProtoMessage (line 193) | func (*Channel) ProtoMessage() {}
method ProtoReflect (line 195) | func (x *Channel) ProtoReflect() protoreflect.Message {
method Descriptor (line 208) | func (*Channel) Descriptor() ([]byte, []int) {
method GetRef (line 212) | func (x *Channel) GetRef() *ChannelRef {
method GetData (line 219) | func (x *Channel) GetData() *ChannelData {
method GetChannelRef (line 226) | func (x *Channel) GetChannelRef() []*ChannelRef {
method GetSubchannelRef (line 233) | func (x *Channel) GetSubchannelRef() []*SubchannelRef {
method GetSocketRef (line 240) | func (x *Channel) GetSocketRef() []*SocketRef {
type Subchannel (line 249) | type Subchannel struct
method Reset (line 270) | func (x *Subchannel) Reset() {
method String (line 277) | func (x *Subchannel) String() string {
method ProtoMessage (line 281) | func (*Subchannel) ProtoMessage() {}
method ProtoReflect (line 283) | func (x *Subchannel) ProtoReflect() protoreflect.Message {
method Descriptor (line 296) | func (*Subchannel) Descriptor() ([]byte, []int) {
method GetRef (line 300) | func (x *Subchannel) GetRef() *SubchannelRef {
method GetData (line 307) | func (x *Subchannel) GetData() *ChannelData {
method GetChannelRef (line 314) | func (x *Subchannel) GetChannelRef() []*ChannelRef {
method GetSubchannelRef (line 321) | func (x *Subchannel) GetSubchannelRef() []*SubchannelRef {
method GetSocketRef (line 328) | func (x *Subchannel) GetSocketRef() []*SocketRef {
type ChannelConnectivityState (line 337) | type ChannelConnectivityState struct
method Reset (line 344) | func (x *ChannelConnectivityState) Reset() {
method String (line 351) | func (x *ChannelConnectivityState) String() string {
method ProtoMessage (line 355) | func (*ChannelConnectivityState) ProtoMessage() {}
method ProtoReflect (line 357) | func (x *ChannelConnectivityState) ProtoReflect() protoreflect.Message {
method Descriptor (line 370) | func (*ChannelConnectivityState) Descriptor() ([]byte, []int) {
method GetState (line 374) | func (x *ChannelConnectivityState) GetState() ChannelConnectivityState...
type ChannelData (line 382) | type ChannelData struct
method Reset (line 405) | func (x *ChannelData) Reset() {
method String (line 412) | func (x *ChannelData) String() string {
method ProtoMessage (line 416) | func (*ChannelData) ProtoMessage() {}
method ProtoReflect (line 418) | func (x *ChannelData) ProtoReflect() protoreflect.Message {
method Descriptor (line 431) | func (*ChannelData) Descriptor() ([]byte, []int) {
method GetState (line 435) | func (x *ChannelData) GetState() *ChannelConnectivityState {
method GetTarget (line 442) | func (x *ChannelData) GetTarget() string {
method GetTrace (line 449) | func (x *ChannelData) GetTrace() *ChannelTrace {
method GetCallsStarted (line 456) | func (x *ChannelData) GetCallsStarted() int64 {
method GetCallsSucceeded (line 463) | func (x *ChannelData) GetCallsSucceeded() int64 {
method GetCallsFailed (line 470) | func (x *ChannelData) GetCallsFailed() int64 {
method GetLastCallStartedTimestamp (line 477) | func (x *ChannelData) GetLastCallStartedTimestamp() *timestamppb.Times...
method GetMaxConnectionsPerSubchannel (line 484) | func (x *ChannelData) GetMaxConnectionsPerSubchannel() uint32 {
type ChannelTraceEvent (line 493) | type ChannelTraceEvent struct
method Reset (line 515) | func (x *ChannelTraceEvent) Reset() {
method String (line 522) | func (x *ChannelTraceEvent) String() string {
method ProtoMessage (line 526) | func (*ChannelTraceEvent) ProtoMessage() {}
method ProtoReflect (line 528) | func (x *ChannelTraceEvent) ProtoReflect() protoreflect.Message {
method Descriptor (line 541) | func (*ChannelTraceEvent) Descriptor() ([]byte, []int) {
method GetDescription (line 545) | func (x *ChannelTraceEvent) GetDescription() string {
method GetSeverity (line 552) | func (x *ChannelTraceEvent) GetSeverity() ChannelTraceEvent_Severity {
method GetTimestamp (line 559) | func (x *ChannelTraceEvent) GetTimestamp() *timestamppb.Timestamp {
method GetChildRef (line 566) | func (x *ChannelTraceEvent) GetChildRef() isChannelTraceEvent_ChildRef {
method GetChannelRef (line 573) | func (x *ChannelTraceEvent) GetChannelRef() *ChannelRef {
method GetSubchannelRef (line 582) | func (x *ChannelTraceEvent) GetSubchannelRef() *SubchannelRef {
type isChannelTraceEvent_ChildRef (line 591) | type isChannelTraceEvent_ChildRef interface
type ChannelTraceEvent_ChannelRef (line 595) | type ChannelTraceEvent_ChannelRef struct
method isChannelTraceEvent_ChildRef (line 603) | func (*ChannelTraceEvent_ChannelRef) isChannelTraceEvent_ChildRef() {}
type ChannelTraceEvent_SubchannelRef (line 599) | type ChannelTraceEvent_SubchannelRef struct
method isChannelTraceEvent_ChildRef (line 605) | func (*ChannelTraceEvent_SubchannelRef) isChannelTraceEvent_ChildRef() {}
type ChannelTrace (line 608) | type ChannelTrace struct
method Reset (line 622) | func (x *ChannelTrace) Reset() {
method String (line 629) | func (x *ChannelTrace) String() string {
method ProtoMessage (line 633) | func (*ChannelTrace) ProtoMessage() {}
method ProtoReflect (line 635) | func (x *ChannelTrace) ProtoReflect() protoreflect.Message {
method Descriptor (line 648) | func (*ChannelTrace) Descriptor() ([]byte, []int) {
method GetNumEventsLogged (line 652) | func (x *ChannelTrace) GetNumEventsLogged() int64 {
method GetCreationTimestamp (line 659) | func (x *ChannelTrace) GetCreationTimestamp() *timestamppb.Timestamp {
method GetEvents (line 666) | func (x *ChannelTrace) GetEvents() []*ChannelTraceEvent {
type ChannelRef (line 674) | type ChannelRef struct
method Reset (line 684) | func (x *ChannelRef) Reset() {
method String (line 691) | func (x *ChannelRef) String() string {
method ProtoMessage (line 695) | func (*ChannelRef) ProtoMessage() {}
method ProtoReflect (line 697) | func (x *ChannelRef) ProtoReflect() protoreflect.Message {
method Descriptor (line 710) | func (*ChannelRef) Descriptor() ([]byte, []int) {
method GetChannelId (line 714) | func (x *ChannelRef) GetChannelId() int64 {
method GetName (line 721) | func (x *ChannelRef) GetName() string {
type SubchannelRef (line 729) | type SubchannelRef struct
method Reset (line 739) | func (x *SubchannelRef) Reset() {
method String (line 746) | func (x *SubchannelRef) String() string {
method ProtoMessage (line 750) | func (*SubchannelRef) ProtoMessage() {}
method ProtoReflect (line 752) | func (x *SubchannelRef) ProtoReflect() protoreflect.Message {
method Descriptor (line 765) | func (*SubchannelRef) Descriptor() ([]byte, []int) {
method GetSubchannelId (line 769) | func (x *SubchannelRef) GetSubchannelId() int64 {
method GetName (line 776) | func (x *SubchannelRef) GetName() string {
type SocketRef (line 784) | type SocketRef struct
method Reset (line 794) | func (x *SocketRef) Reset() {
method String (line 801) | func (x *SocketRef) String() string {
method ProtoMessage (line 805) | func (*SocketRef) ProtoMessage() {}
method ProtoReflect (line 807) | func (x *SocketRef) ProtoReflect() protoreflect.Message {
method Descriptor (line 820) | func (*SocketRef) Descriptor() ([]byte, []int) {
method GetSocketId (line 824) | func (x *SocketRef) GetSocketId() int64 {
method GetName (line 831) | func (x *SocketRef) GetName() string {
type ServerRef (line 839) | type ServerRef struct
method Reset (line 849) | func (x *ServerRef) Reset() {
method String (line 856) | func (x *ServerRef) String() string {
method ProtoMessage (line 860) | func (*ServerRef) ProtoMessage() {}
method ProtoReflect (line 862) | func (x *ServerRef) ProtoReflect() protoreflect.Message {
method Descriptor (line 875) | func (*ServerRef) Descriptor() ([]byte, []int) {
method GetServerId (line 879) | func (x *ServerRef) GetServerId() int64 {
method GetName (line 886) | func (x *ServerRef) GetName() string {
type Server (line 895) | type Server struct
method Reset (line 908) | func (x *Server) Reset() {
method String (line 915) | func (x *Server) String() string {
method ProtoMessage (line 919) | func (*Server) ProtoMessage() {}
method ProtoReflect (line 921) | func (x *Server) ProtoReflect() protoreflect.Message {
method Descriptor (line 934) | func (*Server) Descriptor() ([]byte, []int) {
method GetRef (line 938) | func (x *Server) GetRef() *ServerRef {
method GetData (line 945) | func (x *Server) GetData() *ServerData {
method GetListenSocket (line 952) | func (x *Server) GetListenSocket() []*SocketRef {
type ServerData (line 960) | type ServerData struct
method Reset (line 976) | func (x *ServerData) Reset() {
method String (line 983) | func (x *ServerData) String() string {
method ProtoMessage (line 987) | func (*ServerData) ProtoMessage() {}
method ProtoReflect (line 989) | func (x *ServerData) ProtoReflect() protoreflect.Message {
method Descriptor (line 1002) | func (*ServerData) Descriptor() ([]byte, []int) {
method GetTrace (line 1006) | func (x *ServerData) GetTrace() *ChannelTrace {
method GetCallsStarted (line 1013) | func (x *ServerData) GetCallsStarted() int64 {
method GetCallsSucceeded (line 1020) | func (x *ServerData) GetCallsSucceeded() int64 {
method GetCallsFailed (line 1027) | func (x *ServerData) GetCallsFailed() int64 {
method GetLastCallStartedTimestamp (line 1034) | func (x *ServerData) GetLastCallStartedTimestamp() *timestamppb.Timest...
type Socket (line 1042) | type Socket struct
method Reset (line 1062) | func (x *Socket) Reset() {
method String (line 1069) | func (x *Socket) String() string {
method ProtoMessage (line 1073) | func (*Socket) ProtoMessage() {}
method ProtoReflect (line 1075) | func (x *Socket) ProtoReflect() protoreflect.Message {
method Descriptor (line 1088) | func (*Socket) Descriptor() ([]byte, []int) {
method GetRef (line 1092) | func (x *Socket) GetRef() *SocketRef {
method GetData (line 1099) | func (x *Socket) GetData() *SocketData {
method GetLocal (line 1106) | func (x *Socket) GetLocal() *Address {
method GetRemote (line 1113) | func (x *Socket) GetRemote() *Address {
method GetSecurity (line 1120) | func (x *Socket) GetSecurity() *Security {
method GetRemoteName (line 1127) | func (x *Socket) GetRemoteName() string {
type SocketData (line 1137) | type SocketData struct
method Reset (line 1187) | func (x *SocketData) Reset() {
method String (line 1194) | func (x *SocketData) String() string {
method ProtoMessage (line 1198) | func (*SocketData) ProtoMessage() {}
method ProtoReflect (line 1200) | func (x *SocketData) ProtoReflect() protoreflect.Message {
method Descriptor (line 1213) | func (*SocketData) Descriptor() ([]byte, []int) {
method GetStreamsStarted (line 1217) | func (x *SocketData) GetStreamsStarted() int64 {
method GetStreamsSucceeded (line 1224) | func (x *SocketData) GetStreamsSucceeded() int64 {
method GetStreamsFailed (line 1231) | func (x *SocketData) GetStreamsFailed() int64 {
method GetMessagesSent (line 1238) | func (x *SocketData) GetMessagesSent() int64 {
method GetMessagesReceived (line 1245) | func (x *SocketData) GetMessagesReceived() int64 {
method GetKeepAlivesSent (line 1252) | func (x *SocketData) GetKeepAlivesSent() int64 {
method GetLastLocalStreamCreatedTimestamp (line 1259) | func (x *SocketData) GetLastLocalStreamCreatedTimestamp() *timestamppb...
method GetLastRemoteStreamCreatedTimestamp (line 1266) | func (x *SocketData) GetLastRemoteStreamCreatedTimestamp() *timestampp...
method GetLastMessageSentTimestamp (line 1273) | func (x *SocketData) GetLastMessageSentTimestamp() *timestamppb.Timest...
method GetLastMessageReceivedTimestamp (line 1280) | func (x *SocketData) GetLastMessageReceivedTimestamp() *timestamppb.Ti...
method GetLocalFlowControlWindow (line 1287) | func (x *SocketData) GetLocalFlowControlWindow() *wrapperspb.Int64Value {
method GetRemoteFlowControlWindow (line 1294) | func (x *SocketData) GetRemoteFlowControlWindow() *wrapperspb.Int64Val...
method GetOption (line 1301) | func (x *SocketData) GetOption() []*SocketOption {
method GetReceivedGoawayError (line 1308) | func (x *SocketData) GetReceivedGoawayError() *wrapperspb.UInt32Value {
method GetPeerMaxConcurrentStreams (line 1315) | func (x *SocketData) GetPeerMaxConcurrentStreams() uint32 {
type Address (line 1323) | type Address struct
method Reset (line 1335) | func (x *Address) Reset() {
method String (line 1342) | func (x *Address) String() string {
method ProtoMessage (line 1346) | func (*Address) ProtoMessage() {}
method ProtoReflect (line 1348) | func (x *Address) ProtoReflect() protoreflect.Message {
method Descriptor (line 1361) | func (*Address) Descriptor() ([]byte, []int) {
method GetAddress (line 1365) | func (x *Address) GetAddress() isAddress_Address {
method GetTcpipAddress (line 1372) | func (x *Address) GetTcpipAddress() *Address_TcpIpAddress {
method GetUdsAddress (line 1381) | func (x *Address) GetUdsAddress() *Address_UdsAddress {
method GetOtherAddress (line 1390) | func (x *Address) GetOtherAddress() *Address_OtherAddress {
type isAddress_Address (line 1399) | type isAddress_Address interface
type Address_TcpipAddress (line 1403) | type Address_TcpipAddress struct
method isAddress_Address (line 1415) | func (*Address_TcpipAddress) isAddress_Address() {}
type Address_UdsAddress_ (line 1407) | type Address_UdsAddress_ struct
method isAddress_Address (line 1417) | func (*Address_UdsAddress_) isAddress_Address() {}
type Address_OtherAddress_ (line 1411) | type Address_OtherAddress_ struct
method isAddress_Address (line 1419) | func (*Address_OtherAddress_) isAddress_Address() {}
type Security (line 1422) | type Security struct
method Reset (line 1433) | func (x *Security) Reset() {
method String (line 1440) | func (x *Security) String() string {
method ProtoMessage (line 1444) | func (*Security) ProtoMessage() {}
method ProtoReflect (line 1446) | func (x *Security) ProtoReflect() protoreflect.Message {
method Descriptor (line 1459) | func (*Security) Descriptor() ([]byte, []int) {
method GetModel (line 1463) | func (x *Security) GetModel() isSecurity_Model {
method GetTls (line 1470) | func (x *Security) GetTls() *Security_Tls {
method GetOther (line 1479) | func (x *Security) GetOther() *Security_OtherSecurity {
type isSecurity_Model (line 1488) | type isSecurity_Model interface
type Security_Tls_ (line 1492) | type Security_Tls_ struct
method isSecurity_Model (line 1500) | func (*Security_Tls_) isSecurity_Model() {}
type Security_Other (line 1496) | type Security_Other struct
method isSecurity_Model (line 1502) | func (*Security_Other) isSecurity_Model() {}
type SocketOption (line 1506) | type SocketOption struct
method Reset (line 1521) | func (x *SocketOption) Reset() {
method String (line 1528) | func (x *SocketOption) String() string {
method ProtoMessage (line 1532) | func (*SocketOption) ProtoMessage() {}
method ProtoReflect (line 1534) | func (x *SocketOption) ProtoReflect() protoreflect.Message {
method Descriptor (line 1547) | func (*SocketOption) Descriptor() ([]byte, []int) {
method GetName (line 1551) | func (x *SocketOption) GetName() string {
method GetValue (line 1558) | func (x *SocketOption) GetValue() string {
method GetAdditional (line 1565) | func (x *SocketOption) GetAdditional() *anypb.Any {
type SocketOptionTimeout (line 1574) | type SocketOptionTimeout struct
method Reset (line 1581) | func (x *SocketOptionTimeout) Reset() {
method String (line 1588) | func (x *SocketOptionTimeout) String() string {
method ProtoMessage (line 1592) | func (*SocketOptionTimeout) ProtoMessage() {}
method ProtoReflect (line 1594) | func (x *SocketOptionTimeout) ProtoReflect() protoreflect.Message {
method Descriptor (line 1607) | func (*SocketOptionTimeout) Descriptor() ([]byte, []int) {
method GetDuration (line 1611) | func (x *SocketOptionTimeout) GetDuration() *durationpb.Duration {
type SocketOptionLinger (line 1620) | type SocketOptionLinger struct
method Reset (line 1630) | func (x *SocketOptionLinger) Reset() {
method String (line 1637) | func (x *SocketOptionLinger) String() string {
method ProtoMessage (line 1641) | func (*SocketOptionLinger) ProtoMessage() {}
method ProtoReflect (line 1643) | func (x *SocketOptionLinger) ProtoReflect() protoreflect.Message {
method Descriptor (line 1656) | func (*SocketOptionLinger) Descriptor() ([]byte, []int) {
method GetActive (line 1660) | func (x *SocketOptionLinger) GetActive() bool {
method GetDuration (line 1667) | func (x *SocketOptionLinger) GetDuration() *durationpb.Duration {
type SocketOptionTcpInfo (line 1676) | type SocketOptionTcpInfo struct
method Reset (line 1711) | func (x *SocketOptionTcpInfo) Reset() {
method String (line 1718) | func (x *SocketOptionTcpInfo) String() string {
method ProtoMessage (line 1722) | func (*SocketOptionTcpInfo) ProtoMessage() {}
method ProtoReflect (line 1724) | func (x *SocketOptionTcpInfo) ProtoReflect() protoreflect.Message {
method Descriptor (line 1737) | func (*SocketOptionTcpInfo) Descriptor() ([]byte, []int) {
method GetTcpiState (line 1741) | func (x *SocketOptionTcpInfo) GetTcpiState() uint32 {
method GetTcpiCaState (line 1748) | func (x *SocketOptionTcpInfo) GetTcpiCaState() uint32 {
method GetTcpiRetransmits (line 1755) | func (x *SocketOptionTcpInfo) GetTcpiRetransmits() uint32 {
method GetTcpiProbes (line 1762) | func (x *SocketOptionTcpInfo) GetTcpiProbes() uint32 {
method GetTcpiBackoff (line 1769) | func (x *SocketOptionTcpInfo) GetTcpiBackoff() uint32 {
method GetTcpiOptions (line 1776) | func (x *SocketOptionTcpInfo) GetTcpiOptions() uint32 {
method GetTcpiSndWscale (line 1783) | func (x *SocketOptionTcpInfo) GetTcpiSndWscale() uint32 {
method GetTcpiRcvWscale (line 1790) | func (x *SocketOptionTcpInfo) GetTcpiRcvWscale() uint32 {
method GetTcpiRto (line 1797) | func (x *SocketOptionTcpInfo) GetTcpiRto() uint32 {
method GetTcpiAto (line 1804) | func (x *SocketOptionTcpInfo) GetTcpiAto() uint32 {
method GetTcpiSndMss (line 1811) | func (x *SocketOptionTcpInfo) GetTcpiSndMss() uint32 {
method GetTcpiRcvMss (line 1818) | func (x *SocketOptionTcpInfo) GetTcpiRcvMss() uint32 {
method GetTcpiUnacked (line 1825) | func (x *SocketOptionTcpInfo) GetTcpiUnacked() uint32 {
method GetTcpiSacked (line 1832) | func (x *SocketOptionTcpInfo) GetTcpiSacked() uint32 {
method GetTcpiLost (line 1839) | func (x *SocketOptionTcpInfo) GetTcpiLost() uint32 {
method GetTcpiRetrans (line 1846) | func (x *SocketOptionTcpInfo) GetTcpiRetrans() uint32 {
method GetTcpiFackets (line 1853) | func (x *SocketOptionTcpInfo) GetTcpiFackets() uint32 {
method GetTcpiLastDataSent (line 1860) | func (x *SocketOptionTcpInfo) GetTcpiLastDataSent() uint32 {
method GetTcpiLastAckSent (line 1867) | func (x *SocketOptionTcpInfo) GetTcpiLastAckSent() uint32 {
method GetTcpiLastDataRecv (line 1874) | func (x *SocketOptionTcpInfo) GetTcpiLastDataRecv() uint32 {
method GetTcpiLastAckRecv (line 1881) | func (x *SocketOptionTcpInfo) GetTcpiLastAckRecv() uint32 {
method GetTcpiPmtu (line 1888) | func (x *SocketOptionTcpInfo) GetTcpiPmtu() uint32 {
method GetTcpiRcvSsthresh (line 1895) | func (x *SocketOptionTcpInfo) GetTcpiRcvSsthresh() uint32 {
method GetTcpiRtt (line 1902) | func (x *SocketOptionTcpInfo) GetTcpiRtt() uint32 {
method GetTcpiRttvar (line 1909) | func (x *SocketOptionTcpInfo) GetTcpiRttvar() uint32 {
method GetTcpiSndSsthresh (line 1916) | func (x *SocketOptionTcpInfo) GetTcpiSndSsthresh() uint32 {
method GetTcpiSndCwnd (line 1923) | func (x *SocketOptionTcpInfo) GetTcpiSndCwnd() uint32 {
method GetTcpiAdvmss (line 1930) | func (x *SocketOptionTcpInfo) GetTcpiAdvmss() uint32 {
method GetTcpiReordering (line 1937) | func (x *SocketOptionTcpInfo) GetTcpiReordering() uint32 {
type GetTopChannelsRequest (line 1944) | type GetTopChannelsRequest struct
method Reset (line 1960) | func (x *GetTopChannelsRequest) Reset() {
method String (line 1967) | func (x *GetTopChannelsRequest) String() string {
method ProtoMessage (line 1971) | func (*GetTopChannelsRequest) ProtoMessage() {}
method ProtoReflect (line 1973) | func (x *GetTopChannelsRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 1986) | func (*GetTopChannelsRequest) Descriptor() ([]byte, []int) {
method GetStartChannelId (line 1990) | func (x *GetTopChannelsRequest) GetStartChannelId() int64 {
method GetMaxResults (line 1997) | func (x *GetTopChannelsRequest) GetMaxResults() int64 {
type GetTopChannelsResponse (line 2004) | type GetTopChannelsResponse struct
method Reset (line 2018) | func (x *GetTopChannelsResponse) Reset() {
method String (line 2025) | func (x *GetTopChannelsResponse) String() string {
method ProtoMessage (line 2029) | func (*GetTopChannelsResponse) ProtoMessage() {}
method ProtoReflect (line 2031) | func (x *GetTopChannelsResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 2044) | func (*GetTopChannelsResponse) Descriptor() ([]byte, []int) {
method GetChannel (line 2048) | func (x *GetTopChannelsResponse) GetChannel() []*Channel {
method GetEnd (line 2055) | func (x *GetTopChannelsResponse) GetEnd() bool {
type GetServersRequest (line 2062) | type GetServersRequest struct
method Reset (line 2078) | func (x *GetServersRequest) Reset() {
method String (line 2085) | func (x *GetServersRequest) String() string {
method ProtoMessage (line 2089) | func (*GetServersRequest) ProtoMessage() {}
method ProtoReflect (line 2091) | func (x *GetServersRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 2104) | func (*GetServersRequest) Descriptor() ([]byte, []int) {
method GetStartServerId (line 2108) | func (x *GetServersRequest) GetStartServerId() int64 {
method GetMaxResults (line 2115) | func (x *GetServersRequest) GetMaxResults() int64 {
type GetServersResponse (line 2122) | type GetServersResponse struct
method Reset (line 2136) | func (x *GetServersResponse) Reset() {
method String (line 2143) | func (x *GetServersResponse) String() string {
method ProtoMessage (line 2147) | func (*GetServersResponse) ProtoMessage() {}
method ProtoReflect (line 2149) | func (x *GetServersResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 2162) | func (*GetServersResponse) Descriptor() ([]byte, []int) {
method GetServer (line 2166) | func (x *GetServersResponse) GetServer() []*Server {
method GetEnd (line 2173) | func (x *GetServersResponse) GetEnd() bool {
type GetServerRequest (line 2180) | type GetServerRequest struct
method Reset (line 2188) | func (x *GetServerRequest) Reset() {
method String (line 2195) | func (x *GetServerRequest) String() string {
method ProtoMessage (line 2199) | func (*GetServerRequest) ProtoMessage() {}
method ProtoReflect (line 2201) | func (x *GetServerRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 2214) | func (*GetServerRequest) Descriptor() ([]byte, []int) {
method GetServerId (line 2218) | func (x *GetServerRequest) GetServerId() int64 {
type GetServerResponse (line 2225) | type GetServerResponse struct
method Reset (line 2234) | func (x *GetServerResponse) Reset() {
method String (line 2241) | func (x *GetServerResponse) String() string {
method ProtoMessage (line 2245) | func (*GetServerResponse) ProtoMessage() {}
method ProtoReflect (line 2247) | func (x *GetServerResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 2260) | func (*GetServerResponse) Descriptor() ([]byte, []int) {
method GetServer (line 2264) | func (x *GetServerResponse) GetServer() *Server {
type GetServerSocketsRequest (line 2271) | type GetServerSocketsRequest struct
method Reset (line 2288) | func (x *GetServerSocketsRequest) Reset() {
method String (line 2295) | func (x *GetServerSocketsRequest) String() string {
method ProtoMessage (line 2299) | func (*GetServerSocketsRequest) ProtoMessage() {}
method ProtoReflect (line 2301) | func (x *GetServerSocketsRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 2314) | func (*GetServerSocketsRequest) Descriptor() ([]byte, []int) {
method GetServerId (line 2318) | func (x *GetServerSocketsRequest) GetServerId() int64 {
method GetStartSocketId (line 2325) | func (x *GetServerSocketsRequest) GetStartSocketId() int64 {
method GetMaxResults (line 2332) | func (x *GetServerSocketsRequest) GetMaxResults() int64 {
type GetServerSocketsResponse (line 2339) | type GetServerSocketsResponse struct
method Reset (line 2353) | func (x *GetServerSocketsResponse) Reset() {
method String (line 2360) | func (x *GetServerSocketsResponse) String() string {
method ProtoMessage (line 2364) | func (*GetServerSocketsResponse) ProtoMessage() {}
method ProtoReflect (line 2366) | func (x *GetServerSocketsResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 2379) | func (*GetServerSocketsResponse) Descriptor() ([]byte, []int) {
method GetSocketRef (line 2383) | func (x *GetServerSocketsResponse) GetSocketRef() []*SocketRef {
method GetEnd (line 2390) | func (x *GetServerSocketsResponse) GetEnd() bool {
type GetChannelRequest (line 2397) | type GetChannelRequest struct
method Reset (line 2405) | func (x *GetChannelRequest) Reset() {
method String (line 2412) | func (x *GetChannelRequest) String() string {
method ProtoMessage (line 2416) | func (*GetChannelRequest) ProtoMessage() {}
method ProtoReflect (line 2418) | func (x *GetChannelRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 2431) | func (*GetChannelRequest) Descriptor() ([]byte, []int) {
method GetChannelId (line 2435) | func (x *GetChannelRequest) GetChannelId() int64 {
type GetChannelResponse (line 2442) | type GetChannelResponse struct
method Reset (line 2451) | func (x *GetChannelResponse) Reset() {
method String (line 2458) | func (x *GetChannelResponse) String() string {
method ProtoMessage (line 2462) | func (*GetChannelResponse) ProtoMessage() {}
method ProtoReflect (line 2464) | func (x *GetChannelResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 2477) | func (*GetChannelResponse) Descriptor() ([]byte, []int) {
method GetChannel (line 2481) | func (x *GetChannelResponse) GetChannel() *Channel {
type GetSubchannelRequest (line 2488) | type GetSubchannelRequest struct
method Reset (line 2496) | func (x *GetSubchannelRequest) Reset() {
method String (line 2503) | func (x *GetSubchannelRequest) String() string {
method ProtoMessage (line 2507) | func (*GetSubchannelRequest) ProtoMessage() {}
method ProtoReflect (line 2509) | func (x *GetSubchannelRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 2522) | func (*GetSubchannelRequest) Descriptor() ([]byte, []int) {
method GetSubchannelId (line 2526) | func (x *GetSubchannelRequest) GetSubchannelId() int64 {
type GetSubchannelResponse (line 2533) | type GetSubchannelResponse struct
method Reset (line 2542) | func (x *GetSubchannelResponse) Reset() {
method String (line 2549) | func (x *GetSubchannelResponse) String() string {
method ProtoMessage (line 2553) | func (*GetSubchannelResponse) ProtoMessage() {}
method ProtoReflect (line 2555) | func (x *GetSubchannelResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 2568) | func (*GetSubchannelResponse) Descriptor() ([]byte, []int) {
method GetSubchannel (line 2572) | func (x *GetSubchannelResponse) GetSubchannel() *Subchannel {
type GetSocketRequest (line 2579) | type GetSocketRequest struct
method Reset (line 2591) | func (x *GetSocketRequest) Reset() {
method String (line 2598) | func (x *GetSocketRequest) String() string {
method ProtoMessage (line 2602) | func (*GetSocketRequest) ProtoMessage() {}
method ProtoReflect (line 2604) | func (x *GetSocketRequest) ProtoReflect() protoreflect.Message {
method Descriptor (line 2617) | func (*GetSocketRequest) Descriptor() ([]byte, []int) {
method GetSocketId (line 2621) | func (x *GetSocketRequest) GetSocketId() int64 {
method GetSummary (line 2628) | func (x *GetSocketRequest) GetSummary() bool {
type GetSocketResponse (line 2635) | type GetSocketResponse struct
method Reset (line 2644) | func (x *GetSocketResponse) Reset() {
method String (line 2651) | func (x *GetSocketResponse) String() string {
method ProtoMessage (line 2655) | func (*GetSocketResponse) ProtoMessage() {}
method ProtoReflect (line 2657) | func (x *GetSocketResponse) ProtoReflect() protoreflect.Message {
method Descriptor (line 2670) | func (*GetSocketResponse) Descriptor() ([]byte, []int) {
method GetSocket (line 2674) | func (x *GetSocketResponse) GetSocket() *Socket {
type Address_TcpIpAddress (line 2681) | type Address_TcpIpAddress struct
method Reset (line 2692) | func (x *Address_TcpIpAddress) Reset() {
method String (line 2699) | func (x *Address_TcpIpAddress) String() string {
me
Copy disabled (too large)
Download .json
Condensed preview — 1307 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (14,142K chars).
[
{
"path": ".gemini/config.yaml",
"chars": 269,
"preview": "have_fun: false\nmemory_config:\n disabled: false\ncode_review:\n disable: false\n comment_severity_threshold: MEDIUM\n ma"
},
{
"path": ".github/ISSUE_TEMPLATE/bug.md",
"chars": 800,
"preview": "---\nname: Bug Report\nabout: Report a non-security bug. For suspected security vulnerabilities or crashes, please use \"R"
},
{
"path": ".github/ISSUE_TEMPLATE/feature.md",
"chars": 295,
"preview": "---\nname: Feature Request\nabout: Suggest an idea for gRPC-Go\nlabels: 'Type: Feature'\n\n---\n\nPlease see the FAQ in our mai"
},
{
"path": ".github/ISSUE_TEMPLATE/question.md",
"chars": 157,
"preview": "---\nname: Question\nabout: Ask a question about gRPC-Go\nlabels: 'Type: Question'\n\n---\n\nPlease see the FAQ in our main REA"
},
{
"path": ".github/codecov.yml",
"chars": 424,
"preview": "coverage:\n status:\n project:\n default:\n informational: true\n patch:\n default:\n informatio"
},
{
"path": ".github/pull_request_template.md",
"chars": 225,
"preview": "Thank you for your PR. Please read and follow\nhttps://github.com/grpc/grpc-go/blob/master/CONTRIBUTING.md, especially th"
},
{
"path": ".github/workflows/codeql-analysis.yml",
"chars": 652,
"preview": "name: \"CodeQL\"\n\non:\n push:\n branches: [ master ]\n schedule:\n - cron: '24 20 * * 3'\n\npermissions:\n contents: rea"
},
{
"path": ".github/workflows/coverage.yml",
"chars": 574,
"preview": "name: codecov\non: [push, pull_request]\n\npermissions:\n contents: read\n\njobs:\n upload:\n runs-on: ubuntu-latest\n st"
},
{
"path": ".github/workflows/deps.yml",
"chars": 1658,
"preview": "name: Dependency Changes\n\n# Trigger on PRs.\non:\n pull_request:\n\npermissions:\n contents: read\n\njobs:\n # Compare depend"
},
{
"path": ".github/workflows/lock.yml",
"chars": 395,
"preview": "name: 'Lock Threads'\n\non:\n workflow_dispatch:\n schedule:\n - cron: '22 1 * * *'\n\npermissions:\n contents: read\n\njobs"
},
{
"path": ".github/workflows/pr-validation.yml",
"chars": 2053,
"preview": "name: PR Validation\non:\n pull_request:\n types: [opened, edited, synchronize, labeled, unlabeled, milestoned, demiles"
},
{
"path": ".github/workflows/release.yml",
"chars": 1625,
"preview": "name: Release\n\non:\n release:\n types: [published]\n\npermissions:\n contents: read\n\njobs:\n release:\n permissions:\n "
},
{
"path": ".github/workflows/stale.yml",
"chars": 1028,
"preview": "name: Stale bot\n\non:\n workflow_dispatch:\n schedule:\n - cron: \"44 */2 * * *\"\n\npermissions:\n contents: read\n\njobs:\n s"
},
{
"path": ".github/workflows/testing.yml",
"chars": 3867,
"preview": "name: Testing\n\n# Trigger on pushes, PRs (excluding documentation changes), and nightly.\non:\n push:\n pull_request:\n sc"
},
{
"path": "AUTHORS",
"chars": 12,
"preview": "Google Inc.\n"
},
{
"path": "CODE-OF-CONDUCT.md",
"chars": 138,
"preview": "## Community Code of Conduct\n\ngRPC follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/cod"
},
{
"path": "CONTRIBUTING.md",
"chars": 7086,
"preview": "# How to contribute\n\nWe welcome your patches and contributions to gRPC! Please read the gRPC\norganization's [governance\n"
},
{
"path": "Documentation/anti-patterns.md",
"chars": 7789,
"preview": "## Anti-Patterns of Client creation\n\n### How to properly create a `ClientConn`: `grpc.NewClient`\n\n[`grpc.NewClient`](htt"
},
{
"path": "Documentation/benchmark.md",
"chars": 2640,
"preview": "# Benchmark\n\ngRPC-Go comes with a set of benchmarking utilities to measure performance.\nThese utilities can be found in "
},
{
"path": "Documentation/compression.md",
"chars": 3567,
"preview": "# Compression\n\nThe preferred method for configuring message compression on both clients and\nservers is to use\n[`encoding"
},
{
"path": "Documentation/concurrency.md",
"chars": 2036,
"preview": "# Concurrency\n\nIn general, gRPC-go provides a concurrency-friendly API. What follows are some\nguidelines.\n\n## Clients\n\nA"
},
{
"path": "Documentation/encoding.md",
"chars": 5374,
"preview": "# Encoding\n\nThe gRPC API for sending and receiving is based upon *messages*. However,\nmessages cannot be transmitted di"
},
{
"path": "Documentation/grpc-auth-support.md",
"chars": 3220,
"preview": "# Authentication\n\nAs outlined in the\n[gRPC authentication guide](https://grpc.io/docs/guides/auth.html), there are a\nnum"
},
{
"path": "Documentation/grpc-metadata.md",
"chars": 7808,
"preview": "# Metadata\n\ngRPC supports sending metadata between client and server.\nThis doc shows how to send and receive metadata in"
},
{
"path": "Documentation/keepalive.md",
"chars": 2312,
"preview": "# Keepalive\n\ngRPC sends http2 pings on the transport to detect if the connection is down. If\nthe ping is not acknowledge"
},
{
"path": "Documentation/log_levels.md",
"chars": 1558,
"preview": "# Log Levels\n\nThis document describes the different log levels supported by the grpc-go\nlibrary, and under what conditio"
},
{
"path": "Documentation/proxy.md",
"chars": 1153,
"preview": "# Proxy\n\nHTTP CONNECT proxies are supported by default in gRPC. The proxy address can be\nspecified by the environment va"
},
{
"path": "Documentation/rpc-errors.md",
"chars": 2443,
"preview": "# RPC Errors\n\nAll service method handlers should return `nil` or errors from the\n`status.Status` type. Clients have dire"
},
{
"path": "Documentation/server-reflection-tutorial.md",
"chars": 4590,
"preview": "# gRPC Server Reflection Tutorial\n\ngRPC Server Reflection provides information about publicly-accessible gRPC\nservices o"
},
{
"path": "Documentation/versioning.md",
"chars": 1203,
"preview": "# Versioning and Releases\n\nNote: This document references terminology defined at http://semver.org.\n\n## Release Frequenc"
},
{
"path": "GOVERNANCE.md",
"chars": 141,
"preview": "This repository is governed by the gRPC organization's [governance rules](https://github.com/grpc/grpc-community/blob/ma"
},
{
"path": "LICENSE",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "MAINTAINERS.md",
"chars": 1572,
"preview": "This page lists all active maintainers of this repository. If you were a\nmaintainer and would like to add your name to t"
},
{
"path": "Makefile",
"chars": 953,
"preview": "all: vet test testrace\n\nbuild:\n\tgo build google.golang.org/grpc/...\n\nclean:\n\tgo clean -i google.golang.org/grpc/...\n\ndep"
},
{
"path": "NOTICE.txt",
"chars": 554,
"preview": "Copyright 2014 gRPC authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file "
},
{
"path": "README.md",
"chars": 3989,
"preview": "# gRPC-Go\n\n[][API]\n[;\n * you may n"
},
{
"path": "admin/admin_test.go",
"chars": 930,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "admin/test/admin_test.go",
"chars": 1089,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "admin/test/utils.go",
"chars": 3213,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "attributes/attributes.go",
"chars": 5134,
"preview": "/*\n *\n * Copyright 2019 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "attributes/attributes_test.go",
"chars": 5044,
"preview": "/*\n *\n * Copyright 2019 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "authz/audit/audit_logger.go",
"chars": 4672,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "authz/audit/audit_logging_test.go",
"chars": 10724,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "authz/audit/stdout/stdout_logger.go",
"chars": 3189,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "authz/audit/stdout/stdout_logger_test.go",
"chars": 4455,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "authz/grpc_authz_end2end_test.go",
"chars": 21043,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "authz/grpc_authz_server_interceptors.go",
"chars": 6326,
"preview": "/*\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not "
},
{
"path": "authz/grpc_authz_server_interceptors_test.go",
"chars": 3133,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "authz/rbac_translator.go",
"chars": 13047,
"preview": "/*\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not "
},
{
"path": "authz/rbac_translator_test.go",
"chars": 33510,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "backoff/backoff.go",
"chars": 1738,
"preview": "/*\n *\n * Copyright 2019 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "backoff.go",
"chars": 1996,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/balancer.go",
"chars": 16244,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/base/balancer.go",
"chars": 8524,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/base/balancer_test.go",
"chars": 3757,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/base/base.go",
"chars": 2373,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/conn_state_evaluator.go",
"chars": 2646,
"preview": "/*\n *\n * Copyright 2022 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/conn_state_evaluator_test.go",
"chars": 7968,
"preview": "/*\n *\n * Copyright 2022 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/endpointsharding/endpointsharding.go",
"chars": 12865,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/endpointsharding/endpointsharding_ext_test.go",
"chars": 13117,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/endpointsharding/endpointsharding_test.go",
"chars": 2018,
"preview": "/*\n *\n * Copyright 2025 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/grpclb/grpc_lb_v1/load_balancer.pb.go",
"chars": 27408,
"preview": "// Copyright 2015 The gRPC Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
},
{
"path": "balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go",
"chars": 5579,
"preview": "// Copyright 2015 The gRPC Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
},
{
"path": "balancer/grpclb/grpclb.go",
"chars": 17885,
"preview": "/*\n *\n * Copyright 2016 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/grpclb/grpclb_config.go",
"chars": 1684,
"preview": "/*\n *\n * Copyright 2019 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/grpclb/grpclb_config_test.go",
"chars": 2855,
"preview": "/*\n *\n * Copyright 2019 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/grpclb/grpclb_picker.go",
"chars": 5803,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/grpclb/grpclb_remote_balancer.go",
"chars": 13235,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/grpclb/grpclb_test.go",
"chars": 55559,
"preview": "/*\n *\n * Copyright 2016 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/grpclb/grpclb_util.go",
"chars": 4549,
"preview": "/*\n *\n * Copyright 2016 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/grpclb/grpclb_util_test.go",
"chars": 6626,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/grpclb/state/state.go",
"chars": 1679,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/lazy/lazy.go",
"chars": 4454,
"preview": "/*\n *\n * Copyright 2025 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/lazy/lazy_ext_test.go",
"chars": 15401,
"preview": "/*\n *\n * Copyright 2025 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/leastrequest/leastrequest.go",
"chars": 7743,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/leastrequest/leastrequest_test.go",
"chars": 25972,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/pickfirst/internal/internal.go",
"chars": 1152,
"preview": "/*\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not "
},
{
"path": "balancer/pickfirst/metrics_test.go",
"chars": 10947,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/pickfirst/pickfirst.go",
"chars": 34063,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/pickfirst/pickfirst_ext_test.go",
"chars": 109252,
"preview": "/*\n *\n * Copyright 2022 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/pickfirst/pickfirst_test.go",
"chars": 13051,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/pickfirst/pickfirstleaf/pickfirstleaf.go",
"chars": 1423,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/randomsubsetting/randomsubsetting.go",
"chars": 6029,
"preview": "/*\n *\n * Copyright 2025 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/randomsubsetting/randomsubsetting_test.go",
"chars": 7719,
"preview": "/*\n *\n * Copyright 2025 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/config.go",
"chars": 2611,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/config_test.go",
"chars": 5679,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/logging.go",
"chars": 956,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/picker.go",
"chars": 4324,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/picker_test.go",
"chars": 10128,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/ring.go",
"chars": 6728,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/ring_test.go",
"chars": 3330,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/ringhash.go",
"chars": 14077,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/ringhash_e2e_test.go",
"chars": 111469,
"preview": "/*\n *\n * Copyright 2022 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/ringhash/ringhash_test.go",
"chars": 28006,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/balancer.go",
"chars": 27094,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/balancer_test.go",
"chars": 55987,
"preview": "/*\n *\n * Copyright 2022 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/cache.go",
"chars": 12860,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/cache_test.go",
"chars": 8078,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/child_policy.go",
"chars": 4339,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/config.go",
"chars": 11767,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/config_test.go",
"chars": 17161,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/control_channel.go",
"chars": 9275,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/control_channel_test.go",
"chars": 15772,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/helpers_test.go",
"chars": 10426,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/internal/adaptive/adaptive.go",
"chars": 4845,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/internal/adaptive/adaptive_test.go",
"chars": 5375,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/internal/adaptive/lookback.go",
"chars": 2511,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/internal/adaptive/lookback_test.go",
"chars": 2040,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/internal/keys/builder.go",
"chars": 8373,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/internal/keys/builder_test.go",
"chars": 19166,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/internal/test/e2e/e2e.go",
"chars": 691,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/internal/test/e2e/rls_child_policy.go",
"chars": 4076,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/internal/test/e2e/rls_lb_config.go",
"chars": 3081,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/metrics_test.go",
"chars": 15127,
"preview": "/*\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not "
},
{
"path": "balancer/rls/picker.go",
"chars": 15628,
"preview": "/*\n *\n * Copyright 2022 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/rls/picker_test.go",
"chars": 41357,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/roundrobin/roundrobin.go",
"chars": 2164,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/subconn.go",
"chars": 5705,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedroundrobin/balancer.go",
"chars": 22802,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedroundrobin/balancer_test.go",
"chars": 30152,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedroundrobin/config.go",
"chars": 2569,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedroundrobin/internal/internal.go",
"chars": 1588,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedroundrobin/logging.go",
"chars": 965,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedroundrobin/metrics_test.go",
"chars": 6379,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedroundrobin/scheduler.go",
"chars": 4296,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedtarget/logging.go",
"chars": 974,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedtarget/weightedaggregator/aggregator.go",
"chars": 10599,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedtarget/weightedtarget.go",
"chars": 6439,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedtarget/weightedtarget_config.go",
"chars": 1433,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedtarget/weightedtarget_config_test.go",
"chars": 2457,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer/weightedtarget/weightedtarget_test.go",
"chars": 54885,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer_wrapper.go",
"chars": 17961,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "balancer_wrapper_test.go",
"chars": 2739,
"preview": "/*\n *\n * Copyright 2023 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/benchmain/main.go",
"chars": 37696,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/benchmark.go",
"chars": 10717,
"preview": "/*\n *\n * Copyright 2014 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/benchresult/main.go",
"chars": 4947,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/client/main.go",
"chars": 6432,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/flags/flags.go",
"chars": 4487,
"preview": "/*\n *\n * Copyright 2019 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/flags/flags_test.go",
"chars": 4413,
"preview": "/*\n *\n * Copyright 2019 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/latency/latency.go",
"chars": 9754,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/latency/latency_test.go",
"chars": 10723,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/primitives/code_string_test.go",
"chars": 3191,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/primitives/context_test.go",
"chars": 3438,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/primitives/primitives_test.go",
"chars": 7611,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/primitives/safe_config_selector_test.go",
"chars": 2437,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/primitives/syncmap_test.go",
"chars": 3336,
"preview": "/*\n *\n * Copyright 2019 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/run_bench.sh",
"chars": 4079,
"preview": "#!/bin/bash\n\nrpcs=(1)\nconns=(1)\nwarmup=10\ndur=10\nreqs=(1)\nresps=(1)\nrpc_types=(unary)\n\n# idx[0] = idx value for rpcs\n# i"
},
{
"path": "benchmark/server/main.go",
"chars": 2637,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/stats/curve.go",
"chars": 4730,
"preview": "/*\n *\n * Copyright 2019 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/stats/histogram.go",
"chars": 6604,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/stats/stats.go",
"chars": 18897,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/worker/benchmark_client.go",
"chars": 14639,
"preview": "/*\n *\n * Copyright 2016 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/worker/benchmark_server.go",
"chars": 5577,
"preview": "/*\n *\n * Copyright 2016 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "benchmark/worker/main.go",
"chars": 6126,
"preview": "/*\n *\n * Copyright 2016 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "binarylog/binarylog_end2end_test.go",
"chars": 31523,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "binarylog/grpc_binarylog_v1/binarylog.pb.go",
"chars": 33196,
"preview": "// Copyright 2018 The gRPC Authors\n// All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"Li"
},
{
"path": "binarylog/sink.go",
"chars": 2181,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "call.go",
"chars": 2463,
"preview": "/*\n *\n * Copyright 2014 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "channelz/channelz.go",
"chars": 1217,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "channelz/grpc_channelz_v1/channelz.pb.go",
"chars": 116153,
"preview": "// Copyright 2018 The gRPC Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
},
{
"path": "channelz/grpc_channelz_v1/channelz_grpc.pb.go",
"chars": 15955,
"preview": "// Copyright 2018 The gRPC Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not "
},
{
"path": "channelz/internal/protoconv/channel.go",
"chars": 4854,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "channelz/internal/protoconv/server.go",
"chars": 2312,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "channelz/internal/protoconv/socket.go",
"chars": 5302,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "channelz/internal/protoconv/sockopt_linux.go",
"chars": 4317,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "channelz/internal/protoconv/sockopt_nonlinux.go",
"chars": 871,
"preview": "//go:build !linux\n// +build !linux\n\n/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Versi"
},
{
"path": "channelz/internal/protoconv/subchannel.go",
"chars": 2177,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "channelz/internal/protoconv/util.go",
"chars": 848,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "channelz/service/service.go",
"chars": 3617,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "channelz/service/service_sktopt_test.go",
"chars": 3105,
"preview": "//go:build linux && (386 || amd64)\n// +build linux\n// +build 386 amd64\n\n/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Lice"
},
{
"path": "channelz/service/service_test.go",
"chars": 29262,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "clientconn.go",
"chars": 67613,
"preview": "/*\n *\n * Copyright 2014 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "clientconn_authority_test.go",
"chars": 4558,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "clientconn_parsed_target_test.go",
"chars": 11527,
"preview": "/*\n *\n * Copyright 2021 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "clientconn_test.go",
"chars": 32568,
"preview": "/*\n *\n * Copyright 2014 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "cmd/protoc-gen-go-grpc/README.md",
"chars": 1299,
"preview": "# protoc-gen-go-grpc\n\nThis tool generates Go language bindings of `service`s in protobuf definition\nfiles for gRPC. For"
},
{
"path": "cmd/protoc-gen-go-grpc/go.mod",
"chars": 467,
"preview": "module google.golang.org/grpc/cmd/protoc-gen-go-grpc\n\ngo 1.25.0\n\nrequire (\n\tgoogle.golang.org/grpc v1.70.0\n\tgoogle.golan"
},
{
"path": "cmd/protoc-gen-go-grpc/go.sum",
"chars": 2965,
"preview": "github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=\ngithub.com/go-logr/logr v1.4.2/go.mod h1:"
},
{
"path": "cmd/protoc-gen-go-grpc/grpc.go",
"chars": 20489,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "cmd/protoc-gen-go-grpc/main.go",
"chars": 2220,
"preview": "/*\n *\n * Copyright 2020 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "cmd/protoc-gen-go-grpc/protoc-gen-go-grpc_test.sh",
"chars": 1639,
"preview": "#!/bin/bash -e\n\n# Copyright 2024 gRPC authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you"
},
{
"path": "cmd/protoc-gen-go-grpc/unimpl_test.go",
"chars": 1287,
"preview": "/*\n *\n * Copyright 2024 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "codec.go",
"chars": 3154,
"preview": "/*\n *\n * Copyright 2014 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "codec_test.go",
"chars": 897,
"preview": "/*\n *\n * Copyright 2014 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "codes/code_string.go",
"chars": 2437,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "codes/codes.go",
"chars": 9418,
"preview": "/*\n *\n * Copyright 2014 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "codes/codes_test.go",
"chars": 2879,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "connectivity/connectivity.go",
"chars": 2684,
"preview": "/*\n *\n * Copyright 2017 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "credentials/alts/alts.go",
"chars": 11110,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "credentials/alts/alts_test.go",
"chars": 15169,
"preview": "//go:build linux || windows\n// +build linux windows\n\n/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apac"
},
{
"path": "credentials/alts/internal/authinfo/authinfo.go",
"chars": 3213,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "credentials/alts/internal/authinfo/authinfo_test.go",
"chars": 4682,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "credentials/alts/internal/common.go",
"chars": 2263,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "credentials/alts/internal/conn/aeadrekey.go",
"chars": 4069,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "credentials/alts/internal/conn/aeadrekey_test.go",
"chars": 15508,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "credentials/alts/internal/conn/aes128gcm.go",
"chars": 3265,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "credentials/alts/internal/conn/aes128gcm_test.go",
"chars": 7964,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
},
{
"path": "credentials/alts/internal/conn/aes128gcmrekey.go",
"chars": 3679,
"preview": "/*\n *\n * Copyright 2018 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may n"
}
]
// ... and 1107 more files (download for full content)
About this extraction
This page contains the full source code of the grpc/grpc-go GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1307 files (12.5 MB), approximately 3.4M tokens, and a symbol index with 13673 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.