mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	Merge pull request #2638 from crazy-max/update-buildkit
vendor: update buildkit to 664c2b469f19
This commit is contained in:
		@@ -893,7 +893,7 @@ func detectSharedMounts(ctx context.Context, reqs map[string][]*reqForNode) (_ m
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			var ss *sharedSession
 | 
								var ss *sharedSession
 | 
				
			||||||
			if idx == -1 {
 | 
								if idx == -1 {
 | 
				
			||||||
				s, err := session.NewSession(ctx, "", fs.so[0].SharedKey)
 | 
									s, err := session.NewSession(ctx, fs.so[0].SharedKey)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					return nil, err
 | 
										return nil, err
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								go.mod
									
									
									
									
									
								
							@@ -8,7 +8,7 @@ require (
 | 
				
			|||||||
	github.com/aws/aws-sdk-go-v2/config v1.26.6
 | 
						github.com/aws/aws-sdk-go-v2/config v1.26.6
 | 
				
			||||||
	github.com/compose-spec/compose-go/v2 v2.1.6
 | 
						github.com/compose-spec/compose-go/v2 v2.1.6
 | 
				
			||||||
	github.com/containerd/console v1.0.4
 | 
						github.com/containerd/console v1.0.4
 | 
				
			||||||
	github.com/containerd/containerd v1.7.19
 | 
						github.com/containerd/containerd v1.7.20
 | 
				
			||||||
	github.com/containerd/continuity v0.4.3
 | 
						github.com/containerd/continuity v0.4.3
 | 
				
			||||||
	github.com/containerd/errdefs v0.1.0
 | 
						github.com/containerd/errdefs v0.1.0
 | 
				
			||||||
	github.com/containerd/log v0.1.0
 | 
						github.com/containerd/log v0.1.0
 | 
				
			||||||
@@ -16,9 +16,9 @@ require (
 | 
				
			|||||||
	github.com/containerd/typeurl/v2 v2.1.1
 | 
						github.com/containerd/typeurl/v2 v2.1.1
 | 
				
			||||||
	github.com/creack/pty v1.1.21
 | 
						github.com/creack/pty v1.1.21
 | 
				
			||||||
	github.com/distribution/reference v0.6.0
 | 
						github.com/distribution/reference v0.6.0
 | 
				
			||||||
	github.com/docker/cli v27.0.3+incompatible
 | 
						github.com/docker/cli v27.1.1+incompatible
 | 
				
			||||||
	github.com/docker/cli-docs-tool v0.8.0
 | 
						github.com/docker/cli-docs-tool v0.8.0
 | 
				
			||||||
	github.com/docker/docker v27.0.3+incompatible
 | 
						github.com/docker/docker v27.1.1+incompatible
 | 
				
			||||||
	github.com/docker/go-units v0.5.0
 | 
						github.com/docker/go-units v0.5.0
 | 
				
			||||||
	github.com/gofrs/flock v0.12.1
 | 
						github.com/gofrs/flock v0.12.1
 | 
				
			||||||
	github.com/gogo/protobuf v1.3.2
 | 
						github.com/gogo/protobuf v1.3.2
 | 
				
			||||||
@@ -29,7 +29,7 @@ require (
 | 
				
			|||||||
	github.com/hashicorp/hcl/v2 v2.20.1
 | 
						github.com/hashicorp/hcl/v2 v2.20.1
 | 
				
			||||||
	github.com/in-toto/in-toto-golang v0.5.0
 | 
						github.com/in-toto/in-toto-golang v0.5.0
 | 
				
			||||||
	github.com/mitchellh/hashstructure/v2 v2.0.2
 | 
						github.com/mitchellh/hashstructure/v2 v2.0.2
 | 
				
			||||||
	github.com/moby/buildkit v0.15.1
 | 
						github.com/moby/buildkit v0.15.1-0.20240810140024-664c2b469f19
 | 
				
			||||||
	github.com/moby/sys/mountinfo v0.7.1
 | 
						github.com/moby/sys/mountinfo v0.7.1
 | 
				
			||||||
	github.com/moby/sys/signal v0.7.0
 | 
						github.com/moby/sys/signal v0.7.0
 | 
				
			||||||
	github.com/morikuni/aec v1.0.0
 | 
						github.com/morikuni/aec v1.0.0
 | 
				
			||||||
@@ -54,7 +54,7 @@ require (
 | 
				
			|||||||
	golang.org/x/sys v0.22.0
 | 
						golang.org/x/sys v0.22.0
 | 
				
			||||||
	golang.org/x/term v0.20.0
 | 
						golang.org/x/term v0.20.0
 | 
				
			||||||
	golang.org/x/text v0.15.0
 | 
						golang.org/x/text v0.15.0
 | 
				
			||||||
	google.golang.org/grpc v1.59.0
 | 
						google.golang.org/grpc v1.60.1
 | 
				
			||||||
	gopkg.in/yaml.v3 v3.0.1
 | 
						gopkg.in/yaml.v3 v3.0.1
 | 
				
			||||||
	k8s.io/api v0.29.2
 | 
						k8s.io/api v0.29.2
 | 
				
			||||||
	k8s.io/apimachinery v0.29.2
 | 
						k8s.io/apimachinery v0.29.2
 | 
				
			||||||
@@ -128,7 +128,7 @@ require (
 | 
				
			|||||||
	github.com/moby/patternmatcher v0.6.0 // indirect
 | 
						github.com/moby/patternmatcher v0.6.0 // indirect
 | 
				
			||||||
	github.com/moby/spdystream v0.2.0 // indirect
 | 
						github.com/moby/spdystream v0.2.0 // indirect
 | 
				
			||||||
	github.com/moby/sys/sequential v0.5.0 // indirect
 | 
						github.com/moby/sys/sequential v0.5.0 // indirect
 | 
				
			||||||
	github.com/moby/sys/user v0.1.0 // indirect
 | 
						github.com/moby/sys/user v0.3.0 // indirect
 | 
				
			||||||
	github.com/moby/term v0.5.0 // indirect
 | 
						github.com/moby/term v0.5.0 // indirect
 | 
				
			||||||
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
						github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 | 
				
			||||||
	github.com/modern-go/reflect2 v1.0.2 // indirect
 | 
						github.com/modern-go/reflect2 v1.0.2 // indirect
 | 
				
			||||||
@@ -152,9 +152,8 @@ require (
 | 
				
			|||||||
	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
 | 
						go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect
 | 
				
			||||||
	go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1 // indirect
 | 
						go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1 // indirect
 | 
				
			||||||
	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
 | 
						go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
 | 
				
			||||||
	go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect
 | 
						go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 // indirect
 | 
				
			||||||
	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0 // indirect
 | 
						go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 // indirect
 | 
				
			||||||
	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 // indirect
 | 
					 | 
				
			||||||
	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
 | 
						go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
 | 
				
			||||||
	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect
 | 
						go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect
 | 
				
			||||||
	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect
 | 
						go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect
 | 
				
			||||||
@@ -163,13 +162,13 @@ require (
 | 
				
			|||||||
	golang.org/x/crypto v0.23.0 // indirect
 | 
						golang.org/x/crypto v0.23.0 // indirect
 | 
				
			||||||
	golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
 | 
						golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
 | 
				
			||||||
	golang.org/x/net v0.25.0 // indirect
 | 
						golang.org/x/net v0.25.0 // indirect
 | 
				
			||||||
	golang.org/x/oauth2 v0.11.0 // indirect
 | 
						golang.org/x/oauth2 v0.13.0 // indirect
 | 
				
			||||||
	golang.org/x/time v0.3.0 // indirect
 | 
						golang.org/x/time v0.3.0 // indirect
 | 
				
			||||||
	golang.org/x/tools v0.17.0 // indirect
 | 
						golang.org/x/tools v0.17.0 // indirect
 | 
				
			||||||
	google.golang.org/appengine v1.6.8 // indirect
 | 
						google.golang.org/appengine v1.6.8 // indirect
 | 
				
			||||||
	google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect
 | 
						google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 // indirect
 | 
				
			||||||
	google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect
 | 
						google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f // indirect
 | 
				
			||||||
	google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect
 | 
						google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect
 | 
				
			||||||
	google.golang.org/protobuf v1.33.0 // indirect
 | 
						google.golang.org/protobuf v1.33.0 // indirect
 | 
				
			||||||
	gopkg.in/inf.v0 v0.9.1 // indirect
 | 
						gopkg.in/inf.v0 v0.9.1 // indirect
 | 
				
			||||||
	gopkg.in/yaml.v2 v2.4.0 // indirect
 | 
						gopkg.in/yaml.v2 v2.4.0 // indirect
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										64
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								go.sum
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
cloud.google.com/go v0.110.8 h1:tyNdfIxjzaWctIiLYOTalaLKZ17SI44SKFW26QbOhME=
 | 
					cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y=
 | 
				
			||||||
cloud.google.com/go/compute v1.23.1 h1:V97tBoDaZHb6leicZ1G6DLK2BAaZLJ/7+9BB/En3hR0=
 | 
					cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
 | 
				
			||||||
cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78=
 | 
					cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
 | 
				
			||||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
 | 
					cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
 | 
				
			||||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
 | 
					cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
 | 
				
			||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
 | 
					github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
 | 
				
			||||||
@@ -90,8 +90,8 @@ github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaD
 | 
				
			|||||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
 | 
					github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
 | 
				
			||||||
github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
 | 
					github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro=
 | 
				
			||||||
github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
 | 
					github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
 | 
				
			||||||
github.com/containerd/containerd v1.7.19 h1:/xQ4XRJ0tamDkdzrrBAUy/LE5nCcxFKdBm4EcPrSMEE=
 | 
					github.com/containerd/containerd v1.7.20 h1:Sl6jQYk3TRavaU83h66QMbI2Nqg9Jm6qzwX57Vsn1SQ=
 | 
				
			||||||
github.com/containerd/containerd v1.7.19/go.mod h1:h4FtNYUUMB4Phr6v+xG89RYKj9XccvbNSCKjdufCrkc=
 | 
					github.com/containerd/containerd v1.7.20/go.mod h1:52GsS5CwquuqPuLncsXwG0t2CiUce+KsNHJZQJvAgR0=
 | 
				
			||||||
github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA=
 | 
					github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA=
 | 
				
			||||||
github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig=
 | 
					github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig=
 | 
				
			||||||
github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8=
 | 
					github.com/containerd/continuity v0.4.3 h1:6HVkalIp+2u1ZLH1J/pYX2oBVXlJZvh1X1A7bEZ9Su8=
 | 
				
			||||||
@@ -102,8 +102,8 @@ github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY
 | 
				
			|||||||
github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=
 | 
					github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=
 | 
				
			||||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
 | 
					github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
 | 
				
			||||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
 | 
					github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
 | 
				
			||||||
github.com/containerd/nydus-snapshotter v0.13.7 h1:x7DHvGnzJOu1ZPwPYkeOPk5MjZZYbdddygEjaSDoFTk=
 | 
					github.com/containerd/nydus-snapshotter v0.14.0 h1:6/eAi6d7MjaeLLuMO8Udfe5GVsDudmrDNO4SGETMBco=
 | 
				
			||||||
github.com/containerd/nydus-snapshotter v0.13.7/go.mod h1:VPVKQ3jmHFIcUIV2yiQ1kImZuBFS3GXDohKs9mRABVE=
 | 
					github.com/containerd/nydus-snapshotter v0.14.0/go.mod h1:TT4jv2SnIDxEBu4H2YOvWQHPOap031ydTaHTuvc5VQk=
 | 
				
			||||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
 | 
					github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
 | 
				
			||||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
 | 
					github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
 | 
				
			||||||
github.com/containerd/stargz-snapshotter v0.15.1 h1:fpsP4kf/Z4n2EYnU0WT8ZCE3eiKDwikDhL6VwxIlgeA=
 | 
					github.com/containerd/stargz-snapshotter v0.15.1 h1:fpsP4kf/Z4n2EYnU0WT8ZCE3eiKDwikDhL6VwxIlgeA=
 | 
				
			||||||
@@ -124,15 +124,15 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 | 
				
			|||||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
 | 
					github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
 | 
				
			||||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
 | 
					github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
 | 
				
			||||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
 | 
					github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
 | 
				
			||||||
github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlSN5BLDioCQ=
 | 
					github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE=
 | 
				
			||||||
github.com/docker/cli v27.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 | 
					github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 | 
				
			||||||
github.com/docker/cli-docs-tool v0.8.0 h1:YcDWl7rQJC3lJ7WVZRwSs3bc9nka97QLWfyJQli8yJU=
 | 
					github.com/docker/cli-docs-tool v0.8.0 h1:YcDWl7rQJC3lJ7WVZRwSs3bc9nka97QLWfyJQli8yJU=
 | 
				
			||||||
github.com/docker/cli-docs-tool v0.8.0/go.mod h1:8TQQ3E7mOXoYUs811LiPdUnAhXrcVsBIrW21a5pUbdk=
 | 
					github.com/docker/cli-docs-tool v0.8.0/go.mod h1:8TQQ3E7mOXoYUs811LiPdUnAhXrcVsBIrW21a5pUbdk=
 | 
				
			||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
					github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
				
			||||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
 | 
					github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
 | 
				
			||||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
					github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
				
			||||||
github.com/docker/docker v27.0.3+incompatible h1:aBGI9TeQ4MPlhquTQKq9XbK79rKFVwXNUAYz9aXyEBE=
 | 
					github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
 | 
				
			||||||
github.com/docker/docker v27.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 | 
					github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 | 
				
			||||||
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
 | 
					github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
 | 
				
			||||||
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
 | 
					github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
 | 
				
			||||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
 | 
					github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
 | 
				
			||||||
@@ -307,8 +307,8 @@ github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/z
 | 
				
			|||||||
github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 | 
					github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 | 
				
			||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 | 
					github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 | 
				
			||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 | 
					github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 | 
				
			||||||
github.com/moby/buildkit v0.15.1 h1:J6wrew7hphKqlq1wuu6yaUb/1Ra7gEzDAovylGztAKM=
 | 
					github.com/moby/buildkit v0.15.1-0.20240810140024-664c2b469f19 h1:0T8RSjj+Li33TiaWxzxUPJ15kGSuOwSjkiL4H86v/Tc=
 | 
				
			||||||
github.com/moby/buildkit v0.15.1/go.mod h1:Yis8ZMUJTHX9XhH9zVyK2igqSHV3sxi3UN0uztZocZk=
 | 
					github.com/moby/buildkit v0.15.1-0.20240810140024-664c2b469f19/go.mod h1:uJOz8k3rWgVrcMPArjtz85jrwOWD4MaLBzk64mCe1yY=
 | 
				
			||||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
 | 
					github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
 | 
				
			||||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
 | 
					github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
 | 
				
			||||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
 | 
					github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
 | 
				
			||||||
@@ -323,8 +323,8 @@ github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5
 | 
				
			|||||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
 | 
					github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
 | 
				
			||||||
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
 | 
					github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
 | 
				
			||||||
github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
 | 
					github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
 | 
				
			||||||
github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
 | 
					github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
 | 
				
			||||||
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
 | 
					github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
 | 
				
			||||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
 | 
					github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
 | 
				
			||||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
 | 
					github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
 | 
				
			||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
					github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
				
			||||||
@@ -395,8 +395,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg
 | 
				
			|||||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
 | 
					github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
 | 
				
			||||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
 | 
					github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
 | 
				
			||||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 | 
					github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 | 
				
			||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
 | 
					github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
 | 
				
			||||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
 | 
					github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
 | 
				
			||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
 | 
					github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
 | 
				
			||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
					github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
				
			||||||
github.com/secure-systems-lab/go-securesystemslib v0.4.0 h1:b23VGrQhTA8cN2CbBw7/FulN9fTtqYUdS5+Oxzt+DUE=
 | 
					github.com/secure-systems-lab/go-securesystemslib v0.4.0 h1:b23VGrQhTA8cN2CbBw7/FulN9fTtqYUdS5+Oxzt+DUE=
 | 
				
			||||||
@@ -477,12 +477,10 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJ
 | 
				
			|||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
 | 
					go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
 | 
				
			||||||
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
 | 
					go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
 | 
				
			||||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
 | 
					go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 h1:ZtfnDL+tUrs1F0Pzfwbg2d59Gru9NCH3bgSHBM6LDwU=
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 h1:jd0+5t/YynESZqsSyPz+7PAFdEop0dlN0+PkyHYo8oI=
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0/go.mod h1:hG4Fj/y8TR/tlEDREo8tWstl9fO9gcFkn4xrx0Io8xU=
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0/go.mod h1:U707O40ee1FpQGyhvqnzmCJm1Wh6OX6GGBVn0E6Uyyk=
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0 h1:NmnYCiR0qNufkldjVvyQfZTHSdzeHoZ41zggMsdMcLM=
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 h1:bflGWrfYyuulcdxf14V6n9+CoQcu5SAAdHmDPAJnlps=
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0/go.mod h1:UVAO61+umUsHLtYb8KXXRoHtxUkdOPkYidzW3gipRLQ=
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0/go.mod h1:qcTO4xHAxZLaLxPd60TdE88rxtItPHgHWqOhOGRr0as=
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 h1:wNMDy/LVGLj2h3p6zg4d0gypKfWKSWI14E1C4smOgl8=
 | 
					 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0/go.mod h1:YfbDdXAAkemWJK3H/DshvlrxqFB2rtW4rY6ky/3x/H0=
 | 
					 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk=
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk=
 | 
				
			||||||
@@ -530,8 +528,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 | 
				
			|||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 | 
					golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 | 
				
			||||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
 | 
					golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
 | 
				
			||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 | 
					golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 | 
				
			||||||
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
 | 
					golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
 | 
				
			||||||
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
 | 
					golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
 | 
				
			||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
@@ -588,15 +586,15 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
 | 
				
			|||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 | 
					google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 | 
				
			||||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
 | 
					google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
 | 
				
			||||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
 | 
					google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
 | 
				
			||||||
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA=
 | 
					google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg=
 | 
				
			||||||
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI=
 | 
					google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic=
 | 
				
			||||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k=
 | 
					google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY=
 | 
				
			||||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870=
 | 
					google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI=
 | 
				
			||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo=
 | 
					google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU=
 | 
				
			||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc=
 | 
					google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA=
 | 
				
			||||||
google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 | 
					google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 | 
				
			||||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
 | 
					google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
 | 
				
			||||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
 | 
					google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
 | 
				
			||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 | 
					google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 | 
				
			||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
					google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
				
			||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
					google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/github.com/containerd/containerd/version/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/containerd/containerd/version/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -23,7 +23,7 @@ var (
 | 
				
			|||||||
	Package = "github.com/containerd/containerd"
 | 
						Package = "github.com/containerd/containerd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Version holds the complete version number. Filled in at linking time.
 | 
						// Version holds the complete version number. Filled in at linking time.
 | 
				
			||||||
	Version = "1.7.19+unknown"
 | 
						Version = "1.7.20+unknown"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Revision is filled with the VCS (e.g. git) revision being used to build
 | 
						// Revision is filled with the VCS (e.g. git) revision being used to build
 | 
				
			||||||
	// the program at linking time.
 | 
						// the program at linking time.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/github.com/docker/cli/cli/command/cli.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/docker/cli/cli/command/cli.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -324,7 +324,7 @@ func newAPIClientFromEndpoint(ep docker.Endpoint, configFile *configfile.ConfigF
 | 
				
			|||||||
	if len(configFile.HTTPHeaders) > 0 {
 | 
						if len(configFile.HTTPHeaders) > 0 {
 | 
				
			||||||
		opts = append(opts, client.WithHTTPHeaders(configFile.HTTPHeaders))
 | 
							opts = append(opts, client.WithHTTPHeaders(configFile.HTTPHeaders))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	opts = append(opts, client.WithUserAgent(UserAgent()))
 | 
						opts = append(opts, withCustomHeadersFromEnv(), client.WithUserAgent(UserAgent()))
 | 
				
			||||||
	return client.NewClientWithOpts(opts...)
 | 
						return client.NewClientWithOpts(opts...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										109
									
								
								vendor/github.com/docker/cli/cli/command/cli_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/docker/cli/cli/command/cli_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,13 +2,18 @@ package command
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"encoding/csv"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/docker/cli/cli/streams"
 | 
						"github.com/docker/cli/cli/streams"
 | 
				
			||||||
	"github.com/docker/docker/client"
 | 
						"github.com/docker/docker/client"
 | 
				
			||||||
 | 
						"github.com/docker/docker/errdefs"
 | 
				
			||||||
	"github.com/moby/term"
 | 
						"github.com/moby/term"
 | 
				
			||||||
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CLIOption is a functional argument to apply options to a [DockerCli]. These
 | 
					// CLIOption is a functional argument to apply options to a [DockerCli]. These
 | 
				
			||||||
@@ -108,3 +113,107 @@ func WithAPIClient(c client.APIClient) CLIOption {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// envOverrideHTTPHeaders is the name of the environment-variable that can be
 | 
				
			||||||
 | 
					// used to set custom HTTP headers to be sent by the client. This environment
 | 
				
			||||||
 | 
					// variable is the equivalent to the HttpHeaders field in the configuration
 | 
				
			||||||
 | 
					// file.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// WARNING: If both config and environment-variable are set, the environment
 | 
				
			||||||
 | 
					// variable currently overrides all headers set in the configuration file.
 | 
				
			||||||
 | 
					// This behavior may change in a future update, as we are considering the
 | 
				
			||||||
 | 
					// environment variable to be appending to existing headers (and to only
 | 
				
			||||||
 | 
					// override headers with the same name).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// While this env-var allows for custom headers to be set, it does not allow
 | 
				
			||||||
 | 
					// for built-in headers (such as "User-Agent", if set) to be overridden.
 | 
				
			||||||
 | 
					// Also see [client.WithHTTPHeaders] and [client.WithUserAgent].
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This environment variable can be used in situations where headers must be
 | 
				
			||||||
 | 
					// set for a specific invocation of the CLI, but should not be set by default,
 | 
				
			||||||
 | 
					// and therefore cannot be set in the config-file.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// envOverrideHTTPHeaders accepts a comma-separated (CSV) list of key=value pairs,
 | 
				
			||||||
 | 
					// where key must be a non-empty, valid MIME header format. Whitespaces surrounding
 | 
				
			||||||
 | 
					// the key are trimmed, and the key is normalised. Whitespaces in values are
 | 
				
			||||||
 | 
					// preserved, but "key=value" pairs with an empty value (e.g. "key=") are ignored.
 | 
				
			||||||
 | 
					// Tuples without a "=" produce an error.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// It follows CSV rules for escaping, allowing "key=value" pairs to be quoted
 | 
				
			||||||
 | 
					// if they must contain commas, which allows for multiple values for a single
 | 
				
			||||||
 | 
					// header to be set. If a key is repeated in the list, later values override
 | 
				
			||||||
 | 
					// prior values.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// For example, the following value:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//	one=one-value,"two=two,value","three= a value with whitespace  ",four=,five=five=one,five=five-two
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Produces four headers (four is omitted as it has an empty value set):
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// - one (value is "one-value")
 | 
				
			||||||
 | 
					// - two (value is "two,value")
 | 
				
			||||||
 | 
					// - three (value is " a value with whitespace  ")
 | 
				
			||||||
 | 
					// - five (value is "five-two", the later value has overridden the prior value)
 | 
				
			||||||
 | 
					const envOverrideHTTPHeaders = "DOCKER_CUSTOM_HEADERS"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// withCustomHeadersFromEnv overriding custom HTTP headers to be sent by the
 | 
				
			||||||
 | 
					// client through the [envOverrideHTTPHeaders] environment-variable. This
 | 
				
			||||||
 | 
					// environment variable is the equivalent to the HttpHeaders field in the
 | 
				
			||||||
 | 
					// configuration file.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// WARNING: If both config and environment-variable are set, the environment-
 | 
				
			||||||
 | 
					// variable currently overrides all headers set in the configuration file.
 | 
				
			||||||
 | 
					// This behavior may change in a future update, as we are considering the
 | 
				
			||||||
 | 
					// environment-variable to be appending to existing headers (and to only
 | 
				
			||||||
 | 
					// override headers with the same name).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// TODO(thaJeztah): this is a client Option, and should be moved to the client. It is non-exported for that reason.
 | 
				
			||||||
 | 
					func withCustomHeadersFromEnv() client.Opt {
 | 
				
			||||||
 | 
						return func(apiClient *client.Client) error {
 | 
				
			||||||
 | 
							value := os.Getenv(envOverrideHTTPHeaders)
 | 
				
			||||||
 | 
							if value == "" {
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							csvReader := csv.NewReader(strings.NewReader(value))
 | 
				
			||||||
 | 
							fields, err := csvReader.Read()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return errdefs.InvalidParameter(errors.Errorf("failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs", envOverrideHTTPHeaders))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(fields) == 0 {
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							env := map[string]string{}
 | 
				
			||||||
 | 
							for _, kv := range fields {
 | 
				
			||||||
 | 
								k, v, hasValue := strings.Cut(kv, "=")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Only strip whitespace in keys; preserve whitespace in values.
 | 
				
			||||||
 | 
								k = strings.TrimSpace(k)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if k == "" {
 | 
				
			||||||
 | 
									return errdefs.InvalidParameter(errors.Errorf(`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`, envOverrideHTTPHeaders, kv))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// We don't currently allow empty key=value pairs, and produce an error.
 | 
				
			||||||
 | 
								// This is something we could allow in future (e.g. to read value
 | 
				
			||||||
 | 
								// from an environment variable with the same name). In the meantime,
 | 
				
			||||||
 | 
								// produce an error to prevent users from depending on this.
 | 
				
			||||||
 | 
								if !hasValue {
 | 
				
			||||||
 | 
									return errdefs.InvalidParameter(errors.Errorf(`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`, envOverrideHTTPHeaders, kv))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								env[http.CanonicalHeaderKey(k)] = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if len(env) == 0 {
 | 
				
			||||||
 | 
								// We should probably not hit this case, as we don't skip values
 | 
				
			||||||
 | 
								// (only return errors), but we don't want to discard existing
 | 
				
			||||||
 | 
								// headers with an empty set.
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// TODO(thaJeztah): add a client.WithExtraHTTPHeaders() function to allow these headers to be _added_ to existing ones, instead of _replacing_
 | 
				
			||||||
 | 
							//  see https://github.com/docker/cli/pull/5098#issuecomment-2147403871  (when updating, also update the WARNING in the function and env-var GoDoc)
 | 
				
			||||||
 | 
							return client.WithHTTPHeaders(env)(apiClient)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								vendor/github.com/docker/cli/cli/command/registry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								vendor/github.com/docker/cli/cli/command/registry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,10 +1,8 @@
 | 
				
			|||||||
package command
 | 
					package command
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
@@ -18,7 +16,6 @@ import (
 | 
				
			|||||||
	"github.com/docker/docker/api/types"
 | 
						"github.com/docker/docker/api/types"
 | 
				
			||||||
	registrytypes "github.com/docker/docker/api/types/registry"
 | 
						registrytypes "github.com/docker/docker/api/types/registry"
 | 
				
			||||||
	"github.com/docker/docker/registry"
 | 
						"github.com/docker/docker/registry"
 | 
				
			||||||
	"github.com/moby/term"
 | 
					 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,7 +41,7 @@ func RegistryAuthenticationPrivilegedFunc(cli Cli, index *registrytypes.IndexInf
 | 
				
			|||||||
		default:
 | 
							default:
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err = ConfigureAuth(cli, "", "", &authConfig, isDefaultRegistry)
 | 
							err = ConfigureAuth(ctx, cli, "", "", &authConfig, isDefaultRegistry)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return "", err
 | 
								return "", err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -90,7 +87,7 @@ func GetDefaultAuthConfig(cfg *configfile.ConfigFile, checkCredStore bool, serve
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ConfigureAuth handles prompting of user's username and password if needed
 | 
					// ConfigureAuth handles prompting of user's username and password if needed
 | 
				
			||||||
func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *registrytypes.AuthConfig, isDefaultRegistry bool) error {
 | 
					func ConfigureAuth(ctx context.Context, cli Cli, flUser, flPassword string, authconfig *registrytypes.AuthConfig, isDefaultRegistry bool) error {
 | 
				
			||||||
	// On Windows, force the use of the regular OS stdin stream.
 | 
						// On Windows, force the use of the regular OS stdin stream.
 | 
				
			||||||
	//
 | 
						//
 | 
				
			||||||
	// See:
 | 
						// See:
 | 
				
			||||||
@@ -125,9 +122,15 @@ func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *registrytypes
 | 
				
			|||||||
				fmt.Fprintln(cli.Out())
 | 
									fmt.Fprintln(cli.Out())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		promptWithDefault(cli.Out(), "Username", authconfig.Username)
 | 
					
 | 
				
			||||||
 | 
							var prompt string
 | 
				
			||||||
 | 
							if authconfig.Username == "" {
 | 
				
			||||||
 | 
								prompt = "Username: "
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								prompt = fmt.Sprintf("Username (%s): ", authconfig.Username)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		flUser, err = readInput(cli.In())
 | 
							flUser, err = PromptForInput(ctx, cli.In(), cli.Out(), prompt)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -139,16 +142,13 @@ func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *registrytypes
 | 
				
			|||||||
		return errors.Errorf("Error: Non-null Username Required")
 | 
							return errors.Errorf("Error: Non-null Username Required")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if flPassword == "" {
 | 
						if flPassword == "" {
 | 
				
			||||||
		oldState, err := term.SaveState(cli.In().FD())
 | 
							restoreInput, err := DisableInputEcho(cli.In())
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fmt.Fprintf(cli.Out(), "Password: ")
 | 
							defer restoreInput()
 | 
				
			||||||
		_ = term.DisableEcho(cli.In().FD(), oldState)
 | 
					
 | 
				
			||||||
		defer func() {
 | 
							flPassword, err = PromptForInput(ctx, cli.In(), cli.Out(), "Password: ")
 | 
				
			||||||
			_ = term.RestoreTerminal(cli.In().FD(), oldState)
 | 
					 | 
				
			||||||
		}()
 | 
					 | 
				
			||||||
		flPassword, err = readInput(cli.In())
 | 
					 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -164,25 +164,6 @@ func ConfigureAuth(cli Cli, flUser, flPassword string, authconfig *registrytypes
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// readInput reads, and returns user input from in. It tries to return a
 | 
					 | 
				
			||||||
// single line, not including the end-of-line bytes, and trims leading
 | 
					 | 
				
			||||||
// and trailing whitespace.
 | 
					 | 
				
			||||||
func readInput(in io.Reader) (string, error) {
 | 
					 | 
				
			||||||
	line, _, err := bufio.NewReader(in).ReadLine()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", errors.Wrap(err, "error while reading input")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return strings.TrimSpace(string(line)), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func promptWithDefault(out io.Writer, prompt string, configDefault string) {
 | 
					 | 
				
			||||||
	if configDefault == "" {
 | 
					 | 
				
			||||||
		fmt.Fprintf(out, "%s: ", prompt)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		fmt.Fprintf(out, "%s (%s): ", prompt, configDefault)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RetrieveAuthTokenFromImage retrieves an encoded auth token given a complete
 | 
					// RetrieveAuthTokenFromImage retrieves an encoded auth token given a complete
 | 
				
			||||||
// image. The auth configuration is serialized as a base64url encoded RFC4648,
 | 
					// image. The auth configuration is serialized as a base64url encoded RFC4648,
 | 
				
			||||||
// section 5) JSON string for sending through the X-Registry-Auth header.
 | 
					// section 5) JSON string for sending through the X-Registry-Auth header.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										43
									
								
								vendor/github.com/docker/cli/cli/command/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/docker/cli/cli/command/utils.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -19,6 +19,7 @@ import (
 | 
				
			|||||||
	"github.com/docker/docker/api/types/versions"
 | 
						"github.com/docker/docker/api/types/versions"
 | 
				
			||||||
	"github.com/docker/docker/errdefs"
 | 
						"github.com/docker/docker/errdefs"
 | 
				
			||||||
	"github.com/moby/sys/sequential"
 | 
						"github.com/moby/sys/sequential"
 | 
				
			||||||
 | 
						"github.com/moby/term"
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
	"github.com/spf13/pflag"
 | 
						"github.com/spf13/pflag"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -76,6 +77,48 @@ func PrettyPrint(i any) string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var ErrPromptTerminated = errdefs.Cancelled(errors.New("prompt terminated"))
 | 
					var ErrPromptTerminated = errdefs.Cancelled(errors.New("prompt terminated"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DisableInputEcho disables input echo on the provided streams.In.
 | 
				
			||||||
 | 
					// This is useful when the user provides sensitive information like passwords.
 | 
				
			||||||
 | 
					// The function returns a restore function that should be called to restore the
 | 
				
			||||||
 | 
					// terminal state.
 | 
				
			||||||
 | 
					func DisableInputEcho(ins *streams.In) (restore func() error, err error) {
 | 
				
			||||||
 | 
						oldState, err := term.SaveState(ins.FD())
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						restore = func() error {
 | 
				
			||||||
 | 
							return term.RestoreTerminal(ins.FD(), oldState)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return restore, term.DisableEcho(ins.FD(), oldState)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PromptForInput requests input from the user.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// If the user terminates the CLI with SIGINT or SIGTERM while the prompt is
 | 
				
			||||||
 | 
					// active, the prompt will return an empty string ("") with an ErrPromptTerminated error.
 | 
				
			||||||
 | 
					// When the prompt returns an error, the caller should propagate the error up
 | 
				
			||||||
 | 
					// the stack and close the io.Reader used for the prompt which will prevent the
 | 
				
			||||||
 | 
					// background goroutine from blocking indefinitely.
 | 
				
			||||||
 | 
					func PromptForInput(ctx context.Context, in io.Reader, out io.Writer, message string) (string, error) {
 | 
				
			||||||
 | 
						_, _ = fmt.Fprint(out, message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result := make(chan string)
 | 
				
			||||||
 | 
						go func() {
 | 
				
			||||||
 | 
							scanner := bufio.NewScanner(in)
 | 
				
			||||||
 | 
							if scanner.Scan() {
 | 
				
			||||||
 | 
								result <- strings.TrimSpace(scanner.Text())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
						case <-ctx.Done():
 | 
				
			||||||
 | 
							_, _ = fmt.Fprintln(out, "")
 | 
				
			||||||
 | 
							return "", ErrPromptTerminated
 | 
				
			||||||
 | 
						case r := <-result:
 | 
				
			||||||
 | 
							return r, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PromptForConfirmation requests and checks confirmation from the user.
 | 
					// PromptForConfirmation requests and checks confirmation from the user.
 | 
				
			||||||
// This will display the provided message followed by ' [y/N] '. If the user
 | 
					// This will display the provided message followed by ' [y/N] '. If the user
 | 
				
			||||||
// input 'y' or 'Y' it returns true otherwise false. If no message is provided,
 | 
					// input 'y' or 'Y' it returns true otherwise false. If no message is provided,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								vendor/github.com/docker/cli/cli/config/configfile/file.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/docker/cli/cli/config/configfile/file.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -303,6 +303,7 @@ func (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig,
 | 
				
			|||||||
	for registryHostname := range configFile.CredentialHelpers {
 | 
						for registryHostname := range configFile.CredentialHelpers {
 | 
				
			||||||
		newAuth, err := configFile.GetAuthConfig(registryHostname)
 | 
							newAuth, err := configFile.GetAuthConfig(registryHostname)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
 | 
								// TODO(thaJeztah): use context-logger, so that this output can be suppressed (in tests).
 | 
				
			||||||
			logrus.WithError(err).Warnf("Failed to get credentials for registry: %s", registryHostname)
 | 
								logrus.WithError(err).Warnf("Failed to get credentials for registry: %s", registryHostname)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								vendor/github.com/docker/cli/cli/context/store/store.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/docker/cli/cli/context/store/store.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -124,6 +124,9 @@ func (s *ContextStore) List() ([]Metadata, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Names return Metadata names for a Lister
 | 
					// Names return Metadata names for a Lister
 | 
				
			||||||
func Names(s Lister) ([]string, error) {
 | 
					func Names(s Lister) ([]string, error) {
 | 
				
			||||||
 | 
						if s == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("nil lister")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	list, err := s.List()
 | 
						list, err := s.List()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								vendor/github.com/docker/cli/opts/port.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/docker/cli/opts/port.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -149,6 +149,7 @@ func ConvertPortToPortConfig(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for _, binding := range portBindings[port] {
 | 
						for _, binding := range portBindings[port] {
 | 
				
			||||||
		if p := net.ParseIP(binding.HostIP); p != nil && !p.IsUnspecified() {
 | 
							if p := net.ParseIP(binding.HostIP); p != nil && !p.IsUnspecified() {
 | 
				
			||||||
 | 
								// TODO(thaJeztah): use context-logger, so that this output can be suppressed (in tests).
 | 
				
			||||||
			logrus.Warnf("ignoring IP-address (%s:%s) service will listen on '0.0.0.0'", net.JoinHostPort(binding.HostIP, binding.HostPort), port)
 | 
								logrus.Warnf("ignoring IP-address (%s:%s) service will listen on '0.0.0.0'", net.JoinHostPort(binding.HostIP, binding.HostPort), port)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								vendor/github.com/docker/docker/api/swagger.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/docker/docker/api/swagger.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -5334,7 +5334,7 @@ definitions:
 | 
				
			|||||||
          The version Go used to compile the daemon, and the version of the Go
 | 
					          The version Go used to compile the daemon, and the version of the Go
 | 
				
			||||||
          runtime in use.
 | 
					          runtime in use.
 | 
				
			||||||
        type: "string"
 | 
					        type: "string"
 | 
				
			||||||
        example: "go1.21.11"
 | 
					        example: "go1.21.12"
 | 
				
			||||||
      Os:
 | 
					      Os:
 | 
				
			||||||
        description: |
 | 
					        description: |
 | 
				
			||||||
          The operating system that the daemon is running on ("linux" or "windows")
 | 
					          The operating system that the daemon is running on ("linux" or "windows")
 | 
				
			||||||
@@ -9563,7 +9563,7 @@ paths:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, `update`, and `prune`
 | 
					        Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, `update`, and `prune`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Images report these events: `create, `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, `untag`, and `prune`
 | 
					        Images report these events: `create`, `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, `untag`, and `prune`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Volumes report these events: `create`, `mount`, `unmount`, `destroy`, and `prune`
 | 
					        Volumes report these events: `create`, `mount`, `unmount`, `destroy`, and `prune`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								vendor/github.com/docker/docker/api/types/system/info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/docker/docker/api/types/system/info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -77,9 +77,6 @@ type Info struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	Containerd *ContainerdInfo `json:",omitempty"`
 | 
						Containerd *ContainerdInfo `json:",omitempty"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Legacy API fields for older API versions.
 | 
					 | 
				
			||||||
	legacyFields
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Warnings contains a slice of warnings that occurred  while collecting
 | 
						// Warnings contains a slice of warnings that occurred  while collecting
 | 
				
			||||||
	// system information. These warnings are intended to be informational
 | 
						// system information. These warnings are intended to be informational
 | 
				
			||||||
	// messages for the user, and are not intended to be parsed / used for
 | 
						// messages for the user, and are not intended to be parsed / used for
 | 
				
			||||||
@@ -124,10 +121,6 @@ type ContainerdNamespaces struct {
 | 
				
			|||||||
	Plugins string
 | 
						Plugins string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type legacyFields struct {
 | 
					 | 
				
			||||||
	ExecutionDriver string `json:",omitempty"` // Deprecated: deprecated since API v1.25, but returned for older versions.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PluginsInfo is a temp struct holding Plugins name
 | 
					// PluginsInfo is a temp struct holding Plugins name
 | 
				
			||||||
// registered with docker daemon. It is used by [Info] struct
 | 
					// registered with docker daemon. It is used by [Info] struct
 | 
				
			||||||
type PluginsInfo struct {
 | 
					type PluginsInfo struct {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										326
									
								
								vendor/github.com/moby/buildkit/api/services/control/control.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										326
									
								
								vendor/github.com/moby/buildkit/api/services/control/control.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1520,6 +1520,7 @@ type BuildHistoryRecord struct {
 | 
				
			|||||||
	NumTotalSteps        int32                       `protobuf:"varint,16,opt,name=numTotalSteps,proto3" json:"numTotalSteps,omitempty"`
 | 
						NumTotalSteps        int32                       `protobuf:"varint,16,opt,name=numTotalSteps,proto3" json:"numTotalSteps,omitempty"`
 | 
				
			||||||
	NumCompletedSteps    int32                       `protobuf:"varint,17,opt,name=numCompletedSteps,proto3" json:"numCompletedSteps,omitempty"`
 | 
						NumCompletedSteps    int32                       `protobuf:"varint,17,opt,name=numCompletedSteps,proto3" json:"numCompletedSteps,omitempty"`
 | 
				
			||||||
	ExternalError        *Descriptor                 `protobuf:"bytes,18,opt,name=externalError,proto3" json:"externalError,omitempty"`
 | 
						ExternalError        *Descriptor                 `protobuf:"bytes,18,opt,name=externalError,proto3" json:"externalError,omitempty"`
 | 
				
			||||||
 | 
						NumWarnings          int32                       `protobuf:"varint,19,opt,name=numWarnings,proto3" json:"numWarnings,omitempty"`
 | 
				
			||||||
	XXX_NoUnkeyedLiteral struct{}                    `json:"-"`
 | 
						XXX_NoUnkeyedLiteral struct{}                    `json:"-"`
 | 
				
			||||||
	XXX_unrecognized     []byte                      `json:"-"`
 | 
						XXX_unrecognized     []byte                      `json:"-"`
 | 
				
			||||||
	XXX_sizecache        int32                       `json:"-"`
 | 
						XXX_sizecache        int32                       `json:"-"`
 | 
				
			||||||
@@ -1684,6 +1685,13 @@ func (m *BuildHistoryRecord) GetExternalError() *Descriptor {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *BuildHistoryRecord) GetNumWarnings() int32 {
 | 
				
			||||||
 | 
						if m != nil {
 | 
				
			||||||
 | 
							return m.NumWarnings
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UpdateBuildHistoryRequest struct {
 | 
					type UpdateBuildHistoryRequest struct {
 | 
				
			||||||
	Ref                  string   `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
 | 
						Ref                  string   `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
 | 
				
			||||||
	Pinned               bool     `protobuf:"varint,2,opt,name=Pinned,proto3" json:"Pinned,omitempty"`
 | 
						Pinned               bool     `protobuf:"varint,2,opt,name=Pinned,proto3" json:"Pinned,omitempty"`
 | 
				
			||||||
@@ -2025,154 +2033,155 @@ func init() {
 | 
				
			|||||||
func init() { proto.RegisterFile("control.proto", fileDescriptor_0c5120591600887d) }
 | 
					func init() { proto.RegisterFile("control.proto", fileDescriptor_0c5120591600887d) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var fileDescriptor_0c5120591600887d = []byte{
 | 
					var fileDescriptor_0c5120591600887d = []byte{
 | 
				
			||||||
	// 2340 bytes of a gzipped FileDescriptorProto
 | 
						// 2354 bytes of a gzipped FileDescriptorProto
 | 
				
			||||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x19, 0x4d, 0x73, 0x1b, 0x59,
 | 
						0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x19, 0x4d, 0x73, 0x1b, 0x59,
 | 
				
			||||||
	0x31, 0x23, 0xc9, 0xb2, 0xd4, 0x92, 0x1c, 0xf9, 0x25, 0x1b, 0x86, 0x21, 0x6b, 0x3b, 0xb3, 0x09,
 | 
						0x31, 0x23, 0xc9, 0xb2, 0xd4, 0x92, 0x1c, 0xf9, 0x25, 0x1b, 0x86, 0x21, 0x6b, 0x3b, 0xb3, 0x09,
 | 
				
			||||||
	0xb8, 0x42, 0x32, 0xf2, 0x0a, 0x42, 0xb2, 0x0e, 0x84, 0x58, 0x96, 0xd8, 0x38, 0xc4, 0x15, 0xef,
 | 
						0xb8, 0x42, 0x32, 0xf2, 0x0a, 0x42, 0xb2, 0x0e, 0x84, 0x58, 0x96, 0xd8, 0x38, 0xc4, 0x15, 0xef,
 | 
				
			||||||
	0xb3, 0xb3, 0xa1, 0xb6, 0x6a, 0xa1, 0xc6, 0xd2, 0xb3, 0x32, 0xe5, 0xd1, 0xcc, 0xf0, 0xde, 0x93,
 | 
						0xb3, 0xb3, 0xa1, 0xb6, 0x6a, 0xa1, 0xc6, 0xd2, 0xb3, 0x32, 0xe5, 0xd1, 0xcc, 0xf0, 0xde, 0x93,
 | 
				
			||||||
	0x37, 0xe2, 0xc4, 0x89, 0x2a, 0x2e, 0x14, 0x17, 0x8a, 0x0b, 0x77, 0x4e, 0x9c, 0x39, 0x71, 0xe0,
 | 
						0x37, 0xe2, 0xc4, 0x89, 0x2a, 0x2e, 0x14, 0x17, 0x8a, 0x0b, 0x77, 0x4e, 0x9c, 0x39, 0x73, 0xa0,
 | 
				
			||||||
	0x40, 0x55, 0x8e, 0x9c, 0xf7, 0x10, 0xa8, 0xfc, 0x00, 0x8a, 0x23, 0x47, 0xea, 0x7d, 0x8c, 0x34,
 | 
						0x2a, 0x47, 0xce, 0x7b, 0xc8, 0x52, 0xf9, 0x01, 0x14, 0x47, 0x8e, 0xd4, 0xfb, 0x18, 0x69, 0x24,
 | 
				
			||||||
	0x92, 0x46, 0xb6, 0x9c, 0xe4, 0xa4, 0xd7, 0xef, 0x75, 0xf7, 0x74, 0xf7, 0xeb, 0xee, 0xd7, 0xdd,
 | 
						0x8d, 0x6c, 0x39, 0xc9, 0x49, 0xaf, 0xdf, 0xeb, 0xee, 0xe9, 0xee, 0xd7, 0xdd, 0xaf, 0xbb, 0x05,
 | 
				
			||||||
	0x82, 0x4a, 0x3b, 0x0c, 0x38, 0x0d, 0x7d, 0x27, 0xa2, 0x21, 0x0f, 0x51, 0xb5, 0x17, 0x1e, 0x0e,
 | 
						0x95, 0x76, 0x18, 0x70, 0x1a, 0xfa, 0x4e, 0x44, 0x43, 0x1e, 0xa2, 0x6a, 0x2f, 0x3c, 0x1c, 0x38,
 | 
				
			||||||
	0x9c, 0xc3, 0xbe, 0xe7, 0x77, 0x8e, 0x3d, 0xee, 0x9c, 0x7c, 0x6c, 0xd5, 0xbb, 0x1e, 0x7f, 0xd1,
 | 
						0x87, 0x7d, 0xcf, 0xef, 0x1c, 0x7b, 0xdc, 0x39, 0xf9, 0xd8, 0xaa, 0x77, 0x3d, 0xfe, 0xa2, 0x7f,
 | 
				
			||||||
	0x3f, 0x74, 0xda, 0x61, 0xaf, 0xd6, 0x0d, 0xbb, 0x61, 0xad, 0x1b, 0x86, 0x5d, 0x9f, 0xb8, 0x91,
 | 
						0xe8, 0xb4, 0xc3, 0x5e, 0xad, 0x1b, 0x76, 0xc3, 0x5a, 0x37, 0x0c, 0xbb, 0x3e, 0x71, 0x23, 0x8f,
 | 
				
			||||||
	0xc7, 0xf4, 0xb2, 0x46, 0xa3, 0x76, 0x8d, 0x71, 0x97, 0xf7, 0x99, 0xe2, 0x62, 0xdd, 0x9e, 0xa4,
 | 
						0xe9, 0x65, 0x8d, 0x46, 0xed, 0x1a, 0xe3, 0x2e, 0xef, 0x33, 0xc5, 0xc5, 0xba, 0x3d, 0x49, 0x23,
 | 
				
			||||||
	0x91, 0xdb, 0x87, 0xfd, 0x23, 0x09, 0x49, 0x40, 0xae, 0x34, 0x7a, 0x2d, 0x81, 0x2e, 0xbe, 0x5f,
 | 
						0xb7, 0x0f, 0xfb, 0x47, 0x12, 0x92, 0x80, 0x5c, 0x69, 0xf4, 0x5a, 0x02, 0x5d, 0x7c, 0xbf, 0x16,
 | 
				
			||||||
	0x8b, 0xbf, 0x5f, 0x73, 0x23, 0xaf, 0xc6, 0x07, 0x11, 0x61, 0xb5, 0xaf, 0x42, 0x7a, 0x4c, 0xa8,
 | 
						0x7f, 0xbf, 0xe6, 0x46, 0x5e, 0x8d, 0x0f, 0x22, 0xc2, 0x6a, 0x5f, 0x85, 0xf4, 0x98, 0x50, 0x4d,
 | 
				
			||||||
	0x26, 0xb8, 0x35, 0x93, 0x80, 0x85, 0xfe, 0x09, 0xa1, 0xb5, 0xe8, 0xb0, 0x16, 0x46, 0xb1, 0x34,
 | 
						0x70, 0x6b, 0x26, 0x01, 0x0b, 0xfd, 0x13, 0x42, 0x6b, 0xd1, 0x61, 0x2d, 0x8c, 0x62, 0x69, 0xee,
 | 
				
			||||||
	0x77, 0x4e, 0xc1, 0xee, 0xd3, 0x36, 0x89, 0x42, 0xdf, 0x6b, 0x0f, 0x04, 0x8d, 0x5a, 0x69, 0xb2,
 | 
						0x9c, 0x82, 0xdd, 0xa7, 0x6d, 0x12, 0x85, 0xbe, 0xd7, 0x1e, 0x08, 0x1a, 0xb5, 0xd2, 0x64, 0xab,
 | 
				
			||||||
	0x55, 0xad, 0xdd, 0x50, 0x76, 0xee, 0xf5, 0x08, 0xe3, 0x6e, 0x2f, 0x52, 0x08, 0xf6, 0x6f, 0x0c,
 | 
						0x5a, 0xbb, 0xa1, 0xec, 0xdc, 0xeb, 0x11, 0xc6, 0xdd, 0x5e, 0xa4, 0x10, 0xec, 0xdf, 0x19, 0x50,
 | 
				
			||||||
	0x28, 0xef, 0xd1, 0x7e, 0x40, 0x30, 0xf9, 0x65, 0x9f, 0x30, 0x8e, 0xae, 0x40, 0xfe, 0xc8, 0xf3,
 | 
						0xde, 0xa3, 0xfd, 0x80, 0x60, 0xf2, 0xeb, 0x3e, 0x61, 0x1c, 0x5d, 0x81, 0xfc, 0x91, 0xe7, 0x73,
 | 
				
			||||||
	0x39, 0xa1, 0xa6, 0xb1, 0x96, 0x5d, 0x2f, 0x62, 0x0d, 0xa1, 0x2a, 0x64, 0x5d, 0xdf, 0x37, 0x33,
 | 
						0x42, 0x4d, 0x63, 0x2d, 0xbb, 0x5e, 0xc4, 0x1a, 0x42, 0x55, 0xc8, 0xba, 0xbe, 0x6f, 0x66, 0xd6,
 | 
				
			||||||
	0x6b, 0xc6, 0x7a, 0x01, 0x8b, 0x25, 0x5a, 0x87, 0xf2, 0x31, 0x21, 0x51, 0xb3, 0x4f, 0x5d, 0xee,
 | 
						0x8c, 0xf5, 0x02, 0x16, 0x4b, 0xb4, 0x0e, 0xe5, 0x63, 0x42, 0xa2, 0x66, 0x9f, 0xba, 0xdc, 0x0b,
 | 
				
			||||||
	0x85, 0x81, 0x99, 0x5d, 0x33, 0xd6, 0xb3, 0x8d, 0xdc, 0xab, 0xd7, 0xab, 0x06, 0x1e, 0x3b, 0x41,
 | 
						0x03, 0x33, 0xbb, 0x66, 0xac, 0x67, 0x1b, 0xb9, 0x57, 0xaf, 0x57, 0x0d, 0x3c, 0x76, 0x82, 0x6c,
 | 
				
			||||||
	0x36, 0x14, 0x05, 0xdc, 0x18, 0x70, 0xc2, 0xcc, 0x5c, 0x02, 0x6d, 0xb4, 0x6d, 0xdf, 0x84, 0x6a,
 | 
						0x28, 0x0a, 0xb8, 0x31, 0xe0, 0x84, 0x99, 0xb9, 0x04, 0xda, 0x68, 0xdb, 0xbe, 0x09, 0xd5, 0xa6,
 | 
				
			||||||
	0xd3, 0x63, 0xc7, 0xcf, 0x98, 0xdb, 0x3d, 0x4b, 0x16, 0xfb, 0x31, 0x2c, 0x27, 0x70, 0x59, 0x14,
 | 
						0xc7, 0x8e, 0x9f, 0x31, 0xb7, 0x7b, 0x96, 0x2c, 0xf6, 0x63, 0x58, 0x4e, 0xe0, 0xb2, 0x28, 0x0c,
 | 
				
			||||||
	0x06, 0x8c, 0xa0, 0x3b, 0x90, 0xa7, 0xa4, 0x1d, 0xd2, 0x8e, 0x44, 0x2e, 0xd5, 0x3f, 0x74, 0x26,
 | 
						0x18, 0x41, 0x77, 0x20, 0x4f, 0x49, 0x3b, 0xa4, 0x1d, 0x89, 0x5c, 0xaa, 0x7f, 0xe8, 0x4c, 0xba,
 | 
				
			||||||
	0xdd, 0xc0, 0xd1, 0x04, 0x02, 0x09, 0x6b, 0x64, 0xfb, 0x8f, 0x59, 0x28, 0x25, 0xf6, 0xd1, 0x12,
 | 
						0x81, 0xa3, 0x09, 0x04, 0x12, 0xd6, 0xc8, 0xf6, 0x9f, 0xb3, 0x50, 0x4a, 0xec, 0xa3, 0x25, 0xc8,
 | 
				
			||||||
	0x64, 0x76, 0x9a, 0xa6, 0xb1, 0x66, 0xac, 0x17, 0x71, 0x66, 0xa7, 0x89, 0x4c, 0x58, 0xdc, 0xed,
 | 
						0xec, 0x34, 0x4d, 0x63, 0xcd, 0x58, 0x2f, 0xe2, 0xcc, 0x4e, 0x13, 0x99, 0xb0, 0xb8, 0xdb, 0xe7,
 | 
				
			||||||
	0x73, 0xf7, 0xd0, 0x27, 0x5a, 0xf7, 0x18, 0x44, 0x97, 0x61, 0x61, 0x27, 0x78, 0xc6, 0x88, 0x54,
 | 
						0xee, 0xa1, 0x4f, 0xb4, 0xee, 0x31, 0x88, 0x2e, 0xc3, 0xc2, 0x4e, 0xf0, 0x8c, 0x11, 0xa9, 0x78,
 | 
				
			||||||
	0xbc, 0x80, 0x15, 0x80, 0x10, 0xe4, 0xf6, 0xbd, 0x5f, 0x11, 0xa5, 0x26, 0x96, 0x6b, 0x64, 0x41,
 | 
						0x01, 0x2b, 0x00, 0x21, 0xc8, 0xed, 0x7b, 0xbf, 0x21, 0x4a, 0x4d, 0x2c, 0xd7, 0xc8, 0x82, 0xfc,
 | 
				
			||||||
	0x7e, 0xcf, 0xa5, 0x24, 0xe0, 0xe6, 0x82, 0xe0, 0xdb, 0xc8, 0x98, 0x06, 0xd6, 0x3b, 0xa8, 0x01,
 | 
						0x9e, 0x4b, 0x49, 0xc0, 0xcd, 0x05, 0xc1, 0xb7, 0x91, 0x31, 0x0d, 0xac, 0x77, 0x50, 0x03, 0x8a,
 | 
				
			||||||
	0xc5, 0x6d, 0x4a, 0x5c, 0x4e, 0x3a, 0x5b, 0xdc, 0xcc, 0xaf, 0x19, 0xeb, 0xa5, 0xba, 0xe5, 0xa8,
 | 
						0xdb, 0x94, 0xb8, 0x9c, 0x74, 0xb6, 0xb8, 0x99, 0x5f, 0x33, 0xd6, 0x4b, 0x75, 0xcb, 0x51, 0xb7,
 | 
				
			||||||
	0x5b, 0x73, 0xe2, 0x5b, 0x73, 0x0e, 0xe2, 0x5b, 0x6b, 0x14, 0x5e, 0xbd, 0x5e, 0xbd, 0xf0, 0xfb,
 | 
						0xe6, 0xc4, 0xb7, 0xe6, 0x1c, 0xc4, 0xb7, 0xd6, 0x28, 0xbc, 0x7a, 0xbd, 0x7a, 0xe1, 0x8f, 0xdf,
 | 
				
			||||||
	0x7f, 0x09, 0xdb, 0x0d, 0xc9, 0xd0, 0x43, 0x80, 0x27, 0x2e, 0xe3, 0xcf, 0x98, 0x64, 0xb2, 0x78,
 | 
						0x08, 0xdb, 0x0d, 0xc9, 0xd0, 0x43, 0x80, 0x27, 0x2e, 0xe3, 0xcf, 0x98, 0x64, 0xb2, 0x78, 0x26,
 | 
				
			||||||
	0x26, 0x93, 0x9c, 0x64, 0x90, 0xa0, 0x41, 0x2b, 0x00, 0xd2, 0x08, 0xdb, 0x61, 0x3f, 0xe0, 0x66,
 | 
						0x93, 0x9c, 0x64, 0x90, 0xa0, 0x41, 0x2b, 0x00, 0xd2, 0x08, 0xdb, 0x61, 0x3f, 0xe0, 0x66, 0x41,
 | 
				
			||||||
	0x41, 0xca, 0x9e, 0xd8, 0x41, 0x6b, 0x50, 0x6a, 0x12, 0xd6, 0xa6, 0x5e, 0x24, 0xaf, 0xba, 0x28,
 | 
						0xca, 0x9e, 0xd8, 0x41, 0x6b, 0x50, 0x6a, 0x12, 0xd6, 0xa6, 0x5e, 0x24, 0xaf, 0xba, 0x28, 0xcd,
 | 
				
			||||||
	0xcd, 0x93, 0xdc, 0x12, 0x1c, 0x94, 0x05, 0x0f, 0x06, 0x11, 0x31, 0x41, 0x22, 0x24, 0x76, 0xc4,
 | 
						0x93, 0xdc, 0x12, 0x1c, 0x94, 0x05, 0x0f, 0x06, 0x11, 0x31, 0x41, 0x22, 0x24, 0x76, 0xc4, 0x5d,
 | 
				
			||||||
	0x5d, 0xee, 0xbf, 0x70, 0x29, 0xe9, 0x98, 0x25, 0x69, 0x2e, 0x0d, 0x09, 0xfb, 0x2a, 0x4b, 0x30,
 | 
						0xee, 0xbf, 0x70, 0x29, 0xe9, 0x98, 0x25, 0x69, 0x2e, 0x0d, 0x09, 0xfb, 0x2a, 0x4b, 0x30, 0xb3,
 | 
				
			||||||
	0xb3, 0x2c, 0x2f, 0x39, 0x06, 0xed, 0x5f, 0x17, 0xa0, 0xbc, 0x2f, 0x42, 0x21, 0x76, 0x87, 0x2a,
 | 
						0x2c, 0x2f, 0x39, 0x06, 0xed, 0xdf, 0x16, 0xa0, 0xbc, 0x2f, 0x42, 0x21, 0x76, 0x87, 0x2a, 0x64,
 | 
				
			||||||
	0x64, 0x31, 0x39, 0xd2, 0x77, 0x23, 0x96, 0xc8, 0x01, 0x68, 0x92, 0x23, 0x2f, 0xf0, 0xa4, 0x54,
 | 
						0x31, 0x39, 0xd2, 0x77, 0x23, 0x96, 0xc8, 0x01, 0x68, 0x92, 0x23, 0x2f, 0xf0, 0xa4, 0x54, 0x19,
 | 
				
			||||||
	0x19, 0xa9, 0xf8, 0x92, 0x13, 0x1d, 0x3a, 0xa3, 0x5d, 0x9c, 0xc0, 0x40, 0x0e, 0xa0, 0xd6, 0xcb,
 | 
						0xa9, 0xf8, 0x92, 0x13, 0x1d, 0x3a, 0xa3, 0x5d, 0x9c, 0xc0, 0x40, 0x0e, 0xa0, 0xd6, 0xcb, 0x28,
 | 
				
			||||||
	0x28, 0xa4, 0x9c, 0xd0, 0x26, 0x89, 0x28, 0x69, 0x0b, 0x03, 0xca, 0xfb, 0x2b, 0xe2, 0x94, 0x13,
 | 
						0xa4, 0x9c, 0xd0, 0x26, 0x89, 0x28, 0x69, 0x0b, 0x03, 0xca, 0xfb, 0x2b, 0xe2, 0x94, 0x13, 0xd4,
 | 
				
			||||||
	0xd4, 0x87, 0x6f, 0xc4, 0xbb, 0x5b, 0x9c, 0x53, 0x96, 0x20, 0xca, 0x49, 0x27, 0xbb, 0x3f, 0xed,
 | 
						0x87, 0x6f, 0xc5, 0xbb, 0x5b, 0x9c, 0x53, 0x96, 0x20, 0xca, 0x49, 0x27, 0xbb, 0x3f, 0xed, 0x64,
 | 
				
			||||||
	0x64, 0x49, 0x91, 0x9d, 0x19, 0xd4, 0xad, 0x80, 0xd3, 0x01, 0x9e, 0xc5, 0x5b, 0xd8, 0x64, 0x9f,
 | 
						0x49, 0x91, 0x9d, 0x19, 0xd4, 0xad, 0x80, 0xd3, 0x01, 0x9e, 0xc5, 0x5b, 0xd8, 0x64, 0x9f, 0x30,
 | 
				
			||||||
	0x30, 0x26, 0x74, 0x92, 0x0e, 0x83, 0x63, 0x10, 0x59, 0x50, 0xf8, 0x09, 0x0d, 0x03, 0x4e, 0x82,
 | 
						0x26, 0x74, 0x92, 0x0e, 0x83, 0x63, 0x10, 0x59, 0x50, 0xf8, 0x19, 0x0d, 0x03, 0x4e, 0x82, 0x8e,
 | 
				
			||||||
	0x8e, 0x74, 0x96, 0x22, 0x1e, 0xc2, 0xe8, 0x39, 0x54, 0xe2, 0xb5, 0x64, 0x68, 0x2e, 0x4a, 0x11,
 | 
						0x74, 0x96, 0x22, 0x1e, 0xc2, 0xe8, 0x39, 0x54, 0xe2, 0xb5, 0x64, 0x68, 0x2e, 0x4a, 0x11, 0x3f,
 | 
				
			||||||
	0x3f, 0x3e, 0x43, 0xc4, 0x31, 0x1a, 0x25, 0xd8, 0x38, 0x1f, 0xb4, 0x09, 0x0b, 0xdb, 0x6e, 0xfb,
 | 
						0x3e, 0x43, 0xc4, 0x31, 0x1a, 0x25, 0xd8, 0x38, 0x1f, 0xb4, 0x09, 0x0b, 0xdb, 0x6e, 0xfb, 0x05,
 | 
				
			||||||
	0x05, 0x91, 0x7e, 0x51, 0xaa, 0xaf, 0x4c, 0x33, 0x94, 0xc7, 0x4f, 0xa5, 0x23, 0x30, 0x19, 0xda,
 | 
						0x91, 0x7e, 0x51, 0xaa, 0xaf, 0x4c, 0x33, 0x94, 0xc7, 0x4f, 0xa5, 0x23, 0x30, 0x19, 0xda, 0x17,
 | 
				
			||||||
	0x17, 0xb0, 0x22, 0x41, 0x3f, 0x87, 0x72, 0x2b, 0xe0, 0x1e, 0xf7, 0x49, 0x4f, 0xde, 0x71, 0x51,
 | 
						0xb0, 0x22, 0x41, 0xbf, 0x84, 0x72, 0x2b, 0xe0, 0x1e, 0xf7, 0x49, 0x4f, 0xde, 0x71, 0x51, 0xdc,
 | 
				
			||||||
	0xdc, 0x71, 0x63, 0xf3, 0xeb, 0xd7, 0xab, 0x3f, 0x98, 0x99, 0xd1, 0xfa, 0xdc, 0xf3, 0x6b, 0x24,
 | 
						0x71, 0x63, 0xf3, 0xeb, 0xd7, 0xab, 0x3f, 0x9a, 0x99, 0xd1, 0xfa, 0xdc, 0xf3, 0x6b, 0x24, 0x41,
 | 
				
			||||||
	0x41, 0xe5, 0x24, 0x58, 0xe0, 0x31, 0x7e, 0xe8, 0x0b, 0x58, 0x8a, 0x85, 0xdd, 0x09, 0xa2, 0x3e,
 | 
						0xe5, 0x24, 0x58, 0xe0, 0x31, 0x7e, 0xe8, 0x0b, 0x58, 0x8a, 0x85, 0xdd, 0x09, 0xa2, 0x3e, 0x67,
 | 
				
			||||||
	0x67, 0x26, 0x48, 0xad, 0xeb, 0x73, 0x6a, 0xad, 0x88, 0x94, 0xda, 0x13, 0x9c, 0x84, 0xb1, 0x77,
 | 
						0x26, 0x48, 0xad, 0xeb, 0x73, 0x6a, 0xad, 0x88, 0x94, 0xda, 0x13, 0x9c, 0x84, 0xb1, 0x77, 0x02,
 | 
				
			||||||
	0x02, 0x4e, 0x68, 0xe0, 0xfa, 0xda, 0x69, 0x87, 0x30, 0xda, 0x11, 0xbe, 0x29, 0x12, 0xef, 0x9e,
 | 
						0x4e, 0x68, 0xe0, 0xfa, 0xda, 0x69, 0x87, 0x30, 0xda, 0x11, 0xbe, 0x29, 0x12, 0xef, 0x9e, 0x4c,
 | 
				
			||||||
	0x4c, 0xb7, 0x66, 0x59, 0x9a, 0xe6, 0xc6, 0xf4, 0x57, 0x93, 0xe9, 0xd9, 0x51, 0xc8, 0x78, 0x8c,
 | 
						0xb7, 0x66, 0x59, 0x9a, 0xe6, 0xc6, 0xf4, 0x57, 0x93, 0xe9, 0xd9, 0x51, 0xc8, 0x78, 0x8c, 0x14,
 | 
				
			||||||
	0x14, 0xdd, 0x83, 0x62, 0xec, 0x08, 0xcc, 0xac, 0x48, 0xe9, 0xad, 0x69, 0x3e, 0x31, 0x0a, 0x1e,
 | 
						0xdd, 0x83, 0x62, 0xec, 0x08, 0xcc, 0xac, 0x48, 0xe9, 0xad, 0x69, 0x3e, 0x31, 0x0a, 0x1e, 0x21,
 | 
				
			||||||
	0x21, 0x5b, 0x8f, 0xe1, 0xea, 0x69, 0x0e, 0x26, 0x02, 0xe6, 0x98, 0x0c, 0xe2, 0x80, 0x39, 0x26,
 | 
						0x5b, 0x8f, 0xe1, 0xea, 0x69, 0x0e, 0x26, 0x02, 0xe6, 0x98, 0x0c, 0xe2, 0x80, 0x39, 0x26, 0x03,
 | 
				
			||||||
	0x03, 0x91, 0xb3, 0x4e, 0x5c, 0xbf, 0xaf, 0x72, 0x59, 0x11, 0x2b, 0x60, 0x33, 0x73, 0xcf, 0xb0,
 | 
						0x91, 0xb3, 0x4e, 0x5c, 0xbf, 0xaf, 0x72, 0x59, 0x11, 0x2b, 0x60, 0x33, 0x73, 0xcf, 0xb0, 0x1e,
 | 
				
			||||||
	0x1e, 0x02, 0x9a, 0xf6, 0x84, 0x73, 0x71, 0xf8, 0x0c, 0x2e, 0xa5, 0x58, 0x35, 0x85, 0xc5, 0xf5,
 | 
						0x02, 0x9a, 0xf6, 0x84, 0x73, 0x71, 0xf8, 0x0c, 0x2e, 0xa5, 0x58, 0x35, 0x85, 0xc5, 0xf5, 0x24,
 | 
				
			||||||
	0x24, 0x8b, 0xe9, 0x80, 0x1d, 0xb1, 0xb4, 0xff, 0x92, 0x85, 0x72, 0xd2, 0xb7, 0xd0, 0x06, 0x5c,
 | 
						0x8b, 0xe9, 0x80, 0x1d, 0xb1, 0xb4, 0xff, 0x96, 0x85, 0x72, 0xd2, 0xb7, 0xd0, 0x06, 0x5c, 0x52,
 | 
				
			||||||
	0x52, 0x1a, 0x63, 0x72, 0x94, 0x08, 0x46, 0xc5, 0x3c, 0xed, 0x08, 0xd5, 0xe1, 0xf2, 0x4e, 0x4f,
 | 
						0x1a, 0x63, 0x72, 0x94, 0x08, 0x46, 0xc5, 0x3c, 0xed, 0x08, 0xd5, 0xe1, 0xf2, 0x4e, 0x4f, 0x6f,
 | 
				
			||||||
	0x6f, 0x27, 0xe3, 0x37, 0x23, 0x93, 0x4d, 0xea, 0x19, 0x0a, 0xe1, 0x03, 0xc5, 0x6a, 0x32, 0xe8,
 | 
						0x27, 0xe3, 0x37, 0x23, 0x93, 0x4d, 0xea, 0x19, 0x0a, 0xe1, 0x03, 0xc5, 0x6a, 0x32, 0xe8, 0xb3,
 | 
				
			||||||
	0xb3, 0xf2, 0x76, 0x3e, 0x39, 0x3d, 0x00, 0x9c, 0x54, 0x5a, 0xe5, 0x62, 0xe9, 0x7c, 0xd1, 0x8f,
 | 
						0xf2, 0x76, 0x3e, 0x39, 0x3d, 0x00, 0x9c, 0x54, 0x5a, 0xe5, 0x62, 0xe9, 0x7c, 0xd1, 0x4f, 0x60,
 | 
				
			||||||
	0x60, 0x51, 0x1d, 0x30, 0x9d, 0x57, 0x3e, 0x3a, 0xfd, 0x13, 0x8a, 0x59, 0x4c, 0x23, 0xc8, 0x95,
 | 
						0x51, 0x1d, 0x30, 0x9d, 0x57, 0x3e, 0x3a, 0xfd, 0x13, 0x8a, 0x59, 0x4c, 0x23, 0xc8, 0x95, 0x1e,
 | 
				
			||||||
	0x1e, 0xcc, 0x5c, 0x38, 0x07, 0xb9, 0xa6, 0xb1, 0x1e, 0x81, 0x35, 0x5b, 0xe4, 0xf3, 0xb8, 0x80,
 | 
						0xcc, 0x5c, 0x38, 0x07, 0xb9, 0xa6, 0xb1, 0x1e, 0x81, 0x35, 0x5b, 0xe4, 0xf3, 0xb8, 0x80, 0xfd,
 | 
				
			||||||
	0xfd, 0x67, 0x03, 0x96, 0xa7, 0x3e, 0x24, 0x9e, 0x44, 0xf9, 0x28, 0x28, 0x16, 0x72, 0x8d, 0x9a,
 | 
						0x57, 0x03, 0x96, 0xa7, 0x3e, 0x24, 0x9e, 0x44, 0xf9, 0x28, 0x28, 0x16, 0x72, 0x8d, 0x9a, 0xb0,
 | 
				
			||||||
	0xb0, 0xa0, 0x92, 0x54, 0x46, 0x0a, 0xec, 0xcc, 0x21, 0xb0, 0x93, 0xc8, 0x50, 0x8a, 0xd8, 0xba,
 | 
						0xa0, 0x92, 0x54, 0x46, 0x0a, 0xec, 0xcc, 0x21, 0xb0, 0x93, 0xc8, 0x50, 0x8a, 0xd8, 0xba, 0x07,
 | 
				
			||||||
	0x07, 0xf0, 0x76, 0xce, 0x6a, 0xff, 0xd5, 0x80, 0x8a, 0x4e, 0x08, 0xba, 0x7e, 0x70, 0xa1, 0x3a,
 | 
						0xf0, 0x76, 0xce, 0x6a, 0xff, 0xdd, 0x80, 0x8a, 0x4e, 0x08, 0xba, 0x7e, 0x70, 0xa1, 0x3a, 0x8c,
 | 
				
			||||||
	0x8c, 0x31, 0xbd, 0xa7, 0x2b, 0x89, 0x3b, 0x33, 0x73, 0x89, 0x42, 0x73, 0x26, 0xe9, 0x94, 0x8c,
 | 
						0x31, 0xbd, 0xa7, 0x2b, 0x89, 0x3b, 0x33, 0x73, 0x89, 0x42, 0x73, 0x26, 0xe9, 0x94, 0x8c, 0x53,
 | 
				
			||||||
	0x53, 0xec, 0xac, 0xed, 0xd8, 0xaf, 0x26, 0x50, 0xcf, 0x25, 0xf9, 0x35, 0xa8, 0xec, 0xcb, 0x3a,
 | 
						0xec, 0xac, 0xed, 0xd8, 0xaf, 0x26, 0x50, 0xcf, 0x25, 0xf9, 0x35, 0xa8, 0xec, 0xcb, 0x3a, 0x75,
 | 
				
			||||||
	0x75, 0xe6, 0xb3, 0x68, 0xff, 0xd7, 0x80, 0xa5, 0x18, 0x47, 0x6b, 0xf7, 0x7d, 0x28, 0x9c, 0x10,
 | 
						0xe6, 0xb3, 0x68, 0xff, 0xd7, 0x80, 0xa5, 0x18, 0x47, 0x6b, 0xf7, 0x43, 0x28, 0x9c, 0x10, 0xca,
 | 
				
			||||||
	0xca, 0xc9, 0x4b, 0xc2, 0xb4, 0x56, 0xe6, 0xb4, 0x56, 0x9f, 0x4b, 0x0c, 0x3c, 0xc4, 0x44, 0x9b,
 | 
						0xc9, 0x4b, 0xc2, 0xb4, 0x56, 0xe6, 0xb4, 0x56, 0x9f, 0x4b, 0x0c, 0x3c, 0xc4, 0x44, 0x9b, 0x50,
 | 
				
			||||||
	0x50, 0x50, 0x35, 0x31, 0x89, 0x2f, 0x6a, 0x65, 0x16, 0x95, 0xfe, 0xde, 0x10, 0x1f, 0xd5, 0x20,
 | 
						0x50, 0x35, 0x31, 0x89, 0x2f, 0x6a, 0x65, 0x16, 0x95, 0xfe, 0xde, 0x10, 0x1f, 0xd5, 0x20, 0xe7,
 | 
				
			||||||
	0xe7, 0x87, 0x5d, 0xa6, 0x63, 0xe6, 0x5b, 0xb3, 0xe8, 0x9e, 0x84, 0x5d, 0x2c, 0x11, 0xd1, 0x7d,
 | 
						0x87, 0x5d, 0xa6, 0x63, 0xe6, 0x3b, 0xb3, 0xe8, 0x9e, 0x84, 0x5d, 0x2c, 0x11, 0xd1, 0x7d, 0x28,
 | 
				
			||||||
	0x28, 0x7c, 0xe5, 0xd2, 0xc0, 0x0b, 0xba, 0x71, 0x14, 0xac, 0xce, 0x22, 0x7a, 0xae, 0xf0, 0xf0,
 | 
						0x7c, 0xe5, 0xd2, 0xc0, 0x0b, 0xba, 0x71, 0x14, 0xac, 0xce, 0x22, 0x7a, 0xae, 0xf0, 0xf0, 0x90,
 | 
				
			||||||
	0x90, 0x40, 0x94, 0x71, 0x79, 0x75, 0x86, 0x1e, 0x43, 0xbe, 0xe3, 0x75, 0x09, 0xe3, 0xca, 0x24,
 | 
						0x40, 0x94, 0x71, 0x79, 0x75, 0x86, 0x1e, 0x43, 0xbe, 0xe3, 0x75, 0x09, 0xe3, 0xca, 0x24, 0x8d,
 | 
				
			||||||
	0x8d, 0xba, 0x78, 0x8f, 0xbe, 0x7e, 0xbd, 0x7a, 0x33, 0xf1, 0xe0, 0x84, 0x11, 0x09, 0x44, 0xd3,
 | 
						0xba, 0x78, 0x8f, 0xbe, 0x7e, 0xbd, 0x7a, 0x33, 0xf1, 0xe0, 0x84, 0x11, 0x09, 0x44, 0xd3, 0xe0,
 | 
				
			||||||
	0xe0, 0x7a, 0x01, 0xa1, 0xa2, 0x07, 0xb8, 0xad, 0x48, 0x9c, 0xa6, 0xfc, 0xc1, 0x9a, 0x83, 0xe0,
 | 
						0x7a, 0x01, 0xa1, 0xa2, 0x07, 0xb8, 0xad, 0x48, 0x9c, 0xa6, 0xfc, 0xc1, 0x9a, 0x83, 0xe0, 0xe5,
 | 
				
			||||||
	0xe5, 0xa9, 0x67, 0x45, 0xe6, 0x8b, 0xb7, 0xe3, 0xa5, 0x38, 0x88, 0x30, 0x08, 0xdc, 0x1e, 0xd1,
 | 
						0xa9, 0x67, 0x45, 0xe6, 0x8b, 0xb7, 0xe3, 0xa5, 0x38, 0x88, 0x30, 0x08, 0xdc, 0x1e, 0xd1, 0xe5,
 | 
				
			||||||
	0xe5, 0x86, 0x5c, 0x8b, 0xaa, 0xa8, 0x2d, 0xfc, 0xbc, 0x23, 0xeb, 0xc5, 0x02, 0xd6, 0x10, 0xda,
 | 
						0x86, 0x5c, 0x8b, 0xaa, 0xa8, 0x2d, 0xfc, 0xbc, 0x23, 0xeb, 0xc5, 0x02, 0xd6, 0x10, 0xda, 0x84,
 | 
				
			||||||
	0x84, 0x45, 0xc6, 0x5d, 0x2a, 0x72, 0xce, 0xc2, 0x9c, 0xe5, 0x5c, 0x4c, 0x80, 0x1e, 0x40, 0xb1,
 | 
						0x45, 0xc6, 0x5d, 0x2a, 0x72, 0xce, 0xc2, 0x9c, 0xe5, 0x5c, 0x4c, 0x80, 0x1e, 0x40, 0xb1, 0x1d,
 | 
				
			||||||
	0x1d, 0xf6, 0x22, 0x9f, 0x08, 0xea, 0xfc, 0x9c, 0xd4, 0x23, 0x12, 0xe1, 0x7a, 0x84, 0xd2, 0x90,
 | 
						0xf6, 0x22, 0x9f, 0x08, 0xea, 0xfc, 0x9c, 0xd4, 0x23, 0x12, 0xe1, 0x7a, 0x84, 0xd2, 0x90, 0xca,
 | 
				
			||||||
	0xca, 0x42, 0xb2, 0x88, 0x15, 0x80, 0xee, 0x42, 0x25, 0xa2, 0x61, 0x97, 0x12, 0xc6, 0x3e, 0xa5,
 | 
						0x42, 0xb2, 0x88, 0x15, 0x80, 0xee, 0x42, 0x25, 0xa2, 0x61, 0x97, 0x12, 0xc6, 0x3e, 0xa5, 0x61,
 | 
				
			||||||
	0x61, 0x3f, 0xd2, 0xc5, 0xc0, 0xb2, 0x48, 0xde, 0x7b, 0xc9, 0x03, 0x3c, 0x8e, 0x67, 0xff, 0x27,
 | 
						0x3f, 0xd2, 0xc5, 0xc0, 0xb2, 0x48, 0xde, 0x7b, 0xc9, 0x03, 0x3c, 0x8e, 0x67, 0xff, 0x27, 0x03,
 | 
				
			||||||
	0x03, 0xe5, 0xa4, 0x8b, 0x4c, 0x55, 0xd8, 0x8f, 0x21, 0xaf, 0x1c, 0x4e, 0xf9, 0xfa, 0xdb, 0xd9,
 | 
						0xe5, 0xa4, 0x8b, 0x4c, 0x55, 0xd8, 0x8f, 0x21, 0xaf, 0x1c, 0x4e, 0xf9, 0xfa, 0xdb, 0xd9, 0x58,
 | 
				
			||||||
	0x58, 0x71, 0x48, 0xb5, 0xb1, 0x09, 0x8b, 0xed, 0x3e, 0x95, 0xe5, 0xb7, 0x2a, 0xca, 0x63, 0x50,
 | 
						0x71, 0x48, 0xb5, 0xb1, 0x09, 0x8b, 0xed, 0x3e, 0x95, 0xe5, 0xb7, 0x2a, 0xca, 0x63, 0x50, 0x68,
 | 
				
			||||||
	0x68, 0xca, 0x43, 0xee, 0xfa, 0xd2, 0xc6, 0x59, 0xac, 0x00, 0x51, 0x91, 0x0f, 0xbb, 0xa4, 0xf3,
 | 
						0xca, 0x43, 0xee, 0xfa, 0xd2, 0xc6, 0x59, 0xac, 0x00, 0x51, 0x91, 0x0f, 0xbb, 0xa4, 0xf3, 0x55,
 | 
				
			||||||
	0x55, 0xe4, 0x43, 0xb2, 0xe4, 0xfd, 0x2d, 0xbe, 0xd3, 0xfd, 0x15, 0xce, 0x7d, 0x7f, 0xf6, 0x3f,
 | 
						0xe4, 0x43, 0xb2, 0xe4, 0xfd, 0x2d, 0xbe, 0xd3, 0xfd, 0x15, 0xce, 0x7d, 0x7f, 0xf6, 0x3f, 0x0d,
 | 
				
			||||||
	0x0c, 0x28, 0x0e, 0x63, 0x2b, 0x61, 0x5d, 0xe3, 0x9d, 0xad, 0x3b, 0x66, 0x99, 0xcc, 0xdb, 0x59,
 | 
						0x28, 0x0e, 0x63, 0x2b, 0x61, 0x5d, 0xe3, 0x9d, 0xad, 0x3b, 0x66, 0x99, 0xcc, 0xdb, 0x59, 0xe6,
 | 
				
			||||||
	0xe6, 0x0a, 0xe4, 0x19, 0xa7, 0xc4, 0xed, 0xa9, 0x7e, 0x11, 0x6b, 0x48, 0x64, 0xb1, 0x1e, 0xeb,
 | 
						0x0a, 0xe4, 0x19, 0xa7, 0xc4, 0xed, 0xa9, 0x7e, 0x11, 0x6b, 0x48, 0x64, 0xb1, 0x1e, 0xeb, 0xca,
 | 
				
			||||||
	0xca, 0x1b, 0x2a, 0x63, 0xb1, 0xb4, 0xff, 0x67, 0x40, 0x65, 0x2c, 0xdc, 0xdf, 0xab, 0x2e, 0x97,
 | 
						0x1b, 0x2a, 0x63, 0xb1, 0xb4, 0xff, 0x67, 0x40, 0x65, 0x2c, 0xdc, 0xdf, 0xab, 0x2e, 0x97, 0x61,
 | 
				
			||||||
	0x61, 0xc1, 0x27, 0x27, 0x44, 0x75, 0xb4, 0x59, 0xac, 0x00, 0xb1, 0xcb, 0x5e, 0x84, 0x94, 0x4b,
 | 
						0xc1, 0x27, 0x27, 0x44, 0x75, 0xb4, 0x59, 0xac, 0x00, 0xb1, 0xcb, 0x5e, 0x84, 0x94, 0x4b, 0xe1,
 | 
				
			||||||
	0xe1, 0xca, 0x58, 0x01, 0x42, 0xe6, 0x0e, 0xe1, 0xae, 0xe7, 0xcb, 0xbc, 0x54, 0xc6, 0x1a, 0x12,
 | 
						0xca, 0x58, 0x01, 0x42, 0xe6, 0x0e, 0xe1, 0xae, 0xe7, 0xcb, 0xbc, 0x54, 0xc6, 0x1a, 0x12, 0x32,
 | 
				
			||||||
	0x32, 0xf7, 0xa9, 0xaf, 0x6b, 0x74, 0xb1, 0x44, 0x36, 0xe4, 0xbc, 0xe0, 0x28, 0xd4, 0x6e, 0x23,
 | 
						0xf7, 0xa9, 0xaf, 0x6b, 0x74, 0xb1, 0x44, 0x36, 0xe4, 0xbc, 0xe0, 0x28, 0xd4, 0x6e, 0x23, 0x2b,
 | 
				
			||||||
	0x2b, 0x1b, 0x55, 0xeb, 0xed, 0x04, 0x47, 0x21, 0x96, 0x67, 0xe8, 0x1a, 0xe4, 0xa9, 0x1b, 0x74,
 | 
						0x1b, 0x55, 0xeb, 0xed, 0x04, 0x47, 0x21, 0x96, 0x67, 0xe8, 0x1a, 0xe4, 0xa9, 0x1b, 0x74, 0x49,
 | 
				
			||||||
	0x49, 0x5c, 0xa0, 0x17, 0x05, 0x16, 0x16, 0x3b, 0x58, 0x1f, 0xd8, 0x36, 0x94, 0x65, 0x57, 0xbc,
 | 
						0x5c, 0xa0, 0x17, 0x05, 0x16, 0x16, 0x3b, 0x58, 0x1f, 0xd8, 0x36, 0x94, 0x65, 0x57, 0xbc, 0x4b,
 | 
				
			||||||
	0x4b, 0x98, 0xe8, 0xc1, 0x84, 0x5b, 0x77, 0x5c, 0xee, 0x4a, 0xb5, 0xcb, 0x58, 0xae, 0xed, 0x5b,
 | 
						0x98, 0xe8, 0xc1, 0x84, 0x5b, 0x77, 0x5c, 0xee, 0x4a, 0xb5, 0xcb, 0x58, 0xae, 0xed, 0x5b, 0x80,
 | 
				
			||||||
	0x80, 0x9e, 0x78, 0x8c, 0x3f, 0x97, 0x33, 0x05, 0x76, 0x56, 0xcb, 0xbc, 0x0f, 0x97, 0xc6, 0xb0,
 | 
						0x9e, 0x78, 0x8c, 0x3f, 0x97, 0x33, 0x05, 0x76, 0x56, 0xcb, 0xbc, 0x0f, 0x97, 0xc6, 0xb0, 0xf5,
 | 
				
			||||||
	0xf5, 0xb3, 0xf0, 0xc3, 0x89, 0xa6, 0xf9, 0xfa, 0x74, 0xc6, 0x95, 0xa3, 0x0b, 0x47, 0x11, 0x4e,
 | 
						0xb3, 0xf0, 0xe3, 0x89, 0xa6, 0xf9, 0xfa, 0x74, 0xc6, 0x95, 0xa3, 0x0b, 0x47, 0x11, 0x4e, 0xf4,
 | 
				
			||||||
	0xf4, 0xce, 0x15, 0x28, 0x49, 0xbd, 0xd4, 0xb7, 0x6d, 0x17, 0xca, 0x0a, 0xd4, 0xcc, 0x3f, 0x83,
 | 
						0xce, 0x15, 0x28, 0x49, 0xbd, 0xd4, 0xb7, 0x6d, 0x17, 0xca, 0x0a, 0xd4, 0xcc, 0x3f, 0x83, 0x8b,
 | 
				
			||||||
	0x8b, 0x31, 0xa3, 0xcf, 0x09, 0x95, 0xed, 0x8c, 0x21, 0xed, 0xf2, 0x9d, 0x59, 0x5f, 0x69, 0x8c,
 | 
						0x31, 0xa3, 0xcf, 0x09, 0x95, 0xed, 0x8c, 0x21, 0xed, 0xf2, 0xbd, 0x59, 0x5f, 0x69, 0x8c, 0xa3,
 | 
				
			||||||
	0xa3, 0xe3, 0x49, 0x7a, 0x9b, 0xc0, 0x25, 0x89, 0xf3, 0xc8, 0x63, 0x3c, 0xa4, 0x83, 0x58, 0xeb,
 | 
						0xe3, 0x49, 0x7a, 0x9b, 0xc0, 0x25, 0x89, 0xf3, 0xc8, 0x63, 0x3c, 0xa4, 0x83, 0x58, 0xeb, 0x15,
 | 
				
			||||||
	0x15, 0x80, 0xad, 0x36, 0xf7, 0x4e, 0xc8, 0xd3, 0xc0, 0x57, 0xcf, 0x68, 0x01, 0x27, 0x76, 0xe2,
 | 
						0x80, 0xad, 0x36, 0xf7, 0x4e, 0xc8, 0xd3, 0xc0, 0x57, 0xcf, 0x68, 0x01, 0x27, 0x76, 0xe2, 0x27,
 | 
				
			||||||
	0x27, 0x32, 0x33, 0xea, 0x1c, 0xaf, 0x42, 0xb1, 0xe5, 0x52, 0x7f, 0xd0, 0x7a, 0xe9, 0x71, 0xdd,
 | 
						0x32, 0x33, 0xea, 0x1c, 0xaf, 0x42, 0xb1, 0xe5, 0x52, 0x7f, 0xd0, 0x7a, 0xe9, 0x71, 0xdd, 0xc0,
 | 
				
			||||||
	0xc0, 0x8f, 0x36, 0xec, 0xdf, 0x19, 0xb0, 0x9c, 0xfc, 0x4e, 0xeb, 0x44, 0xa4, 0x8b, 0xfb, 0x90,
 | 
						0x8f, 0x36, 0xec, 0x3f, 0x18, 0xb0, 0x9c, 0xfc, 0x4e, 0xeb, 0x44, 0xa4, 0x8b, 0xfb, 0x90, 0xe3,
 | 
				
			||||||
	0xe3, 0x71, 0x1d, 0xb3, 0x94, 0xa6, 0xc4, 0x14, 0x89, 0x28, 0x75, 0xb0, 0x24, 0x4a, 0x58, 0x5a,
 | 
						0x71, 0x1d, 0xb3, 0x94, 0xa6, 0xc4, 0x14, 0x89, 0x28, 0x75, 0xb0, 0x24, 0x4a, 0x58, 0x5a, 0x05,
 | 
				
			||||||
	0x05, 0xce, 0xf5, 0xd3, 0xc9, 0x27, 0x2c, 0xfd, 0xb7, 0x22, 0xa0, 0xe9, 0xe3, 0x94, 0x8e, 0x38,
 | 
						0xce, 0xf5, 0xd3, 0xc9, 0x27, 0x2c, 0xfd, 0x4d, 0x11, 0xd0, 0xf4, 0x71, 0x4a, 0x47, 0x9c, 0x6c,
 | 
				
			||||||
	0xd9, 0x20, 0x66, 0x26, 0x1a, 0xc4, 0x2f, 0x27, 0x1b, 0x44, 0xf5, 0x34, 0xdf, 0x9d, 0x47, 0x92,
 | 
						0x10, 0x33, 0x13, 0x0d, 0xe2, 0x97, 0x93, 0x0d, 0xa2, 0x7a, 0x9a, 0xef, 0xce, 0x23, 0xc9, 0x1c,
 | 
				
			||||||
	0x39, 0xda, 0xc4, 0xb1, 0x3e, 0x26, 0x77, 0x8e, 0x3e, 0x06, 0xad, 0xc7, 0x2f, 0x8e, 0x7a, 0xeb,
 | 
						0x6d, 0xe2, 0x58, 0x1f, 0x93, 0x3b, 0x47, 0x1f, 0x83, 0xd6, 0xe3, 0x17, 0x47, 0xbd, 0x75, 0x28,
 | 
				
			||||||
	0x50, 0x9c, 0x53, 0x68, 0xd4, 0x76, 0x74, 0x5d, 0xa1, 0x5f, 0xa1, 0x07, 0xe7, 0x9b, 0x96, 0xe4,
 | 
						0xce, 0x29, 0x34, 0x6a, 0x3b, 0xba, 0xae, 0xd0, 0xaf, 0xd0, 0x83, 0xf3, 0x4d, 0x4b, 0x72, 0x93,
 | 
				
			||||||
	0x26, 0x27, 0x25, 0x0d, 0x28, 0x6d, 0xc7, 0x89, 0xf2, 0x1c, 0xa3, 0x92, 0x24, 0x11, 0xda, 0xd0,
 | 
						0x93, 0x92, 0x06, 0x94, 0xb6, 0xe3, 0x44, 0x79, 0x8e, 0x51, 0x49, 0x92, 0x08, 0x6d, 0xe8, 0xc2,
 | 
				
			||||||
	0x85, 0x8d, 0x4a, 0xcd, 0x57, 0xa7, 0x55, 0x8c, 0xc7, 0x22, 0x21, 0xd5, 0x95, 0xcd, 0x51, 0x4a,
 | 
						0x46, 0xa5, 0xe6, 0xab, 0xd3, 0x2a, 0xc6, 0x63, 0x91, 0x90, 0xea, 0xca, 0xe6, 0x28, 0xa5, 0xb4,
 | 
				
			||||||
	0x69, 0x59, 0x94, 0x06, 0xda, 0x9c, 0xcb, 0xf6, 0x73, 0xd6, 0x97, 0xe8, 0x13, 0xc8, 0x63, 0xc2,
 | 
						0x2c, 0x4a, 0x03, 0x6d, 0xce, 0x65, 0xfb, 0x39, 0xeb, 0x4b, 0xf4, 0x09, 0xe4, 0x31, 0x61, 0x7d,
 | 
				
			||||||
	0xfa, 0x3e, 0x97, 0xf3, 0x97, 0x52, 0xfd, 0xda, 0x0c, 0xee, 0x0a, 0x49, 0xc6, 0xaa, 0x26, 0x40,
 | 
						0x9f, 0xcb, 0xf9, 0x4b, 0xa9, 0x7e, 0x6d, 0x06, 0x77, 0x85, 0x24, 0x63, 0x55, 0x13, 0xa0, 0x9f,
 | 
				
			||||||
	0x3f, 0x85, 0x45, 0xb5, 0x62, 0x66, 0x69, 0xd6, 0xd8, 0x20, 0x45, 0x32, 0x4d, 0xa3, 0x1b, 0x0a,
 | 
						0xc3, 0xa2, 0x5a, 0x31, 0xb3, 0x34, 0x6b, 0x6c, 0x90, 0x22, 0x99, 0xa6, 0xd1, 0x0d, 0x85, 0x86,
 | 
				
			||||||
	0x0d, 0x89, 0x70, 0xfc, 0x94, 0x04, 0x44, 0xcf, 0x05, 0x45, 0x6b, 0xbc, 0x80, 0x13, 0x3b, 0xa8,
 | 
						0x44, 0x38, 0x7e, 0x4a, 0x02, 0xa2, 0xe7, 0x82, 0xa2, 0x35, 0x5e, 0xc0, 0x89, 0x1d, 0x54, 0x87,
 | 
				
			||||||
	0x0e, 0x0b, 0x9c, 0xba, 0x6d, 0x62, 0x56, 0xe6, 0x30, 0xa1, 0x42, 0x15, 0x89, 0x2d, 0xf2, 0x82,
 | 
						0x05, 0x4e, 0xdd, 0x36, 0x31, 0x2b, 0x73, 0x98, 0x50, 0xa1, 0x8a, 0xc4, 0x16, 0x79, 0x41, 0x40,
 | 
				
			||||||
	0x80, 0x74, 0xcc, 0x25, 0x55, 0x29, 0x29, 0x08, 0x7d, 0x1b, 0x96, 0x82, 0x7e, 0x4f, 0x36, 0x0b,
 | 
						0x3a, 0xe6, 0x92, 0xaa, 0x94, 0x14, 0x84, 0xbe, 0x0b, 0x4b, 0x41, 0xbf, 0x27, 0x9b, 0x85, 0xce,
 | 
				
			||||||
	0x9d, 0x7d, 0x4e, 0x22, 0x66, 0x5e, 0x94, 0xdf, 0x9b, 0xd8, 0x45, 0xd7, 0xa1, 0x12, 0xf4, 0x7b,
 | 
						0x3e, 0x27, 0x11, 0x33, 0x2f, 0xca, 0xef, 0x4d, 0xec, 0xa2, 0xeb, 0x50, 0x09, 0xfa, 0xbd, 0x03,
 | 
				
			||||||
	0x07, 0xe2, 0x85, 0x57, 0x68, 0x55, 0x89, 0x36, 0xbe, 0x89, 0x6e, 0xc1, 0xb2, 0xa0, 0x8b, 0x6f,
 | 
						0xf1, 0xc2, 0x2b, 0xb4, 0xaa, 0x44, 0x1b, 0xdf, 0x44, 0xb7, 0x60, 0x59, 0xd0, 0xc5, 0xb7, 0xad,
 | 
				
			||||||
	0x5b, 0x61, 0x2e, 0x4b, 0xcc, 0xe9, 0x03, 0xd4, 0x80, 0x0a, 0x79, 0xa9, 0x06, 0x02, 0x2d, 0xe9,
 | 
						0x30, 0x97, 0x25, 0xe6, 0xf4, 0x01, 0x6a, 0x40, 0x85, 0xbc, 0x54, 0x03, 0x81, 0x96, 0xf4, 0x5f,
 | 
				
			||||||
	0xbf, 0x68, 0x0e, 0x7d, 0xc6, 0x49, 0xde, 0x43, 0xdf, 0xfd, 0x3e, 0xba, 0x0a, 0xeb, 0x4b, 0x28,
 | 
						0x34, 0x87, 0x3e, 0xe3, 0x24, 0x68, 0x0d, 0x4a, 0x41, 0xbf, 0xf7, 0x3c, 0x2e, 0x7c, 0x2f, 0xc9,
 | 
				
			||||||
	0x27, 0xef, 0x32, 0x85, 0xf6, 0xee, 0x78, 0xd7, 0x3e, 0x87, 0x6f, 0x25, 0x9a, 0x96, 0x01, 0x7c,
 | 
						0x6f, 0x25, 0xb7, 0xde, 0x43, 0x67, 0xfe, 0x3e, 0xfa, 0x0e, 0xeb, 0x4b, 0x28, 0x27, 0x6f, 0x3b,
 | 
				
			||||||
	0xf3, 0x59, 0xd4, 0x71, 0x39, 0x49, 0xcb, 0xde, 0xd3, 0x59, 0xec, 0x0a, 0xe4, 0xf7, 0xd4, 0x65,
 | 
						0x85, 0xf6, 0xee, 0x78, 0x5f, 0x3f, 0x87, 0xf7, 0x25, 0xda, 0x9a, 0x01, 0x7c, 0xfb, 0x59, 0xd4,
 | 
				
			||||||
	0xab, 0x99, 0xab, 0x86, 0xc4, 0x7e, 0x93, 0x88, 0x0b, 0xd0, 0x29, 0x5b, 0x43, 0x32, 0xeb, 0x79,
 | 
						0x71, 0x39, 0x49, 0xcb, 0xef, 0xd3, 0x79, 0xee, 0x0a, 0xe4, 0xf7, 0x94, 0x3b, 0xa8, 0xa9, 0xac,
 | 
				
			||||||
	0x81, 0xeb, 0xc7, 0x83, 0xd7, 0x02, 0x1e, 0xc2, 0xf6, 0x55, 0xb0, 0xd2, 0x3e, 0xad, 0x0c, 0x65,
 | 
						0x86, 0xc4, 0x7e, 0x93, 0x88, 0x2b, 0xd2, 0x49, 0x5d, 0x43, 0x32, 0x2f, 0x7a, 0x81, 0xeb, 0xc7,
 | 
				
			||||||
	0xff, 0x29, 0x03, 0x30, 0xba, 0x1c, 0xf4, 0x21, 0x40, 0x8f, 0x74, 0x3c, 0xf7, 0x17, 0x7c, 0xd4,
 | 
						0xa3, 0xd9, 0x02, 0x1e, 0xc2, 0xf6, 0x55, 0xb0, 0xd2, 0x3e, 0xad, 0x0c, 0x65, 0xff, 0x25, 0x03,
 | 
				
			||||||
	0xb0, 0x16, 0xe5, 0x8e, 0xec, 0x5a, 0x47, 0xad, 0x45, 0xe6, 0x9d, 0x5b, 0x0b, 0x04, 0x39, 0x26,
 | 
						0x30, 0xba, 0x3e, 0xf4, 0x21, 0x40, 0x8f, 0x74, 0x3c, 0xf7, 0x57, 0x7c, 0xd4, 0xd2, 0x16, 0xe5,
 | 
				
			||||||
	0xe4, 0x55, 0x65, 0x90, 0x5c, 0xa3, 0xa7, 0x50, 0x72, 0x83, 0x20, 0xe4, 0x32, 0x4c, 0xe2, 0x66,
 | 
						0x8e, 0xec, 0x6b, 0x47, 0xcd, 0x47, 0xe6, 0x9d, 0x9b, 0x0f, 0x04, 0x39, 0x26, 0xe4, 0x55, 0x85,
 | 
				
			||||||
	0xfe, 0xf6, 0x69, 0xee, 0xe4, 0x6c, 0x8d, 0xf0, 0x55, 0x14, 0x26, 0x39, 0x58, 0x0f, 0xa0, 0x3a,
 | 
						0x92, 0x5c, 0xa3, 0xa7, 0x50, 0x72, 0x83, 0x20, 0xe4, 0x32, 0x90, 0xe2, 0x76, 0xff, 0xf6, 0x69,
 | 
				
			||||||
	0x89, 0x70, 0xae, 0x66, 0xf3, 0xef, 0x19, 0xb8, 0x38, 0x71, 0xad, 0xe8, 0x11, 0x54, 0x15, 0x34,
 | 
						0x0e, 0xe7, 0x6c, 0x8d, 0xf0, 0x55, 0x9c, 0x26, 0x39, 0x58, 0x0f, 0xa0, 0x3a, 0x89, 0x70, 0xae,
 | 
				
			||||||
	0x31, 0x80, 0x39, 0xcb, 0xf1, 0xa7, 0xa8, 0xd0, 0x43, 0x28, 0x6f, 0x71, 0x2e, 0x32, 0xad, 0xd2,
 | 
						0x76, 0xf4, 0x1f, 0x19, 0xb8, 0x38, 0x71, 0xad, 0xe8, 0x11, 0x54, 0x15, 0x34, 0x31, 0xa2, 0x39,
 | 
				
			||||||
	0x57, 0xb5, 0x98, 0xa7, 0x73, 0x19, 0xa3, 0x40, 0x8f, 0x46, 0x69, 0x2b, 0x3b, 0x6b, 0x90, 0x30,
 | 
						0x2b, 0x34, 0xa6, 0xa8, 0xd0, 0x43, 0x28, 0x6f, 0x71, 0x2e, 0x72, 0xb1, 0xd2, 0x57, 0x35, 0xa1,
 | 
				
			||||||
	0x21, 0x7f, 0x7a, 0xce, 0xb2, 0x7e, 0x36, 0x3b, 0x00, 0xb2, 0xca, 0x4a, 0xf5, 0xf1, 0x00, 0x38,
 | 
						0xa7, 0x73, 0x19, 0xa3, 0x40, 0x8f, 0x46, 0x89, 0x2d, 0x3b, 0x6b, 0xd4, 0x30, 0x21, 0x7f, 0x7a,
 | 
				
			||||||
	0x23, 0x6b, 0x8d, 0x6c, 0xf8, 0x07, 0x03, 0x0a, 0x71, 0x80, 0xa6, 0xce, 0x42, 0xee, 0x8f, 0xcf,
 | 
						0x56, 0xb3, 0x7e, 0x31, 0x3b, 0x00, 0xb2, 0xca, 0x4a, 0xf5, 0xf1, 0x00, 0x38, 0x23, 0xaf, 0x8d,
 | 
				
			||||||
	0x42, 0x6e, 0xcc, 0x7e, 0x34, 0xdf, 0xe7, 0x08, 0xe4, 0xe6, 0x8f, 0xe1, 0x83, 0xd4, 0x82, 0x05,
 | 
						0x6c, 0xf8, 0x27, 0x03, 0x0a, 0x71, 0x80, 0xa6, 0x4e, 0x4b, 0xee, 0x8f, 0x4f, 0x4b, 0x6e, 0xcc,
 | 
				
			||||||
	0x95, 0x60, 0x71, 0xff, 0x60, 0x0b, 0x1f, 0xb4, 0x9a, 0xd5, 0x0b, 0xa8, 0x0c, 0x85, 0xed, 0xa7,
 | 
						0x7e, 0x56, 0xdf, 0xe7, 0x90, 0xe4, 0xe6, 0x4f, 0xe1, 0x83, 0xd4, 0x92, 0x06, 0x95, 0x60, 0x71,
 | 
				
			||||||
	0xbb, 0x7b, 0x4f, 0x5a, 0x07, 0xad, 0xaa, 0x21, 0x8e, 0x9a, 0x2d, 0xb1, 0x6e, 0x56, 0x33, 0xf5,
 | 
						0xff, 0x60, 0x0b, 0x1f, 0xb4, 0x9a, 0xd5, 0x0b, 0xa8, 0x0c, 0x85, 0xed, 0xa7, 0xbb, 0x7b, 0x4f,
 | 
				
			||||||
	0xdf, 0xe6, 0x61, 0x71, 0x5b, 0xfd, 0xf3, 0x86, 0x0e, 0xa0, 0x38, 0xfc, 0x4b, 0x06, 0xd9, 0x29,
 | 
						0x5a, 0x07, 0xad, 0xaa, 0x21, 0x8e, 0x9a, 0x2d, 0xb1, 0x6e, 0x56, 0x33, 0xf5, 0xdf, 0xe7, 0x61,
 | 
				
			||||||
	0xa6, 0x99, 0xf8, 0x6f, 0xc7, 0xfa, 0xe8, 0x54, 0x1c, 0xfd, 0xa0, 0x3d, 0x82, 0x05, 0xf9, 0xe7,
 | 
						0x71, 0x5b, 0xfd, 0x37, 0x87, 0x0e, 0xa0, 0x38, 0xfc, 0xd3, 0x06, 0xd9, 0x29, 0xa6, 0x99, 0xf8,
 | 
				
			||||||
	0x14, 0x4a, 0x19, 0x3b, 0x24, 0xff, 0xb5, 0xb2, 0x4e, 0xff, 0xb3, 0x67, 0xc3, 0x10, 0x9c, 0xe4,
 | 
						0xf7, 0xc7, 0xfa, 0xe8, 0x54, 0x1c, 0xfd, 0xe4, 0x3d, 0x82, 0x05, 0xf9, 0xf7, 0x15, 0x4a, 0x19,
 | 
				
			||||||
	0xcc, 0x26, 0x8d, 0x53, 0x72, 0x30, 0x6c, 0xad, 0x9e, 0x31, 0xec, 0x41, 0xbb, 0x90, 0xd7, 0x8d,
 | 
						0x4c, 0x24, 0xff, 0xd7, 0xb2, 0x4e, 0xff, 0x3b, 0x68, 0xc3, 0x10, 0x9c, 0xe4, 0x54, 0x27, 0x8d,
 | 
				
			||||||
	0x6c, 0x1a, 0x6a, 0x72, 0x32, 0x63, 0xad, 0xcd, 0x46, 0x50, 0xcc, 0x36, 0x0c, 0xb4, 0x3b, 0x9c,
 | 
						0x53, 0x72, 0x74, 0x6c, 0xad, 0x9e, 0x31, 0x0e, 0x42, 0xbb, 0x90, 0xd7, 0xad, 0x6e, 0x1a, 0x6a,
 | 
				
			||||||
	0xf5, 0xa7, 0x89, 0x96, 0xec, 0x02, 0xac, 0x33, 0xce, 0xd7, 0x8d, 0x0d, 0x03, 0x7d, 0x01, 0xa5,
 | 
						0x72, 0x76, 0x63, 0xad, 0xcd, 0x46, 0x50, 0xcc, 0x36, 0x0c, 0xb4, 0x3b, 0xfc, 0x37, 0x20, 0x4d,
 | 
				
			||||||
	0x44, 0x9d, 0x8f, 0x52, 0xaa, 0xcc, 0xe9, 0xa6, 0xc1, 0xba, 0x71, 0x06, 0x96, 0xd6, 0xbc, 0x05,
 | 
						0xb4, 0x64, 0x9f, 0x60, 0x9d, 0x71, 0xbe, 0x6e, 0x6c, 0x18, 0xe8, 0x0b, 0x28, 0x25, 0x3a, 0x01,
 | 
				
			||||||
	0x39, 0x99, 0x00, 0x52, 0x8c, 0x9d, 0x68, 0x03, 0xd2, 0xc4, 0x1c, 0x6b, 0x0b, 0x0e, 0x55, 0xe3,
 | 
						0x94, 0x52, 0x87, 0x4e, 0xb7, 0x15, 0xd6, 0x8d, 0x33, 0xb0, 0xb4, 0xe6, 0x2d, 0xc8, 0xc9, 0x04,
 | 
				
			||||||
	0x42, 0x82, 0xa4, 0xf7, 0xa1, 0x1b, 0x67, 0xd5, 0x1b, 0x33, 0xdd, 0x66, 0xca, 0x89, 0x37, 0x0c,
 | 
						0x90, 0x62, 0xec, 0x44, 0xa3, 0x90, 0x26, 0xe6, 0x58, 0xe3, 0x70, 0xa8, 0x5a, 0x1b, 0x12, 0x24,
 | 
				
			||||||
	0x14, 0x02, 0x9a, 0x4e, 0xfa, 0xe8, 0xbb, 0x29, 0x5e, 0x32, 0xeb, 0x55, 0xb2, 0x6e, 0xcd, 0x87,
 | 
						0xbd, 0x0f, 0xdd, 0x38, 0xab, 0x22, 0x99, 0xe9, 0x36, 0x53, 0x4e, 0xbc, 0x61, 0xa0, 0x10, 0xd0,
 | 
				
			||||||
	0xac, 0x94, 0x6a, 0x94, 0x5f, 0xbd, 0x59, 0x31, 0xfe, 0xf9, 0x66, 0xc5, 0xf8, 0xf7, 0x9b, 0x15,
 | 
						0x74, 0xd2, 0x47, 0xdf, 0x4f, 0xf1, 0x92, 0x59, 0xaf, 0x92, 0x75, 0x6b, 0x3e, 0x64, 0xa5, 0x54,
 | 
				
			||||||
	0xe3, 0x30, 0x2f, 0x2b, 0xc9, 0xef, 0xfd, 0x3f, 0x00, 0x00, 0xff, 0xff, 0x12, 0xae, 0x41, 0x43,
 | 
						0xa3, 0xfc, 0xea, 0xcd, 0x8a, 0xf1, 0xaf, 0x37, 0x2b, 0xc6, 0xbf, 0xdf, 0xac, 0x18, 0x87, 0x79,
 | 
				
			||||||
	0x99, 0x1e, 0x00, 0x00,
 | 
						0x59, 0x6b, 0xfe, 0xe0, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xaa, 0x06, 0xac, 0x18, 0xbb, 0x1e,
 | 
				
			||||||
 | 
						0x00, 0x00,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Reference imports to suppress errors if they are not otherwise used.
 | 
					// Reference imports to suppress errors if they are not otherwise used.
 | 
				
			||||||
@@ -4030,6 +4039,13 @@ func (m *BuildHistoryRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 | 
				
			|||||||
		i -= len(m.XXX_unrecognized)
 | 
							i -= len(m.XXX_unrecognized)
 | 
				
			||||||
		copy(dAtA[i:], m.XXX_unrecognized)
 | 
							copy(dAtA[i:], m.XXX_unrecognized)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if m.NumWarnings != 0 {
 | 
				
			||||||
 | 
							i = encodeVarintControl(dAtA, i, uint64(m.NumWarnings))
 | 
				
			||||||
 | 
							i--
 | 
				
			||||||
 | 
							dAtA[i] = 0x1
 | 
				
			||||||
 | 
							i--
 | 
				
			||||||
 | 
							dAtA[i] = 0x98
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if m.ExternalError != nil {
 | 
						if m.ExternalError != nil {
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			size, err := m.ExternalError.MarshalToSizedBuffer(dAtA[:i])
 | 
								size, err := m.ExternalError.MarshalToSizedBuffer(dAtA[:i])
 | 
				
			||||||
@@ -5242,6 +5258,9 @@ func (m *BuildHistoryRecord) Size() (n int) {
 | 
				
			|||||||
		l = m.ExternalError.Size()
 | 
							l = m.ExternalError.Size()
 | 
				
			||||||
		n += 2 + l + sovControl(uint64(l))
 | 
							n += 2 + l + sovControl(uint64(l))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if m.NumWarnings != 0 {
 | 
				
			||||||
 | 
							n += 2 + sovControl(uint64(m.NumWarnings))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if m.XXX_unrecognized != nil {
 | 
						if m.XXX_unrecognized != nil {
 | 
				
			||||||
		n += len(m.XXX_unrecognized)
 | 
							n += len(m.XXX_unrecognized)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -10303,6 +10322,25 @@ func (m *BuildHistoryRecord) Unmarshal(dAtA []byte) error {
 | 
				
			|||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			iNdEx = postIndex
 | 
								iNdEx = postIndex
 | 
				
			||||||
 | 
							case 19:
 | 
				
			||||||
 | 
								if wireType != 0 {
 | 
				
			||||||
 | 
									return fmt.Errorf("proto: wrong wireType = %d for field NumWarnings", wireType)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								m.NumWarnings = 0
 | 
				
			||||||
 | 
								for shift := uint(0); ; shift += 7 {
 | 
				
			||||||
 | 
									if shift >= 64 {
 | 
				
			||||||
 | 
										return ErrIntOverflowControl
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if iNdEx >= l {
 | 
				
			||||||
 | 
										return io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									b := dAtA[iNdEx]
 | 
				
			||||||
 | 
									iNdEx++
 | 
				
			||||||
 | 
									m.NumWarnings |= int32(b&0x7F) << shift
 | 
				
			||||||
 | 
									if b < 0x80 {
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			iNdEx = preIndex
 | 
								iNdEx = preIndex
 | 
				
			||||||
			skippy, err := skipControl(dAtA[iNdEx:])
 | 
								skippy, err := skipControl(dAtA[iNdEx:])
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								vendor/github.com/moby/buildkit/api/services/control/control.proto
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/moby/buildkit/api/services/control/control.proto
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -212,6 +212,7 @@ message BuildHistoryRecord {
 | 
				
			|||||||
	int32 numTotalSteps = 16;
 | 
						int32 numTotalSteps = 16;
 | 
				
			||||||
	int32 numCompletedSteps = 17;
 | 
						int32 numCompletedSteps = 17;
 | 
				
			||||||
	Descriptor externalError = 18;
 | 
						Descriptor externalError = 18;
 | 
				
			||||||
 | 
						int32 numWarnings = 19;
 | 
				
			||||||
	// TODO: tags
 | 
						// TODO: tags
 | 
				
			||||||
	// TODO: unclipped logs
 | 
						// TODO: unclipped logs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								vendor/github.com/moby/buildkit/client/solve.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/moby/buildkit/client/solve.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -7,7 +7,6 @@ import (
 | 
				
			|||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"maps"
 | 
						"maps"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,7 +119,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
 | 
				
			|||||||
		if opt.SessionPreInitialized {
 | 
							if opt.SessionPreInitialized {
 | 
				
			||||||
			return nil, errors.Errorf("no session provided for preinitialized option")
 | 
								return nil, errors.Errorf("no session provided for preinitialized option")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		s, err = session.NewSession(statusContext, defaultSessionName(), opt.SharedKey)
 | 
							s, err = session.NewSession(statusContext, opt.SharedKey)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, errors.Wrap(err, "failed to create session")
 | 
								return nil, errors.Wrap(err, "failed to create session")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -419,14 +418,6 @@ func prepareSyncedFiles(def *llb.Definition, localMounts map[string]fsutil.FS) (
 | 
				
			|||||||
	return result, nil
 | 
						return result, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func defaultSessionName() string {
 | 
					 | 
				
			||||||
	wd, err := os.Getwd()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "unknown"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return filepath.Base(wd)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type cacheOptions struct {
 | 
					type cacheOptions struct {
 | 
				
			||||||
	options        controlapi.CacheOptions
 | 
						options        controlapi.CacheOptions
 | 
				
			||||||
	contentStores  map[string]content.Store // key: ID of content store ("local:" + csDir)
 | 
						contentStores  map[string]content.Store // key: ID of content store ("local:" + csDir)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										31
									
								
								vendor/github.com/moby/buildkit/errdefs/errdefs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/moby/buildkit/errdefs/errdefs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					package errdefs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type internalErr struct {
 | 
				
			||||||
 | 
						error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (internalErr) System() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err internalErr) Unwrap() error {
 | 
				
			||||||
 | 
						return err.error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type system interface {
 | 
				
			||||||
 | 
						System()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _ system = internalErr{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Internal(err error) error {
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return internalErr{err}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func IsInternal(err error) bool {
 | 
				
			||||||
 | 
						var s system
 | 
				
			||||||
 | 
						return errors.As(err, &s)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								vendor/github.com/moby/buildkit/frontend/dockerui/attr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/moby/buildkit/frontend/dockerui/attr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -125,6 +125,16 @@ func parseSourceDateEpoch(v string) (*time.Time, error) {
 | 
				
			|||||||
	return &tm, nil
 | 
						return &tm, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseLocalSessionIDs(opt map[string]string) map[string]string {
 | 
				
			||||||
 | 
						m := map[string]string{}
 | 
				
			||||||
 | 
						for k, v := range opt {
 | 
				
			||||||
 | 
							if strings.HasPrefix(k, localSessionIDPrefix) {
 | 
				
			||||||
 | 
								m[strings.TrimPrefix(k, localSessionIDPrefix)] = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return m
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func filter(opt map[string]string, key string) map[string]string {
 | 
					func filter(opt map[string]string, key string) map[string]string {
 | 
				
			||||||
	m := map[string]string{}
 | 
						m := map[string]string{}
 | 
				
			||||||
	for k, v := range opt {
 | 
						for k, v := range opt {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								vendor/github.com/moby/buildkit/frontend/dockerui/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/moby/buildkit/frontend/dockerui/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -28,6 +28,7 @@ import (
 | 
				
			|||||||
const (
 | 
					const (
 | 
				
			||||||
	buildArgPrefix       = "build-arg:"
 | 
						buildArgPrefix       = "build-arg:"
 | 
				
			||||||
	labelPrefix          = "label:"
 | 
						labelPrefix          = "label:"
 | 
				
			||||||
 | 
						localSessionIDPrefix = "local-sessionid:"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	keyTarget           = "target"
 | 
						keyTarget           = "target"
 | 
				
			||||||
	keyCgroupParent     = "cgroup-parent"
 | 
						keyCgroupParent     = "cgroup-parent"
 | 
				
			||||||
@@ -83,6 +84,7 @@ type Client struct {
 | 
				
			|||||||
	ignoreCache      []string
 | 
						ignoreCache      []string
 | 
				
			||||||
	g                flightcontrol.CachedGroup[*buildContext]
 | 
						g                flightcontrol.CachedGroup[*buildContext]
 | 
				
			||||||
	bopts            client.BuildOpts
 | 
						bopts            client.BuildOpts
 | 
				
			||||||
 | 
						localsSessionIDs map[string]string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dockerignore     []byte
 | 
						dockerignore     []byte
 | 
				
			||||||
	dockerignoreName string
 | 
						dockerignoreName string
 | 
				
			||||||
@@ -298,6 +300,9 @@ func (bc *Client) init() error {
 | 
				
			|||||||
			return errors.Wrapf(err, "failed to parse %s", keyCopyIgnoredCheckEnabled)
 | 
								return errors.Wrapf(err, "failed to parse %s", keyCopyIgnoredCheckEnabled)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bc.localsSessionIDs = parseLocalSessionIDs(opts)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -331,9 +336,14 @@ func (bc *Client) ReadEntrypoint(ctx context.Context, lang string, opts ...llb.L
 | 
				
			|||||||
			filenames = append(filenames, path.Join(path.Dir(bctx.filename), strings.ToLower(DefaultDockerfileName)))
 | 
								filenames = append(filenames, path.Join(path.Dir(bctx.filename), strings.ToLower(DefaultDockerfileName)))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							sessionID := bc.bopts.SessionID
 | 
				
			||||||
 | 
							if v, ok := bc.localsSessionIDs[bctx.dockerfileLocalName]; ok {
 | 
				
			||||||
 | 
								sessionID = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		opts = append([]llb.LocalOption{
 | 
							opts = append([]llb.LocalOption{
 | 
				
			||||||
			llb.FollowPaths(filenames),
 | 
								llb.FollowPaths(filenames),
 | 
				
			||||||
			llb.SessionID(bc.bopts.SessionID),
 | 
								llb.SessionID(sessionID),
 | 
				
			||||||
			llb.SharedKeyHint(bctx.dockerfileLocalName),
 | 
								llb.SharedKeyHint(bctx.dockerfileLocalName),
 | 
				
			||||||
			WithInternalName(name),
 | 
								WithInternalName(name),
 | 
				
			||||||
			llb.Differ(llb.DiffNone, false),
 | 
								llb.Differ(llb.DiffNone, false),
 | 
				
			||||||
@@ -427,8 +437,13 @@ func (bc *Client) MainContext(ctx context.Context, opts ...llb.LocalOption) (*ll
 | 
				
			|||||||
		return nil, errors.Wrapf(err, "failed to read dockerignore patterns")
 | 
							return nil, errors.Wrapf(err, "failed to read dockerignore patterns")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sessionID := bc.bopts.SessionID
 | 
				
			||||||
 | 
						if v, ok := bc.localsSessionIDs[bctx.contextLocalName]; ok {
 | 
				
			||||||
 | 
							sessionID = v
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opts = append([]llb.LocalOption{
 | 
						opts = append([]llb.LocalOption{
 | 
				
			||||||
		llb.SessionID(bc.bopts.SessionID),
 | 
							llb.SessionID(sessionID),
 | 
				
			||||||
		llb.ExcludePatterns(excludes),
 | 
							llb.ExcludePatterns(excludes),
 | 
				
			||||||
		llb.SharedKeyHint(bctx.contextLocalName),
 | 
							llb.SharedKeyHint(bctx.contextLocalName),
 | 
				
			||||||
		WithInternalName("load build context"),
 | 
							WithInternalName("load build context"),
 | 
				
			||||||
@@ -500,8 +515,12 @@ func WithInternalName(name string) llb.ConstraintsOpt {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (bc *Client) dockerIgnorePatterns(ctx context.Context, bctx *buildContext) ([]string, error) {
 | 
					func (bc *Client) dockerIgnorePatterns(ctx context.Context, bctx *buildContext) ([]string, error) {
 | 
				
			||||||
	if bc.dockerignore == nil {
 | 
						if bc.dockerignore == nil {
 | 
				
			||||||
 | 
							sessionID := bc.bopts.SessionID
 | 
				
			||||||
 | 
							if v, ok := bc.localsSessionIDs[bctx.contextLocalName]; ok {
 | 
				
			||||||
 | 
								sessionID = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		st := llb.Local(bctx.contextLocalName,
 | 
							st := llb.Local(bctx.contextLocalName,
 | 
				
			||||||
			llb.SessionID(bc.bopts.SessionID),
 | 
								llb.SessionID(sessionID),
 | 
				
			||||||
			llb.FollowPaths([]string{DefaultDockerignoreName}),
 | 
								llb.FollowPaths([]string{DefaultDockerignoreName}),
 | 
				
			||||||
			llb.SharedKeyHint(bctx.contextLocalName+"-"+DefaultDockerignoreName),
 | 
								llb.SharedKeyHint(bctx.contextLocalName+"-"+DefaultDockerignoreName),
 | 
				
			||||||
			WithInternalName("load "+DefaultDockerignoreName),
 | 
								WithInternalName("load "+DefaultDockerignoreName),
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								vendor/github.com/moby/buildkit/frontend/dockerui/namedcontext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/moby/buildkit/frontend/dockerui/namedcontext.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -187,8 +187,12 @@ func (bc *Client) namedContextRecursive(ctx context.Context, name string, nameWi
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return &st, &img, nil
 | 
							return &st, &img, nil
 | 
				
			||||||
	case "local":
 | 
						case "local":
 | 
				
			||||||
 | 
							sessionID := bc.bopts.SessionID
 | 
				
			||||||
 | 
							if v, ok := bc.localsSessionIDs[vv[1]]; ok {
 | 
				
			||||||
 | 
								sessionID = v
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		st := llb.Local(vv[1],
 | 
							st := llb.Local(vv[1],
 | 
				
			||||||
			llb.SessionID(bc.bopts.SessionID),
 | 
								llb.SessionID(sessionID),
 | 
				
			||||||
			llb.FollowPaths([]string{DefaultDockerignoreName}),
 | 
								llb.FollowPaths([]string{DefaultDockerignoreName}),
 | 
				
			||||||
			llb.SharedKeyHint("context:"+nameWithPlatform+"-"+DefaultDockerignoreName),
 | 
								llb.SharedKeyHint("context:"+nameWithPlatform+"-"+DefaultDockerignoreName),
 | 
				
			||||||
			llb.WithCustomName("[context "+nameWithPlatform+"] load "+DefaultDockerignoreName),
 | 
								llb.WithCustomName("[context "+nameWithPlatform+"] load "+DefaultDockerignoreName),
 | 
				
			||||||
@@ -226,7 +230,7 @@ func (bc *Client) namedContextRecursive(ctx context.Context, name string, nameWi
 | 
				
			|||||||
		localOutput := &asyncLocalOutput{
 | 
							localOutput := &asyncLocalOutput{
 | 
				
			||||||
			name:             vv[1],
 | 
								name:             vv[1],
 | 
				
			||||||
			nameWithPlatform: nameWithPlatform,
 | 
								nameWithPlatform: nameWithPlatform,
 | 
				
			||||||
			sessionID:        bc.bopts.SessionID,
 | 
								sessionID:        sessionID,
 | 
				
			||||||
			excludes:         excludes,
 | 
								excludes:         excludes,
 | 
				
			||||||
			extraOpts:        opt.AsyncLocalOpts,
 | 
								extraOpts:        opt.AsyncLocalOpts,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								vendor/github.com/moby/buildkit/session/manager.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/moby/buildkit/session/manager.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -16,7 +16,6 @@ type Caller interface {
 | 
				
			|||||||
	Context() context.Context
 | 
						Context() context.Context
 | 
				
			||||||
	Supports(method string) bool
 | 
						Supports(method string) bool
 | 
				
			||||||
	Conn() *grpc.ClientConn
 | 
						Conn() *grpc.ClientConn
 | 
				
			||||||
	Name() string
 | 
					 | 
				
			||||||
	SharedKey() string
 | 
						SharedKey() string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -106,7 +105,6 @@ func (sm *Manager) handleConn(ctx context.Context, conn net.Conn, opts map[strin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	h := http.Header(opts)
 | 
						h := http.Header(opts)
 | 
				
			||||||
	id := h.Get(headerSessionID)
 | 
						id := h.Get(headerSessionID)
 | 
				
			||||||
	name := h.Get(headerSessionName)
 | 
					 | 
				
			||||||
	sharedKey := h.Get(headerSessionSharedKey)
 | 
						sharedKey := h.Get(headerSessionSharedKey)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx, cc, err := grpcClientConn(ctx, conn)
 | 
						ctx, cc, err := grpcClientConn(ctx, conn)
 | 
				
			||||||
@@ -118,7 +116,6 @@ func (sm *Manager) handleConn(ctx context.Context, conn net.Conn, opts map[strin
 | 
				
			|||||||
	c := &client{
 | 
						c := &client{
 | 
				
			||||||
		Session: Session{
 | 
							Session: Session{
 | 
				
			||||||
			id:        id,
 | 
								id:        id,
 | 
				
			||||||
			name:      name,
 | 
					 | 
				
			||||||
			sharedKey: sharedKey,
 | 
								sharedKey: sharedKey,
 | 
				
			||||||
			ctx:       ctx,
 | 
								ctx:       ctx,
 | 
				
			||||||
			cancelCtx: cancel,
 | 
								cancelCtx: cancel,
 | 
				
			||||||
@@ -197,10 +194,6 @@ func (c *client) Context() context.Context {
 | 
				
			|||||||
	return c.context()
 | 
						return c.context()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *client) Name() string {
 | 
					 | 
				
			||||||
	return c.name
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *client) SharedKey() string {
 | 
					func (c *client) SharedKey() string {
 | 
				
			||||||
	return c.sharedKey
 | 
						return c.sharedKey
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								vendor/github.com/moby/buildkit/session/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/moby/buildkit/session/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -38,7 +38,6 @@ type Attachable interface {
 | 
				
			|||||||
type Session struct {
 | 
					type Session struct {
 | 
				
			||||||
	mu          sync.Mutex // synchronizes conn run and close
 | 
						mu          sync.Mutex // synchronizes conn run and close
 | 
				
			||||||
	id          string
 | 
						id          string
 | 
				
			||||||
	name        string
 | 
					 | 
				
			||||||
	sharedKey   string
 | 
						sharedKey   string
 | 
				
			||||||
	ctx         context.Context
 | 
						ctx         context.Context
 | 
				
			||||||
	cancelCtx   func(error)
 | 
						cancelCtx   func(error)
 | 
				
			||||||
@@ -49,7 +48,7 @@ type Session struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewSession returns a new long running session
 | 
					// NewSession returns a new long running session
 | 
				
			||||||
func NewSession(ctx context.Context, name, sharedKey string) (*Session, error) {
 | 
					func NewSession(ctx context.Context, sharedKey string) (*Session, error) {
 | 
				
			||||||
	id := identity.NewID()
 | 
						id := identity.NewID()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	serverOpts := []grpc.ServerOption{
 | 
						serverOpts := []grpc.ServerOption{
 | 
				
			||||||
@@ -67,7 +66,6 @@ func NewSession(ctx context.Context, name, sharedKey string) (*Session, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	s := &Session{
 | 
						s := &Session{
 | 
				
			||||||
		id:         id,
 | 
							id:         id,
 | 
				
			||||||
		name:       name,
 | 
					 | 
				
			||||||
		sharedKey:  sharedKey,
 | 
							sharedKey:  sharedKey,
 | 
				
			||||||
		grpcServer: grpc.NewServer(serverOpts...),
 | 
							grpcServer: grpc.NewServer(serverOpts...),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -103,7 +101,6 @@ func (s *Session) Run(ctx context.Context, dialer Dialer) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	meta := make(map[string][]string)
 | 
						meta := make(map[string][]string)
 | 
				
			||||||
	meta[headerSessionID] = []string{s.id}
 | 
						meta[headerSessionID] = []string{s.id}
 | 
				
			||||||
	meta[headerSessionName] = []string{s.name}
 | 
					 | 
				
			||||||
	meta[headerSessionSharedKey] = []string{s.sharedKey}
 | 
						meta[headerSessionSharedKey] = []string{s.sharedKey}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for name, svc := range s.grpcServer.GetServiceInfo() {
 | 
						for name, svc := range s.grpcServer.GetServiceInfo() {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								vendor/github.com/moby/buildkit/util/grpcerrors/grpcerrors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/moby/buildkit/util/grpcerrors/grpcerrors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -10,6 +10,7 @@ import (
 | 
				
			|||||||
	gogotypes "github.com/gogo/protobuf/types"
 | 
						gogotypes "github.com/gogo/protobuf/types"
 | 
				
			||||||
	"github.com/golang/protobuf/proto" //nolint:staticcheck
 | 
						"github.com/golang/protobuf/proto" //nolint:staticcheck
 | 
				
			||||||
	"github.com/golang/protobuf/ptypes/any"
 | 
						"github.com/golang/protobuf/ptypes/any"
 | 
				
			||||||
 | 
						"github.com/moby/buildkit/errdefs"
 | 
				
			||||||
	"github.com/moby/buildkit/util/bklog"
 | 
						"github.com/moby/buildkit/util/bklog"
 | 
				
			||||||
	"github.com/moby/buildkit/util/stack"
 | 
						"github.com/moby/buildkit/util/stack"
 | 
				
			||||||
	spb "google.golang.org/genproto/googleapis/rpc/status"
 | 
						spb "google.golang.org/genproto/googleapis/rpc/status"
 | 
				
			||||||
@@ -94,6 +95,10 @@ func withDetails(ctx context.Context, s *status.Status, details ...proto.Message
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Code(err error) codes.Code {
 | 
					func Code(err error) codes.Code {
 | 
				
			||||||
 | 
						if errdefs.IsInternal(err) {
 | 
				
			||||||
 | 
							return codes.Internal
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if se, ok := err.(interface {
 | 
						if se, ok := err.(interface {
 | 
				
			||||||
		Code() codes.Code
 | 
							Code() codes.Code
 | 
				
			||||||
	}); ok {
 | 
						}); ok {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								vendor/github.com/moby/buildkit/util/resolver/retryhandler/retry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/moby/buildkit/util/resolver/retryhandler/retry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -64,11 +64,7 @@ func retryError(err error) bool {
 | 
				
			|||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// catches TLS timeout or other network-related temporary errors
 | 
						// catches TLS timeout or other network-related temporary errors
 | 
				
			||||||
	if ne, ok := errors.Cause(err).(net.Error); ok && ne.Temporary() { //nolint:staticcheck // ignoring "SA1019: Temporary is deprecated", continue to propagate net.Error through the "temporary" status
 | 
						if ne := net.Error(nil); errors.As(err, &ne) && ne.Temporary() { //nolint:staticcheck // ignoring "SA1019: Temporary is deprecated", continue to propagate net.Error through the "temporary" status
 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// https://github.com/containerd/containerd/pull/4724
 | 
					 | 
				
			||||||
	if errors.Cause(err).Error() == "no response" {
 | 
					 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/pins.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/pins.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,3 +1,6 @@
 | 
				
			|||||||
 | 
					//go:build !windows
 | 
				
			||||||
 | 
					// +build !windows
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package integration
 | 
					package integration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var pins = map[string]map[string]string{
 | 
					var pins = map[string]map[string]string{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/run.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/run.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -189,7 +189,9 @@ func Run(t *testing.T, testCases []Test, opt ...TestOpt) {
 | 
				
			|||||||
							t.Skip("rootless")
 | 
												t.Skip("rootless")
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						ctx := appcontext.Context()
 | 
											ctx := appcontext.Context()
 | 
				
			||||||
						if !strings.HasSuffix(fn, "NoParallel") {
 | 
											// TODO(profnandaa): to revisit this to allow tests run
 | 
				
			||||||
 | 
											// in parallel on Windows in a stable way. Is flaky currently.
 | 
				
			||||||
 | 
											if !strings.HasSuffix(fn, "NoParallel") && runtime.GOOS != "windows" {
 | 
				
			||||||
							t.Parallel()
 | 
												t.Parallel()
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						require.NoError(t, sandboxLimiter.Acquire(context.TODO(), 1))
 | 
											require.NoError(t, sandboxLimiter.Acquire(context.TODO(), 1))
 | 
				
			||||||
@@ -273,23 +275,7 @@ func copyImagesLocal(t *testing.T, host string, images map[string]string) error
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func OfficialImages(names ...string) map[string]string {
 | 
					func OfficialImages(names ...string) map[string]string {
 | 
				
			||||||
	ns := runtime.GOARCH
 | 
						return officialImages(names...)
 | 
				
			||||||
	if ns == "arm64" {
 | 
					 | 
				
			||||||
		ns = "arm64v8"
 | 
					 | 
				
			||||||
	} else if ns != "amd64" {
 | 
					 | 
				
			||||||
		ns = "library"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	m := map[string]string{}
 | 
					 | 
				
			||||||
	for _, name := range names {
 | 
					 | 
				
			||||||
		ref := "docker.io/" + ns + "/" + name
 | 
					 | 
				
			||||||
		if pns, ok := pins[name]; ok {
 | 
					 | 
				
			||||||
			if dgst, ok := pns[ns]; ok {
 | 
					 | 
				
			||||||
				ref += "@" + dgst
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		m["library/"+name] = ref
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return m
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func withMirrorConfig(mirror string) ConfigUpdater {
 | 
					func withMirrorConfig(mirror string) ConfigUpdater {
 | 
				
			||||||
@@ -439,9 +425,19 @@ func prepareValueMatrix(tc testConf) []matrixValue {
 | 
				
			|||||||
	return m
 | 
						return m
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Skips tests on Windows
 | 
					// Skips tests on platform
 | 
				
			||||||
func SkipOnPlatform(t *testing.T, goos string) {
 | 
					func SkipOnPlatform(t *testing.T, goos string) {
 | 
				
			||||||
	if runtime.GOOS == goos {
 | 
						if runtime.GOOS == goos {
 | 
				
			||||||
		t.Skipf("Skipped on %s", goos)
 | 
							t.Skipf("Skipped on %s", goos)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Selects between two types, returns second
 | 
				
			||||||
 | 
					// argument if on Windows or else first argument.
 | 
				
			||||||
 | 
					// Typically used for selecting test cases.
 | 
				
			||||||
 | 
					func UnixOrWindows[T any](unix, windows T) T {
 | 
				
			||||||
 | 
						if runtime.GOOS == "windows" {
 | 
				
			||||||
 | 
							return windows
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return unix
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/run_unix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/run_unix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					//go:build !windows
 | 
				
			||||||
 | 
					// +build !windows
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package integration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "runtime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func officialImages(names ...string) map[string]string {
 | 
				
			||||||
 | 
						ns := runtime.GOARCH
 | 
				
			||||||
 | 
						if ns == "arm64" {
 | 
				
			||||||
 | 
							ns = "arm64v8"
 | 
				
			||||||
 | 
						} else if ns != "amd64" {
 | 
				
			||||||
 | 
							ns = "library"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						m := map[string]string{}
 | 
				
			||||||
 | 
						for _, name := range names {
 | 
				
			||||||
 | 
							ref := "docker.io/" + ns + "/" + name
 | 
				
			||||||
 | 
							if pns, ok := pins[name]; ok {
 | 
				
			||||||
 | 
								if dgst, ok := pns[ns]; ok {
 | 
				
			||||||
 | 
									ref += "@" + dgst
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							m["library/"+name] = ref
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return m
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/run_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/run_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					package integration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func officialImages(names ...string) map[string]string {
 | 
				
			||||||
 | 
						m := map[string]string{}
 | 
				
			||||||
 | 
						for _, name := range names {
 | 
				
			||||||
 | 
							// select available refs from the mirror map
 | 
				
			||||||
 | 
							// so that we mirror only those needed for the tests
 | 
				
			||||||
 | 
							if ref, ok := windowsImagesMirrorMap[name]; ok {
 | 
				
			||||||
 | 
								m["library/"+name] = ref
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return m
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -94,8 +94,12 @@ func StartCmd(cmd *exec.Cmd, logs map[string]*bytes.Buffer) (func() error, error
 | 
				
			|||||||
		case <-ctx.Done():
 | 
							case <-ctx.Done():
 | 
				
			||||||
		case <-stopped:
 | 
							case <-stopped:
 | 
				
			||||||
		case <-stop:
 | 
							case <-stop:
 | 
				
			||||||
 | 
								// windows processes not responding to SIGTERM
 | 
				
			||||||
 | 
								signal := UnixOrWindows(syscall.SIGTERM, syscall.SIGKILL)
 | 
				
			||||||
 | 
								signalStr := UnixOrWindows("SIGTERM", "SIGKILL")
 | 
				
			||||||
			fmt.Fprintf(cmd.Stderr, "> sending sigterm %v\n", time.Now())
 | 
								fmt.Fprintf(cmd.Stderr, "> sending sigterm %v\n", time.Now())
 | 
				
			||||||
			cmd.Process.Signal(syscall.SIGTERM)
 | 
								fmt.Fprintf(cmd.Stderr, "> sending %s %v\n", signalStr, time.Now())
 | 
				
			||||||
 | 
								cmd.Process.Signal(signal)
 | 
				
			||||||
			go func() {
 | 
								go func() {
 | 
				
			||||||
				select {
 | 
									select {
 | 
				
			||||||
				case <-stopped:
 | 
									case <-stopped:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/util_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/moby/buildkit/util/testutil/integration/util_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,6 +11,13 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var socketScheme = "npipe://"
 | 
					var socketScheme = "npipe://"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var windowsImagesMirrorMap = map[string]string{
 | 
				
			||||||
 | 
						// TODO(profnandaa): currently, amd64 only, to revisit for other archs.
 | 
				
			||||||
 | 
						"nanoserver:latest": "mcr.microsoft.com/windows/nanoserver:ltsc2022",
 | 
				
			||||||
 | 
						"servercore:latest": "mcr.microsoft.com/windows/servercore:ltsc2022",
 | 
				
			||||||
 | 
						"busybox:latest":    "registry.k8s.io/e2e-test-images/busybox@sha256:6d854ffad9666d2041b879a1c128c9922d77faced7745ad676639b07111ab650",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// abstracted function to handle pipe dialing on windows.
 | 
					// abstracted function to handle pipe dialing on windows.
 | 
				
			||||||
// some simplification has been made to discard timeout param.
 | 
					// some simplification has been made to discard timeout param.
 | 
				
			||||||
func dialPipe(address string) (net.Conn, error) {
 | 
					func dialPipe(address string) (net.Conn, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								vendor/github.com/moby/sys/user/user.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/moby/sys/user/user.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -197,7 +197,6 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) {
 | 
				
			|||||||
		for {
 | 
							for {
 | 
				
			||||||
			var line []byte
 | 
								var line []byte
 | 
				
			||||||
			line, isPrefix, err = rd.ReadLine()
 | 
								line, isPrefix, err = rd.ReadLine()
 | 
				
			||||||
 | 
					 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				// We should return no error if EOF is reached
 | 
									// We should return no error if EOF is reached
 | 
				
			||||||
				// without a match.
 | 
									// without a match.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										201
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										201
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,201 +0,0 @@
 | 
				
			|||||||
                                 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.
 | 
					 | 
				
			||||||
							
								
								
									
										28
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -61,7 +61,11 @@ func newClient(ctx context.Context, cfg oconf.Config) (*client, error) {
 | 
				
			|||||||
	if c.conn == nil {
 | 
						if c.conn == nil {
 | 
				
			||||||
		// If the caller did not provide a ClientConn when the client was
 | 
							// If the caller did not provide a ClientConn when the client was
 | 
				
			||||||
		// created, create one using the configuration they did provide.
 | 
							// created, create one using the configuration they did provide.
 | 
				
			||||||
		conn, err := grpc.DialContext(ctx, cfg.Metrics.Endpoint, cfg.DialOptions...)
 | 
							userAgent := "OTel Go OTLP over gRPC metrics exporter/" + Version()
 | 
				
			||||||
 | 
							dialOpts := []grpc.DialOption{grpc.WithUserAgent(userAgent)}
 | 
				
			||||||
 | 
							dialOpts = append(dialOpts, cfg.DialOptions...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							conn, err := grpc.DialContext(ctx, cfg.Metrics.Endpoint, dialOpts...)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -172,28 +176,36 @@ func (c *client) exportContext(parent context.Context) (context.Context, context
 | 
				
			|||||||
// duration to wait for if an explicit throttle time is included in err.
 | 
					// duration to wait for if an explicit throttle time is included in err.
 | 
				
			||||||
func retryable(err error) (bool, time.Duration) {
 | 
					func retryable(err error) (bool, time.Duration) {
 | 
				
			||||||
	s := status.Convert(err)
 | 
						s := status.Convert(err)
 | 
				
			||||||
 | 
						return retryableGRPCStatus(s)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func retryableGRPCStatus(s *status.Status) (bool, time.Duration) {
 | 
				
			||||||
	switch s.Code() {
 | 
						switch s.Code() {
 | 
				
			||||||
	case codes.Canceled,
 | 
						case codes.Canceled,
 | 
				
			||||||
		codes.DeadlineExceeded,
 | 
							codes.DeadlineExceeded,
 | 
				
			||||||
		codes.ResourceExhausted,
 | 
					 | 
				
			||||||
		codes.Aborted,
 | 
							codes.Aborted,
 | 
				
			||||||
		codes.OutOfRange,
 | 
							codes.OutOfRange,
 | 
				
			||||||
		codes.Unavailable,
 | 
							codes.Unavailable,
 | 
				
			||||||
		codes.DataLoss:
 | 
							codes.DataLoss:
 | 
				
			||||||
		return true, throttleDelay(s)
 | 
							// Additionally, handle RetryInfo.
 | 
				
			||||||
 | 
							_, d := throttleDelay(s)
 | 
				
			||||||
 | 
							return true, d
 | 
				
			||||||
 | 
						case codes.ResourceExhausted:
 | 
				
			||||||
 | 
							// Retry only if the server signals that the recovery from resource exhaustion is possible.
 | 
				
			||||||
 | 
							return throttleDelay(s)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Not a retry-able error.
 | 
						// Not a retry-able error.
 | 
				
			||||||
	return false, 0
 | 
						return false, 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// throttleDelay returns a duration to wait for if an explicit throttle time
 | 
					// throttleDelay returns if the status is RetryInfo
 | 
				
			||||||
// is included in the response status.
 | 
					// and the duration to wait for if an explicit throttle time is included.
 | 
				
			||||||
func throttleDelay(s *status.Status) time.Duration {
 | 
					func throttleDelay(s *status.Status) (bool, time.Duration) {
 | 
				
			||||||
	for _, detail := range s.Details() {
 | 
						for _, detail := range s.Details() {
 | 
				
			||||||
		if t, ok := detail.(*errdetails.RetryInfo); ok {
 | 
							if t, ok := detail.(*errdetails.RetryInfo); ok {
 | 
				
			||||||
			return t.RetryDelay.AsDuration()
 | 
								return true, t.RetryDelay.AsDuration()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0
 | 
						return false, 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -109,13 +109,7 @@ func compressorToCompression(compressor string) oconf.Compression {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// WithCompressor sets the compressor the gRPC client uses.
 | 
					// WithCompressor sets the compressor the gRPC client uses.
 | 
				
			||||||
//
 | 
					// Supported compressor values: "gzip".
 | 
				
			||||||
// It is the responsibility of the caller to ensure that the compressor set
 | 
					 | 
				
			||||||
// has been registered with google.golang.org/grpc/encoding (see
 | 
					 | 
				
			||||||
// encoding.RegisterCompressor for more information). For example, to register
 | 
					 | 
				
			||||||
// the gzip compressor import the package:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	import _ "google.golang.org/grpc/encoding/gzip"
 | 
					 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// If the OTEL_EXPORTER_OTLP_COMPRESSION or
 | 
					// If the OTEL_EXPORTER_OTLP_COMPRESSION or
 | 
				
			||||||
// OTEL_EXPORTER_OTLP_METRICS_COMPRESSION environment variable is set, and
 | 
					// OTEL_EXPORTER_OTLP_METRICS_COMPRESSION environment variable is set, and
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										83
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										83
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -12,6 +12,85 @@
 | 
				
			|||||||
// See the License for the specific language governing permissions and
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Package otlpmetricgrpc provides an otlpmetric.Exporter that communicates
 | 
					/*
 | 
				
			||||||
// with an OTLP receiving endpoint using gRPC.
 | 
					Package otlpmetricgrpc provides an OTLP metrics exporter using gRPC.
 | 
				
			||||||
 | 
					By default the telemetry is sent to https://localhost:4317.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Exporter should be created using [New] and used with a [metric.PeriodicReader].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The environment variables described below can be used for configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT (default: "https://localhost:4317") -
 | 
				
			||||||
 | 
					target to which the exporter sends telemetry.
 | 
				
			||||||
 | 
					The target syntax is defined in https://github.com/grpc/grpc/blob/master/doc/naming.md.
 | 
				
			||||||
 | 
					The value must contain a host.
 | 
				
			||||||
 | 
					The value may additionally a port, a scheme, and a path.
 | 
				
			||||||
 | 
					The value accepts "http" and "https" scheme.
 | 
				
			||||||
 | 
					The value should not contain a query string or fragment.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_ENDPOINT takes precedence over OTEL_EXPORTER_OTLP_ENDPOINT.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithEndpoint], [WithInsecure], [WithGRPCConn] options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_INSECURE, OTEL_EXPORTER_OTLP_METRICS_INSECURE (default: "false") -
 | 
				
			||||||
 | 
					setting "true" disables client transport security for the exporter's gRPC connection.
 | 
				
			||||||
 | 
					You can use this only when an endpoint is provided without the http or https scheme.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT setting overrides
 | 
				
			||||||
 | 
					the scheme defined via OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_INSECURE takes precedence over OTEL_EXPORTER_OTLP_INSECURE.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithInsecure], [WithGRPCConn] options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_METRICS_HEADERS (default: none) -
 | 
				
			||||||
 | 
					key-value pairs used as gRPC metadata associated with gRPC requests.
 | 
				
			||||||
 | 
					The value is expected to be represented in a format matching to the [W3C Baggage HTTP Header Content Format],
 | 
				
			||||||
 | 
					except that additional semi-colon delimited metadata is not supported.
 | 
				
			||||||
 | 
					Example value: "key1=value1,key2=value2".
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_HEADERS takes precedence over OTEL_EXPORTER_OTLP_HEADERS.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithHeaders] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_METRICS_TIMEOUT (default: "10000") -
 | 
				
			||||||
 | 
					maximum time in milliseconds the OTLP exporter waits for each batch export.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_TIMEOUT takes precedence over OTEL_EXPORTER_OTLP_TIMEOUT.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTimeout] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_METRICS_COMPRESSION (default: none) -
 | 
				
			||||||
 | 
					the gRPC compressor the exporter uses.
 | 
				
			||||||
 | 
					Supported value: "gzip".
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_COMPRESSION takes precedence over OTEL_EXPORTER_OTLP_COMPRESSION.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithCompressor], [WithGRPCConn] options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_CERTIFICATE, OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE (default: none) -
 | 
				
			||||||
 | 
					the filepath to the trusted certificate to use when verifying a server's TLS credentials.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE takes precedence over OTEL_EXPORTER_OTLP_CERTIFICATE.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTLSCredentials], [WithGRPCConn] options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE (default: none) -
 | 
				
			||||||
 | 
					the filepath to the client certificate/chain trust for clients private key to use in mTLS communication in PEM format.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE takes precedence over OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTLSCredentials], [WithGRPCConn] options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY (default: none) -
 | 
				
			||||||
 | 
					the filepath  to the clients private key to use in mTLS communication in PEM format.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY takes precedence over OTEL_EXPORTER_OTLP_CLIENT_KEY.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTLSCredentials], [WithGRPCConn] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE (default: "cumulative") -
 | 
				
			||||||
 | 
					aggregation temporality to use on the basis of instrument kind. Supported values:
 | 
				
			||||||
 | 
					  - "cumulative" - Cumulative aggregation temporality for all instrument kinds,
 | 
				
			||||||
 | 
					  - "delta" - Delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds;
 | 
				
			||||||
 | 
					    Cumulative aggregation for UpDownCounter and Asynchronous UpDownCounter instrument kinds,
 | 
				
			||||||
 | 
					  - "lowmemory" - Delta aggregation temporality for Synchronous Counter and Histogram instrument kinds;
 | 
				
			||||||
 | 
					    Cumulative aggregation temporality for Synchronous UpDownCounter, Asynchronous Counter, and Asynchronous UpDownCounter instrument kinds.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTemporalitySelector] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION (default: "explicit_bucket_histogram") -
 | 
				
			||||||
 | 
					default aggregation to use for histogram instruments. Supported values:
 | 
				
			||||||
 | 
					  - "explicit_bucket_histogram" - [Explicit Bucket Histogram Aggregation],
 | 
				
			||||||
 | 
					  - "base2_exponential_bucket_histogram" - [Base2 Exponential Bucket Histogram Aggregation].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithAggregationSelector] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[W3C Baggage HTTP Header Content Format]: https://www.w3.org/TR/baggage/#header-content
 | 
				
			||||||
 | 
					[Explicit Bucket Histogram Aggregation]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation
 | 
				
			||||||
 | 
					[Base2 Exponential Bucket Histogram Aggregation]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/sdk.md#base2-exponential-bucket-histogram-aggregation
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
package otlpmetricgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
 | 
					package otlpmetricgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,13 +174,13 @@ func stringToHeader(value string) map[string]string {
 | 
				
			|||||||
			global.Error(errors.New("missing '="), "parse headers", "input", header)
 | 
								global.Error(errors.New("missing '="), "parse headers", "input", header)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		name, err := url.QueryUnescape(n)
 | 
							name, err := url.PathUnescape(n)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			global.Error(err, "escape header key", "key", n)
 | 
								global.Error(err, "escape header key", "key", n)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		trimmedName := strings.TrimSpace(name)
 | 
							trimmedName := strings.TrimSpace(name)
 | 
				
			||||||
		value, err := url.QueryUnescape(v)
 | 
							value, err := url.PathUnescape(v)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			global.Error(err, "escape header value", "value", v)
 | 
								global.Error(err, "escape header value", "value", v)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,6 @@ import (
 | 
				
			|||||||
	"google.golang.org/grpc/credentials/insecure"
 | 
						"google.golang.org/grpc/credentials/insecure"
 | 
				
			||||||
	"google.golang.org/grpc/encoding/gzip"
 | 
						"google.golang.org/grpc/encoding/gzip"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric"
 | 
					 | 
				
			||||||
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry"
 | 
						"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry"
 | 
				
			||||||
	"go.opentelemetry.io/otel/sdk/metric"
 | 
						"go.opentelemetry.io/otel/sdk/metric"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -122,7 +121,6 @@ func cleanPath(urlPath string, defaultPath string) string {
 | 
				
			|||||||
// NewGRPCConfig returns a new Config with all settings applied from opts and
 | 
					// NewGRPCConfig returns a new Config with all settings applied from opts and
 | 
				
			||||||
// any unset setting using the default gRPC config values.
 | 
					// any unset setting using the default gRPC config values.
 | 
				
			||||||
func NewGRPCConfig(opts ...GRPCOption) Config {
 | 
					func NewGRPCConfig(opts ...GRPCOption) Config {
 | 
				
			||||||
	userAgent := "OTel OTLP Exporter Go/" + otlpmetric.Version()
 | 
					 | 
				
			||||||
	cfg := Config{
 | 
						cfg := Config{
 | 
				
			||||||
		Metrics: SignalConfig{
 | 
							Metrics: SignalConfig{
 | 
				
			||||||
			Endpoint:    fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorGRPCPort),
 | 
								Endpoint:    fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorGRPCPort),
 | 
				
			||||||
@@ -134,7 +132,6 @@ func NewGRPCConfig(opts ...GRPCOption) Config {
 | 
				
			|||||||
			AggregationSelector: metric.DefaultAggregationSelector,
 | 
								AggregationSelector: metric.DefaultAggregationSelector,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		RetryConfig: retry.DefaultConfig,
 | 
							RetryConfig: retry.DefaultConfig,
 | 
				
			||||||
		DialOptions: []grpc.DialOption{grpc.WithUserAgent(userAgent)},
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cfg = ApplyGRPCEnvConfigs(cfg)
 | 
						cfg = ApplyGRPCEnvConfigs(cfg)
 | 
				
			||||||
	for _, opt := range opts {
 | 
						for _, opt := range opts {
 | 
				
			||||||
@@ -158,9 +155,6 @@ func NewGRPCConfig(opts ...GRPCOption) Config {
 | 
				
			|||||||
	if cfg.Metrics.Compression == GzipCompression {
 | 
						if cfg.Metrics.Compression == GzipCompression {
 | 
				
			||||||
		cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name)))
 | 
							cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name)))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(cfg.DialOptions) != 0 {
 | 
					 | 
				
			||||||
		cfg.DialOptions = append(cfg.DialOptions, cfg.DialOptions...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if cfg.ReconnectionPeriod != 0 {
 | 
						if cfg.ReconnectionPeriod != 0 {
 | 
				
			||||||
		p := grpc.ConnectParams{
 | 
							p := grpc.ConnectParams{
 | 
				
			||||||
			Backoff:           backoff.DefaultConfig,
 | 
								Backoff:           backoff.DefaultConfig,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,9 +12,9 @@
 | 
				
			|||||||
// See the License for the specific language governing permissions and
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package otlpmetric // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric"
 | 
					package otlpmetricgrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Version is the current release version of the OpenTelemetry OTLP metrics exporter in use.
 | 
					// Version is the current release version of the OpenTelemetry OTLP over gRPC metrics exporter in use.
 | 
				
			||||||
func Version() string {
 | 
					func Version() string {
 | 
				
			||||||
	return "0.42.0"
 | 
						return "0.44.0"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -18,6 +18,7 @@ import (
 | 
				
			|||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"compress/gzip"
 | 
						"compress/gzip"
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
@@ -30,7 +31,6 @@ import (
 | 
				
			|||||||
	"google.golang.org/protobuf/proto"
 | 
						"google.golang.org/protobuf/proto"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"go.opentelemetry.io/otel"
 | 
						"go.opentelemetry.io/otel"
 | 
				
			||||||
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric"
 | 
					 | 
				
			||||||
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal"
 | 
						"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal"
 | 
				
			||||||
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf"
 | 
						"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/oconf"
 | 
				
			||||||
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry"
 | 
						"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry"
 | 
				
			||||||
@@ -89,7 +89,7 @@ func newClient(cfg oconf.Config) (*client, error) {
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	userAgent := "OTel OTLP Exporter Go/" + otlpmetric.Version()
 | 
						userAgent := "OTel Go OTLP over HTTP/protobuf metrics exporter/" + Version()
 | 
				
			||||||
	req.Header.Set("User-Agent", userAgent)
 | 
						req.Header.Set("User-Agent", userAgent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if n := len(cfg.Metrics.Headers); n > 0 {
 | 
						if n := len(cfg.Metrics.Headers); n > 0 {
 | 
				
			||||||
@@ -148,6 +148,10 @@ func (c *client) UploadMetrics(ctx context.Context, protoMetrics *metricpb.Resou
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		request.reset(iCtx)
 | 
							request.reset(iCtx)
 | 
				
			||||||
		resp, err := c.httpClient.Do(request.Request)
 | 
							resp, err := c.httpClient.Do(request.Request)
 | 
				
			||||||
 | 
							var urlErr *url.Error
 | 
				
			||||||
 | 
							if errors.As(err, &urlErr) && urlErr.Temporary() {
 | 
				
			||||||
 | 
								return newResponseError(http.Header{})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -162,8 +166,11 @@ func (c *client) UploadMetrics(ctx context.Context, protoMetrics *metricpb.Resou
 | 
				
			|||||||
			if _, err := io.Copy(&respData, resp.Body); err != nil {
 | 
								if _, err := io.Copy(&respData, resp.Body); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if respData.Len() == 0 {
 | 
				
			||||||
 | 
									return nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if respData.Len() != 0 {
 | 
								if resp.Header.Get("Content-Type") == "application/x-protobuf" {
 | 
				
			||||||
				var respProto colmetricpb.ExportMetricsServiceResponse
 | 
									var respProto colmetricpb.ExportMetricsServiceResponse
 | 
				
			||||||
				if err := proto.Unmarshal(respData.Bytes(), &respProto); err != nil {
 | 
									if err := proto.Unmarshal(respData.Bytes(), &respProto); err != nil {
 | 
				
			||||||
					return err
 | 
										return err
 | 
				
			||||||
@@ -179,7 +186,10 @@ func (c *client) UploadMetrics(ctx context.Context, protoMetrics *metricpb.Resou
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
		case sc == http.StatusTooManyRequests, sc == http.StatusServiceUnavailable:
 | 
							case sc == http.StatusTooManyRequests,
 | 
				
			||||||
 | 
								sc == http.StatusBadGateway,
 | 
				
			||||||
 | 
								sc == http.StatusServiceUnavailable,
 | 
				
			||||||
 | 
								sc == http.StatusGatewayTimeout:
 | 
				
			||||||
			// Retry-able failure.
 | 
								// Retry-able failure.
 | 
				
			||||||
			rErr = newResponseError(resp.Header)
 | 
								rErr = newResponseError(resp.Header)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										81
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								vendor/go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -12,7 +12,82 @@
 | 
				
			|||||||
// See the License for the specific language governing permissions and
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Package otlpmetrichttp provides an otlpmetric.Exporter that communicates
 | 
					/*
 | 
				
			||||||
// with an OTLP receiving endpoint using protobuf encoded metric data over
 | 
					Package otlpmetrichttp provides an OTLP metrics exporter using HTTP with protobuf payloads.
 | 
				
			||||||
// HTTP.
 | 
					By default the telemetry is sent to https://localhost:4318/v1/metrics.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Exporter should be created using [New] and used with a [metric.PeriodicReader].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The environment variables described below can be used for configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_ENDPOINT (default: "https://localhost:4318") -
 | 
				
			||||||
 | 
					target base URL ("/v1/metrics" is appended) to which the exporter sends telemetry.
 | 
				
			||||||
 | 
					The value must contain a scheme ("http" or "https") and host.
 | 
				
			||||||
 | 
					The value may additionally contain a port and a path.
 | 
				
			||||||
 | 
					The value should not contain a query string or fragment.
 | 
				
			||||||
 | 
					The configuration can be overridden by OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
 | 
				
			||||||
 | 
					environment variable and by [WithEndpoint], [WithInsecure] options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_ENDPOINT (default: "https://localhost:4318/v1/metrics") -
 | 
				
			||||||
 | 
					target URL to which the exporter sends telemetry.
 | 
				
			||||||
 | 
					The value must contain a scheme ("http" or "https") and host.
 | 
				
			||||||
 | 
					The value may additionally contain a port and a path.
 | 
				
			||||||
 | 
					The value should not contain a query string or fragment.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithEndpoint], [WitnInsecure], [WithURLPath] options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_METRICS_HEADERS (default: none) -
 | 
				
			||||||
 | 
					key-value pairs used as headers associated with HTTP requests.
 | 
				
			||||||
 | 
					The value is expected to be represented in a format matching to the [W3C Baggage HTTP Header Content Format],
 | 
				
			||||||
 | 
					except that additional semi-colon delimited metadata is not supported.
 | 
				
			||||||
 | 
					Example value: "key1=value1,key2=value2".
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_HEADERS takes precedence over OTEL_EXPORTER_OTLP_HEADERS.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithHeaders] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_METRICS_TIMEOUT (default: "10000") -
 | 
				
			||||||
 | 
					maximum time in milliseconds the OTLP exporter waits for each batch export.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_TIMEOUT takes precedence over OTEL_EXPORTER_OTLP_TIMEOUT.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTimeout] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_METRICS_COMPRESSION (default: none) -
 | 
				
			||||||
 | 
					compression strategy the exporter uses to compress the HTTP body.
 | 
				
			||||||
 | 
					Supported values: "gzip".
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_COMPRESSION takes precedence over OTEL_EXPORTER_OTLP_COMPRESSION.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithCompression] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_CERTIFICATE, OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE (default: none) -
 | 
				
			||||||
 | 
					filepath to the trusted certificate to use when verifying a server's TLS credentials.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE takes precedence over OTEL_EXPORTER_OTLP_CERTIFICATE.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTLSClientConfig] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE (default: none) -
 | 
				
			||||||
 | 
					filepath to the client certificate/chain trust for clients private key to use in mTLS communication in PEM format.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE takes precedence over OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTLSClientConfig] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY (default: none) -
 | 
				
			||||||
 | 
					filepath to the clients private key to use in mTLS communication in PEM format.
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY takes precedence over OTEL_EXPORTER_OTLP_CLIENT_KEY.
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTLSClientConfig] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE (default: "cumulative") -
 | 
				
			||||||
 | 
					aggregation temporality to use on the basis of instrument kind. Supported values:
 | 
				
			||||||
 | 
					  - "cumulative" - Cumulative aggregation temporality for all instrument kinds,
 | 
				
			||||||
 | 
					  - "delta" - Delta aggregation temporality for Counter, Asynchronous Counter and Histogram instrument kinds;
 | 
				
			||||||
 | 
					    Cumulative aggregation for UpDownCounter and Asynchronous UpDownCounter instrument kinds,
 | 
				
			||||||
 | 
					  - "lowmemory" - Delta aggregation temporality for Synchronous Counter and Histogram instrument kinds;
 | 
				
			||||||
 | 
					    Cumulative aggregation temporality for Synchronous UpDownCounter, Asynchronous Counter, and Asynchronous UpDownCounter instrument kinds.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithTemporalitySelector] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION (default: "explicit_bucket_histogram") -
 | 
				
			||||||
 | 
					default aggregation to use for histogram instruments. Supported values:
 | 
				
			||||||
 | 
					  - "explicit_bucket_histogram" - [Explicit Bucket Histogram Aggregation],
 | 
				
			||||||
 | 
					  - "base2_exponential_bucket_histogram" - [Base2 Exponential Bucket Histogram Aggregation].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The configuration can be overridden by [WithAggregationSelector] option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[W3C Baggage HTTP Header Content Format]: https://www.w3.org/TR/baggage/#header-content
 | 
				
			||||||
 | 
					[Explicit Bucket Histogram Aggregation]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation
 | 
				
			||||||
 | 
					[Base2 Exponential Bucket Histogram Aggregation]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.26.0/specification/metrics/sdk.md#base2-exponential-bucket-histogram-aggregation
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
package otlpmetrichttp // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
 | 
					package otlpmetrichttp // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,13 +174,13 @@ func stringToHeader(value string) map[string]string {
 | 
				
			|||||||
			global.Error(errors.New("missing '="), "parse headers", "input", header)
 | 
								global.Error(errors.New("missing '="), "parse headers", "input", header)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		name, err := url.QueryUnescape(n)
 | 
							name, err := url.PathUnescape(n)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			global.Error(err, "escape header key", "key", n)
 | 
								global.Error(err, "escape header key", "key", n)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		trimmedName := strings.TrimSpace(name)
 | 
							trimmedName := strings.TrimSpace(name)
 | 
				
			||||||
		value, err := url.QueryUnescape(v)
 | 
							value, err := url.PathUnescape(v)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			global.Error(err, "escape header value", "value", v)
 | 
								global.Error(err, "escape header value", "value", v)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,6 @@ import (
 | 
				
			|||||||
	"google.golang.org/grpc/credentials/insecure"
 | 
						"google.golang.org/grpc/credentials/insecure"
 | 
				
			||||||
	"google.golang.org/grpc/encoding/gzip"
 | 
						"google.golang.org/grpc/encoding/gzip"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric"
 | 
					 | 
				
			||||||
	"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry"
 | 
						"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal/retry"
 | 
				
			||||||
	"go.opentelemetry.io/otel/sdk/metric"
 | 
						"go.opentelemetry.io/otel/sdk/metric"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -122,7 +121,6 @@ func cleanPath(urlPath string, defaultPath string) string {
 | 
				
			|||||||
// NewGRPCConfig returns a new Config with all settings applied from opts and
 | 
					// NewGRPCConfig returns a new Config with all settings applied from opts and
 | 
				
			||||||
// any unset setting using the default gRPC config values.
 | 
					// any unset setting using the default gRPC config values.
 | 
				
			||||||
func NewGRPCConfig(opts ...GRPCOption) Config {
 | 
					func NewGRPCConfig(opts ...GRPCOption) Config {
 | 
				
			||||||
	userAgent := "OTel OTLP Exporter Go/" + otlpmetric.Version()
 | 
					 | 
				
			||||||
	cfg := Config{
 | 
						cfg := Config{
 | 
				
			||||||
		Metrics: SignalConfig{
 | 
							Metrics: SignalConfig{
 | 
				
			||||||
			Endpoint:    fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorGRPCPort),
 | 
								Endpoint:    fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorGRPCPort),
 | 
				
			||||||
@@ -134,7 +132,6 @@ func NewGRPCConfig(opts ...GRPCOption) Config {
 | 
				
			|||||||
			AggregationSelector: metric.DefaultAggregationSelector,
 | 
								AggregationSelector: metric.DefaultAggregationSelector,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		RetryConfig: retry.DefaultConfig,
 | 
							RetryConfig: retry.DefaultConfig,
 | 
				
			||||||
		DialOptions: []grpc.DialOption{grpc.WithUserAgent(userAgent)},
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cfg = ApplyGRPCEnvConfigs(cfg)
 | 
						cfg = ApplyGRPCEnvConfigs(cfg)
 | 
				
			||||||
	for _, opt := range opts {
 | 
						for _, opt := range opts {
 | 
				
			||||||
@@ -158,9 +155,6 @@ func NewGRPCConfig(opts ...GRPCOption) Config {
 | 
				
			|||||||
	if cfg.Metrics.Compression == GzipCompression {
 | 
						if cfg.Metrics.Compression == GzipCompression {
 | 
				
			||||||
		cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name)))
 | 
							cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name)))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(cfg.DialOptions) != 0 {
 | 
					 | 
				
			||||||
		cfg.DialOptions = append(cfg.DialOptions, cfg.DialOptions...)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if cfg.ReconnectionPeriod != 0 {
 | 
						if cfg.ReconnectionPeriod != 0 {
 | 
				
			||||||
		p := grpc.ConnectParams{
 | 
							p := grpc.ConnectParams{
 | 
				
			||||||
			Backoff:           backoff.DefaultConfig,
 | 
								Backoff:           backoff.DefaultConfig,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,9 +12,9 @@
 | 
				
			|||||||
// See the License for the specific language governing permissions and
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Package otlpmetric provides an OpenTelemetry metric Exporter that can be
 | 
					package otlpmetrichttp // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
 | 
				
			||||||
// used with PeriodicReader. It transforms metricdata into OTLP and transmits
 | 
					
 | 
				
			||||||
// the transformed data to OTLP receivers. The Exporter is configurable to use
 | 
					// Version is the current release version of the OpenTelemetry OTLP over HTTP/protobuf metrics exporter in use.
 | 
				
			||||||
// different Clients, each using a distinct transport protocol to communicate
 | 
					func Version() string {
 | 
				
			||||||
// to an OTLP receiving endpoint.
 | 
						return "0.44.0"
 | 
				
			||||||
package otlpmetric // import "go.opentelemetry.io/otel/exporters/otlp/otlpmetric"
 | 
					}
 | 
				
			||||||
							
								
								
									
										198
									
								
								vendor/golang.org/x/oauth2/deviceauth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								vendor/golang.org/x/oauth2/deviceauth.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,198 @@
 | 
				
			|||||||
 | 
					package oauth2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"golang.org/x/oauth2/internal"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						errAuthorizationPending = "authorization_pending"
 | 
				
			||||||
 | 
						errSlowDown             = "slow_down"
 | 
				
			||||||
 | 
						errAccessDenied         = "access_denied"
 | 
				
			||||||
 | 
						errExpiredToken         = "expired_token"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeviceAuthResponse describes a successful RFC 8628 Device Authorization Response
 | 
				
			||||||
 | 
					// https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
 | 
				
			||||||
 | 
					type DeviceAuthResponse struct {
 | 
				
			||||||
 | 
						// DeviceCode
 | 
				
			||||||
 | 
						DeviceCode string `json:"device_code"`
 | 
				
			||||||
 | 
						// UserCode is the code the user should enter at the verification uri
 | 
				
			||||||
 | 
						UserCode string `json:"user_code"`
 | 
				
			||||||
 | 
						// VerificationURI is where user should enter the user code
 | 
				
			||||||
 | 
						VerificationURI string `json:"verification_uri"`
 | 
				
			||||||
 | 
						// VerificationURIComplete (if populated) includes the user code in the verification URI. This is typically shown to the user in non-textual form, such as a QR code.
 | 
				
			||||||
 | 
						VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
 | 
				
			||||||
 | 
						// Expiry is when the device code and user code expire
 | 
				
			||||||
 | 
						Expiry time.Time `json:"expires_in,omitempty"`
 | 
				
			||||||
 | 
						// Interval is the duration in seconds that Poll should wait between requests
 | 
				
			||||||
 | 
						Interval int64 `json:"interval,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d DeviceAuthResponse) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						type Alias DeviceAuthResponse
 | 
				
			||||||
 | 
						var expiresIn int64
 | 
				
			||||||
 | 
						if !d.Expiry.IsZero() {
 | 
				
			||||||
 | 
							expiresIn = int64(time.Until(d.Expiry).Seconds())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return json.Marshal(&struct {
 | 
				
			||||||
 | 
							ExpiresIn int64 `json:"expires_in,omitempty"`
 | 
				
			||||||
 | 
							*Alias
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							ExpiresIn: expiresIn,
 | 
				
			||||||
 | 
							Alias:     (*Alias)(&d),
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *DeviceAuthResponse) UnmarshalJSON(data []byte) error {
 | 
				
			||||||
 | 
						type Alias DeviceAuthResponse
 | 
				
			||||||
 | 
						aux := &struct {
 | 
				
			||||||
 | 
							ExpiresIn int64 `json:"expires_in"`
 | 
				
			||||||
 | 
							// workaround misspelling of verification_uri
 | 
				
			||||||
 | 
							VerificationURL string `json:"verification_url"`
 | 
				
			||||||
 | 
							*Alias
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							Alias: (*Alias)(c),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(data, &aux); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if aux.ExpiresIn != 0 {
 | 
				
			||||||
 | 
							c.Expiry = time.Now().UTC().Add(time.Second * time.Duration(aux.ExpiresIn))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c.VerificationURI == "" {
 | 
				
			||||||
 | 
							c.VerificationURI = aux.VerificationURL
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeviceAuth returns a device auth struct which contains a device code
 | 
				
			||||||
 | 
					// and authorization information provided for users to enter on another device.
 | 
				
			||||||
 | 
					func (c *Config) DeviceAuth(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuthResponse, error) {
 | 
				
			||||||
 | 
						// https://datatracker.ietf.org/doc/html/rfc8628#section-3.1
 | 
				
			||||||
 | 
						v := url.Values{
 | 
				
			||||||
 | 
							"client_id": {c.ClientID},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(c.Scopes) > 0 {
 | 
				
			||||||
 | 
							v.Set("scope", strings.Join(c.Scopes, " "))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, opt := range opts {
 | 
				
			||||||
 | 
							opt.setValue(v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return retrieveDeviceAuth(ctx, c, v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAuthResponse, error) {
 | 
				
			||||||
 | 
						if c.Endpoint.DeviceAuthURL == "" {
 | 
				
			||||||
 | 
							return nil, errors.New("endpoint missing DeviceAuthURL")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req, err := http.NewRequest("POST", c.Endpoint.DeviceAuthURL, strings.NewReader(v.Encode()))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
 | 
				
			||||||
 | 
						req.Header.Set("Accept", "application/json")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t := time.Now()
 | 
				
			||||||
 | 
						r, err := internal.ContextClient(ctx).Do(req)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("oauth2: cannot auth device: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if code := r.StatusCode; code < 200 || code > 299 {
 | 
				
			||||||
 | 
							return nil, &RetrieveError{
 | 
				
			||||||
 | 
								Response: r,
 | 
				
			||||||
 | 
								Body:     body,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						da := &DeviceAuthResponse{}
 | 
				
			||||||
 | 
						err = json.Unmarshal(body, &da)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("unmarshal %s", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !da.Expiry.IsZero() {
 | 
				
			||||||
 | 
							// Make a small adjustment to account for time taken by the request
 | 
				
			||||||
 | 
							da.Expiry = da.Expiry.Add(-time.Since(t))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return da, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeviceAccessToken polls the server to exchange a device code for a token.
 | 
				
			||||||
 | 
					func (c *Config) DeviceAccessToken(ctx context.Context, da *DeviceAuthResponse, opts ...AuthCodeOption) (*Token, error) {
 | 
				
			||||||
 | 
						if !da.Expiry.IsZero() {
 | 
				
			||||||
 | 
							var cancel context.CancelFunc
 | 
				
			||||||
 | 
							ctx, cancel = context.WithDeadline(ctx, da.Expiry)
 | 
				
			||||||
 | 
							defer cancel()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// https://datatracker.ietf.org/doc/html/rfc8628#section-3.4
 | 
				
			||||||
 | 
						v := url.Values{
 | 
				
			||||||
 | 
							"client_id":   {c.ClientID},
 | 
				
			||||||
 | 
							"grant_type":  {"urn:ietf:params:oauth:grant-type:device_code"},
 | 
				
			||||||
 | 
							"device_code": {da.DeviceCode},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(c.Scopes) > 0 {
 | 
				
			||||||
 | 
							v.Set("scope", strings.Join(c.Scopes, " "))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, opt := range opts {
 | 
				
			||||||
 | 
							opt.setValue(v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// "If no value is provided, clients MUST use 5 as the default."
 | 
				
			||||||
 | 
						// https://datatracker.ietf.org/doc/html/rfc8628#section-3.2
 | 
				
			||||||
 | 
						interval := da.Interval
 | 
				
			||||||
 | 
						if interval == 0 {
 | 
				
			||||||
 | 
							interval = 5
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ticker := time.NewTicker(time.Duration(interval) * time.Second)
 | 
				
			||||||
 | 
						defer ticker.Stop()
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							select {
 | 
				
			||||||
 | 
							case <-ctx.Done():
 | 
				
			||||||
 | 
								return nil, ctx.Err()
 | 
				
			||||||
 | 
							case <-ticker.C:
 | 
				
			||||||
 | 
								tok, err := retrieveToken(ctx, c, v)
 | 
				
			||||||
 | 
								if err == nil {
 | 
				
			||||||
 | 
									return tok, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								e, ok := err.(*RetrieveError)
 | 
				
			||||||
 | 
								if !ok {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								switch e.ErrorCode {
 | 
				
			||||||
 | 
								case errSlowDown:
 | 
				
			||||||
 | 
									// https://datatracker.ietf.org/doc/html/rfc8628#section-3.5
 | 
				
			||||||
 | 
									// "the interval MUST be increased by 5 seconds for this and all subsequent requests"
 | 
				
			||||||
 | 
									interval += 5
 | 
				
			||||||
 | 
									ticker.Reset(time.Duration(interval) * time.Second)
 | 
				
			||||||
 | 
								case errAuthorizationPending:
 | 
				
			||||||
 | 
									// Do nothing.
 | 
				
			||||||
 | 
								case errAccessDenied, errExpiredToken:
 | 
				
			||||||
 | 
									fallthrough
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									return tok, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										68
									
								
								vendor/golang.org/x/oauth2/internal/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										68
									
								
								vendor/golang.org/x/oauth2/internal/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -18,6 +18,7 @@ import (
 | 
				
			|||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
						"sync/atomic"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -115,41 +116,60 @@ const (
 | 
				
			|||||||
	AuthStyleInHeader AuthStyle = 2
 | 
						AuthStyleInHeader AuthStyle = 2
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// authStyleCache is the set of tokenURLs we've successfully used via
 | 
					// LazyAuthStyleCache is a backwards compatibility compromise to let Configs
 | 
				
			||||||
 | 
					// have a lazily-initialized AuthStyleCache.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The two users of this, oauth2.Config and oauth2/clientcredentials.Config,
 | 
				
			||||||
 | 
					// both would ideally just embed an unexported AuthStyleCache but because both
 | 
				
			||||||
 | 
					// were historically allowed to be copied by value we can't retroactively add an
 | 
				
			||||||
 | 
					// uncopyable Mutex to them.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// We could use an atomic.Pointer, but that was added recently enough (in Go
 | 
				
			||||||
 | 
					// 1.18) that we'd break Go 1.17 users where the tests as of 2023-08-03
 | 
				
			||||||
 | 
					// still pass. By using an atomic.Value, it supports both Go 1.17 and
 | 
				
			||||||
 | 
					// copying by value, even if that's not ideal.
 | 
				
			||||||
 | 
					type LazyAuthStyleCache struct {
 | 
				
			||||||
 | 
						v atomic.Value // of *AuthStyleCache
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (lc *LazyAuthStyleCache) Get() *AuthStyleCache {
 | 
				
			||||||
 | 
						if c, ok := lc.v.Load().(*AuthStyleCache); ok {
 | 
				
			||||||
 | 
							return c
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c := new(AuthStyleCache)
 | 
				
			||||||
 | 
						if !lc.v.CompareAndSwap(nil, c) {
 | 
				
			||||||
 | 
							c = lc.v.Load().(*AuthStyleCache)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AuthStyleCache is the set of tokenURLs we've successfully used via
 | 
				
			||||||
// RetrieveToken and which style auth we ended up using.
 | 
					// RetrieveToken and which style auth we ended up using.
 | 
				
			||||||
// It's called a cache, but it doesn't (yet?) shrink. It's expected that
 | 
					// It's called a cache, but it doesn't (yet?) shrink. It's expected that
 | 
				
			||||||
// the set of OAuth2 servers a program contacts over time is fixed and
 | 
					// the set of OAuth2 servers a program contacts over time is fixed and
 | 
				
			||||||
// small.
 | 
					// small.
 | 
				
			||||||
var authStyleCache struct {
 | 
					type AuthStyleCache struct {
 | 
				
			||||||
	sync.Mutex
 | 
						mu sync.Mutex
 | 
				
			||||||
	m  map[string]AuthStyle // keyed by tokenURL
 | 
						m  map[string]AuthStyle // keyed by tokenURL
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ResetAuthCache resets the global authentication style cache used
 | 
					 | 
				
			||||||
// for AuthStyleUnknown token requests.
 | 
					 | 
				
			||||||
func ResetAuthCache() {
 | 
					 | 
				
			||||||
	authStyleCache.Lock()
 | 
					 | 
				
			||||||
	defer authStyleCache.Unlock()
 | 
					 | 
				
			||||||
	authStyleCache.m = nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// lookupAuthStyle reports which auth style we last used with tokenURL
 | 
					// lookupAuthStyle reports which auth style we last used with tokenURL
 | 
				
			||||||
// when calling RetrieveToken and whether we have ever done so.
 | 
					// when calling RetrieveToken and whether we have ever done so.
 | 
				
			||||||
func lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) {
 | 
					func (c *AuthStyleCache) lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) {
 | 
				
			||||||
	authStyleCache.Lock()
 | 
						c.mu.Lock()
 | 
				
			||||||
	defer authStyleCache.Unlock()
 | 
						defer c.mu.Unlock()
 | 
				
			||||||
	style, ok = authStyleCache.m[tokenURL]
 | 
						style, ok = c.m[tokenURL]
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// setAuthStyle adds an entry to authStyleCache, documented above.
 | 
					// setAuthStyle adds an entry to authStyleCache, documented above.
 | 
				
			||||||
func setAuthStyle(tokenURL string, v AuthStyle) {
 | 
					func (c *AuthStyleCache) setAuthStyle(tokenURL string, v AuthStyle) {
 | 
				
			||||||
	authStyleCache.Lock()
 | 
						c.mu.Lock()
 | 
				
			||||||
	defer authStyleCache.Unlock()
 | 
						defer c.mu.Unlock()
 | 
				
			||||||
	if authStyleCache.m == nil {
 | 
						if c.m == nil {
 | 
				
			||||||
		authStyleCache.m = make(map[string]AuthStyle)
 | 
							c.m = make(map[string]AuthStyle)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	authStyleCache.m[tokenURL] = v
 | 
						c.m[tokenURL] = v
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newTokenRequest returns a new *http.Request to retrieve a new token
 | 
					// newTokenRequest returns a new *http.Request to retrieve a new token
 | 
				
			||||||
@@ -189,10 +209,10 @@ func cloneURLValues(v url.Values) url.Values {
 | 
				
			|||||||
	return v2
 | 
						return v2
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle) (*Token, error) {
 | 
					func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle, styleCache *AuthStyleCache) (*Token, error) {
 | 
				
			||||||
	needsAuthStyleProbe := authStyle == 0
 | 
						needsAuthStyleProbe := authStyle == 0
 | 
				
			||||||
	if needsAuthStyleProbe {
 | 
						if needsAuthStyleProbe {
 | 
				
			||||||
		if style, ok := lookupAuthStyle(tokenURL); ok {
 | 
							if style, ok := styleCache.lookupAuthStyle(tokenURL); ok {
 | 
				
			||||||
			authStyle = style
 | 
								authStyle = style
 | 
				
			||||||
			needsAuthStyleProbe = false
 | 
								needsAuthStyleProbe = false
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
@@ -222,7 +242,7 @@ func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string,
 | 
				
			|||||||
		token, err = doTokenRoundTrip(ctx, req)
 | 
							token, err = doTokenRoundTrip(ctx, req)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if needsAuthStyleProbe && err == nil {
 | 
						if needsAuthStyleProbe && err == nil {
 | 
				
			||||||
		setAuthStyle(tokenURL, authStyle)
 | 
							styleCache.setAuthStyle(tokenURL, authStyle)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Don't overwrite `RefreshToken` with an empty value
 | 
						// Don't overwrite `RefreshToken` with an empty value
 | 
				
			||||||
	// if this was a token refreshing request.
 | 
						// if this was a token refreshing request.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								vendor/golang.org/x/oauth2/oauth2.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/golang.org/x/oauth2/oauth2.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -58,6 +58,10 @@ type Config struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Scope specifies optional requested permissions.
 | 
						// Scope specifies optional requested permissions.
 | 
				
			||||||
	Scopes []string
 | 
						Scopes []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// authStyleCache caches which auth style to use when Endpoint.AuthStyle is
 | 
				
			||||||
 | 
						// the zero value (AuthStyleAutoDetect).
 | 
				
			||||||
 | 
						authStyleCache internal.LazyAuthStyleCache
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A TokenSource is anything that can return a token.
 | 
					// A TokenSource is anything that can return a token.
 | 
				
			||||||
@@ -72,6 +76,7 @@ type TokenSource interface {
 | 
				
			|||||||
// endpoint URLs.
 | 
					// endpoint URLs.
 | 
				
			||||||
type Endpoint struct {
 | 
					type Endpoint struct {
 | 
				
			||||||
	AuthURL       string
 | 
						AuthURL       string
 | 
				
			||||||
 | 
						DeviceAuthURL string
 | 
				
			||||||
	TokenURL      string
 | 
						TokenURL      string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// AuthStyle optionally specifies how the endpoint wants the
 | 
						// AuthStyle optionally specifies how the endpoint wants the
 | 
				
			||||||
@@ -139,15 +144,19 @@ func SetAuthURLParam(key, value string) AuthCodeOption {
 | 
				
			|||||||
// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
 | 
					// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
 | 
				
			||||||
// that asks for permissions for the required scopes explicitly.
 | 
					// that asks for permissions for the required scopes explicitly.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// State is a token to protect the user from CSRF attacks. You must
 | 
					// State is an opaque value used by the client to maintain state between the
 | 
				
			||||||
// always provide a non-empty string and validate that it matches the
 | 
					// request and callback. The authorization server includes this value when
 | 
				
			||||||
// state query parameter on your redirect callback.
 | 
					// redirecting the user agent back to the client.
 | 
				
			||||||
// See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
 | 
					 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Opts may include AccessTypeOnline or AccessTypeOffline, as well
 | 
					// Opts may include AccessTypeOnline or AccessTypeOffline, as well
 | 
				
			||||||
// as ApprovalForce.
 | 
					// as ApprovalForce.
 | 
				
			||||||
// It can also be used to pass the PKCE challenge.
 | 
					//
 | 
				
			||||||
// See https://www.oauth.com/oauth2-servers/pkce/ for more info.
 | 
					// To protect against CSRF attacks, opts should include a PKCE challenge
 | 
				
			||||||
 | 
					// (S256ChallengeOption). Not all servers support PKCE. An alternative is to
 | 
				
			||||||
 | 
					// generate a random state parameter and verify it after exchange.
 | 
				
			||||||
 | 
					// See https://datatracker.ietf.org/doc/html/rfc6749#section-10.12 (predating
 | 
				
			||||||
 | 
					// PKCE), https://www.oauth.com/oauth2-servers/pkce/ and
 | 
				
			||||||
 | 
					// https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.html#name-cross-site-request-forgery (describing both approaches)
 | 
				
			||||||
func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
 | 
					func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
 | 
				
			||||||
	var buf bytes.Buffer
 | 
						var buf bytes.Buffer
 | 
				
			||||||
	buf.WriteString(c.Endpoint.AuthURL)
 | 
						buf.WriteString(c.Endpoint.AuthURL)
 | 
				
			||||||
@@ -162,7 +171,6 @@ func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
 | 
				
			|||||||
		v.Set("scope", strings.Join(c.Scopes, " "))
 | 
							v.Set("scope", strings.Join(c.Scopes, " "))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if state != "" {
 | 
						if state != "" {
 | 
				
			||||||
		// TODO(light): Docs say never to omit state; don't allow empty.
 | 
					 | 
				
			||||||
		v.Set("state", state)
 | 
							v.Set("state", state)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, opt := range opts {
 | 
						for _, opt := range opts {
 | 
				
			||||||
@@ -207,10 +215,11 @@ func (c *Config) PasswordCredentialsToken(ctx context.Context, username, passwor
 | 
				
			|||||||
// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
 | 
					// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// The code will be in the *http.Request.FormValue("code"). Before
 | 
					// The code will be in the *http.Request.FormValue("code"). Before
 | 
				
			||||||
// calling Exchange, be sure to validate FormValue("state").
 | 
					// calling Exchange, be sure to validate FormValue("state") if you are
 | 
				
			||||||
 | 
					// using it to protect against CSRF attacks.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Opts may include the PKCE verifier code if previously used in AuthCodeURL.
 | 
					// If using PKCE to protect against CSRF attacks, opts should include a
 | 
				
			||||||
// See https://www.oauth.com/oauth2-servers/pkce/ for more info.
 | 
					// VerifierOption.
 | 
				
			||||||
func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOption) (*Token, error) {
 | 
					func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOption) (*Token, error) {
 | 
				
			||||||
	v := url.Values{
 | 
						v := url.Values{
 | 
				
			||||||
		"grant_type": {"authorization_code"},
 | 
							"grant_type": {"authorization_code"},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										68
									
								
								vendor/golang.org/x/oauth2/pkce.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								vendor/golang.org/x/oauth2/pkce.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					// Copyright 2023 The Go Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a BSD-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					package oauth2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/rand"
 | 
				
			||||||
 | 
						"crypto/sha256"
 | 
				
			||||||
 | 
						"encoding/base64"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						codeChallengeKey       = "code_challenge"
 | 
				
			||||||
 | 
						codeChallengeMethodKey = "code_challenge_method"
 | 
				
			||||||
 | 
						codeVerifierKey        = "code_verifier"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GenerateVerifier generates a PKCE code verifier with 32 octets of randomness.
 | 
				
			||||||
 | 
					// This follows recommendations in RFC 7636.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// A fresh verifier should be generated for each authorization.
 | 
				
			||||||
 | 
					// S256ChallengeOption(verifier) should then be passed to Config.AuthCodeURL
 | 
				
			||||||
 | 
					// (or Config.DeviceAccess) and VerifierOption(verifier) to Config.Exchange
 | 
				
			||||||
 | 
					// (or Config.DeviceAccessToken).
 | 
				
			||||||
 | 
					func GenerateVerifier() string {
 | 
				
			||||||
 | 
						// "RECOMMENDED that the output of a suitable random number generator be
 | 
				
			||||||
 | 
						// used to create a 32-octet sequence.  The octet sequence is then
 | 
				
			||||||
 | 
						// base64url-encoded to produce a 43-octet URL-safe string to use as the
 | 
				
			||||||
 | 
						// code verifier."
 | 
				
			||||||
 | 
						// https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
 | 
				
			||||||
 | 
						data := make([]byte, 32)
 | 
				
			||||||
 | 
						if _, err := rand.Read(data); err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return base64.RawURLEncoding.EncodeToString(data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VerifierOption returns a PKCE code verifier AuthCodeOption. It should be
 | 
				
			||||||
 | 
					// passed to Config.Exchange or Config.DeviceAccessToken only.
 | 
				
			||||||
 | 
					func VerifierOption(verifier string) AuthCodeOption {
 | 
				
			||||||
 | 
						return setParam{k: codeVerifierKey, v: verifier}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// S256ChallengeFromVerifier returns a PKCE code challenge derived from verifier with method S256.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Prefer to use S256ChallengeOption where possible.
 | 
				
			||||||
 | 
					func S256ChallengeFromVerifier(verifier string) string {
 | 
				
			||||||
 | 
						sha := sha256.Sum256([]byte(verifier))
 | 
				
			||||||
 | 
						return base64.RawURLEncoding.EncodeToString(sha[:])
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// S256ChallengeOption derives a PKCE code challenge derived from verifier with
 | 
				
			||||||
 | 
					// method S256. It should be passed to Config.AuthCodeURL or Config.DeviceAccess
 | 
				
			||||||
 | 
					// only.
 | 
				
			||||||
 | 
					func S256ChallengeOption(verifier string) AuthCodeOption {
 | 
				
			||||||
 | 
						return challengeOption{
 | 
				
			||||||
 | 
							challenge_method: "S256",
 | 
				
			||||||
 | 
							challenge:        S256ChallengeFromVerifier(verifier),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type challengeOption struct{ challenge_method, challenge string }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p challengeOption) setValue(m url.Values) {
 | 
				
			||||||
 | 
						m.Set(codeChallengeMethodKey, p.challenge_method)
 | 
				
			||||||
 | 
						m.Set(codeChallengeKey, p.challenge)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2
									
								
								vendor/golang.org/x/oauth2/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/golang.org/x/oauth2/token.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -164,7 +164,7 @@ func tokenFromInternal(t *internal.Token) *Token {
 | 
				
			|||||||
// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
 | 
					// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
 | 
				
			||||||
// with an error..
 | 
					// with an error..
 | 
				
			||||||
func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
 | 
					func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
 | 
				
			||||||
	tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle))
 | 
						tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle), c.authStyleCache.Get())
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if rErr, ok := err.(*internal.RetrieveError); ok {
 | 
							if rErr, ok := err.(*internal.RetrieveError); ok {
 | 
				
			||||||
			return nil, (*RetrieveError)(rErr)
 | 
								return nil, (*RetrieveError)(rErr)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,21 +32,13 @@ import (
 | 
				
			|||||||
	"google.golang.org/grpc/resolver"
 | 
						"google.golang.org/grpc/resolver"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ccbMode int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	ccbModeActive = iota
 | 
					 | 
				
			||||||
	ccbModeIdle
 | 
					 | 
				
			||||||
	ccbModeClosed
 | 
					 | 
				
			||||||
	ccbModeExitingIdle
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ccBalancerWrapper sits between the ClientConn and the Balancer.
 | 
					// ccBalancerWrapper sits between the ClientConn and the Balancer.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// ccBalancerWrapper implements methods corresponding to the ones on the
 | 
					// ccBalancerWrapper implements methods corresponding to the ones on the
 | 
				
			||||||
// balancer.Balancer interface. The ClientConn is free to call these methods
 | 
					// balancer.Balancer interface. The ClientConn is free to call these methods
 | 
				
			||||||
// concurrently and the ccBalancerWrapper ensures that calls from the ClientConn
 | 
					// concurrently and the ccBalancerWrapper ensures that calls from the ClientConn
 | 
				
			||||||
// to the Balancer happen synchronously and in order.
 | 
					// to the Balancer happen in order by performing them in the serializer, without
 | 
				
			||||||
 | 
					// any mutexes held.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// ccBalancerWrapper also implements the balancer.ClientConn interface and is
 | 
					// ccBalancerWrapper also implements the balancer.ClientConn interface and is
 | 
				
			||||||
// passed to the Balancer implementations. It invokes unexported methods on the
 | 
					// passed to the Balancer implementations. It invokes unexported methods on the
 | 
				
			||||||
@@ -59,85 +51,73 @@ type ccBalancerWrapper struct {
 | 
				
			|||||||
	// read-only afterwards, and therefore can be accessed without a mutex.
 | 
						// read-only afterwards, and therefore can be accessed without a mutex.
 | 
				
			||||||
	cc               *ClientConn
 | 
						cc               *ClientConn
 | 
				
			||||||
	opts             balancer.BuildOptions
 | 
						opts             balancer.BuildOptions
 | 
				
			||||||
 | 
						serializer       *grpcsync.CallbackSerializer
 | 
				
			||||||
 | 
						serializerCancel context.CancelFunc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Outgoing (gRPC --> balancer) calls are guaranteed to execute in a
 | 
						// The following fields are only accessed within the serializer or during
 | 
				
			||||||
	// mutually exclusive manner as they are scheduled in the serializer. Fields
 | 
						// initialization.
 | 
				
			||||||
	// accessed *only* in these serializer callbacks, can therefore be accessed
 | 
					 | 
				
			||||||
	// without a mutex.
 | 
					 | 
				
			||||||
	balancer        *gracefulswitch.Balancer
 | 
					 | 
				
			||||||
	curBalancerName string
 | 
						curBalancerName string
 | 
				
			||||||
 | 
						balancer        *gracefulswitch.Balancer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// mu guards access to the below fields. Access to the serializer and its
 | 
						// The following field is protected by mu.  Caller must take cc.mu before
 | 
				
			||||||
	// cancel function needs to be mutex protected because they are overwritten
 | 
						// taking mu.
 | 
				
			||||||
	// when the wrapper exits idle mode.
 | 
					 | 
				
			||||||
	mu     sync.Mutex
 | 
						mu     sync.Mutex
 | 
				
			||||||
	serializer       *grpcsync.CallbackSerializer // To serialize all outoing calls.
 | 
						closed bool
 | 
				
			||||||
	serializerCancel context.CancelFunc           // To close the seralizer at close/enterIdle time.
 | 
					 | 
				
			||||||
	mode             ccbMode                      // Tracks the current mode of the wrapper.
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newCCBalancerWrapper creates a new balancer wrapper. The underlying balancer
 | 
					// newCCBalancerWrapper creates a new balancer wrapper in idle state. The
 | 
				
			||||||
// is not created until the switchTo() method is invoked.
 | 
					// underlying balancer is not created until the switchTo() method is invoked.
 | 
				
			||||||
func newCCBalancerWrapper(cc *ClientConn, bopts balancer.BuildOptions) *ccBalancerWrapper {
 | 
					func newCCBalancerWrapper(cc *ClientConn) *ccBalancerWrapper {
 | 
				
			||||||
	ctx, cancel := context.WithCancel(context.Background())
 | 
						ctx, cancel := context.WithCancel(cc.ctx)
 | 
				
			||||||
	ccb := &ccBalancerWrapper{
 | 
						ccb := &ccBalancerWrapper{
 | 
				
			||||||
		cc: cc,
 | 
							cc: cc,
 | 
				
			||||||
		opts:             bopts,
 | 
							opts: balancer.BuildOptions{
 | 
				
			||||||
 | 
								DialCreds:        cc.dopts.copts.TransportCredentials,
 | 
				
			||||||
 | 
								CredsBundle:      cc.dopts.copts.CredsBundle,
 | 
				
			||||||
 | 
								Dialer:           cc.dopts.copts.Dialer,
 | 
				
			||||||
 | 
								Authority:        cc.authority,
 | 
				
			||||||
 | 
								CustomUserAgent:  cc.dopts.copts.UserAgent,
 | 
				
			||||||
 | 
								ChannelzParentID: cc.channelzID,
 | 
				
			||||||
 | 
								Target:           cc.parsedTarget,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		serializer:       grpcsync.NewCallbackSerializer(ctx),
 | 
							serializer:       grpcsync.NewCallbackSerializer(ctx),
 | 
				
			||||||
		serializerCancel: cancel,
 | 
							serializerCancel: cancel,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ccb.balancer = gracefulswitch.NewBalancer(ccb, bopts)
 | 
						ccb.balancer = gracefulswitch.NewBalancer(ccb, ccb.opts)
 | 
				
			||||||
	return ccb
 | 
						return ccb
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// updateClientConnState is invoked by grpc to push a ClientConnState update to
 | 
					// updateClientConnState is invoked by grpc to push a ClientConnState update to
 | 
				
			||||||
// the underlying balancer.
 | 
					// the underlying balancer.  This is always executed from the serializer, so
 | 
				
			||||||
 | 
					// it is safe to call into the balancer here.
 | 
				
			||||||
func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error {
 | 
					func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error {
 | 
				
			||||||
	ccb.mu.Lock()
 | 
						errCh := make(chan error)
 | 
				
			||||||
	errCh := make(chan error, 1)
 | 
						ok := ccb.serializer.Schedule(func(ctx context.Context) {
 | 
				
			||||||
	// Here and everywhere else where Schedule() is called, it is done with the
 | 
							defer close(errCh)
 | 
				
			||||||
	// lock held. But the lock guards only the scheduling part. The actual
 | 
							if ctx.Err() != nil || ccb.balancer == nil {
 | 
				
			||||||
	// callback is called asynchronously without the lock being held.
 | 
								return
 | 
				
			||||||
	ok := ccb.serializer.Schedule(func(_ context.Context) {
 | 
					 | 
				
			||||||
		errCh <- ccb.balancer.UpdateClientConnState(*ccs)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		// If we are unable to schedule a function with the serializer, it
 | 
					 | 
				
			||||||
		// indicates that it has been closed. A serializer is only closed when
 | 
					 | 
				
			||||||
		// the wrapper is closed or is in idle.
 | 
					 | 
				
			||||||
		ccb.mu.Unlock()
 | 
					 | 
				
			||||||
		return fmt.Errorf("grpc: cannot send state update to a closed or idle balancer")
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	ccb.mu.Unlock()
 | 
							err := ccb.balancer.UpdateClientConnState(*ccs)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// We get here only if the above call to Schedule succeeds, in which case it
 | 
					 | 
				
			||||||
	// is guaranteed that the scheduled function will run. Therefore it is safe
 | 
					 | 
				
			||||||
	// to block on this channel.
 | 
					 | 
				
			||||||
	err := <-errCh
 | 
					 | 
				
			||||||
		if logger.V(2) && err != nil {
 | 
							if logger.V(2) && err != nil {
 | 
				
			||||||
			logger.Infof("error from balancer.UpdateClientConnState: %v", err)
 | 
								logger.Infof("error from balancer.UpdateClientConnState: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	return err
 | 
							errCh <- err
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// updateSubConnState is invoked by grpc to push a subConn state update to the
 | 
					 | 
				
			||||||
// underlying balancer.
 | 
					 | 
				
			||||||
func (ccb *ccBalancerWrapper) updateSubConnState(sc balancer.SubConn, s connectivity.State, err error) {
 | 
					 | 
				
			||||||
	ccb.mu.Lock()
 | 
					 | 
				
			||||||
	ccb.serializer.Schedule(func(_ context.Context) {
 | 
					 | 
				
			||||||
		// Even though it is optional for balancers, gracefulswitch ensures
 | 
					 | 
				
			||||||
		// opts.StateListener is set, so this cannot ever be nil.
 | 
					 | 
				
			||||||
		sc.(*acBalancerWrapper).stateListener(balancer.SubConnState{ConnectivityState: s, ConnectionError: err})
 | 
					 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	ccb.mu.Unlock()
 | 
						if !ok {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return <-errCh
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// resolverError is invoked by grpc to push a resolver error to the underlying
 | 
				
			||||||
 | 
					// balancer.  The call to the balancer is executed from the serializer.
 | 
				
			||||||
func (ccb *ccBalancerWrapper) resolverError(err error) {
 | 
					func (ccb *ccBalancerWrapper) resolverError(err error) {
 | 
				
			||||||
	ccb.mu.Lock()
 | 
						ccb.serializer.Schedule(func(ctx context.Context) {
 | 
				
			||||||
	ccb.serializer.Schedule(func(_ context.Context) {
 | 
							if ctx.Err() != nil || ccb.balancer == nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ccb.balancer.ResolverError(err)
 | 
							ccb.balancer.ResolverError(err)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	ccb.mu.Unlock()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// switchTo is invoked by grpc to instruct the balancer wrapper to switch to the
 | 
					// switchTo is invoked by grpc to instruct the balancer wrapper to switch to the
 | 
				
			||||||
@@ -151,8 +131,10 @@ func (ccb *ccBalancerWrapper) resolverError(err error) {
 | 
				
			|||||||
// the ccBalancerWrapper keeps track of the current LB policy name, and skips
 | 
					// the ccBalancerWrapper keeps track of the current LB policy name, and skips
 | 
				
			||||||
// the graceful balancer switching process if the name does not change.
 | 
					// the graceful balancer switching process if the name does not change.
 | 
				
			||||||
func (ccb *ccBalancerWrapper) switchTo(name string) {
 | 
					func (ccb *ccBalancerWrapper) switchTo(name string) {
 | 
				
			||||||
	ccb.mu.Lock()
 | 
						ccb.serializer.Schedule(func(ctx context.Context) {
 | 
				
			||||||
	ccb.serializer.Schedule(func(_ context.Context) {
 | 
							if ctx.Err() != nil || ccb.balancer == nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// TODO: Other languages use case-sensitive balancer registries. We should
 | 
							// TODO: Other languages use case-sensitive balancer registries. We should
 | 
				
			||||||
		// switch as well. See: https://github.com/grpc/grpc-go/issues/5288.
 | 
							// switch as well. See: https://github.com/grpc/grpc-go/issues/5288.
 | 
				
			||||||
		if strings.EqualFold(ccb.curBalancerName, name) {
 | 
							if strings.EqualFold(ccb.curBalancerName, name) {
 | 
				
			||||||
@@ -160,7 +142,6 @@ func (ccb *ccBalancerWrapper) switchTo(name string) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		ccb.buildLoadBalancingPolicy(name)
 | 
							ccb.buildLoadBalancingPolicy(name)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	ccb.mu.Unlock()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// buildLoadBalancingPolicy performs the following:
 | 
					// buildLoadBalancingPolicy performs the following:
 | 
				
			||||||
@@ -187,115 +168,49 @@ func (ccb *ccBalancerWrapper) buildLoadBalancingPolicy(name string) {
 | 
				
			|||||||
	ccb.curBalancerName = builder.Name()
 | 
						ccb.curBalancerName = builder.Name()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// close initiates async shutdown of the wrapper.  cc.mu must be held when
 | 
				
			||||||
 | 
					// calling this function.  To determine the wrapper has finished shutting down,
 | 
				
			||||||
 | 
					// the channel should block on ccb.serializer.Done() without cc.mu held.
 | 
				
			||||||
func (ccb *ccBalancerWrapper) close() {
 | 
					func (ccb *ccBalancerWrapper) close() {
 | 
				
			||||||
 | 
						ccb.mu.Lock()
 | 
				
			||||||
 | 
						ccb.closed = true
 | 
				
			||||||
 | 
						ccb.mu.Unlock()
 | 
				
			||||||
	channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: closing")
 | 
						channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: closing")
 | 
				
			||||||
	ccb.closeBalancer(ccbModeClosed)
 | 
						ccb.serializer.Schedule(func(context.Context) {
 | 
				
			||||||
}
 | 
							if ccb.balancer == nil {
 | 
				
			||||||
 | 
					 | 
				
			||||||
// enterIdleMode is invoked by grpc when the channel enters idle mode upon
 | 
					 | 
				
			||||||
// expiry of idle_timeout. This call blocks until the balancer is closed.
 | 
					 | 
				
			||||||
func (ccb *ccBalancerWrapper) enterIdleMode() {
 | 
					 | 
				
			||||||
	channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: entering idle mode")
 | 
					 | 
				
			||||||
	ccb.closeBalancer(ccbModeIdle)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// closeBalancer is invoked when the channel is being closed or when it enters
 | 
					 | 
				
			||||||
// idle mode upon expiry of idle_timeout.
 | 
					 | 
				
			||||||
func (ccb *ccBalancerWrapper) closeBalancer(m ccbMode) {
 | 
					 | 
				
			||||||
	ccb.mu.Lock()
 | 
					 | 
				
			||||||
	if ccb.mode == ccbModeClosed || ccb.mode == ccbModeIdle {
 | 
					 | 
				
			||||||
		ccb.mu.Unlock()
 | 
					 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							ccb.balancer.Close()
 | 
				
			||||||
	ccb.mode = m
 | 
							ccb.balancer = nil
 | 
				
			||||||
	done := ccb.serializer.Done()
 | 
						})
 | 
				
			||||||
	b := ccb.balancer
 | 
					 | 
				
			||||||
	ok := ccb.serializer.Schedule(func(_ context.Context) {
 | 
					 | 
				
			||||||
		// Close the serializer to ensure that no more calls from gRPC are sent
 | 
					 | 
				
			||||||
		// to the balancer.
 | 
					 | 
				
			||||||
	ccb.serializerCancel()
 | 
						ccb.serializerCancel()
 | 
				
			||||||
		// Empty the current balancer name because we don't have a balancer
 | 
					}
 | 
				
			||||||
		// anymore and also so that we act on the next call to switchTo by
 | 
					
 | 
				
			||||||
		// creating a new balancer specified by the new resolver.
 | 
					// exitIdle invokes the balancer's exitIdle method in the serializer.
 | 
				
			||||||
		ccb.curBalancerName = ""
 | 
					func (ccb *ccBalancerWrapper) exitIdle() {
 | 
				
			||||||
	})
 | 
						ccb.serializer.Schedule(func(ctx context.Context) {
 | 
				
			||||||
	if !ok {
 | 
							if ctx.Err() != nil || ccb.balancer == nil {
 | 
				
			||||||
		ccb.mu.Unlock()
 | 
					 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	ccb.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Give enqueued callbacks a chance to finish before closing the balancer.
 | 
					 | 
				
			||||||
	<-done
 | 
					 | 
				
			||||||
	b.Close()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// exitIdleMode is invoked by grpc when the channel exits idle mode either
 | 
					 | 
				
			||||||
// because of an RPC or because of an invocation of the Connect() API. This
 | 
					 | 
				
			||||||
// recreates the balancer that was closed previously when entering idle mode.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// If the channel is not in idle mode, we know for a fact that we are here as a
 | 
					 | 
				
			||||||
// result of the user calling the Connect() method on the ClientConn. In this
 | 
					 | 
				
			||||||
// case, we can simply forward the call to the underlying balancer, instructing
 | 
					 | 
				
			||||||
// it to reconnect to the backends.
 | 
					 | 
				
			||||||
func (ccb *ccBalancerWrapper) exitIdleMode() {
 | 
					 | 
				
			||||||
	ccb.mu.Lock()
 | 
					 | 
				
			||||||
	if ccb.mode == ccbModeClosed {
 | 
					 | 
				
			||||||
		// Request to exit idle is a no-op when wrapper is already closed.
 | 
					 | 
				
			||||||
		ccb.mu.Unlock()
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ccb.mode == ccbModeIdle {
 | 
					 | 
				
			||||||
		// Recreate the serializer which was closed when we entered idle.
 | 
					 | 
				
			||||||
		ctx, cancel := context.WithCancel(context.Background())
 | 
					 | 
				
			||||||
		ccb.serializer = grpcsync.NewCallbackSerializer(ctx)
 | 
					 | 
				
			||||||
		ccb.serializerCancel = cancel
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// The ClientConn guarantees that mutual exclusion between close() and
 | 
					 | 
				
			||||||
	// exitIdleMode(), and since we just created a new serializer, we can be
 | 
					 | 
				
			||||||
	// sure that the below function will be scheduled.
 | 
					 | 
				
			||||||
	done := make(chan struct{})
 | 
					 | 
				
			||||||
	ccb.serializer.Schedule(func(_ context.Context) {
 | 
					 | 
				
			||||||
		defer close(done)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ccb.mu.Lock()
 | 
					 | 
				
			||||||
		defer ccb.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ccb.mode != ccbModeIdle {
 | 
					 | 
				
			||||||
		ccb.balancer.ExitIdle()
 | 
							ccb.balancer.ExitIdle()
 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Gracefulswitch balancer does not support a switchTo operation after
 | 
					 | 
				
			||||||
		// being closed. Hence we need to create a new one here.
 | 
					 | 
				
			||||||
		ccb.balancer = gracefulswitch.NewBalancer(ccb, ccb.opts)
 | 
					 | 
				
			||||||
		ccb.mode = ccbModeActive
 | 
					 | 
				
			||||||
		channelz.Info(logger, ccb.cc.channelzID, "ccBalancerWrapper: exiting idle mode")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	ccb.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	<-done
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ccb *ccBalancerWrapper) isIdleOrClosed() bool {
 | 
					 | 
				
			||||||
	ccb.mu.Lock()
 | 
					 | 
				
			||||||
	defer ccb.mu.Unlock()
 | 
					 | 
				
			||||||
	return ccb.mode == ccbModeIdle || ccb.mode == ccbModeClosed
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
 | 
					func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
 | 
				
			||||||
	if ccb.isIdleOrClosed() {
 | 
						ccb.cc.mu.Lock()
 | 
				
			||||||
		return nil, fmt.Errorf("grpc: cannot create SubConn when balancer is closed or idle")
 | 
						defer ccb.cc.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ccb.mu.Lock()
 | 
				
			||||||
 | 
						if ccb.closed {
 | 
				
			||||||
 | 
							ccb.mu.Unlock()
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("balancer is being closed; no new SubConns allowed")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ccb.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(addrs) == 0 {
 | 
						if len(addrs) == 0 {
 | 
				
			||||||
		return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list")
 | 
							return nil, fmt.Errorf("grpc: cannot create SubConn with empty address list")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ac, err := ccb.cc.newAddrConn(addrs, opts)
 | 
						ac, err := ccb.cc.newAddrConnLocked(addrs, opts)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		channelz.Warningf(logger, ccb.cc.channelzID, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err)
 | 
							channelz.Warningf(logger, ccb.cc.channelzID, "acBalancerWrapper: NewSubConn: failed to newAddrConn: %v", err)
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -316,10 +231,6 @@ func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) {
 | 
					func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) {
 | 
				
			||||||
	if ccb.isIdleOrClosed() {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	acbw, ok := sc.(*acBalancerWrapper)
 | 
						acbw, ok := sc.(*acBalancerWrapper)
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -328,25 +239,39 @@ func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resol
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) {
 | 
					func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) {
 | 
				
			||||||
	if ccb.isIdleOrClosed() {
 | 
						ccb.cc.mu.Lock()
 | 
				
			||||||
 | 
						defer ccb.cc.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ccb.mu.Lock()
 | 
				
			||||||
 | 
						if ccb.closed {
 | 
				
			||||||
 | 
							ccb.mu.Unlock()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ccb.mu.Unlock()
 | 
				
			||||||
	// Update picker before updating state.  Even though the ordering here does
 | 
						// Update picker before updating state.  Even though the ordering here does
 | 
				
			||||||
	// not matter, it can lead to multiple calls of Pick in the common start-up
 | 
						// not matter, it can lead to multiple calls of Pick in the common start-up
 | 
				
			||||||
	// case where we wait for ready and then perform an RPC.  If the picker is
 | 
						// case where we wait for ready and then perform an RPC.  If the picker is
 | 
				
			||||||
	// updated later, we could call the "connecting" picker when the state is
 | 
						// updated later, we could call the "connecting" picker when the state is
 | 
				
			||||||
	// updated, and then call the "ready" picker after the picker gets updated.
 | 
						// updated, and then call the "ready" picker after the picker gets updated.
 | 
				
			||||||
	ccb.cc.blockingpicker.updatePicker(s.Picker)
 | 
					
 | 
				
			||||||
 | 
						// Note that there is no need to check if the balancer wrapper was closed,
 | 
				
			||||||
 | 
						// as we know the graceful switch LB policy will not call cc if it has been
 | 
				
			||||||
 | 
						// closed.
 | 
				
			||||||
 | 
						ccb.cc.pickerWrapper.updatePicker(s.Picker)
 | 
				
			||||||
	ccb.cc.csMgr.updateState(s.ConnectivityState)
 | 
						ccb.cc.csMgr.updateState(s.ConnectivityState)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOptions) {
 | 
					func (ccb *ccBalancerWrapper) ResolveNow(o resolver.ResolveNowOptions) {
 | 
				
			||||||
	if ccb.isIdleOrClosed() {
 | 
						ccb.cc.mu.RLock()
 | 
				
			||||||
 | 
						defer ccb.cc.mu.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ccb.mu.Lock()
 | 
				
			||||||
 | 
						if ccb.closed {
 | 
				
			||||||
 | 
							ccb.mu.Unlock()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						ccb.mu.Unlock()
 | 
				
			||||||
	ccb.cc.resolveNow(o)
 | 
						ccb.cc.resolveNowLocked(o)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ccb *ccBalancerWrapper) Target() string {
 | 
					func (ccb *ccBalancerWrapper) Target() string {
 | 
				
			||||||
@@ -364,6 +289,20 @@ type acBalancerWrapper struct {
 | 
				
			|||||||
	producers map[balancer.ProducerBuilder]*refCountedProducer
 | 
						producers map[balancer.ProducerBuilder]*refCountedProducer
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// updateState is invoked by grpc to push a subConn state update to the
 | 
				
			||||||
 | 
					// underlying balancer.
 | 
				
			||||||
 | 
					func (acbw *acBalancerWrapper) updateState(s connectivity.State, err error) {
 | 
				
			||||||
 | 
						acbw.ccb.serializer.Schedule(func(ctx context.Context) {
 | 
				
			||||||
 | 
							if ctx.Err() != nil || acbw.ccb.balancer == nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Even though it is optional for balancers, gracefulswitch ensures
 | 
				
			||||||
 | 
							// opts.StateListener is set, so this cannot ever be nil.
 | 
				
			||||||
 | 
							// TODO: delete this comment when UpdateSubConnState is removed.
 | 
				
			||||||
 | 
							acbw.stateListener(balancer.SubConnState{ConnectivityState: s, ConnectionError: err})
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (acbw *acBalancerWrapper) String() string {
 | 
					func (acbw *acBalancerWrapper) String() string {
 | 
				
			||||||
	return fmt.Sprintf("SubConn(id:%d)", acbw.ac.channelzID.Int())
 | 
						return fmt.Sprintf("SubConn(id:%d)", acbw.ac.channelzID.Int())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -377,20 +316,7 @@ func (acbw *acBalancerWrapper) Connect() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (acbw *acBalancerWrapper) Shutdown() {
 | 
					func (acbw *acBalancerWrapper) Shutdown() {
 | 
				
			||||||
	ccb := acbw.ccb
 | 
						acbw.ccb.cc.removeAddrConn(acbw.ac, errConnDrain)
 | 
				
			||||||
	if ccb.isIdleOrClosed() {
 | 
					 | 
				
			||||||
		// It it safe to ignore this call when the balancer is closed or in idle
 | 
					 | 
				
			||||||
		// because the ClientConn takes care of closing the connections.
 | 
					 | 
				
			||||||
		//
 | 
					 | 
				
			||||||
		// Not returning early from here when the balancer is closed or in idle
 | 
					 | 
				
			||||||
		// leads to a deadlock though, because of the following sequence of
 | 
					 | 
				
			||||||
		// calls when holding cc.mu:
 | 
					 | 
				
			||||||
		// cc.exitIdleMode --> ccb.enterIdleMode --> gsw.Close -->
 | 
					 | 
				
			||||||
		// ccb.RemoveAddrConn --> cc.removeAddrConn
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ccb.cc.removeAddrConn(acbw.ac, errConnDrain)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewStream begins a streaming RPC on the addrConn.  If the addrConn is not
 | 
					// NewStream begins a streaming RPC on the addrConn.  If the addrConn is not
 | 
				
			||||||
							
								
								
									
										488
									
								
								vendor/google.golang.org/grpc/clientconn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										488
									
								
								vendor/google.golang.org/grpc/clientconn.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -33,9 +33,7 @@ import (
 | 
				
			|||||||
	"google.golang.org/grpc/balancer/base"
 | 
						"google.golang.org/grpc/balancer/base"
 | 
				
			||||||
	"google.golang.org/grpc/codes"
 | 
						"google.golang.org/grpc/codes"
 | 
				
			||||||
	"google.golang.org/grpc/connectivity"
 | 
						"google.golang.org/grpc/connectivity"
 | 
				
			||||||
	"google.golang.org/grpc/credentials"
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/internal"
 | 
						"google.golang.org/grpc/internal"
 | 
				
			||||||
	"google.golang.org/grpc/internal/backoff"
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/internal/channelz"
 | 
						"google.golang.org/grpc/internal/channelz"
 | 
				
			||||||
	"google.golang.org/grpc/internal/grpcsync"
 | 
						"google.golang.org/grpc/internal/grpcsync"
 | 
				
			||||||
	"google.golang.org/grpc/internal/idle"
 | 
						"google.golang.org/grpc/internal/idle"
 | 
				
			||||||
@@ -48,9 +46,9 @@ import (
 | 
				
			|||||||
	"google.golang.org/grpc/status"
 | 
						"google.golang.org/grpc/status"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_ "google.golang.org/grpc/balancer/roundrobin"           // To register roundrobin.
 | 
						_ "google.golang.org/grpc/balancer/roundrobin"           // To register roundrobin.
 | 
				
			||||||
	_ "google.golang.org/grpc/internal/resolver/dns"         // To register dns resolver.
 | 
					 | 
				
			||||||
	_ "google.golang.org/grpc/internal/resolver/passthrough" // To register passthrough resolver.
 | 
						_ "google.golang.org/grpc/internal/resolver/passthrough" // To register passthrough resolver.
 | 
				
			||||||
	_ "google.golang.org/grpc/internal/resolver/unix"        // To register unix resolver.
 | 
						_ "google.golang.org/grpc/internal/resolver/unix"        // To register unix resolver.
 | 
				
			||||||
 | 
						_ "google.golang.org/grpc/resolver/dns"                  // To register dns resolver.
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -119,23 +117,8 @@ func (dcs *defaultConfigSelector) SelectConfig(rpcInfo iresolver.RPCInfo) (*ires
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DialContext creates a client connection to the given target. By default, it's
 | 
					// newClient returns a new client in idle mode.
 | 
				
			||||||
// a non-blocking dial (the function won't wait for connections to be
 | 
					func newClient(target string, opts ...DialOption) (conn *ClientConn, err error) {
 | 
				
			||||||
// established, and connecting happens in the background). To make it a blocking
 | 
					 | 
				
			||||||
// dial, use WithBlock() dial option.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// In the non-blocking case, the ctx does not act against the connection. It
 | 
					 | 
				
			||||||
// only controls the setup steps.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// In the blocking case, ctx can be used to cancel or expire the pending
 | 
					 | 
				
			||||||
// connection. Once this function returns, the cancellation and expiration of
 | 
					 | 
				
			||||||
// ctx will be noop. Users should call ClientConn.Close to terminate all the
 | 
					 | 
				
			||||||
// pending operations after this function returns.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The target name syntax is defined in
 | 
					 | 
				
			||||||
// https://github.com/grpc/grpc/blob/master/doc/naming.md.
 | 
					 | 
				
			||||||
// e.g. to use dns resolver, a "dns:///" prefix should be applied to the target.
 | 
					 | 
				
			||||||
func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) {
 | 
					 | 
				
			||||||
	cc := &ClientConn{
 | 
						cc := &ClientConn{
 | 
				
			||||||
		target: target,
 | 
							target: target,
 | 
				
			||||||
		conns:  make(map[*addrConn]struct{}),
 | 
							conns:  make(map[*addrConn]struct{}),
 | 
				
			||||||
@@ -143,23 +126,11 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
 | 
				
			|||||||
		czData: new(channelzData),
 | 
							czData: new(channelzData),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// We start the channel off in idle mode, but kick it out of idle at the end
 | 
					 | 
				
			||||||
	// of this method, instead of waiting for the first RPC. Other gRPC
 | 
					 | 
				
			||||||
	// implementations do wait for the first RPC to kick the channel out of
 | 
					 | 
				
			||||||
	// idle. But doing so would be a major behavior change for our users who are
 | 
					 | 
				
			||||||
	// used to seeing the channel active after Dial.
 | 
					 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	// Taking this approach of kicking it out of idle at the end of this method
 | 
					 | 
				
			||||||
	// allows us to share the code between channel creation and exiting idle
 | 
					 | 
				
			||||||
	// mode. This will also make it easy for us to switch to starting the
 | 
					 | 
				
			||||||
	// channel off in idle, if at all we ever get to do that.
 | 
					 | 
				
			||||||
	cc.idlenessState = ccIdlenessStateIdle
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cc.retryThrottler.Store((*retryThrottler)(nil))
 | 
						cc.retryThrottler.Store((*retryThrottler)(nil))
 | 
				
			||||||
	cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{nil})
 | 
						cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{nil})
 | 
				
			||||||
	cc.ctx, cc.cancel = context.WithCancel(context.Background())
 | 
						cc.ctx, cc.cancel = context.WithCancel(context.Background())
 | 
				
			||||||
	cc.exitIdleCond = sync.NewCond(&cc.mu)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Apply dial options.
 | 
				
			||||||
	disableGlobalOpts := false
 | 
						disableGlobalOpts := false
 | 
				
			||||||
	for _, opt := range opts {
 | 
						for _, opt := range opts {
 | 
				
			||||||
		if _, ok := opt.(*disableGlobalDialOptions); ok {
 | 
							if _, ok := opt.(*disableGlobalDialOptions); ok {
 | 
				
			||||||
@@ -177,21 +148,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
 | 
				
			|||||||
	for _, opt := range opts {
 | 
						for _, opt := range opts {
 | 
				
			||||||
		opt.apply(&cc.dopts)
 | 
							opt.apply(&cc.dopts)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	chainUnaryClientInterceptors(cc)
 | 
						chainUnaryClientInterceptors(cc)
 | 
				
			||||||
	chainStreamClientInterceptors(cc)
 | 
						chainStreamClientInterceptors(cc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			cc.Close()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Register ClientConn with channelz.
 | 
					 | 
				
			||||||
	cc.channelzRegistration(target)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelzID)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := cc.validateTransportCredentials(); err != nil {
 | 
						if err := cc.validateTransportCredentials(); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -205,10 +164,80 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	cc.mkp = cc.dopts.copts.KeepaliveParams
 | 
						cc.mkp = cc.dopts.copts.KeepaliveParams
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if cc.dopts.copts.UserAgent != "" {
 | 
						// Register ClientConn with channelz.
 | 
				
			||||||
		cc.dopts.copts.UserAgent += " " + grpcUA
 | 
						cc.channelzRegistration(target)
 | 
				
			||||||
	} else {
 | 
					
 | 
				
			||||||
		cc.dopts.copts.UserAgent = grpcUA
 | 
						// TODO: Ideally it should be impossible to error from this function after
 | 
				
			||||||
 | 
						// channelz registration.  This will require removing some channelz logs
 | 
				
			||||||
 | 
						// from the following functions that can error.  Errors can be returned to
 | 
				
			||||||
 | 
						// the user, and successful logs can be emitted here, after the checks have
 | 
				
			||||||
 | 
						// passed and channelz is subsequently registered.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Determine the resolver to use.
 | 
				
			||||||
 | 
						if err := cc.parseTargetAndFindResolver(); err != nil {
 | 
				
			||||||
 | 
							channelz.RemoveEntry(cc.channelzID)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err = cc.determineAuthority(); err != nil {
 | 
				
			||||||
 | 
							channelz.RemoveEntry(cc.channelzID)
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cc.csMgr = newConnectivityStateManager(cc.ctx, cc.channelzID)
 | 
				
			||||||
 | 
						cc.pickerWrapper = newPickerWrapper(cc.dopts.copts.StatsHandlers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cc.initIdleStateLocked() // Safe to call without the lock, since nothing else has a reference to cc.
 | 
				
			||||||
 | 
						cc.idlenessMgr = idle.NewManager((*idler)(cc), cc.dopts.idleTimeout)
 | 
				
			||||||
 | 
						return cc, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DialContext creates a client connection to the given target. By default, it's
 | 
				
			||||||
 | 
					// a non-blocking dial (the function won't wait for connections to be
 | 
				
			||||||
 | 
					// established, and connecting happens in the background). To make it a blocking
 | 
				
			||||||
 | 
					// dial, use WithBlock() dial option.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// In the non-blocking case, the ctx does not act against the connection. It
 | 
				
			||||||
 | 
					// only controls the setup steps.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// In the blocking case, ctx can be used to cancel or expire the pending
 | 
				
			||||||
 | 
					// connection. Once this function returns, the cancellation and expiration of
 | 
				
			||||||
 | 
					// ctx will be noop. Users should call ClientConn.Close to terminate all the
 | 
				
			||||||
 | 
					// pending operations after this function returns.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The target name syntax is defined in
 | 
				
			||||||
 | 
					// https://github.com/grpc/grpc/blob/master/doc/naming.md.
 | 
				
			||||||
 | 
					// e.g. to use dns resolver, a "dns:///" prefix should be applied to the target.
 | 
				
			||||||
 | 
					func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) {
 | 
				
			||||||
 | 
						cc, err := newClient(target, opts...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We start the channel off in idle mode, but kick it out of idle now,
 | 
				
			||||||
 | 
						// instead of waiting for the first RPC. Other gRPC implementations do wait
 | 
				
			||||||
 | 
						// for the first RPC to kick the channel out of idle. But doing so would be
 | 
				
			||||||
 | 
						// a major behavior change for our users who are used to seeing the channel
 | 
				
			||||||
 | 
						// active after Dial.
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// Taking this approach of kicking it out of idle at the end of this method
 | 
				
			||||||
 | 
						// allows us to share the code between channel creation and exiting idle
 | 
				
			||||||
 | 
						// mode. This will also make it easy for us to switch to starting the
 | 
				
			||||||
 | 
						// channel off in idle, i.e. by making newClient exported.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								cc.Close()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// This creates the name resolver, load balancer, etc.
 | 
				
			||||||
 | 
						if err := cc.idlenessMgr.ExitIdleMode(); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Return now for non-blocking dials.
 | 
				
			||||||
 | 
						if !cc.dopts.block {
 | 
				
			||||||
 | 
							return cc, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if cc.dopts.timeout > 0 {
 | 
						if cc.dopts.timeout > 0 {
 | 
				
			||||||
@@ -231,49 +260,6 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if cc.dopts.bs == nil {
 | 
					 | 
				
			||||||
		cc.dopts.bs = backoff.DefaultExponential
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Determine the resolver to use.
 | 
					 | 
				
			||||||
	if err := cc.parseTargetAndFindResolver(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err = cc.determineAuthority(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if cc.dopts.scChan != nil {
 | 
					 | 
				
			||||||
		// Blocking wait for the initial service config.
 | 
					 | 
				
			||||||
		select {
 | 
					 | 
				
			||||||
		case sc, ok := <-cc.dopts.scChan:
 | 
					 | 
				
			||||||
			if ok {
 | 
					 | 
				
			||||||
				cc.sc = &sc
 | 
					 | 
				
			||||||
				cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{&sc})
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		case <-ctx.Done():
 | 
					 | 
				
			||||||
			return nil, ctx.Err()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if cc.dopts.scChan != nil {
 | 
					 | 
				
			||||||
		go cc.scWatcher()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// This creates the name resolver, load balancer, blocking picker etc.
 | 
					 | 
				
			||||||
	if err := cc.exitIdleMode(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Configure idleness support with configured idle timeout or default idle
 | 
					 | 
				
			||||||
	// timeout duration. Idleness can be explicitly disabled by the user, by
 | 
					 | 
				
			||||||
	// setting the dial option to 0.
 | 
					 | 
				
			||||||
	cc.idlenessMgr = idle.NewManager(idle.ManagerOptions{Enforcer: (*idler)(cc), Timeout: cc.dopts.idleTimeout, Logger: logger})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Return early for non-blocking dials.
 | 
					 | 
				
			||||||
	if !cc.dopts.block {
 | 
					 | 
				
			||||||
		return cc, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// A blocking dial blocks until the clientConn is ready.
 | 
						// A blocking dial blocks until the clientConn is ready.
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		s := cc.GetState()
 | 
							s := cc.GetState()
 | 
				
			||||||
@@ -320,8 +306,8 @@ func (cc *ClientConn) addTraceEvent(msg string) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type idler ClientConn
 | 
					type idler ClientConn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (i *idler) EnterIdleMode() error {
 | 
					func (i *idler) EnterIdleMode() {
 | 
				
			||||||
	return (*ClientConn)(i).enterIdleMode()
 | 
						(*ClientConn)(i).enterIdleMode()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (i *idler) ExitIdleMode() error {
 | 
					func (i *idler) ExitIdleMode() error {
 | 
				
			||||||
@@ -329,117 +315,71 @@ func (i *idler) ExitIdleMode() error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// exitIdleMode moves the channel out of idle mode by recreating the name
 | 
					// exitIdleMode moves the channel out of idle mode by recreating the name
 | 
				
			||||||
// resolver and load balancer.
 | 
					// resolver and load balancer.  This should never be called directly; use
 | 
				
			||||||
func (cc *ClientConn) exitIdleMode() error {
 | 
					// cc.idlenessMgr.ExitIdleMode instead.
 | 
				
			||||||
 | 
					func (cc *ClientConn) exitIdleMode() (err error) {
 | 
				
			||||||
	cc.mu.Lock()
 | 
						cc.mu.Lock()
 | 
				
			||||||
	if cc.conns == nil {
 | 
						if cc.conns == nil {
 | 
				
			||||||
		cc.mu.Unlock()
 | 
							cc.mu.Unlock()
 | 
				
			||||||
		return errConnClosing
 | 
							return errConnClosing
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if cc.idlenessState != ccIdlenessStateIdle {
 | 
					 | 
				
			||||||
		channelz.Infof(logger, cc.channelzID, "ClientConn asked to exit idle mode, current mode is %v", cc.idlenessState)
 | 
					 | 
				
			||||||
		cc.mu.Unlock()
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		// When Close() and exitIdleMode() race against each other, one of the
 | 
					 | 
				
			||||||
		// following two can happen:
 | 
					 | 
				
			||||||
		// - Close() wins the race and runs first. exitIdleMode() runs after, and
 | 
					 | 
				
			||||||
		//   sees that the ClientConn is already closed and hence returns early.
 | 
					 | 
				
			||||||
		// - exitIdleMode() wins the race and runs first and recreates the balancer
 | 
					 | 
				
			||||||
		//   and releases the lock before recreating the resolver. If Close() runs
 | 
					 | 
				
			||||||
		//   in this window, it will wait for exitIdleMode to complete.
 | 
					 | 
				
			||||||
		//
 | 
					 | 
				
			||||||
		// We achieve this synchronization using the below condition variable.
 | 
					 | 
				
			||||||
		cc.mu.Lock()
 | 
					 | 
				
			||||||
		cc.idlenessState = ccIdlenessStateActive
 | 
					 | 
				
			||||||
		cc.exitIdleCond.Signal()
 | 
					 | 
				
			||||||
		cc.mu.Unlock()
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cc.idlenessState = ccIdlenessStateExitingIdle
 | 
					 | 
				
			||||||
	exitedIdle := false
 | 
					 | 
				
			||||||
	if cc.blockingpicker == nil {
 | 
					 | 
				
			||||||
		cc.blockingpicker = newPickerWrapper(cc.dopts.copts.StatsHandlers)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		cc.blockingpicker.exitIdleMode()
 | 
					 | 
				
			||||||
		exitedIdle = true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var credsClone credentials.TransportCredentials
 | 
					 | 
				
			||||||
	if creds := cc.dopts.copts.TransportCredentials; creds != nil {
 | 
					 | 
				
			||||||
		credsClone = creds.Clone()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if cc.balancerWrapper == nil {
 | 
					 | 
				
			||||||
		cc.balancerWrapper = newCCBalancerWrapper(cc, balancer.BuildOptions{
 | 
					 | 
				
			||||||
			DialCreds:        credsClone,
 | 
					 | 
				
			||||||
			CredsBundle:      cc.dopts.copts.CredsBundle,
 | 
					 | 
				
			||||||
			Dialer:           cc.dopts.copts.Dialer,
 | 
					 | 
				
			||||||
			Authority:        cc.authority,
 | 
					 | 
				
			||||||
			CustomUserAgent:  cc.dopts.copts.UserAgent,
 | 
					 | 
				
			||||||
			ChannelzParentID: cc.channelzID,
 | 
					 | 
				
			||||||
			Target:           cc.parsedTarget,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		cc.balancerWrapper.exitIdleMode()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cc.firstResolveEvent = grpcsync.NewEvent()
 | 
					 | 
				
			||||||
	cc.mu.Unlock()
 | 
						cc.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// This needs to be called without cc.mu because this builds a new resolver
 | 
						// This needs to be called without cc.mu because this builds a new resolver
 | 
				
			||||||
	// which might update state or report error inline which needs to be handled
 | 
						// which might update state or report error inline, which would then need to
 | 
				
			||||||
	// by cc.updateResolverState() which also grabs cc.mu.
 | 
						// acquire cc.mu.
 | 
				
			||||||
	if err := cc.initResolverWrapper(credsClone); err != nil {
 | 
						if err := cc.resolverWrapper.start(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if exitedIdle {
 | 
					 | 
				
			||||||
	cc.addTraceEvent("exiting idle mode")
 | 
						cc.addTraceEvent("exiting idle mode")
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// enterIdleMode puts the channel in idle mode, and as part of it shuts down the
 | 
					 | 
				
			||||||
// name resolver, load balancer and any subchannels.
 | 
					 | 
				
			||||||
func (cc *ClientConn) enterIdleMode() error {
 | 
					 | 
				
			||||||
	cc.mu.Lock()
 | 
					 | 
				
			||||||
	defer cc.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if cc.conns == nil {
 | 
					 | 
				
			||||||
		return ErrClientConnClosing
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if cc.idlenessState != ccIdlenessStateActive {
 | 
					 | 
				
			||||||
		channelz.Warningf(logger, cc.channelzID, "ClientConn asked to enter idle mode, current mode is %v", cc.idlenessState)
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// initIdleStateLocked initializes common state to how it should be while idle.
 | 
				
			||||||
 | 
					func (cc *ClientConn) initIdleStateLocked() {
 | 
				
			||||||
 | 
						cc.resolverWrapper = newCCResolverWrapper(cc)
 | 
				
			||||||
 | 
						cc.balancerWrapper = newCCBalancerWrapper(cc)
 | 
				
			||||||
 | 
						cc.firstResolveEvent = grpcsync.NewEvent()
 | 
				
			||||||
	// cc.conns == nil is a proxy for the ClientConn being closed. So, instead
 | 
						// cc.conns == nil is a proxy for the ClientConn being closed. So, instead
 | 
				
			||||||
	// of setting it to nil here, we recreate the map. This also means that we
 | 
						// of setting it to nil here, we recreate the map. This also means that we
 | 
				
			||||||
	// don't have to do this when exiting idle mode.
 | 
						// don't have to do this when exiting idle mode.
 | 
				
			||||||
	conns := cc.conns
 | 
					 | 
				
			||||||
	cc.conns = make(map[*addrConn]struct{})
 | 
						cc.conns = make(map[*addrConn]struct{})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: Currently, we close the resolver wrapper upon entering idle mode
 | 
					// enterIdleMode puts the channel in idle mode, and as part of it shuts down the
 | 
				
			||||||
	// and create a new one upon exiting idle mode. This means that the
 | 
					// name resolver, load balancer, and any subchannels.  This should never be
 | 
				
			||||||
	// `cc.resolverWrapper` field would be overwritten everytime we exit idle
 | 
					// called directly; use cc.idlenessMgr.EnterIdleMode instead.
 | 
				
			||||||
	// mode. While this means that we need to hold `cc.mu` when accessing
 | 
					func (cc *ClientConn) enterIdleMode() {
 | 
				
			||||||
	// `cc.resolverWrapper`, it makes the code simpler in the wrapper. We should
 | 
						cc.mu.Lock()
 | 
				
			||||||
	// try to do the same for the balancer and picker wrappers too.
 | 
					
 | 
				
			||||||
	cc.resolverWrapper.close()
 | 
						if cc.conns == nil {
 | 
				
			||||||
	cc.blockingpicker.enterIdleMode()
 | 
							cc.mu.Unlock()
 | 
				
			||||||
	cc.balancerWrapper.enterIdleMode()
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						conns := cc.conns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rWrapper := cc.resolverWrapper
 | 
				
			||||||
 | 
						rWrapper.close()
 | 
				
			||||||
 | 
						cc.pickerWrapper.reset()
 | 
				
			||||||
 | 
						bWrapper := cc.balancerWrapper
 | 
				
			||||||
 | 
						bWrapper.close()
 | 
				
			||||||
	cc.csMgr.updateState(connectivity.Idle)
 | 
						cc.csMgr.updateState(connectivity.Idle)
 | 
				
			||||||
	cc.idlenessState = ccIdlenessStateIdle
 | 
					 | 
				
			||||||
	cc.addTraceEvent("entering idle mode")
 | 
						cc.addTraceEvent("entering idle mode")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	go func() {
 | 
						cc.initIdleStateLocked()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cc.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Block until the name resolver and LB policy are closed.
 | 
				
			||||||
 | 
						<-rWrapper.serializer.Done()
 | 
				
			||||||
 | 
						<-bWrapper.serializer.Done()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Close all subchannels after the LB policy is closed.
 | 
				
			||||||
	for ac := range conns {
 | 
						for ac := range conns {
 | 
				
			||||||
		ac.tearDown(errConnIdling)
 | 
							ac.tearDown(errConnIdling)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// validateTransportCredentials performs a series of checks on the configured
 | 
					// validateTransportCredentials performs a series of checks on the configured
 | 
				
			||||||
@@ -649,66 +589,35 @@ type ClientConn struct {
 | 
				
			|||||||
	dopts           dialOptions          // Default and user specified dial options.
 | 
						dopts           dialOptions          // Default and user specified dial options.
 | 
				
			||||||
	channelzID      *channelz.Identifier // Channelz identifier for the channel.
 | 
						channelzID      *channelz.Identifier // Channelz identifier for the channel.
 | 
				
			||||||
	resolverBuilder resolver.Builder     // See parseTargetAndFindResolver().
 | 
						resolverBuilder resolver.Builder     // See parseTargetAndFindResolver().
 | 
				
			||||||
	balancerWrapper *ccBalancerWrapper   // Uses gracefulswitch.balancer underneath.
 | 
						idlenessMgr     *idle.Manager
 | 
				
			||||||
	idlenessMgr     idle.Manager
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The following provide their own synchronization, and therefore don't
 | 
						// The following provide their own synchronization, and therefore don't
 | 
				
			||||||
	// require cc.mu to be held to access them.
 | 
						// require cc.mu to be held to access them.
 | 
				
			||||||
	csMgr              *connectivityStateManager
 | 
						csMgr              *connectivityStateManager
 | 
				
			||||||
	blockingpicker     *pickerWrapper
 | 
						pickerWrapper      *pickerWrapper
 | 
				
			||||||
	safeConfigSelector iresolver.SafeConfigSelector
 | 
						safeConfigSelector iresolver.SafeConfigSelector
 | 
				
			||||||
	czData             *channelzData
 | 
						czData             *channelzData
 | 
				
			||||||
	retryThrottler     atomic.Value // Updated from service config.
 | 
						retryThrottler     atomic.Value // Updated from service config.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// firstResolveEvent is used to track whether the name resolver sent us at
 | 
					 | 
				
			||||||
	// least one update. RPCs block on this event.
 | 
					 | 
				
			||||||
	firstResolveEvent *grpcsync.Event
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// mu protects the following fields.
 | 
						// mu protects the following fields.
 | 
				
			||||||
	// TODO: split mu so the same mutex isn't used for everything.
 | 
						// TODO: split mu so the same mutex isn't used for everything.
 | 
				
			||||||
	mu              sync.RWMutex
 | 
						mu              sync.RWMutex
 | 
				
			||||||
	resolverWrapper *ccResolverWrapper         // Initialized in Dial; cleared in Close.
 | 
						resolverWrapper *ccResolverWrapper         // Always recreated whenever entering idle to simplify Close.
 | 
				
			||||||
 | 
						balancerWrapper *ccBalancerWrapper         // Always recreated whenever entering idle to simplify Close.
 | 
				
			||||||
	sc              *ServiceConfig             // Latest service config received from the resolver.
 | 
						sc              *ServiceConfig             // Latest service config received from the resolver.
 | 
				
			||||||
	conns           map[*addrConn]struct{}     // Set to nil on close.
 | 
						conns           map[*addrConn]struct{}     // Set to nil on close.
 | 
				
			||||||
	mkp             keepalive.ClientParameters // May be updated upon receipt of a GoAway.
 | 
						mkp             keepalive.ClientParameters // May be updated upon receipt of a GoAway.
 | 
				
			||||||
	idlenessState   ccIdlenessState            // Tracks idleness state of the channel.
 | 
						// firstResolveEvent is used to track whether the name resolver sent us at
 | 
				
			||||||
	exitIdleCond    *sync.Cond                 // Signalled when channel exits idle.
 | 
						// least one update. RPCs block on this event.  May be accessed without mu
 | 
				
			||||||
 | 
						// if we know we cannot be asked to enter idle mode while accessing it (e.g.
 | 
				
			||||||
 | 
						// when the idle manager has already been closed, or if we are already
 | 
				
			||||||
 | 
						// entering idle mode).
 | 
				
			||||||
 | 
						firstResolveEvent *grpcsync.Event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lceMu               sync.Mutex // protects lastConnectionError
 | 
						lceMu               sync.Mutex // protects lastConnectionError
 | 
				
			||||||
	lastConnectionError error
 | 
						lastConnectionError error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ccIdlenessState tracks the idleness state of the channel.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Channels start off in `active` and move to `idle` after a period of
 | 
					 | 
				
			||||||
// inactivity. When moving back to `active` upon an incoming RPC, they
 | 
					 | 
				
			||||||
// transition through `exiting_idle`. This state is useful for synchronization
 | 
					 | 
				
			||||||
// with Close().
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// This state tracking is mostly for self-protection. The idlenessManager is
 | 
					 | 
				
			||||||
// expected to keep track of the state as well, and is expected not to call into
 | 
					 | 
				
			||||||
// the ClientConn unnecessarily.
 | 
					 | 
				
			||||||
type ccIdlenessState int8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	ccIdlenessStateActive ccIdlenessState = iota
 | 
					 | 
				
			||||||
	ccIdlenessStateIdle
 | 
					 | 
				
			||||||
	ccIdlenessStateExitingIdle
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s ccIdlenessState) String() string {
 | 
					 | 
				
			||||||
	switch s {
 | 
					 | 
				
			||||||
	case ccIdlenessStateActive:
 | 
					 | 
				
			||||||
		return "active"
 | 
					 | 
				
			||||||
	case ccIdlenessStateIdle:
 | 
					 | 
				
			||||||
		return "idle"
 | 
					 | 
				
			||||||
	case ccIdlenessStateExitingIdle:
 | 
					 | 
				
			||||||
		return "exitingIdle"
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return "unknown"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or
 | 
					// WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or
 | 
				
			||||||
// ctx expires. A true value is returned in former case and false in latter.
 | 
					// ctx expires. A true value is returned in former case and false in latter.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@@ -748,29 +657,15 @@ func (cc *ClientConn) GetState() connectivity.State {
 | 
				
			|||||||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a later
 | 
					// Notice: This API is EXPERIMENTAL and may be changed or removed in a later
 | 
				
			||||||
// release.
 | 
					// release.
 | 
				
			||||||
func (cc *ClientConn) Connect() {
 | 
					func (cc *ClientConn) Connect() {
 | 
				
			||||||
	cc.exitIdleMode()
 | 
						if err := cc.idlenessMgr.ExitIdleMode(); err != nil {
 | 
				
			||||||
 | 
							cc.addTraceEvent(err.Error())
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// If the ClientConn was not in idle mode, we need to call ExitIdle on the
 | 
						// If the ClientConn was not in idle mode, we need to call ExitIdle on the
 | 
				
			||||||
	// LB policy so that connections can be created.
 | 
						// LB policy so that connections can be created.
 | 
				
			||||||
	cc.balancerWrapper.exitIdleMode()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (cc *ClientConn) scWatcher() {
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		select {
 | 
					 | 
				
			||||||
		case sc, ok := <-cc.dopts.scChan:
 | 
					 | 
				
			||||||
			if !ok {
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
	cc.mu.Lock()
 | 
						cc.mu.Lock()
 | 
				
			||||||
			// TODO: load balance policy runtime change is ignored.
 | 
						cc.balancerWrapper.exitIdle()
 | 
				
			||||||
			// We may revisit this decision in the future.
 | 
					 | 
				
			||||||
			cc.sc = &sc
 | 
					 | 
				
			||||||
			cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{&sc})
 | 
					 | 
				
			||||||
	cc.mu.Unlock()
 | 
						cc.mu.Unlock()
 | 
				
			||||||
		case <-cc.ctx.Done():
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// waitForResolvedAddrs blocks until the resolver has provided addresses or the
 | 
					// waitForResolvedAddrs blocks until the resolver has provided addresses or the
 | 
				
			||||||
@@ -804,11 +699,11 @@ func init() {
 | 
				
			|||||||
	internal.SubscribeToConnectivityStateChanges = func(cc *ClientConn, s grpcsync.Subscriber) func() {
 | 
						internal.SubscribeToConnectivityStateChanges = func(cc *ClientConn, s grpcsync.Subscriber) func() {
 | 
				
			||||||
		return cc.csMgr.pubSub.Subscribe(s)
 | 
							return cc.csMgr.pubSub.Subscribe(s)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	internal.EnterIdleModeForTesting = func(cc *ClientConn) error {
 | 
						internal.EnterIdleModeForTesting = func(cc *ClientConn) {
 | 
				
			||||||
		return cc.enterIdleMode()
 | 
							cc.idlenessMgr.EnterIdleModeForTesting()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	internal.ExitIdleModeForTesting = func(cc *ClientConn) error {
 | 
						internal.ExitIdleModeForTesting = func(cc *ClientConn) error {
 | 
				
			||||||
		return cc.exitIdleMode()
 | 
							return cc.idlenessMgr.ExitIdleMode()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -824,9 +719,8 @@ func (cc *ClientConn) maybeApplyDefaultServiceConfig(addrs []resolver.Address) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cc *ClientConn) updateResolverState(s resolver.State, err error) error {
 | 
					func (cc *ClientConn) updateResolverStateAndUnlock(s resolver.State, err error) error {
 | 
				
			||||||
	defer cc.firstResolveEvent.Fire()
 | 
						defer cc.firstResolveEvent.Fire()
 | 
				
			||||||
	cc.mu.Lock()
 | 
					 | 
				
			||||||
	// Check if the ClientConn is already closed. Some fields (e.g.
 | 
						// Check if the ClientConn is already closed. Some fields (e.g.
 | 
				
			||||||
	// balancerWrapper) are set to nil when closing the ClientConn, and could
 | 
						// balancerWrapper) are set to nil when closing the ClientConn, and could
 | 
				
			||||||
	// cause nil pointer panic if we don't have this check.
 | 
						// cause nil pointer panic if we don't have this check.
 | 
				
			||||||
@@ -872,7 +766,7 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error {
 | 
				
			|||||||
			if cc.sc == nil {
 | 
								if cc.sc == nil {
 | 
				
			||||||
				// Apply the failing LB only if we haven't received valid service config
 | 
									// Apply the failing LB only if we haven't received valid service config
 | 
				
			||||||
				// from the name resolver in the past.
 | 
									// from the name resolver in the past.
 | 
				
			||||||
				cc.applyFailingLB(s.ServiceConfig)
 | 
									cc.applyFailingLBLocked(s.ServiceConfig)
 | 
				
			||||||
				cc.mu.Unlock()
 | 
									cc.mu.Unlock()
 | 
				
			||||||
				return ret
 | 
									return ret
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -894,15 +788,13 @@ func (cc *ClientConn) updateResolverState(s resolver.State, err error) error {
 | 
				
			|||||||
	return ret
 | 
						return ret
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// applyFailingLB is akin to configuring an LB policy on the channel which
 | 
					// applyFailingLBLocked is akin to configuring an LB policy on the channel which
 | 
				
			||||||
// always fails RPCs. Here, an actual LB policy is not configured, but an always
 | 
					// always fails RPCs. Here, an actual LB policy is not configured, but an always
 | 
				
			||||||
// erroring picker is configured, which returns errors with information about
 | 
					// erroring picker is configured, which returns errors with information about
 | 
				
			||||||
// what was invalid in the received service config. A config selector with no
 | 
					// what was invalid in the received service config. A config selector with no
 | 
				
			||||||
// service config is configured, and the connectivity state of the channel is
 | 
					// service config is configured, and the connectivity state of the channel is
 | 
				
			||||||
// set to TransientFailure.
 | 
					// set to TransientFailure.
 | 
				
			||||||
//
 | 
					func (cc *ClientConn) applyFailingLBLocked(sc *serviceconfig.ParseResult) {
 | 
				
			||||||
// Caller must hold cc.mu.
 | 
					 | 
				
			||||||
func (cc *ClientConn) applyFailingLB(sc *serviceconfig.ParseResult) {
 | 
					 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	if sc.Err != nil {
 | 
						if sc.Err != nil {
 | 
				
			||||||
		err = status.Errorf(codes.Unavailable, "error parsing service config: %v", sc.Err)
 | 
							err = status.Errorf(codes.Unavailable, "error parsing service config: %v", sc.Err)
 | 
				
			||||||
@@ -910,14 +802,10 @@ func (cc *ClientConn) applyFailingLB(sc *serviceconfig.ParseResult) {
 | 
				
			|||||||
		err = status.Errorf(codes.Unavailable, "illegal service config type: %T", sc.Config)
 | 
							err = status.Errorf(codes.Unavailable, "illegal service config type: %T", sc.Config)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{nil})
 | 
						cc.safeConfigSelector.UpdateConfigSelector(&defaultConfigSelector{nil})
 | 
				
			||||||
	cc.blockingpicker.updatePicker(base.NewErrPicker(err))
 | 
						cc.pickerWrapper.updatePicker(base.NewErrPicker(err))
 | 
				
			||||||
	cc.csMgr.updateState(connectivity.TransientFailure)
 | 
						cc.csMgr.updateState(connectivity.TransientFailure)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cc *ClientConn) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State, err error) {
 | 
					 | 
				
			||||||
	cc.balancerWrapper.updateSubConnState(sc, s, err)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Makes a copy of the input addresses slice and clears out the balancer
 | 
					// Makes a copy of the input addresses slice and clears out the balancer
 | 
				
			||||||
// attributes field. Addresses are passed during subconn creation and address
 | 
					// attributes field. Addresses are passed during subconn creation and address
 | 
				
			||||||
// update operations. In both cases, we will clear the balancer attributes by
 | 
					// update operations. In both cases, we will clear the balancer attributes by
 | 
				
			||||||
@@ -932,10 +820,14 @@ func copyAddressesWithoutBalancerAttributes(in []resolver.Address) []resolver.Ad
 | 
				
			|||||||
	return out
 | 
						return out
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newAddrConn creates an addrConn for addrs and adds it to cc.conns.
 | 
					// newAddrConnLocked creates an addrConn for addrs and adds it to cc.conns.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Caller needs to make sure len(addrs) > 0.
 | 
					// Caller needs to make sure len(addrs) > 0.
 | 
				
			||||||
func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (*addrConn, error) {
 | 
					func (cc *ClientConn) newAddrConnLocked(addrs []resolver.Address, opts balancer.NewSubConnOptions) (*addrConn, error) {
 | 
				
			||||||
 | 
						if cc.conns == nil {
 | 
				
			||||||
 | 
							return nil, ErrClientConnClosing
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ac := &addrConn{
 | 
						ac := &addrConn{
 | 
				
			||||||
		state:        connectivity.Idle,
 | 
							state:        connectivity.Idle,
 | 
				
			||||||
		cc:           cc,
 | 
							cc:           cc,
 | 
				
			||||||
@@ -947,12 +839,6 @@ func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSub
 | 
				
			|||||||
		stateChan:    make(chan struct{}),
 | 
							stateChan:    make(chan struct{}),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ac.ctx, ac.cancel = context.WithCancel(cc.ctx)
 | 
						ac.ctx, ac.cancel = context.WithCancel(cc.ctx)
 | 
				
			||||||
	// Track ac in cc. This needs to be done before any getTransport(...) is called.
 | 
					 | 
				
			||||||
	cc.mu.Lock()
 | 
					 | 
				
			||||||
	defer cc.mu.Unlock()
 | 
					 | 
				
			||||||
	if cc.conns == nil {
 | 
					 | 
				
			||||||
		return nil, ErrClientConnClosing
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	ac.channelzID, err = channelz.RegisterSubChannel(ac, cc.channelzID, "")
 | 
						ac.channelzID, err = channelz.RegisterSubChannel(ac, cc.channelzID, "")
 | 
				
			||||||
@@ -968,6 +854,7 @@ func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSub
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Track ac in cc. This needs to be done before any getTransport(...) is called.
 | 
				
			||||||
	cc.conns[ac] = struct{}{}
 | 
						cc.conns[ac] = struct{}{}
 | 
				
			||||||
	return ac, nil
 | 
						return ac, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1174,7 +1061,7 @@ func (cc *ClientConn) healthCheckConfig() *healthCheckConfig {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, balancer.PickResult, error) {
 | 
					func (cc *ClientConn) getTransport(ctx context.Context, failfast bool, method string) (transport.ClientTransport, balancer.PickResult, error) {
 | 
				
			||||||
	return cc.blockingpicker.pick(ctx, failfast, balancer.PickInfo{
 | 
						return cc.pickerWrapper.pick(ctx, failfast, balancer.PickInfo{
 | 
				
			||||||
		Ctx:            ctx,
 | 
							Ctx:            ctx,
 | 
				
			||||||
		FullMethodName: method,
 | 
							FullMethodName: method,
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
@@ -1216,12 +1103,12 @@ func (cc *ClientConn) applyServiceConfigAndBalancer(sc *ServiceConfig, configSel
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (cc *ClientConn) resolveNow(o resolver.ResolveNowOptions) {
 | 
					func (cc *ClientConn) resolveNow(o resolver.ResolveNowOptions) {
 | 
				
			||||||
	cc.mu.RLock()
 | 
						cc.mu.RLock()
 | 
				
			||||||
	r := cc.resolverWrapper
 | 
						cc.resolverWrapper.resolveNow(o)
 | 
				
			||||||
	cc.mu.RUnlock()
 | 
						cc.mu.RUnlock()
 | 
				
			||||||
	if r == nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
	go r.resolveNow(o)
 | 
					
 | 
				
			||||||
 | 
					func (cc *ClientConn) resolveNowLocked(o resolver.ResolveNowOptions) {
 | 
				
			||||||
 | 
						cc.resolverWrapper.resolveNow(o)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ResetConnectBackoff wakes up all subchannels in transient failure and causes
 | 
					// ResetConnectBackoff wakes up all subchannels in transient failure and causes
 | 
				
			||||||
@@ -1253,40 +1140,32 @@ func (cc *ClientConn) Close() error {
 | 
				
			|||||||
		<-cc.csMgr.pubSub.Done()
 | 
							<-cc.csMgr.pubSub.Done()
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Prevent calls to enter/exit idle immediately, and ensure we are not
 | 
				
			||||||
 | 
						// currently entering/exiting idle mode.
 | 
				
			||||||
 | 
						cc.idlenessMgr.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cc.mu.Lock()
 | 
						cc.mu.Lock()
 | 
				
			||||||
	if cc.conns == nil {
 | 
						if cc.conns == nil {
 | 
				
			||||||
		cc.mu.Unlock()
 | 
							cc.mu.Unlock()
 | 
				
			||||||
		return ErrClientConnClosing
 | 
							return ErrClientConnClosing
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for cc.idlenessState == ccIdlenessStateExitingIdle {
 | 
					 | 
				
			||||||
		cc.exitIdleCond.Wait()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	conns := cc.conns
 | 
						conns := cc.conns
 | 
				
			||||||
	cc.conns = nil
 | 
						cc.conns = nil
 | 
				
			||||||
	cc.csMgr.updateState(connectivity.Shutdown)
 | 
						cc.csMgr.updateState(connectivity.Shutdown)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pWrapper := cc.blockingpicker
 | 
						// We can safely unlock and continue to access all fields now as
 | 
				
			||||||
	rWrapper := cc.resolverWrapper
 | 
						// cc.conns==nil, preventing any further operations on cc.
 | 
				
			||||||
	bWrapper := cc.balancerWrapper
 | 
					 | 
				
			||||||
	idlenessMgr := cc.idlenessMgr
 | 
					 | 
				
			||||||
	cc.mu.Unlock()
 | 
						cc.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cc.resolverWrapper.close()
 | 
				
			||||||
	// The order of closing matters here since the balancer wrapper assumes the
 | 
						// The order of closing matters here since the balancer wrapper assumes the
 | 
				
			||||||
	// picker is closed before it is closed.
 | 
						// picker is closed before it is closed.
 | 
				
			||||||
	if pWrapper != nil {
 | 
						cc.pickerWrapper.close()
 | 
				
			||||||
		pWrapper.close()
 | 
						cc.balancerWrapper.close()
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
	if bWrapper != nil {
 | 
						<-cc.resolverWrapper.serializer.Done()
 | 
				
			||||||
		bWrapper.close()
 | 
						<-cc.balancerWrapper.serializer.Done()
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if rWrapper != nil {
 | 
					 | 
				
			||||||
		rWrapper.close()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if idlenessMgr != nil {
 | 
					 | 
				
			||||||
		idlenessMgr.Close()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for ac := range conns {
 | 
						for ac := range conns {
 | 
				
			||||||
		ac.tearDown(ErrClientConnClosing)
 | 
							ac.tearDown(ErrClientConnClosing)
 | 
				
			||||||
@@ -1307,7 +1186,7 @@ type addrConn struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	cc     *ClientConn
 | 
						cc     *ClientConn
 | 
				
			||||||
	dopts  dialOptions
 | 
						dopts  dialOptions
 | 
				
			||||||
	acbw   balancer.SubConn
 | 
						acbw   *acBalancerWrapper
 | 
				
			||||||
	scopts balancer.NewSubConnOptions
 | 
						scopts balancer.NewSubConnOptions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// transport is set when there's a viable transport (note: ac state may not be READY as LB channel
 | 
						// transport is set when there's a viable transport (note: ac state may not be READY as LB channel
 | 
				
			||||||
@@ -1345,7 +1224,7 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error)
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v, last error: %s", s, lastErr)
 | 
							channelz.Infof(logger, ac.channelzID, "Subchannel Connectivity change to %v, last error: %s", s, lastErr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ac.cc.handleSubConnStateChange(ac.acbw, s, lastErr)
 | 
						ac.acbw.updateState(s, lastErr)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// adjustParams updates parameters used to create transports upon
 | 
					// adjustParams updates parameters used to create transports upon
 | 
				
			||||||
@@ -1849,7 +1728,7 @@ func (cc *ClientConn) parseTargetAndFindResolver() error {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", cc.target, err)
 | 
							channelz.Infof(logger, cc.channelzID, "dial target %q parse failed: %v", cc.target, err)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		channelz.Infof(logger, cc.channelzID, "parsed dial target is: %+v", parsedTarget)
 | 
							channelz.Infof(logger, cc.channelzID, "parsed dial target is: %#v", parsedTarget)
 | 
				
			||||||
		rb = cc.getResolver(parsedTarget.URL.Scheme)
 | 
							rb = cc.getResolver(parsedTarget.URL.Scheme)
 | 
				
			||||||
		if rb != nil {
 | 
							if rb != nil {
 | 
				
			||||||
			cc.parsedTarget = parsedTarget
 | 
								cc.parsedTarget = parsedTarget
 | 
				
			||||||
@@ -2007,32 +1886,3 @@ func (cc *ClientConn) determineAuthority() error {
 | 
				
			|||||||
	channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority)
 | 
						channelz.Infof(logger, cc.channelzID, "Channel authority set to %q", cc.authority)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// initResolverWrapper creates a ccResolverWrapper, which builds the name
 | 
					 | 
				
			||||||
// resolver. This method grabs the lock to assign the newly built resolver
 | 
					 | 
				
			||||||
// wrapper to the cc.resolverWrapper field.
 | 
					 | 
				
			||||||
func (cc *ClientConn) initResolverWrapper(creds credentials.TransportCredentials) error {
 | 
					 | 
				
			||||||
	rw, err := newCCResolverWrapper(cc, ccResolverWrapperOpts{
 | 
					 | 
				
			||||||
		target:  cc.parsedTarget,
 | 
					 | 
				
			||||||
		builder: cc.resolverBuilder,
 | 
					 | 
				
			||||||
		bOpts: resolver.BuildOptions{
 | 
					 | 
				
			||||||
			DisableServiceConfig: cc.dopts.disableServiceConfig,
 | 
					 | 
				
			||||||
			DialCreds:            creds,
 | 
					 | 
				
			||||||
			CredsBundle:          cc.dopts.copts.CredsBundle,
 | 
					 | 
				
			||||||
			Dialer:               cc.dopts.copts.Dialer,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		channelzID: cc.channelzID,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("failed to build resolver: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Resolver implementations may report state update or error inline when
 | 
					 | 
				
			||||||
	// built (or right after), and this is handled in cc.updateResolverState.
 | 
					 | 
				
			||||||
	// Also, an error from the resolver might lead to a re-resolution request
 | 
					 | 
				
			||||||
	// from the balancer, which is handled in resolveNow() where
 | 
					 | 
				
			||||||
	// `cc.resolverWrapper` is accessed. Hence, we need to hold the lock here.
 | 
					 | 
				
			||||||
	cc.mu.Lock()
 | 
					 | 
				
			||||||
	cc.resolverWrapper = rw
 | 
					 | 
				
			||||||
	cc.mu.Unlock()
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								vendor/google.golang.org/grpc/codes/codes.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/google.golang.org/grpc/codes/codes.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -25,7 +25,13 @@ import (
 | 
				
			|||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A Code is an unsigned 32-bit error code as defined in the gRPC spec.
 | 
					// A Code is a status code defined according to the [gRPC documentation].
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Only the codes defined as consts in this package are valid codes. Do not use
 | 
				
			||||||
 | 
					// other code values.  Behavior of other codes is implementation-specific and
 | 
				
			||||||
 | 
					// interoperability between implementations is not guaranteed.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// [gRPC documentation]: https://github.com/grpc/grpc/blob/master/doc/statuscodes.md
 | 
				
			||||||
type Code uint32
 | 
					type Code uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										75
									
								
								vendor/google.golang.org/grpc/credentials/tls.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								vendor/google.golang.org/grpc/credentials/tls.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -44,10 +44,25 @@ func (t TLSInfo) AuthType() string {
 | 
				
			|||||||
	return "tls"
 | 
						return "tls"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// cipherSuiteLookup returns the string version of a TLS cipher suite ID.
 | 
				
			||||||
 | 
					func cipherSuiteLookup(cipherSuiteID uint16) string {
 | 
				
			||||||
 | 
						for _, s := range tls.CipherSuites() {
 | 
				
			||||||
 | 
							if s.ID == cipherSuiteID {
 | 
				
			||||||
 | 
								return s.Name
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, s := range tls.InsecureCipherSuites() {
 | 
				
			||||||
 | 
							if s.ID == cipherSuiteID {
 | 
				
			||||||
 | 
								return s.Name
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return fmt.Sprintf("unknown ID: %v", cipherSuiteID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetSecurityValue returns security info requested by channelz.
 | 
					// GetSecurityValue returns security info requested by channelz.
 | 
				
			||||||
func (t TLSInfo) GetSecurityValue() ChannelzSecurityValue {
 | 
					func (t TLSInfo) GetSecurityValue() ChannelzSecurityValue {
 | 
				
			||||||
	v := &TLSChannelzSecurityValue{
 | 
						v := &TLSChannelzSecurityValue{
 | 
				
			||||||
		StandardName: cipherSuiteLookup[t.State.CipherSuite],
 | 
							StandardName: cipherSuiteLookup(t.State.CipherSuite),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Currently there's no way to get LocalCertificate info from tls package.
 | 
						// Currently there's no way to get LocalCertificate info from tls package.
 | 
				
			||||||
	if len(t.State.PeerCertificates) > 0 {
 | 
						if len(t.State.PeerCertificates) > 0 {
 | 
				
			||||||
@@ -138,10 +153,39 @@ func (c *tlsCreds) OverrideServerName(serverNameOverride string) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The following cipher suites are forbidden for use with HTTP/2 by
 | 
				
			||||||
 | 
					// https://datatracker.ietf.org/doc/html/rfc7540#appendix-A
 | 
				
			||||||
 | 
					var tls12ForbiddenCipherSuites = map[uint16]struct{}{
 | 
				
			||||||
 | 
						tls.TLS_RSA_WITH_AES_128_CBC_SHA:         {},
 | 
				
			||||||
 | 
						tls.TLS_RSA_WITH_AES_256_CBC_SHA:         {},
 | 
				
			||||||
 | 
						tls.TLS_RSA_WITH_AES_128_GCM_SHA256:      {},
 | 
				
			||||||
 | 
						tls.TLS_RSA_WITH_AES_256_GCM_SHA384:      {},
 | 
				
			||||||
 | 
						tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: {},
 | 
				
			||||||
 | 
						tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: {},
 | 
				
			||||||
 | 
						tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:   {},
 | 
				
			||||||
 | 
						tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:   {},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewTLS uses c to construct a TransportCredentials based on TLS.
 | 
					// NewTLS uses c to construct a TransportCredentials based on TLS.
 | 
				
			||||||
func NewTLS(c *tls.Config) TransportCredentials {
 | 
					func NewTLS(c *tls.Config) TransportCredentials {
 | 
				
			||||||
	tc := &tlsCreds{credinternal.CloneTLSConfig(c)}
 | 
						tc := &tlsCreds{credinternal.CloneTLSConfig(c)}
 | 
				
			||||||
	tc.config.NextProtos = credinternal.AppendH2ToNextProtos(tc.config.NextProtos)
 | 
						tc.config.NextProtos = credinternal.AppendH2ToNextProtos(tc.config.NextProtos)
 | 
				
			||||||
 | 
						// If the user did not configure a MinVersion and did not configure a
 | 
				
			||||||
 | 
						// MaxVersion < 1.2, use MinVersion=1.2, which is required by
 | 
				
			||||||
 | 
						// https://datatracker.ietf.org/doc/html/rfc7540#section-9.2
 | 
				
			||||||
 | 
						if tc.config.MinVersion == 0 && (tc.config.MaxVersion == 0 || tc.config.MaxVersion >= tls.VersionTLS12) {
 | 
				
			||||||
 | 
							tc.config.MinVersion = tls.VersionTLS12
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// If the user did not configure CipherSuites, use all "secure" cipher
 | 
				
			||||||
 | 
						// suites reported by the TLS package, but remove some explicitly forbidden
 | 
				
			||||||
 | 
						// by https://datatracker.ietf.org/doc/html/rfc7540#appendix-A
 | 
				
			||||||
 | 
						if tc.config.CipherSuites == nil {
 | 
				
			||||||
 | 
							for _, cs := range tls.CipherSuites() {
 | 
				
			||||||
 | 
								if _, ok := tls12ForbiddenCipherSuites[cs.ID]; !ok {
 | 
				
			||||||
 | 
									tc.config.CipherSuites = append(tc.config.CipherSuites, cs.ID)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return tc
 | 
						return tc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -205,32 +249,3 @@ type TLSChannelzSecurityValue struct {
 | 
				
			|||||||
	LocalCertificate  []byte
 | 
						LocalCertificate  []byte
 | 
				
			||||||
	RemoteCertificate []byte
 | 
						RemoteCertificate []byte
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
var cipherSuiteLookup = map[uint16]string{
 | 
					 | 
				
			||||||
	tls.TLS_RSA_WITH_RC4_128_SHA:                "TLS_RSA_WITH_RC4_128_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA:           "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_RSA_WITH_AES_128_CBC_SHA:            "TLS_RSA_WITH_AES_128_CBC_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_RSA_WITH_AES_256_CBC_SHA:            "TLS_RSA_WITH_AES_256_CBC_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_RSA_WITH_AES_128_GCM_SHA256:         "TLS_RSA_WITH_AES_128_GCM_SHA256",
 | 
					 | 
				
			||||||
	tls.TLS_RSA_WITH_AES_256_GCM_SHA384:         "TLS_RSA_WITH_AES_256_GCM_SHA384",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:        "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:    "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:    "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA:          "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:     "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:   "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:   "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
 | 
					 | 
				
			||||||
	tls.TLS_FALLBACK_SCSV:                       "TLS_FALLBACK_SCSV",
 | 
					 | 
				
			||||||
	tls.TLS_RSA_WITH_AES_128_CBC_SHA256:         "TLS_RSA_WITH_AES_128_CBC_SHA256",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:   "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:    "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
 | 
					 | 
				
			||||||
	tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:  "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
 | 
					 | 
				
			||||||
	tls.TLS_AES_128_GCM_SHA256:                  "TLS_AES_128_GCM_SHA256",
 | 
					 | 
				
			||||||
	tls.TLS_AES_256_GCM_SHA384:                  "TLS_AES_256_GCM_SHA384",
 | 
					 | 
				
			||||||
	tls.TLS_CHACHA20_POLY1305_SHA256:            "TLS_CHACHA20_POLY1305_SHA256",
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										46
									
								
								vendor/google.golang.org/grpc/dialoptions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/google.golang.org/grpc/dialoptions.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -46,6 +46,7 @@ func init() {
 | 
				
			|||||||
	internal.WithBinaryLogger = withBinaryLogger
 | 
						internal.WithBinaryLogger = withBinaryLogger
 | 
				
			||||||
	internal.JoinDialOptions = newJoinDialOption
 | 
						internal.JoinDialOptions = newJoinDialOption
 | 
				
			||||||
	internal.DisableGlobalDialOptions = newDisableGlobalDialOptions
 | 
						internal.DisableGlobalDialOptions = newDisableGlobalDialOptions
 | 
				
			||||||
 | 
						internal.WithRecvBufferPool = withRecvBufferPool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// dialOptions configure a Dial call. dialOptions are set by the DialOption
 | 
					// dialOptions configure a Dial call. dialOptions are set by the DialOption
 | 
				
			||||||
@@ -63,7 +64,6 @@ type dialOptions struct {
 | 
				
			|||||||
	block                       bool
 | 
						block                       bool
 | 
				
			||||||
	returnLastError             bool
 | 
						returnLastError             bool
 | 
				
			||||||
	timeout                     time.Duration
 | 
						timeout                     time.Duration
 | 
				
			||||||
	scChan                      <-chan ServiceConfig
 | 
					 | 
				
			||||||
	authority                   string
 | 
						authority                   string
 | 
				
			||||||
	binaryLogger                binarylog.Logger
 | 
						binaryLogger                binarylog.Logger
 | 
				
			||||||
	copts                       transport.ConnectOptions
 | 
						copts                       transport.ConnectOptions
 | 
				
			||||||
@@ -250,19 +250,6 @@ func WithDecompressor(dc Decompressor) DialOption {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// WithServiceConfig returns a DialOption which has a channel to read the
 | 
					 | 
				
			||||||
// service configuration.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Deprecated: service config should be received through name resolver or via
 | 
					 | 
				
			||||||
// WithDefaultServiceConfig, as specified at
 | 
					 | 
				
			||||||
// https://github.com/grpc/grpc/blob/master/doc/service_config.md.  Will be
 | 
					 | 
				
			||||||
// removed in a future 1.x release.
 | 
					 | 
				
			||||||
func WithServiceConfig(c <-chan ServiceConfig) DialOption {
 | 
					 | 
				
			||||||
	return newFuncDialOption(func(o *dialOptions) {
 | 
					 | 
				
			||||||
		o.scChan = c
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// WithConnectParams configures the ClientConn to use the provided ConnectParams
 | 
					// WithConnectParams configures the ClientConn to use the provided ConnectParams
 | 
				
			||||||
// for creating and maintaining connections to servers.
 | 
					// for creating and maintaining connections to servers.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@@ -413,6 +400,17 @@ func WithTimeout(d time.Duration) DialOption {
 | 
				
			|||||||
// connections. If FailOnNonTempDialError() is set to true, and an error is
 | 
					// connections. If FailOnNonTempDialError() is set to true, and an error is
 | 
				
			||||||
// returned by f, gRPC checks the error's Temporary() method to decide if it
 | 
					// returned by f, gRPC checks the error's Temporary() method to decide if it
 | 
				
			||||||
// should try to reconnect to the network address.
 | 
					// should try to reconnect to the network address.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Note: All supported releases of Go (as of December 2023) override the OS
 | 
				
			||||||
 | 
					// defaults for TCP keepalive time and interval to 15s. To enable TCP keepalive
 | 
				
			||||||
 | 
					// with OS defaults for keepalive time and interval, use a net.Dialer that sets
 | 
				
			||||||
 | 
					// the KeepAlive field to a negative value, and sets the SO_KEEPALIVE socket
 | 
				
			||||||
 | 
					// option to true from the Control field. For a concrete example of how to do
 | 
				
			||||||
 | 
					// this, see internal.NetDialerWithTCPKeepalive().
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// For more information, please see [issue 23459] in the Go github repo.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// [issue 23459]: https://github.com/golang/go/issues/23459
 | 
				
			||||||
func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption {
 | 
					func WithContextDialer(f func(context.Context, string) (net.Conn, error)) DialOption {
 | 
				
			||||||
	return newFuncDialOption(func(o *dialOptions) {
 | 
						return newFuncDialOption(func(o *dialOptions) {
 | 
				
			||||||
		o.copts.Dialer = f
 | 
							o.copts.Dialer = f
 | 
				
			||||||
@@ -487,7 +485,7 @@ func FailOnNonTempDialError(f bool) DialOption {
 | 
				
			|||||||
// the RPCs.
 | 
					// the RPCs.
 | 
				
			||||||
func WithUserAgent(s string) DialOption {
 | 
					func WithUserAgent(s string) DialOption {
 | 
				
			||||||
	return newFuncDialOption(func(o *dialOptions) {
 | 
						return newFuncDialOption(func(o *dialOptions) {
 | 
				
			||||||
		o.copts.UserAgent = s
 | 
							o.copts.UserAgent = s + " " + grpcUA
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -637,14 +635,16 @@ func withHealthCheckFunc(f internal.HealthChecker) DialOption {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func defaultDialOptions() dialOptions {
 | 
					func defaultDialOptions() dialOptions {
 | 
				
			||||||
	return dialOptions{
 | 
						return dialOptions{
 | 
				
			||||||
		healthCheckFunc: internal.HealthCheckFunc,
 | 
					 | 
				
			||||||
		copts: transport.ConnectOptions{
 | 
							copts: transport.ConnectOptions{
 | 
				
			||||||
			WriteBufferSize: defaultWriteBufSize,
 | 
					 | 
				
			||||||
			ReadBufferSize:  defaultReadBufSize,
 | 
								ReadBufferSize:  defaultReadBufSize,
 | 
				
			||||||
 | 
								WriteBufferSize: defaultWriteBufSize,
 | 
				
			||||||
			UseProxy:        true,
 | 
								UseProxy:        true,
 | 
				
			||||||
 | 
								UserAgent:       grpcUA,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		recvBufferPool: nopBufferPool{},
 | 
							bs:              internalbackoff.DefaultExponential,
 | 
				
			||||||
 | 
							healthCheckFunc: internal.HealthCheckFunc,
 | 
				
			||||||
		idleTimeout:     30 * time.Minute,
 | 
							idleTimeout:     30 * time.Minute,
 | 
				
			||||||
 | 
							recvBufferPool:  nopBufferPool{},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -705,11 +705,13 @@ func WithIdleTimeout(d time.Duration) DialOption {
 | 
				
			|||||||
// options are used: WithStatsHandler, EnableTracing, or binary logging. In such
 | 
					// options are used: WithStatsHandler, EnableTracing, or binary logging. In such
 | 
				
			||||||
// cases, the shared buffer pool will be ignored.
 | 
					// cases, the shared buffer pool will be ignored.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// # Experimental
 | 
					// Deprecated: use experimental.WithRecvBufferPool instead.  Will be deleted in
 | 
				
			||||||
//
 | 
					// v1.60.0 or later.
 | 
				
			||||||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
 | 
					 | 
				
			||||||
// later release.
 | 
					 | 
				
			||||||
func WithRecvBufferPool(bufferPool SharedBufferPool) DialOption {
 | 
					func WithRecvBufferPool(bufferPool SharedBufferPool) DialOption {
 | 
				
			||||||
 | 
						return withRecvBufferPool(bufferPool)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func withRecvBufferPool(bufferPool SharedBufferPool) DialOption {
 | 
				
			||||||
	return newFuncDialOption(func(o *dialOptions) {
 | 
						return newFuncDialOption(func(o *dialOptions) {
 | 
				
			||||||
		o.recvBufferPool = bufferPool
 | 
							o.recvBufferPool = bufferPool
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										37
									
								
								vendor/google.golang.org/grpc/internal/buffer/unbounded.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/google.golang.org/grpc/internal/buffer/unbounded.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -18,7 +18,10 @@
 | 
				
			|||||||
// Package buffer provides an implementation of an unbounded buffer.
 | 
					// Package buffer provides an implementation of an unbounded buffer.
 | 
				
			||||||
package buffer
 | 
					package buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "sync"
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Unbounded is an implementation of an unbounded buffer which does not use
 | 
					// Unbounded is an implementation of an unbounded buffer which does not use
 | 
				
			||||||
// extra goroutines. This is typically used for passing updates from one entity
 | 
					// extra goroutines. This is typically used for passing updates from one entity
 | 
				
			||||||
@@ -36,6 +39,7 @@ import "sync"
 | 
				
			|||||||
type Unbounded struct {
 | 
					type Unbounded struct {
 | 
				
			||||||
	c       chan any
 | 
						c       chan any
 | 
				
			||||||
	closed  bool
 | 
						closed  bool
 | 
				
			||||||
 | 
						closing bool
 | 
				
			||||||
	mu      sync.Mutex
 | 
						mu      sync.Mutex
 | 
				
			||||||
	backlog []any
 | 
						backlog []any
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -45,32 +49,32 @@ func NewUnbounded() *Unbounded {
 | 
				
			|||||||
	return &Unbounded{c: make(chan any, 1)}
 | 
						return &Unbounded{c: make(chan any, 1)}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var errBufferClosed = errors.New("Put called on closed buffer.Unbounded")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Put adds t to the unbounded buffer.
 | 
					// Put adds t to the unbounded buffer.
 | 
				
			||||||
func (b *Unbounded) Put(t any) {
 | 
					func (b *Unbounded) Put(t any) error {
 | 
				
			||||||
	b.mu.Lock()
 | 
						b.mu.Lock()
 | 
				
			||||||
	defer b.mu.Unlock()
 | 
						defer b.mu.Unlock()
 | 
				
			||||||
	if b.closed {
 | 
						if b.closing {
 | 
				
			||||||
		return
 | 
							return errBufferClosed
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(b.backlog) == 0 {
 | 
						if len(b.backlog) == 0 {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case b.c <- t:
 | 
							case b.c <- t:
 | 
				
			||||||
			return
 | 
								return nil
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	b.backlog = append(b.backlog, t)
 | 
						b.backlog = append(b.backlog, t)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Load sends the earliest buffered data, if any, onto the read channel
 | 
					// Load sends the earliest buffered data, if any, onto the read channel returned
 | 
				
			||||||
// returned by Get(). Users are expected to call this every time they read a
 | 
					// by Get(). Users are expected to call this every time they successfully read a
 | 
				
			||||||
// value from the read channel.
 | 
					// value from the read channel.
 | 
				
			||||||
func (b *Unbounded) Load() {
 | 
					func (b *Unbounded) Load() {
 | 
				
			||||||
	b.mu.Lock()
 | 
						b.mu.Lock()
 | 
				
			||||||
	defer b.mu.Unlock()
 | 
						defer b.mu.Unlock()
 | 
				
			||||||
	if b.closed {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(b.backlog) > 0 {
 | 
						if len(b.backlog) > 0 {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case b.c <- b.backlog[0]:
 | 
							case b.c <- b.backlog[0]:
 | 
				
			||||||
@@ -78,6 +82,8 @@ func (b *Unbounded) Load() {
 | 
				
			|||||||
			b.backlog = b.backlog[1:]
 | 
								b.backlog = b.backlog[1:]
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						} else if b.closing && !b.closed {
 | 
				
			||||||
 | 
							close(b.c)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -88,18 +94,23 @@ func (b *Unbounded) Load() {
 | 
				
			|||||||
// send the next buffered value onto the channel if there is any.
 | 
					// send the next buffered value onto the channel if there is any.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// If the unbounded buffer is closed, the read channel returned by this method
 | 
					// If the unbounded buffer is closed, the read channel returned by this method
 | 
				
			||||||
// is closed.
 | 
					// is closed after all data is drained.
 | 
				
			||||||
func (b *Unbounded) Get() <-chan any {
 | 
					func (b *Unbounded) Get() <-chan any {
 | 
				
			||||||
	return b.c
 | 
						return b.c
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Close closes the unbounded buffer.
 | 
					// Close closes the unbounded buffer. No subsequent data may be Put(), and the
 | 
				
			||||||
 | 
					// channel returned from Get() will be closed after all the data is read and
 | 
				
			||||||
 | 
					// Load() is called for the final time.
 | 
				
			||||||
func (b *Unbounded) Close() {
 | 
					func (b *Unbounded) Close() {
 | 
				
			||||||
	b.mu.Lock()
 | 
						b.mu.Lock()
 | 
				
			||||||
	defer b.mu.Unlock()
 | 
						defer b.mu.Unlock()
 | 
				
			||||||
	if b.closed {
 | 
						if b.closing {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						b.closing = true
 | 
				
			||||||
 | 
						if len(b.backlog) == 0 {
 | 
				
			||||||
		b.closed = true
 | 
							b.closed = true
 | 
				
			||||||
		close(b.c)
 | 
							close(b.c)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								vendor/google.golang.org/grpc/internal/channelz/funcs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/google.golang.org/grpc/internal/channelz/funcs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -31,6 +31,7 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"google.golang.org/grpc/grpclog"
 | 
						"google.golang.org/grpc/grpclog"
 | 
				
			||||||
 | 
						"google.golang.org/grpc/internal"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -58,6 +59,12 @@ func TurnOn() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						internal.ChannelzTurnOffForTesting = func() {
 | 
				
			||||||
 | 
							atomic.StoreInt32(&curState, 0)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsOn returns whether channelz data collection is on.
 | 
					// IsOn returns whether channelz data collection is on.
 | 
				
			||||||
func IsOn() bool {
 | 
					func IsOn() bool {
 | 
				
			||||||
	return atomic.LoadInt32(&curState) == 1
 | 
						return atomic.LoadInt32(&curState) == 1
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/google.golang.org/grpc/internal/envconfig/envconfig.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -36,9 +36,6 @@ var (
 | 
				
			|||||||
	// "GRPC_RING_HASH_CAP".  This does not override the default bounds
 | 
						// "GRPC_RING_HASH_CAP".  This does not override the default bounds
 | 
				
			||||||
	// checking which NACKs configs specifying ring sizes > 8*1024*1024 (~8M).
 | 
						// checking which NACKs configs specifying ring sizes > 8*1024*1024 (~8M).
 | 
				
			||||||
	RingHashCap = uint64FromEnv("GRPC_RING_HASH_CAP", 4096, 1, 8*1024*1024)
 | 
						RingHashCap = uint64FromEnv("GRPC_RING_HASH_CAP", 4096, 1, 8*1024*1024)
 | 
				
			||||||
	// PickFirstLBConfig is set if we should support configuration of the
 | 
					 | 
				
			||||||
	// pick_first LB policy.
 | 
					 | 
				
			||||||
	PickFirstLBConfig = boolFromEnv("GRPC_EXPERIMENTAL_PICKFIRST_LB_CONFIG", true)
 | 
					 | 
				
			||||||
	// LeastRequestLB is set if we should support the least_request_experimental
 | 
						// LeastRequestLB is set if we should support the least_request_experimental
 | 
				
			||||||
	// LB policy, which can be enabled by setting the environment variable
 | 
						// LB policy, which can be enabled by setting the environment variable
 | 
				
			||||||
	// "GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST" to "true".
 | 
						// "GRPC_EXPERIMENTAL_ENABLE_LEAST_REQUEST" to "true".
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										39
									
								
								vendor/google.golang.org/grpc/internal/envconfig/xds.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								vendor/google.golang.org/grpc/internal/envconfig/xds.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -50,46 +50,7 @@ var (
 | 
				
			|||||||
	//
 | 
						//
 | 
				
			||||||
	// When both bootstrap FileName and FileContent are set, FileName is used.
 | 
						// When both bootstrap FileName and FileContent are set, FileName is used.
 | 
				
			||||||
	XDSBootstrapFileContent = os.Getenv(XDSBootstrapFileContentEnv)
 | 
						XDSBootstrapFileContent = os.Getenv(XDSBootstrapFileContentEnv)
 | 
				
			||||||
	// XDSRingHash indicates whether ring hash support is enabled, which can be
 | 
					 | 
				
			||||||
	// disabled by setting the environment variable
 | 
					 | 
				
			||||||
	// "GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH" to "false".
 | 
					 | 
				
			||||||
	XDSRingHash = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH", true)
 | 
					 | 
				
			||||||
	// XDSClientSideSecurity is used to control processing of security
 | 
					 | 
				
			||||||
	// configuration on the client-side.
 | 
					 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	// Note that there is no env var protection for the server-side because we
 | 
					 | 
				
			||||||
	// have a brand new API on the server-side and users explicitly need to use
 | 
					 | 
				
			||||||
	// the new API to get security integration on the server.
 | 
					 | 
				
			||||||
	XDSClientSideSecurity = boolFromEnv("GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT", true)
 | 
					 | 
				
			||||||
	// XDSAggregateAndDNS indicates whether processing of aggregated cluster and
 | 
					 | 
				
			||||||
	// DNS cluster is enabled, which can be disabled by setting the environment
 | 
					 | 
				
			||||||
	// variable "GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER"
 | 
					 | 
				
			||||||
	// to "false".
 | 
					 | 
				
			||||||
	XDSAggregateAndDNS = boolFromEnv("GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER", true)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// XDSRBAC indicates whether xDS configured RBAC HTTP Filter is enabled,
 | 
					 | 
				
			||||||
	// which can be disabled by setting the environment variable
 | 
					 | 
				
			||||||
	// "GRPC_XDS_EXPERIMENTAL_RBAC" to "false".
 | 
					 | 
				
			||||||
	XDSRBAC = boolFromEnv("GRPC_XDS_EXPERIMENTAL_RBAC", true)
 | 
					 | 
				
			||||||
	// XDSOutlierDetection indicates whether outlier detection support is
 | 
					 | 
				
			||||||
	// enabled, which can be disabled by setting the environment variable
 | 
					 | 
				
			||||||
	// "GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION" to "false".
 | 
					 | 
				
			||||||
	XDSOutlierDetection = boolFromEnv("GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION", true)
 | 
					 | 
				
			||||||
	// XDSFederation indicates whether federation support is enabled, which can
 | 
					 | 
				
			||||||
	// be enabled by setting the environment variable
 | 
					 | 
				
			||||||
	// "GRPC_EXPERIMENTAL_XDS_FEDERATION" to "true".
 | 
					 | 
				
			||||||
	XDSFederation = boolFromEnv("GRPC_EXPERIMENTAL_XDS_FEDERATION", true)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// XDSRLS indicates whether processing of Cluster Specifier plugins and
 | 
					 | 
				
			||||||
	// support for the RLS CLuster Specifier is enabled, which can be disabled by
 | 
					 | 
				
			||||||
	// setting the environment variable "GRPC_EXPERIMENTAL_XDS_RLS_LB" to
 | 
					 | 
				
			||||||
	// "false".
 | 
					 | 
				
			||||||
	XDSRLS = boolFromEnv("GRPC_EXPERIMENTAL_XDS_RLS_LB", true)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// C2PResolverTestOnlyTrafficDirectorURI is the TD URI for testing.
 | 
						// C2PResolverTestOnlyTrafficDirectorURI is the TD URI for testing.
 | 
				
			||||||
	C2PResolverTestOnlyTrafficDirectorURI = os.Getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI")
 | 
						C2PResolverTestOnlyTrafficDirectorURI = os.Getenv("GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI")
 | 
				
			||||||
	// XDSCustomLBPolicy indicates whether Custom LB Policies are enabled, which
 | 
					 | 
				
			||||||
	// can be disabled by setting the environment variable
 | 
					 | 
				
			||||||
	// "GRPC_EXPERIMENTAL_XDS_CUSTOM_LB_CONFIG" to "false".
 | 
					 | 
				
			||||||
	XDSCustomLBPolicy = boolFromEnv("GRPC_EXPERIMENTAL_XDS_CUSTOM_LB_CONFIG", true)
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								vendor/google.golang.org/grpc/internal/experimental.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/google.golang.org/grpc/internal/experimental.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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 internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						// WithRecvBufferPool is implemented by the grpc package and returns a dial
 | 
				
			||||||
 | 
						// option to configure a shared buffer pool for a grpc.ClientConn.
 | 
				
			||||||
 | 
						WithRecvBufferPool any // func (grpc.SharedBufferPool) grpc.DialOption
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// RecvBufferPool is implemented by the grpc package and returns a server
 | 
				
			||||||
 | 
						// option to configure a shared buffer pool for a grpc.Server.
 | 
				
			||||||
 | 
						RecvBufferPool any // func (grpc.SharedBufferPool) grpc.ServerOption
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										49
									
								
								vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										49
									
								
								vendor/google.golang.org/grpc/internal/grpcsync/callback_serializer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -20,7 +20,6 @@ package grpcsync
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"google.golang.org/grpc/internal/buffer"
 | 
						"google.golang.org/grpc/internal/buffer"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -38,8 +37,6 @@ type CallbackSerializer struct {
 | 
				
			|||||||
	done chan struct{}
 | 
						done chan struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	callbacks *buffer.Unbounded
 | 
						callbacks *buffer.Unbounded
 | 
				
			||||||
	closedMu  sync.Mutex
 | 
					 | 
				
			||||||
	closed    bool
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewCallbackSerializer returns a new CallbackSerializer instance. The provided
 | 
					// NewCallbackSerializer returns a new CallbackSerializer instance. The provided
 | 
				
			||||||
@@ -65,56 +62,34 @@ func NewCallbackSerializer(ctx context.Context) *CallbackSerializer {
 | 
				
			|||||||
// callbacks to be executed by the serializer. It is not possible to add
 | 
					// callbacks to be executed by the serializer. It is not possible to add
 | 
				
			||||||
// callbacks once the context passed to NewCallbackSerializer is cancelled.
 | 
					// callbacks once the context passed to NewCallbackSerializer is cancelled.
 | 
				
			||||||
func (cs *CallbackSerializer) Schedule(f func(ctx context.Context)) bool {
 | 
					func (cs *CallbackSerializer) Schedule(f func(ctx context.Context)) bool {
 | 
				
			||||||
	cs.closedMu.Lock()
 | 
						return cs.callbacks.Put(f) == nil
 | 
				
			||||||
	defer cs.closedMu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if cs.closed {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cs.callbacks.Put(f)
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cs *CallbackSerializer) run(ctx context.Context) {
 | 
					func (cs *CallbackSerializer) run(ctx context.Context) {
 | 
				
			||||||
	var backlog []func(context.Context)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer close(cs.done)
 | 
						defer close(cs.done)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: when Go 1.21 is the oldest supported version, this loop and Close
 | 
				
			||||||
 | 
						// can be replaced with:
 | 
				
			||||||
 | 
						//
 | 
				
			||||||
 | 
						// context.AfterFunc(ctx, cs.callbacks.Close)
 | 
				
			||||||
	for ctx.Err() == nil {
 | 
						for ctx.Err() == nil {
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case <-ctx.Done():
 | 
							case <-ctx.Done():
 | 
				
			||||||
			// Do nothing here. Next iteration of the for loop will not happen,
 | 
								// Do nothing here. Next iteration of the for loop will not happen,
 | 
				
			||||||
			// since ctx.Err() would be non-nil.
 | 
								// since ctx.Err() would be non-nil.
 | 
				
			||||||
		case callback, ok := <-cs.callbacks.Get():
 | 
							case cb := <-cs.callbacks.Get():
 | 
				
			||||||
			if !ok {
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			cs.callbacks.Load()
 | 
								cs.callbacks.Load()
 | 
				
			||||||
			callback.(func(ctx context.Context))(ctx)
 | 
								cb.(func(context.Context))(ctx)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Fetch pending callbacks if any, and execute them before returning from
 | 
						// Close the buffer to prevent new callbacks from being added.
 | 
				
			||||||
	// this method and closing cs.done.
 | 
					 | 
				
			||||||
	cs.closedMu.Lock()
 | 
					 | 
				
			||||||
	cs.closed = true
 | 
					 | 
				
			||||||
	backlog = cs.fetchPendingCallbacks()
 | 
					 | 
				
			||||||
	cs.callbacks.Close()
 | 
						cs.callbacks.Close()
 | 
				
			||||||
	cs.closedMu.Unlock()
 | 
					 | 
				
			||||||
	for _, b := range backlog {
 | 
					 | 
				
			||||||
		b(ctx)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (cs *CallbackSerializer) fetchPendingCallbacks() []func(context.Context) {
 | 
						// Run all pending callbacks.
 | 
				
			||||||
	var backlog []func(context.Context)
 | 
						for cb := range cs.callbacks.Get() {
 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		select {
 | 
					 | 
				
			||||||
		case b := <-cs.callbacks.Get():
 | 
					 | 
				
			||||||
			backlog = append(backlog, b.(func(context.Context)))
 | 
					 | 
				
			||||||
		cs.callbacks.Load()
 | 
							cs.callbacks.Load()
 | 
				
			||||||
		default:
 | 
							cb.(func(context.Context))(ctx)
 | 
				
			||||||
			return backlog
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										173
									
								
								vendor/google.golang.org/grpc/internal/idle/idle.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										173
									
								
								vendor/google.golang.org/grpc/internal/idle/idle.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -26,8 +26,6 @@ import (
 | 
				
			|||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/grpclog"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// For overriding in unit tests.
 | 
					// For overriding in unit tests.
 | 
				
			||||||
@@ -39,27 +37,12 @@ var timeAfterFunc = func(d time.Duration, f func()) *time.Timer {
 | 
				
			|||||||
// and exit from idle mode.
 | 
					// and exit from idle mode.
 | 
				
			||||||
type Enforcer interface {
 | 
					type Enforcer interface {
 | 
				
			||||||
	ExitIdleMode() error
 | 
						ExitIdleMode() error
 | 
				
			||||||
	EnterIdleMode() error
 | 
						EnterIdleMode()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Manager defines the functionality required to track RPC activity on a
 | 
					// Manager implements idleness detection and calls the configured Enforcer to
 | 
				
			||||||
// channel.
 | 
					// enter/exit idle mode when appropriate.  Must be created by NewManager.
 | 
				
			||||||
type Manager interface {
 | 
					type Manager struct {
 | 
				
			||||||
	OnCallBegin() error
 | 
					 | 
				
			||||||
	OnCallEnd()
 | 
					 | 
				
			||||||
	Close()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type noopManager struct{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (noopManager) OnCallBegin() error { return nil }
 | 
					 | 
				
			||||||
func (noopManager) OnCallEnd()         {}
 | 
					 | 
				
			||||||
func (noopManager) Close()             {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// manager implements the Manager interface. It uses atomic operations to
 | 
					 | 
				
			||||||
// synchronize access to shared state and a mutex to guarantee mutual exclusion
 | 
					 | 
				
			||||||
// in a critical section.
 | 
					 | 
				
			||||||
type manager struct {
 | 
					 | 
				
			||||||
	// State accessed atomically.
 | 
						// State accessed atomically.
 | 
				
			||||||
	lastCallEndTime           int64 // Unix timestamp in nanos; time when the most recent RPC completed.
 | 
						lastCallEndTime           int64 // Unix timestamp in nanos; time when the most recent RPC completed.
 | 
				
			||||||
	activeCallsCount          int32 // Count of active RPCs; -math.MaxInt32 means channel is idle or is trying to get there.
 | 
						activeCallsCount          int32 // Count of active RPCs; -math.MaxInt32 means channel is idle or is trying to get there.
 | 
				
			||||||
@@ -69,8 +52,7 @@ type manager struct {
 | 
				
			|||||||
	// Can be accessed without atomics or mutex since these are set at creation
 | 
						// Can be accessed without atomics or mutex since these are set at creation
 | 
				
			||||||
	// time and read-only after that.
 | 
						// time and read-only after that.
 | 
				
			||||||
	enforcer Enforcer // Functionality provided by grpc.ClientConn.
 | 
						enforcer Enforcer // Functionality provided by grpc.ClientConn.
 | 
				
			||||||
	timeout  int64    // Idle timeout duration nanos stored as an int64.
 | 
						timeout  time.Duration
 | 
				
			||||||
	logger   grpclog.LoggerV2
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// idleMu is used to guarantee mutual exclusion in two scenarios:
 | 
						// idleMu is used to guarantee mutual exclusion in two scenarios:
 | 
				
			||||||
	// - Opposing intentions:
 | 
						// - Opposing intentions:
 | 
				
			||||||
@@ -88,57 +70,48 @@ type manager struct {
 | 
				
			|||||||
	timer        *time.Timer
 | 
						timer        *time.Timer
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ManagerOptions is a collection of options used by
 | 
					 | 
				
			||||||
// NewManager.
 | 
					 | 
				
			||||||
type ManagerOptions struct {
 | 
					 | 
				
			||||||
	Enforcer Enforcer
 | 
					 | 
				
			||||||
	Timeout  time.Duration
 | 
					 | 
				
			||||||
	Logger   grpclog.LoggerV2
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewManager creates a new idleness manager implementation for the
 | 
					// NewManager creates a new idleness manager implementation for the
 | 
				
			||||||
// given idle timeout.
 | 
					// given idle timeout.  It begins in idle mode.
 | 
				
			||||||
func NewManager(opts ManagerOptions) Manager {
 | 
					func NewManager(enforcer Enforcer, timeout time.Duration) *Manager {
 | 
				
			||||||
	if opts.Timeout == 0 {
 | 
						return &Manager{
 | 
				
			||||||
		return noopManager{}
 | 
							enforcer:         enforcer,
 | 
				
			||||||
 | 
							timeout:          timeout,
 | 
				
			||||||
 | 
							actuallyIdle:     true,
 | 
				
			||||||
 | 
							activeCallsCount: -math.MaxInt32,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m := &manager{
 | 
					// resetIdleTimerLocked resets the idle timer to the given duration.  Called
 | 
				
			||||||
		enforcer: opts.Enforcer,
 | 
					// when exiting idle mode or when the timer fires and we need to reset it.
 | 
				
			||||||
		timeout:  int64(opts.Timeout),
 | 
					func (m *Manager) resetIdleTimerLocked(d time.Duration) {
 | 
				
			||||||
		logger:   opts.Logger,
 | 
						if m.isClosed() || m.timeout == 0 || m.actuallyIdle {
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	m.timer = timeAfterFunc(opts.Timeout, m.handleIdleTimeout)
 | 
					 | 
				
			||||||
	return m
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// resetIdleTimer resets the idle timer to the given duration. This method
 | 
					 | 
				
			||||||
// should only be called from the timer callback.
 | 
					 | 
				
			||||||
func (m *manager) resetIdleTimer(d time.Duration) {
 | 
					 | 
				
			||||||
	m.idleMu.Lock()
 | 
					 | 
				
			||||||
	defer m.idleMu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if m.timer == nil {
 | 
					 | 
				
			||||||
		// Only close sets timer to nil. We are done.
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// It is safe to ignore the return value from Reset() because this method is
 | 
						// It is safe to ignore the return value from Reset() because this method is
 | 
				
			||||||
	// only ever called from the timer callback, which means the timer has
 | 
						// only ever called from the timer callback or when exiting idle mode.
 | 
				
			||||||
	// already fired.
 | 
						if m.timer != nil {
 | 
				
			||||||
	m.timer.Reset(d)
 | 
							m.timer.Stop()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						m.timer = timeAfterFunc(d, m.handleIdleTimeout)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Manager) resetIdleTimer(d time.Duration) {
 | 
				
			||||||
 | 
						m.idleMu.Lock()
 | 
				
			||||||
 | 
						defer m.idleMu.Unlock()
 | 
				
			||||||
 | 
						m.resetIdleTimerLocked(d)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// handleIdleTimeout is the timer callback that is invoked upon expiry of the
 | 
					// handleIdleTimeout is the timer callback that is invoked upon expiry of the
 | 
				
			||||||
// configured idle timeout. The channel is considered inactive if there are no
 | 
					// configured idle timeout. The channel is considered inactive if there are no
 | 
				
			||||||
// ongoing calls and no RPC activity since the last time the timer fired.
 | 
					// ongoing calls and no RPC activity since the last time the timer fired.
 | 
				
			||||||
func (m *manager) handleIdleTimeout() {
 | 
					func (m *Manager) handleIdleTimeout() {
 | 
				
			||||||
	if m.isClosed() {
 | 
						if m.isClosed() {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if atomic.LoadInt32(&m.activeCallsCount) > 0 {
 | 
						if atomic.LoadInt32(&m.activeCallsCount) > 0 {
 | 
				
			||||||
		m.resetIdleTimer(time.Duration(m.timeout))
 | 
							m.resetIdleTimer(m.timeout)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -148,24 +121,12 @@ func (m *manager) handleIdleTimeout() {
 | 
				
			|||||||
		// Set the timer to fire after a duration of idle timeout, calculated
 | 
							// Set the timer to fire after a duration of idle timeout, calculated
 | 
				
			||||||
		// from the time the most recent RPC completed.
 | 
							// from the time the most recent RPC completed.
 | 
				
			||||||
		atomic.StoreInt32(&m.activeSinceLastTimerCheck, 0)
 | 
							atomic.StoreInt32(&m.activeSinceLastTimerCheck, 0)
 | 
				
			||||||
		m.resetIdleTimer(time.Duration(atomic.LoadInt64(&m.lastCallEndTime) + m.timeout - time.Now().UnixNano()))
 | 
							m.resetIdleTimer(time.Duration(atomic.LoadInt64(&m.lastCallEndTime)-time.Now().UnixNano()) + m.timeout)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// This CAS operation is extremely likely to succeed given that there has
 | 
						// Now that we've checked that there has been no activity, attempt to enter
 | 
				
			||||||
	// been no activity since the last time we were here.  Setting the
 | 
						// idle mode, which is very likely to succeed.
 | 
				
			||||||
	// activeCallsCount to -math.MaxInt32 indicates to OnCallBegin() that the
 | 
					 | 
				
			||||||
	// channel is either in idle mode or is trying to get there.
 | 
					 | 
				
			||||||
	if !atomic.CompareAndSwapInt32(&m.activeCallsCount, 0, -math.MaxInt32) {
 | 
					 | 
				
			||||||
		// This CAS operation can fail if an RPC started after we checked for
 | 
					 | 
				
			||||||
		// activity at the top of this method, or one was ongoing from before
 | 
					 | 
				
			||||||
		// the last time we were here. In both case, reset the timer and return.
 | 
					 | 
				
			||||||
		m.resetIdleTimer(time.Duration(m.timeout))
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Now that we've set the active calls count to -math.MaxInt32, it's time to
 | 
					 | 
				
			||||||
	// actually move to idle mode.
 | 
					 | 
				
			||||||
	if m.tryEnterIdleMode() {
 | 
						if m.tryEnterIdleMode() {
 | 
				
			||||||
		// Successfully entered idle mode. No timer needed until we exit idle.
 | 
							// Successfully entered idle mode. No timer needed until we exit idle.
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -174,8 +135,7 @@ func (m *manager) handleIdleTimeout() {
 | 
				
			|||||||
	// Failed to enter idle mode due to a concurrent RPC that kept the channel
 | 
						// Failed to enter idle mode due to a concurrent RPC that kept the channel
 | 
				
			||||||
	// active, or because of an error from the channel. Undo the attempt to
 | 
						// active, or because of an error from the channel. Undo the attempt to
 | 
				
			||||||
	// enter idle, and reset the timer to try again later.
 | 
						// enter idle, and reset the timer to try again later.
 | 
				
			||||||
	atomic.AddInt32(&m.activeCallsCount, math.MaxInt32)
 | 
						m.resetIdleTimer(m.timeout)
 | 
				
			||||||
	m.resetIdleTimer(time.Duration(m.timeout))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// tryEnterIdleMode instructs the channel to enter idle mode. But before
 | 
					// tryEnterIdleMode instructs the channel to enter idle mode. But before
 | 
				
			||||||
@@ -185,36 +145,49 @@ func (m *manager) handleIdleTimeout() {
 | 
				
			|||||||
// Return value indicates whether or not the channel moved to idle mode.
 | 
					// Return value indicates whether or not the channel moved to idle mode.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Holds idleMu which ensures mutual exclusion with exitIdleMode.
 | 
					// Holds idleMu which ensures mutual exclusion with exitIdleMode.
 | 
				
			||||||
func (m *manager) tryEnterIdleMode() bool {
 | 
					func (m *Manager) tryEnterIdleMode() bool {
 | 
				
			||||||
 | 
						// Setting the activeCallsCount to -math.MaxInt32 indicates to OnCallBegin()
 | 
				
			||||||
 | 
						// that the channel is either in idle mode or is trying to get there.
 | 
				
			||||||
 | 
						if !atomic.CompareAndSwapInt32(&m.activeCallsCount, 0, -math.MaxInt32) {
 | 
				
			||||||
 | 
							// This CAS operation can fail if an RPC started after we checked for
 | 
				
			||||||
 | 
							// activity in the timer handler, or one was ongoing from before the
 | 
				
			||||||
 | 
							// last time the timer fired, or if a test is attempting to enter idle
 | 
				
			||||||
 | 
							// mode without checking.  In all cases, abort going into idle mode.
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// N.B. if we fail to enter idle mode after this, we must re-add
 | 
				
			||||||
 | 
						// math.MaxInt32 to m.activeCallsCount.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m.idleMu.Lock()
 | 
						m.idleMu.Lock()
 | 
				
			||||||
	defer m.idleMu.Unlock()
 | 
						defer m.idleMu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if atomic.LoadInt32(&m.activeCallsCount) != -math.MaxInt32 {
 | 
						if atomic.LoadInt32(&m.activeCallsCount) != -math.MaxInt32 {
 | 
				
			||||||
		// We raced and lost to a new RPC. Very rare, but stop entering idle.
 | 
							// We raced and lost to a new RPC. Very rare, but stop entering idle.
 | 
				
			||||||
 | 
							atomic.AddInt32(&m.activeCallsCount, math.MaxInt32)
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if atomic.LoadInt32(&m.activeSinceLastTimerCheck) == 1 {
 | 
						if atomic.LoadInt32(&m.activeSinceLastTimerCheck) == 1 {
 | 
				
			||||||
		// An very short RPC could have come in (and also finished) after we
 | 
							// A very short RPC could have come in (and also finished) after we
 | 
				
			||||||
		// checked for calls count and activity in handleIdleTimeout(), but
 | 
							// checked for calls count and activity in handleIdleTimeout(), but
 | 
				
			||||||
		// before the CAS operation. So, we need to check for activity again.
 | 
							// before the CAS operation. So, we need to check for activity again.
 | 
				
			||||||
 | 
							atomic.AddInt32(&m.activeCallsCount, math.MaxInt32)
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// No new RPCs have come in since we last set the active calls count value
 | 
						// No new RPCs have come in since we set the active calls count value to
 | 
				
			||||||
	// -math.MaxInt32 in the timer callback. And since we have the lock, it is
 | 
						// -math.MaxInt32. And since we have the lock, it is safe to enter idle mode
 | 
				
			||||||
	// safe to enter idle mode now.
 | 
						// unconditionally now.
 | 
				
			||||||
	if err := m.enforcer.EnterIdleMode(); err != nil {
 | 
						m.enforcer.EnterIdleMode()
 | 
				
			||||||
		m.logger.Errorf("Failed to enter idle mode: %v", err)
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Successfully entered idle mode.
 | 
					 | 
				
			||||||
	m.actuallyIdle = true
 | 
						m.actuallyIdle = true
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Manager) EnterIdleModeForTesting() {
 | 
				
			||||||
 | 
						m.tryEnterIdleMode()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// OnCallBegin is invoked at the start of every RPC.
 | 
					// OnCallBegin is invoked at the start of every RPC.
 | 
				
			||||||
func (m *manager) OnCallBegin() error {
 | 
					func (m *Manager) OnCallBegin() error {
 | 
				
			||||||
	if m.isClosed() {
 | 
						if m.isClosed() {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -227,7 +200,7 @@ func (m *manager) OnCallBegin() error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Channel is either in idle mode or is in the process of moving to idle
 | 
						// Channel is either in idle mode or is in the process of moving to idle
 | 
				
			||||||
	// mode. Attempt to exit idle mode to allow this RPC.
 | 
						// mode. Attempt to exit idle mode to allow this RPC.
 | 
				
			||||||
	if err := m.exitIdleMode(); err != nil {
 | 
						if err := m.ExitIdleMode(); err != nil {
 | 
				
			||||||
		// Undo the increment to calls count, and return an error causing the
 | 
							// Undo the increment to calls count, and return an error causing the
 | 
				
			||||||
		// RPC to fail.
 | 
							// RPC to fail.
 | 
				
			||||||
		atomic.AddInt32(&m.activeCallsCount, -1)
 | 
							atomic.AddInt32(&m.activeCallsCount, -1)
 | 
				
			||||||
@@ -238,28 +211,30 @@ func (m *manager) OnCallBegin() error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// exitIdleMode instructs the channel to exit idle mode.
 | 
					// ExitIdleMode instructs m to call the enforcer's ExitIdleMode and update m's
 | 
				
			||||||
//
 | 
					// internal state.
 | 
				
			||||||
 | 
					func (m *Manager) ExitIdleMode() error {
 | 
				
			||||||
	// Holds idleMu which ensures mutual exclusion with tryEnterIdleMode.
 | 
						// Holds idleMu which ensures mutual exclusion with tryEnterIdleMode.
 | 
				
			||||||
func (m *manager) exitIdleMode() error {
 | 
					 | 
				
			||||||
	m.idleMu.Lock()
 | 
						m.idleMu.Lock()
 | 
				
			||||||
	defer m.idleMu.Unlock()
 | 
						defer m.idleMu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !m.actuallyIdle {
 | 
						if m.isClosed() || !m.actuallyIdle {
 | 
				
			||||||
		// This can happen in two scenarios:
 | 
							// This can happen in three scenarios:
 | 
				
			||||||
		// - handleIdleTimeout() set the calls count to -math.MaxInt32 and called
 | 
							// - handleIdleTimeout() set the calls count to -math.MaxInt32 and called
 | 
				
			||||||
		//   tryEnterIdleMode(). But before the latter could grab the lock, an RPC
 | 
							//   tryEnterIdleMode(). But before the latter could grab the lock, an RPC
 | 
				
			||||||
		//   came in and OnCallBegin() noticed that the calls count is negative.
 | 
							//   came in and OnCallBegin() noticed that the calls count is negative.
 | 
				
			||||||
		// - Channel is in idle mode, and multiple new RPCs come in at the same
 | 
							// - Channel is in idle mode, and multiple new RPCs come in at the same
 | 
				
			||||||
		//   time, all of them notice a negative calls count in OnCallBegin and get
 | 
							//   time, all of them notice a negative calls count in OnCallBegin and get
 | 
				
			||||||
		//   here. The first one to get the lock would got the channel to exit idle.
 | 
							//   here. The first one to get the lock would got the channel to exit idle.
 | 
				
			||||||
 | 
							// - Channel is not in idle mode, and the user calls Connect which calls
 | 
				
			||||||
 | 
							//   m.ExitIdleMode.
 | 
				
			||||||
		//
 | 
							//
 | 
				
			||||||
		// Either way, nothing to do here.
 | 
							// In any case, there is nothing to do here.
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := m.enforcer.ExitIdleMode(); err != nil {
 | 
						if err := m.enforcer.ExitIdleMode(); err != nil {
 | 
				
			||||||
		return fmt.Errorf("channel failed to exit idle mode: %v", err)
 | 
							return fmt.Errorf("failed to exit idle mode: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Undo the idle entry process. This also respects any new RPC attempts.
 | 
						// Undo the idle entry process. This also respects any new RPC attempts.
 | 
				
			||||||
@@ -267,12 +242,12 @@ func (m *manager) exitIdleMode() error {
 | 
				
			|||||||
	m.actuallyIdle = false
 | 
						m.actuallyIdle = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Start a new timer to fire after the configured idle timeout.
 | 
						// Start a new timer to fire after the configured idle timeout.
 | 
				
			||||||
	m.timer = timeAfterFunc(time.Duration(m.timeout), m.handleIdleTimeout)
 | 
						m.resetIdleTimerLocked(m.timeout)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// OnCallEnd is invoked at the end of every RPC.
 | 
					// OnCallEnd is invoked at the end of every RPC.
 | 
				
			||||||
func (m *manager) OnCallEnd() {
 | 
					func (m *Manager) OnCallEnd() {
 | 
				
			||||||
	if m.isClosed() {
 | 
						if m.isClosed() {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -287,15 +262,17 @@ func (m *manager) OnCallEnd() {
 | 
				
			|||||||
	atomic.AddInt32(&m.activeCallsCount, -1)
 | 
						atomic.AddInt32(&m.activeCallsCount, -1)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *manager) isClosed() bool {
 | 
					func (m *Manager) isClosed() bool {
 | 
				
			||||||
	return atomic.LoadInt32(&m.closed) == 1
 | 
						return atomic.LoadInt32(&m.closed) == 1
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *manager) Close() {
 | 
					func (m *Manager) Close() {
 | 
				
			||||||
	atomic.StoreInt32(&m.closed, 1)
 | 
						atomic.StoreInt32(&m.closed, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m.idleMu.Lock()
 | 
						m.idleMu.Lock()
 | 
				
			||||||
 | 
						if m.timer != nil {
 | 
				
			||||||
		m.timer.Stop()
 | 
							m.timer.Stop()
 | 
				
			||||||
		m.timer = nil
 | 
							m.timer = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	m.idleMu.Unlock()
 | 
						m.idleMu.Unlock()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								vendor/google.golang.org/grpc/internal/internal.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/google.golang.org/grpc/internal/internal.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -73,6 +73,11 @@ var (
 | 
				
			|||||||
	// xDS-enabled server invokes this method on a grpc.Server when a particular
 | 
						// xDS-enabled server invokes this method on a grpc.Server when a particular
 | 
				
			||||||
	// listener moves to "not-serving" mode.
 | 
						// listener moves to "not-serving" mode.
 | 
				
			||||||
	DrainServerTransports any // func(*grpc.Server, string)
 | 
						DrainServerTransports any // func(*grpc.Server, string)
 | 
				
			||||||
 | 
						// IsRegisteredMethod returns whether the passed in method is registered as
 | 
				
			||||||
 | 
						// a method on the server.
 | 
				
			||||||
 | 
						IsRegisteredMethod any // func(*grpc.Server, string) bool
 | 
				
			||||||
 | 
						// ServerFromContext returns the server from the context.
 | 
				
			||||||
 | 
						ServerFromContext any // func(context.Context) *grpc.Server
 | 
				
			||||||
	// AddGlobalServerOptions adds an array of ServerOption that will be
 | 
						// AddGlobalServerOptions adds an array of ServerOption that will be
 | 
				
			||||||
	// effective globally for newly created servers. The priority will be: 1.
 | 
						// effective globally for newly created servers. The priority will be: 1.
 | 
				
			||||||
	// user-provided; 2. this method; 3. default values.
 | 
						// user-provided; 2. this method; 3. default values.
 | 
				
			||||||
@@ -177,10 +182,12 @@ var (
 | 
				
			|||||||
	GRPCResolverSchemeExtraMetadata string = "xds"
 | 
						GRPCResolverSchemeExtraMetadata string = "xds"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// EnterIdleModeForTesting gets the ClientConn to enter IDLE mode.
 | 
						// EnterIdleModeForTesting gets the ClientConn to enter IDLE mode.
 | 
				
			||||||
	EnterIdleModeForTesting any // func(*grpc.ClientConn) error
 | 
						EnterIdleModeForTesting any // func(*grpc.ClientConn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// ExitIdleModeForTesting gets the ClientConn to exit IDLE mode.
 | 
						// ExitIdleModeForTesting gets the ClientConn to exit IDLE mode.
 | 
				
			||||||
	ExitIdleModeForTesting any // func(*grpc.ClientConn) error
 | 
						ExitIdleModeForTesting any // func(*grpc.ClientConn) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ChannelzTurnOffForTesting func()
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HealthChecker defines the signature of the client-side LB channel health checking function.
 | 
					// HealthChecker defines the signature of the client-side LB channel health checking function.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										65
									
								
								vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										65
									
								
								vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -23,7 +23,6 @@ package dns
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
@@ -37,6 +36,7 @@ import (
 | 
				
			|||||||
	"google.golang.org/grpc/internal/backoff"
 | 
						"google.golang.org/grpc/internal/backoff"
 | 
				
			||||||
	"google.golang.org/grpc/internal/envconfig"
 | 
						"google.golang.org/grpc/internal/envconfig"
 | 
				
			||||||
	"google.golang.org/grpc/internal/grpcrand"
 | 
						"google.golang.org/grpc/internal/grpcrand"
 | 
				
			||||||
 | 
						"google.golang.org/grpc/internal/resolver/dns/internal"
 | 
				
			||||||
	"google.golang.org/grpc/resolver"
 | 
						"google.golang.org/grpc/resolver"
 | 
				
			||||||
	"google.golang.org/grpc/serviceconfig"
 | 
						"google.golang.org/grpc/serviceconfig"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -47,15 +47,11 @@ var EnableSRVLookups = false
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var logger = grpclog.Component("dns")
 | 
					var logger = grpclog.Component("dns")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Globals to stub out in tests. TODO: Perhaps these two can be combined into a
 | 
					 | 
				
			||||||
// single variable for testing the resolver?
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	newTimer           = time.NewTimer
 | 
					 | 
				
			||||||
	newTimerDNSResRate = time.NewTimer
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	resolver.Register(NewBuilder())
 | 
						resolver.Register(NewBuilder())
 | 
				
			||||||
 | 
						internal.TimeAfterFunc = time.After
 | 
				
			||||||
 | 
						internal.NewNetResolver = newNetResolver
 | 
				
			||||||
 | 
						internal.AddressDialer = addressDialer
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -70,23 +66,6 @@ const (
 | 
				
			|||||||
	txtAttribute = "grpc_config="
 | 
						txtAttribute = "grpc_config="
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	errMissingAddr = errors.New("dns resolver: missing address")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Addresses ending with a colon that is supposed to be the separator
 | 
					 | 
				
			||||||
	// between host and port is not allowed.  E.g. "::" is a valid address as
 | 
					 | 
				
			||||||
	// it is an IPv6 address (host only) and "[::]:" is invalid as it ends with
 | 
					 | 
				
			||||||
	// a colon as the host and port separator
 | 
					 | 
				
			||||||
	errEndsWithColon = errors.New("dns resolver: missing port after port-separator colon")
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	defaultResolver netResolver = net.DefaultResolver
 | 
					 | 
				
			||||||
	// To prevent excessive re-resolution, we enforce a rate limit on DNS
 | 
					 | 
				
			||||||
	// resolution requests.
 | 
					 | 
				
			||||||
	minDNSResRate = 30 * time.Second
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var addressDialer = func(address string) func(context.Context, string, string) (net.Conn, error) {
 | 
					var addressDialer = func(address string) func(context.Context, string, string) (net.Conn, error) {
 | 
				
			||||||
	return func(ctx context.Context, network, _ string) (net.Conn, error) {
 | 
						return func(ctx context.Context, network, _ string) (net.Conn, error) {
 | 
				
			||||||
		var dialer net.Dialer
 | 
							var dialer net.Dialer
 | 
				
			||||||
@@ -94,7 +73,11 @@ var addressDialer = func(address string) func(context.Context, string, string) (
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var newNetResolver = func(authority string) (netResolver, error) {
 | 
					var newNetResolver = func(authority string) (internal.NetResolver, error) {
 | 
				
			||||||
 | 
						if authority == "" {
 | 
				
			||||||
 | 
							return net.DefaultResolver, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	host, port, err := parseTarget(authority, defaultDNSSvrPort)
 | 
						host, port, err := parseTarget(authority, defaultDNSSvrPort)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -104,7 +87,7 @@ var newNetResolver = func(authority string) (netResolver, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return &net.Resolver{
 | 
						return &net.Resolver{
 | 
				
			||||||
		PreferGo: true,
 | 
							PreferGo: true,
 | 
				
			||||||
		Dial:     addressDialer(authorityWithPort),
 | 
							Dial:     internal.AddressDialer(authorityWithPort),
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -142,14 +125,10 @@ func (b *dnsBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts
 | 
				
			|||||||
		disableServiceConfig: opts.DisableServiceConfig,
 | 
							disableServiceConfig: opts.DisableServiceConfig,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if target.URL.Host == "" {
 | 
						d.resolver, err = internal.NewNetResolver(target.URL.Host)
 | 
				
			||||||
		d.resolver = defaultResolver
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		d.resolver, err = newNetResolver(target.URL.Host)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	d.wg.Add(1)
 | 
						d.wg.Add(1)
 | 
				
			||||||
	go d.watcher()
 | 
						go d.watcher()
 | 
				
			||||||
@@ -161,12 +140,6 @@ func (b *dnsBuilder) Scheme() string {
 | 
				
			|||||||
	return "dns"
 | 
						return "dns"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type netResolver interface {
 | 
					 | 
				
			||||||
	LookupHost(ctx context.Context, host string) (addrs []string, err error)
 | 
					 | 
				
			||||||
	LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*net.SRV, err error)
 | 
					 | 
				
			||||||
	LookupTXT(ctx context.Context, name string) (txts []string, err error)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// deadResolver is a resolver that does nothing.
 | 
					// deadResolver is a resolver that does nothing.
 | 
				
			||||||
type deadResolver struct{}
 | 
					type deadResolver struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -178,7 +151,7 @@ func (deadResolver) Close() {}
 | 
				
			|||||||
type dnsResolver struct {
 | 
					type dnsResolver struct {
 | 
				
			||||||
	host     string
 | 
						host     string
 | 
				
			||||||
	port     string
 | 
						port     string
 | 
				
			||||||
	resolver netResolver
 | 
						resolver internal.NetResolver
 | 
				
			||||||
	ctx      context.Context
 | 
						ctx      context.Context
 | 
				
			||||||
	cancel   context.CancelFunc
 | 
						cancel   context.CancelFunc
 | 
				
			||||||
	cc       resolver.ClientConn
 | 
						cc       resolver.ClientConn
 | 
				
			||||||
@@ -223,29 +196,27 @@ func (d *dnsResolver) watcher() {
 | 
				
			|||||||
			err = d.cc.UpdateState(*state)
 | 
								err = d.cc.UpdateState(*state)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var timer *time.Timer
 | 
							var waitTime time.Duration
 | 
				
			||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			// Success resolving, wait for the next ResolveNow. However, also wait 30
 | 
								// Success resolving, wait for the next ResolveNow. However, also wait 30
 | 
				
			||||||
			// seconds at the very least to prevent constantly re-resolving.
 | 
								// seconds at the very least to prevent constantly re-resolving.
 | 
				
			||||||
			backoffIndex = 1
 | 
								backoffIndex = 1
 | 
				
			||||||
			timer = newTimerDNSResRate(minDNSResRate)
 | 
								waitTime = internal.MinResolutionRate
 | 
				
			||||||
			select {
 | 
								select {
 | 
				
			||||||
			case <-d.ctx.Done():
 | 
								case <-d.ctx.Done():
 | 
				
			||||||
				timer.Stop()
 | 
					 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			case <-d.rn:
 | 
								case <-d.rn:
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			// Poll on an error found in DNS Resolver or an error received from
 | 
								// Poll on an error found in DNS Resolver or an error received from
 | 
				
			||||||
			// ClientConn.
 | 
								// ClientConn.
 | 
				
			||||||
			timer = newTimer(backoff.DefaultExponential.Backoff(backoffIndex))
 | 
								waitTime = backoff.DefaultExponential.Backoff(backoffIndex)
 | 
				
			||||||
			backoffIndex++
 | 
								backoffIndex++
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		select {
 | 
							select {
 | 
				
			||||||
		case <-d.ctx.Done():
 | 
							case <-d.ctx.Done():
 | 
				
			||||||
			timer.Stop()
 | 
					 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		case <-timer.C:
 | 
							case <-internal.TimeAfterFunc(waitTime):
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -387,7 +358,7 @@ func formatIP(addr string) (addrIP string, ok bool) {
 | 
				
			|||||||
// target: ":80" defaultPort: "443" returns host: "localhost", port: "80"
 | 
					// target: ":80" defaultPort: "443" returns host: "localhost", port: "80"
 | 
				
			||||||
func parseTarget(target, defaultPort string) (host, port string, err error) {
 | 
					func parseTarget(target, defaultPort string) (host, port string, err error) {
 | 
				
			||||||
	if target == "" {
 | 
						if target == "" {
 | 
				
			||||||
		return "", "", errMissingAddr
 | 
							return "", "", internal.ErrMissingAddr
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ip := net.ParseIP(target); ip != nil {
 | 
						if ip := net.ParseIP(target); ip != nil {
 | 
				
			||||||
		// target is an IPv4 or IPv6(without brackets) address
 | 
							// target is an IPv4 or IPv6(without brackets) address
 | 
				
			||||||
@@ -397,7 +368,7 @@ func parseTarget(target, defaultPort string) (host, port string, err error) {
 | 
				
			|||||||
		if port == "" {
 | 
							if port == "" {
 | 
				
			||||||
			// If the port field is empty (target ends with colon), e.g. "[::1]:",
 | 
								// If the port field is empty (target ends with colon), e.g. "[::1]:",
 | 
				
			||||||
			// this is an error.
 | 
								// this is an error.
 | 
				
			||||||
			return "", "", errEndsWithColon
 | 
								return "", "", internal.ErrEndsWithColon
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port
 | 
							// target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port
 | 
				
			||||||
		if host == "" {
 | 
							if host == "" {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										70
									
								
								vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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 internal contains functionality internal to the dns resolver package.
 | 
				
			||||||
 | 
					package internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NetResolver groups the methods on net.Resolver that are used by the DNS
 | 
				
			||||||
 | 
					// resolver implementation. This allows the default net.Resolver instance to be
 | 
				
			||||||
 | 
					// overidden from tests.
 | 
				
			||||||
 | 
					type NetResolver interface {
 | 
				
			||||||
 | 
						LookupHost(ctx context.Context, host string) (addrs []string, err error)
 | 
				
			||||||
 | 
						LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*net.SRV, err error)
 | 
				
			||||||
 | 
						LookupTXT(ctx context.Context, name string) (txts []string, err error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						// ErrMissingAddr is the error returned when building a DNS resolver when
 | 
				
			||||||
 | 
						// the provided target name is empty.
 | 
				
			||||||
 | 
						ErrMissingAddr = errors.New("dns resolver: missing address")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ErrEndsWithColon is the error returned when building a DNS resolver when
 | 
				
			||||||
 | 
						// the provided target name ends with a colon that is supposed to be the
 | 
				
			||||||
 | 
						// separator between host and port.  E.g. "::" is a valid address as it is
 | 
				
			||||||
 | 
						// an IPv6 address (host only) and "[::]:" is invalid as it ends with a
 | 
				
			||||||
 | 
						// colon as the host and port separator
 | 
				
			||||||
 | 
						ErrEndsWithColon = errors.New("dns resolver: missing port after port-separator colon")
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The following vars are overridden from tests.
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						// MinResolutionRate is the minimum rate at which re-resolutions are
 | 
				
			||||||
 | 
						// allowed. This helps to prevent excessive re-resolution.
 | 
				
			||||||
 | 
						MinResolutionRate = 30 * time.Second
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TimeAfterFunc is used by the DNS resolver to wait for the given duration
 | 
				
			||||||
 | 
						// to elapse. In non-test code, this is implemented by time.After.  In test
 | 
				
			||||||
 | 
						// code, this can be used to control the amount of time the resolver is
 | 
				
			||||||
 | 
						// blocked waiting for the duration to elapse.
 | 
				
			||||||
 | 
						TimeAfterFunc func(time.Duration) <-chan time.Time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// NewNetResolver returns the net.Resolver instance for the given target.
 | 
				
			||||||
 | 
						NewNetResolver func(string) (NetResolver, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// AddressDialer is the dialer used to dial the DNS server. It accepts the
 | 
				
			||||||
 | 
						// Host portion of the URL corresponding to the user's dial target and
 | 
				
			||||||
 | 
						// returns a dial function.
 | 
				
			||||||
 | 
						AddressDialer func(address string) func(context.Context, string, string) (net.Conn, error)
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										29
									
								
								vendor/google.golang.org/grpc/internal/tcp_keepalive_nonunix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/google.golang.org/grpc/internal/tcp_keepalive_nonunix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					//go:build !unix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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 internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NetDialerWithTCPKeepalive returns a vanilla net.Dialer on non-unix platforms.
 | 
				
			||||||
 | 
					func NetDialerWithTCPKeepalive() *net.Dialer {
 | 
				
			||||||
 | 
						return &net.Dialer{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								vendor/google.golang.org/grpc/internal/tcp_keepalive_unix.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					//go:build unix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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 internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NetDialerWithTCPKeepalive returns a net.Dialer that enables TCP keepalives on
 | 
				
			||||||
 | 
					// the underlying connection with OS default values for keepalive parameters.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// TODO: Once https://github.com/golang/go/issues/62254 lands, and the
 | 
				
			||||||
 | 
					// appropriate Go version becomes less than our least supported Go version, we
 | 
				
			||||||
 | 
					// should look into using the new API to make things more straightforward.
 | 
				
			||||||
 | 
					func NetDialerWithTCPKeepalive() *net.Dialer {
 | 
				
			||||||
 | 
						return &net.Dialer{
 | 
				
			||||||
 | 
							// Setting a negative value here prevents the Go stdlib from overriding
 | 
				
			||||||
 | 
							// the values of TCP keepalive time and interval. It also prevents the
 | 
				
			||||||
 | 
							// Go stdlib from enabling TCP keepalives by default.
 | 
				
			||||||
 | 
							KeepAlive: time.Duration(-1),
 | 
				
			||||||
 | 
							// This method is called after the underlying network socket is created,
 | 
				
			||||||
 | 
							// but before dialing the socket (or calling its connect() method). The
 | 
				
			||||||
 | 
							// combination of unconditionally enabling TCP keepalives here, and
 | 
				
			||||||
 | 
							// disabling the overriding of TCP keepalive parameters by setting the
 | 
				
			||||||
 | 
							// KeepAlive field to a negative value above, results in OS defaults for
 | 
				
			||||||
 | 
							// the TCP keealive interval and time parameters.
 | 
				
			||||||
 | 
							Control: func(_, _ string, c syscall.RawConn) error {
 | 
				
			||||||
 | 
								return c.Control(func(fd uintptr) {
 | 
				
			||||||
 | 
									unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1)
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								vendor/google.golang.org/grpc/internal/transport/handler_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										49
									
								
								vendor/google.golang.org/grpc/internal/transport/handler_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -75,11 +75,25 @@ func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []s
 | 
				
			|||||||
		return nil, errors.New(msg)
 | 
							return nil, errors.New(msg)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var localAddr net.Addr
 | 
				
			||||||
 | 
						if la := r.Context().Value(http.LocalAddrContextKey); la != nil {
 | 
				
			||||||
 | 
							localAddr, _ = la.(net.Addr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var authInfo credentials.AuthInfo
 | 
				
			||||||
 | 
						if r.TLS != nil {
 | 
				
			||||||
 | 
							authInfo = credentials.TLSInfo{State: *r.TLS, CommonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity}}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						p := peer.Peer{
 | 
				
			||||||
 | 
							Addr:      strAddr(r.RemoteAddr),
 | 
				
			||||||
 | 
							LocalAddr: localAddr,
 | 
				
			||||||
 | 
							AuthInfo:  authInfo,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	st := &serverHandlerTransport{
 | 
						st := &serverHandlerTransport{
 | 
				
			||||||
		rw:             w,
 | 
							rw:             w,
 | 
				
			||||||
		req:            r,
 | 
							req:            r,
 | 
				
			||||||
		closedCh:       make(chan struct{}),
 | 
							closedCh:       make(chan struct{}),
 | 
				
			||||||
		writes:         make(chan func()),
 | 
							writes:         make(chan func()),
 | 
				
			||||||
 | 
							peer:           p,
 | 
				
			||||||
		contentType:    contentType,
 | 
							contentType:    contentType,
 | 
				
			||||||
		contentSubtype: contentSubtype,
 | 
							contentSubtype: contentSubtype,
 | 
				
			||||||
		stats:          stats,
 | 
							stats:          stats,
 | 
				
			||||||
@@ -134,6 +148,8 @@ type serverHandlerTransport struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	headerMD metadata.MD
 | 
						headerMD metadata.MD
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						peer peer.Peer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	closeOnce sync.Once
 | 
						closeOnce sync.Once
 | 
				
			||||||
	closedCh  chan struct{} // closed on Close
 | 
						closedCh  chan struct{} // closed on Close
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -165,7 +181,13 @@ func (ht *serverHandlerTransport) Close(err error) {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ht *serverHandlerTransport) RemoteAddr() net.Addr { return strAddr(ht.req.RemoteAddr) }
 | 
					func (ht *serverHandlerTransport) Peer() *peer.Peer {
 | 
				
			||||||
 | 
						return &peer.Peer{
 | 
				
			||||||
 | 
							Addr:      ht.peer.Addr,
 | 
				
			||||||
 | 
							LocalAddr: ht.peer.LocalAddr,
 | 
				
			||||||
 | 
							AuthInfo:  ht.peer.AuthInfo,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// strAddr is a net.Addr backed by either a TCP "ip:port" string, or
 | 
					// strAddr is a net.Addr backed by either a TCP "ip:port" string, or
 | 
				
			||||||
// the empty string if unknown.
 | 
					// the empty string if unknown.
 | 
				
			||||||
@@ -347,10 +369,8 @@ func (ht *serverHandlerTransport) WriteHeader(s *Stream, md metadata.MD) error {
 | 
				
			|||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream)) {
 | 
					func (ht *serverHandlerTransport) HandleStreams(ctx context.Context, startStream func(*Stream)) {
 | 
				
			||||||
	// With this transport type there will be exactly 1 stream: this HTTP request.
 | 
						// With this transport type there will be exactly 1 stream: this HTTP request.
 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx := ht.req.Context()
 | 
					 | 
				
			||||||
	var cancel context.CancelFunc
 | 
						var cancel context.CancelFunc
 | 
				
			||||||
	if ht.timeoutSet {
 | 
						if ht.timeoutSet {
 | 
				
			||||||
		ctx, cancel = context.WithTimeout(ctx, ht.timeout)
 | 
							ctx, cancel = context.WithTimeout(ctx, ht.timeout)
 | 
				
			||||||
@@ -370,10 +390,11 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream)) {
 | 
				
			|||||||
		ht.Close(errors.New("request is done processing"))
 | 
							ht.Close(errors.New("request is done processing"))
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx = metadata.NewIncomingContext(ctx, ht.headerMD)
 | 
				
			||||||
	req := ht.req
 | 
						req := ht.req
 | 
				
			||||||
 | 
					 | 
				
			||||||
	s := &Stream{
 | 
						s := &Stream{
 | 
				
			||||||
		id:               0, // irrelevant
 | 
							id:               0, // irrelevant
 | 
				
			||||||
 | 
							ctx:              ctx,
 | 
				
			||||||
		requestRead:      func(int) {},
 | 
							requestRead:      func(int) {},
 | 
				
			||||||
		cancel:           cancel,
 | 
							cancel:           cancel,
 | 
				
			||||||
		buf:              newRecvBuffer(),
 | 
							buf:              newRecvBuffer(),
 | 
				
			||||||
@@ -381,23 +402,7 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream)) {
 | 
				
			|||||||
		method:           req.URL.Path,
 | 
							method:           req.URL.Path,
 | 
				
			||||||
		recvCompress:     req.Header.Get("grpc-encoding"),
 | 
							recvCompress:     req.Header.Get("grpc-encoding"),
 | 
				
			||||||
		contentSubtype:   ht.contentSubtype,
 | 
							contentSubtype:   ht.contentSubtype,
 | 
				
			||||||
	}
 | 
							headerWireLength: 0, // won't have access to header wire length until golang/go#18997.
 | 
				
			||||||
	pr := &peer.Peer{
 | 
					 | 
				
			||||||
		Addr: ht.RemoteAddr(),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if req.TLS != nil {
 | 
					 | 
				
			||||||
		pr.AuthInfo = credentials.TLSInfo{State: *req.TLS, CommonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity}}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ctx = metadata.NewIncomingContext(ctx, ht.headerMD)
 | 
					 | 
				
			||||||
	s.ctx = peer.NewContext(ctx, pr)
 | 
					 | 
				
			||||||
	for _, sh := range ht.stats {
 | 
					 | 
				
			||||||
		s.ctx = sh.TagRPC(s.ctx, &stats.RPCTagInfo{FullMethodName: s.method})
 | 
					 | 
				
			||||||
		inHeader := &stats.InHeader{
 | 
					 | 
				
			||||||
			FullMethod:  s.method,
 | 
					 | 
				
			||||||
			RemoteAddr:  ht.RemoteAddr(),
 | 
					 | 
				
			||||||
			Compression: s.recvCompress,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		sh.HandleRPC(s.ctx, inHeader)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.trReader = &transportReader{
 | 
						s.trReader = &transportReader{
 | 
				
			||||||
		reader:        &recvBufferReader{ctx: s.ctx, ctxDone: s.ctx.Done(), recv: s.buf, freeBuffer: func(*bytes.Buffer) {}},
 | 
							reader:        &recvBufferReader{ctx: s.ctx, ctxDone: s.ctx.Done(), recv: s.buf, freeBuffer: func(*bytes.Buffer) {}},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								vendor/google.golang.org/grpc/internal/transport/http2_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/google.golang.org/grpc/internal/transport/http2_client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -36,6 +36,7 @@ import (
 | 
				
			|||||||
	"golang.org/x/net/http2/hpack"
 | 
						"golang.org/x/net/http2/hpack"
 | 
				
			||||||
	"google.golang.org/grpc/codes"
 | 
						"google.golang.org/grpc/codes"
 | 
				
			||||||
	"google.golang.org/grpc/credentials"
 | 
						"google.golang.org/grpc/credentials"
 | 
				
			||||||
 | 
						"google.golang.org/grpc/internal"
 | 
				
			||||||
	"google.golang.org/grpc/internal/channelz"
 | 
						"google.golang.org/grpc/internal/channelz"
 | 
				
			||||||
	icredentials "google.golang.org/grpc/internal/credentials"
 | 
						icredentials "google.golang.org/grpc/internal/credentials"
 | 
				
			||||||
	"google.golang.org/grpc/internal/grpclog"
 | 
						"google.golang.org/grpc/internal/grpclog"
 | 
				
			||||||
@@ -43,7 +44,7 @@ import (
 | 
				
			|||||||
	"google.golang.org/grpc/internal/grpcutil"
 | 
						"google.golang.org/grpc/internal/grpcutil"
 | 
				
			||||||
	imetadata "google.golang.org/grpc/internal/metadata"
 | 
						imetadata "google.golang.org/grpc/internal/metadata"
 | 
				
			||||||
	istatus "google.golang.org/grpc/internal/status"
 | 
						istatus "google.golang.org/grpc/internal/status"
 | 
				
			||||||
	"google.golang.org/grpc/internal/syscall"
 | 
						isyscall "google.golang.org/grpc/internal/syscall"
 | 
				
			||||||
	"google.golang.org/grpc/internal/transport/networktype"
 | 
						"google.golang.org/grpc/internal/transport/networktype"
 | 
				
			||||||
	"google.golang.org/grpc/keepalive"
 | 
						"google.golang.org/grpc/keepalive"
 | 
				
			||||||
	"google.golang.org/grpc/metadata"
 | 
						"google.golang.org/grpc/metadata"
 | 
				
			||||||
@@ -176,7 +177,7 @@ func dial(ctx context.Context, fn func(context.Context, string) (net.Conn, error
 | 
				
			|||||||
	if networkType == "tcp" && useProxy {
 | 
						if networkType == "tcp" && useProxy {
 | 
				
			||||||
		return proxyDial(ctx, address, grpcUA)
 | 
							return proxyDial(ctx, address, grpcUA)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return (&net.Dialer{}).DialContext(ctx, networkType, address)
 | 
						return internal.NetDialerWithTCPKeepalive().DialContext(ctx, networkType, address)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func isTemporary(err error) bool {
 | 
					func isTemporary(err error) bool {
 | 
				
			||||||
@@ -262,7 +263,7 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	keepaliveEnabled := false
 | 
						keepaliveEnabled := false
 | 
				
			||||||
	if kp.Time != infinity {
 | 
						if kp.Time != infinity {
 | 
				
			||||||
		if err = syscall.SetTCPUserTimeout(conn, kp.Timeout); err != nil {
 | 
							if err = isyscall.SetTCPUserTimeout(conn, kp.Timeout); err != nil {
 | 
				
			||||||
			return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err)
 | 
								return nil, connectionErrorf(false, err, "transport: failed to set TCP_USER_TIMEOUT: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		keepaliveEnabled = true
 | 
							keepaliveEnabled = true
 | 
				
			||||||
@@ -495,6 +496,7 @@ func (t *http2Client) getPeer() *peer.Peer {
 | 
				
			|||||||
	return &peer.Peer{
 | 
						return &peer.Peer{
 | 
				
			||||||
		Addr:      t.remoteAddr,
 | 
							Addr:      t.remoteAddr,
 | 
				
			||||||
		AuthInfo:  t.authInfo, // Can be nil
 | 
							AuthInfo:  t.authInfo, // Can be nil
 | 
				
			||||||
 | 
							LocalAddr: t.localAddr,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										85
									
								
								vendor/google.golang.org/grpc/internal/transport/http2_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										85
									
								
								vendor/google.golang.org/grpc/internal/transport/http2_server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -69,15 +69,12 @@ var serverConnectionCounter uint64
 | 
				
			|||||||
// http2Server implements the ServerTransport interface with HTTP2.
 | 
					// http2Server implements the ServerTransport interface with HTTP2.
 | 
				
			||||||
type http2Server struct {
 | 
					type http2Server struct {
 | 
				
			||||||
	lastRead        int64 // Keep this field 64-bit aligned. Accessed atomically.
 | 
						lastRead        int64 // Keep this field 64-bit aligned. Accessed atomically.
 | 
				
			||||||
	ctx         context.Context
 | 
					 | 
				
			||||||
	done            chan struct{}
 | 
						done            chan struct{}
 | 
				
			||||||
	conn            net.Conn
 | 
						conn            net.Conn
 | 
				
			||||||
	loopy           *loopyWriter
 | 
						loopy           *loopyWriter
 | 
				
			||||||
	readerDone      chan struct{} // sync point to enable testing.
 | 
						readerDone      chan struct{} // sync point to enable testing.
 | 
				
			||||||
	writerDone  chan struct{} // sync point to enable testing.
 | 
						loopyWriterDone chan struct{}
 | 
				
			||||||
	remoteAddr  net.Addr
 | 
						peer            peer.Peer
 | 
				
			||||||
	localAddr   net.Addr
 | 
					 | 
				
			||||||
	authInfo    credentials.AuthInfo // auth info about the connection
 | 
					 | 
				
			||||||
	inTapHandle     tap.ServerInHandle
 | 
						inTapHandle     tap.ServerInHandle
 | 
				
			||||||
	framer          *framer
 | 
						framer          *framer
 | 
				
			||||||
	// The max number of concurrent streams.
 | 
						// The max number of concurrent streams.
 | 
				
			||||||
@@ -243,16 +240,18 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	done := make(chan struct{})
 | 
						done := make(chan struct{})
 | 
				
			||||||
 | 
						peer := peer.Peer{
 | 
				
			||||||
 | 
							Addr:      conn.RemoteAddr(),
 | 
				
			||||||
 | 
							LocalAddr: conn.LocalAddr(),
 | 
				
			||||||
 | 
							AuthInfo:  authInfo,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	t := &http2Server{
 | 
						t := &http2Server{
 | 
				
			||||||
		ctx:               setConnection(context.Background(), rawConn),
 | 
					 | 
				
			||||||
		done:              done,
 | 
							done:              done,
 | 
				
			||||||
		conn:              conn,
 | 
							conn:              conn,
 | 
				
			||||||
		remoteAddr:        conn.RemoteAddr(),
 | 
							peer:              peer,
 | 
				
			||||||
		localAddr:         conn.LocalAddr(),
 | 
					 | 
				
			||||||
		authInfo:          authInfo,
 | 
					 | 
				
			||||||
		framer:            framer,
 | 
							framer:            framer,
 | 
				
			||||||
		readerDone:        make(chan struct{}),
 | 
							readerDone:        make(chan struct{}),
 | 
				
			||||||
		writerDone:        make(chan struct{}),
 | 
							loopyWriterDone:   make(chan struct{}),
 | 
				
			||||||
		maxStreams:        config.MaxStreams,
 | 
							maxStreams:        config.MaxStreams,
 | 
				
			||||||
		inTapHandle:       config.InTapHandle,
 | 
							inTapHandle:       config.InTapHandle,
 | 
				
			||||||
		fc:                &trInFlow{limit: uint32(icwz)},
 | 
							fc:                &trInFlow{limit: uint32(icwz)},
 | 
				
			||||||
@@ -267,8 +266,6 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
 | 
				
			|||||||
		bufferPool:        newBufferPool(),
 | 
							bufferPool:        newBufferPool(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	t.logger = prefixLoggerForServerTransport(t)
 | 
						t.logger = prefixLoggerForServerTransport(t)
 | 
				
			||||||
	// Add peer information to the http2server context.
 | 
					 | 
				
			||||||
	t.ctx = peer.NewContext(t.ctx, t.getPeer())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t.controlBuf = newControlBuffer(t.done)
 | 
						t.controlBuf = newControlBuffer(t.done)
 | 
				
			||||||
	if dynamicWindow {
 | 
						if dynamicWindow {
 | 
				
			||||||
@@ -277,15 +274,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
 | 
				
			|||||||
			updateFlowControl: t.updateFlowControl,
 | 
								updateFlowControl: t.updateFlowControl,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, sh := range t.stats {
 | 
						t.channelzID, err = channelz.RegisterNormalSocket(t, config.ChannelzParentID, fmt.Sprintf("%s -> %s", t.peer.Addr, t.peer.LocalAddr))
 | 
				
			||||||
		t.ctx = sh.TagConn(t.ctx, &stats.ConnTagInfo{
 | 
					 | 
				
			||||||
			RemoteAddr: t.remoteAddr,
 | 
					 | 
				
			||||||
			LocalAddr:  t.localAddr,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		connBegin := &stats.ConnBegin{}
 | 
					 | 
				
			||||||
		sh.HandleConn(t.ctx, connBegin)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	t.channelzID, err = channelz.RegisterNormalSocket(t, config.ChannelzParentID, fmt.Sprintf("%s -> %s", t.remoteAddr, t.localAddr))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -334,7 +323,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
 | 
				
			|||||||
		t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
 | 
							t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger)
 | 
				
			||||||
		t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
 | 
							t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler
 | 
				
			||||||
		t.loopy.run()
 | 
							t.loopy.run()
 | 
				
			||||||
		close(t.writerDone)
 | 
							close(t.loopyWriterDone)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	go t.keepalive()
 | 
						go t.keepalive()
 | 
				
			||||||
	return t, nil
 | 
						return t, nil
 | 
				
			||||||
@@ -342,7 +331,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// operateHeaders takes action on the decoded headers. Returns an error if fatal
 | 
					// operateHeaders takes action on the decoded headers. Returns an error if fatal
 | 
				
			||||||
// error encountered and transport needs to close, otherwise returns nil.
 | 
					// error encountered and transport needs to close, otherwise returns nil.
 | 
				
			||||||
func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream)) error {
 | 
					func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeadersFrame, handle func(*Stream)) error {
 | 
				
			||||||
	// Acquire max stream ID lock for entire duration
 | 
						// Acquire max stream ID lock for entire duration
 | 
				
			||||||
	t.maxStreamMu.Lock()
 | 
						t.maxStreamMu.Lock()
 | 
				
			||||||
	defer t.maxStreamMu.Unlock()
 | 
						defer t.maxStreamMu.Unlock()
 | 
				
			||||||
@@ -373,6 +362,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
 | 
				
			|||||||
		st:               t,
 | 
							st:               t,
 | 
				
			||||||
		buf:              buf,
 | 
							buf:              buf,
 | 
				
			||||||
		fc:               &inFlow{limit: uint32(t.initialWindowSize)},
 | 
							fc:               &inFlow{limit: uint32(t.initialWindowSize)},
 | 
				
			||||||
 | 
							headerWireLength: int(frame.Header().Length),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		// if false, content-type was missing or invalid
 | 
							// if false, content-type was missing or invalid
 | 
				
			||||||
@@ -511,9 +501,9 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
 | 
				
			|||||||
		s.state = streamReadDone
 | 
							s.state = streamReadDone
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if timeoutSet {
 | 
						if timeoutSet {
 | 
				
			||||||
		s.ctx, s.cancel = context.WithTimeout(t.ctx, timeout)
 | 
							s.ctx, s.cancel = context.WithTimeout(ctx, timeout)
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		s.ctx, s.cancel = context.WithCancel(t.ctx)
 | 
							s.ctx, s.cancel = context.WithCancel(ctx)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Attach the received metadata to the context.
 | 
						// Attach the received metadata to the context.
 | 
				
			||||||
@@ -592,18 +582,6 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
 | 
				
			|||||||
	s.requestRead = func(n int) {
 | 
						s.requestRead = func(n int) {
 | 
				
			||||||
		t.adjustWindow(s, uint32(n))
 | 
							t.adjustWindow(s, uint32(n))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, sh := range t.stats {
 | 
					 | 
				
			||||||
		s.ctx = sh.TagRPC(s.ctx, &stats.RPCTagInfo{FullMethodName: s.method})
 | 
					 | 
				
			||||||
		inHeader := &stats.InHeader{
 | 
					 | 
				
			||||||
			FullMethod:  s.method,
 | 
					 | 
				
			||||||
			RemoteAddr:  t.remoteAddr,
 | 
					 | 
				
			||||||
			LocalAddr:   t.localAddr,
 | 
					 | 
				
			||||||
			Compression: s.recvCompress,
 | 
					 | 
				
			||||||
			WireLength:  int(frame.Header().Length),
 | 
					 | 
				
			||||||
			Header:      mdata.Copy(),
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		sh.HandleRPC(s.ctx, inHeader)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.ctxDone = s.ctx.Done()
 | 
						s.ctxDone = s.ctx.Done()
 | 
				
			||||||
	s.wq = newWriteQuota(defaultWriteQuota, s.ctxDone)
 | 
						s.wq = newWriteQuota(defaultWriteQuota, s.ctxDone)
 | 
				
			||||||
	s.trReader = &transportReader{
 | 
						s.trReader = &transportReader{
 | 
				
			||||||
@@ -629,8 +607,11 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
 | 
				
			|||||||
// HandleStreams receives incoming streams using the given handler. This is
 | 
					// HandleStreams receives incoming streams using the given handler. This is
 | 
				
			||||||
// typically run in a separate goroutine.
 | 
					// typically run in a separate goroutine.
 | 
				
			||||||
// traceCtx attaches trace to ctx and returns the new context.
 | 
					// traceCtx attaches trace to ctx and returns the new context.
 | 
				
			||||||
func (t *http2Server) HandleStreams(handle func(*Stream)) {
 | 
					func (t *http2Server) HandleStreams(ctx context.Context, handle func(*Stream)) {
 | 
				
			||||||
	defer close(t.readerDone)
 | 
						defer func() {
 | 
				
			||||||
 | 
							<-t.loopyWriterDone
 | 
				
			||||||
 | 
							close(t.readerDone)
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		t.controlBuf.throttle()
 | 
							t.controlBuf.throttle()
 | 
				
			||||||
		frame, err := t.framer.fr.ReadFrame()
 | 
							frame, err := t.framer.fr.ReadFrame()
 | 
				
			||||||
@@ -664,7 +645,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		switch frame := frame.(type) {
 | 
							switch frame := frame.(type) {
 | 
				
			||||||
		case *http2.MetaHeadersFrame:
 | 
							case *http2.MetaHeadersFrame:
 | 
				
			||||||
			if err := t.operateHeaders(frame, handle); err != nil {
 | 
								if err := t.operateHeaders(ctx, frame, handle); err != nil {
 | 
				
			||||||
				t.Close(err)
 | 
									t.Close(err)
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -1242,10 +1223,6 @@ func (t *http2Server) Close(err error) {
 | 
				
			|||||||
	for _, s := range streams {
 | 
						for _, s := range streams {
 | 
				
			||||||
		s.cancel()
 | 
							s.cancel()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, sh := range t.stats {
 | 
					 | 
				
			||||||
		connEnd := &stats.ConnEnd{}
 | 
					 | 
				
			||||||
		sh.HandleConn(t.ctx, connEnd)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// deleteStream deletes the stream s from transport's active streams.
 | 
					// deleteStream deletes the stream s from transport's active streams.
 | 
				
			||||||
@@ -1311,10 +1288,6 @@ func (t *http2Server) closeStream(s *Stream, rst bool, rstCode http2.ErrCode, eo
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t *http2Server) RemoteAddr() net.Addr {
 | 
					 | 
				
			||||||
	return t.remoteAddr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (t *http2Server) Drain(debugData string) {
 | 
					func (t *http2Server) Drain(debugData string) {
 | 
				
			||||||
	t.mu.Lock()
 | 
						t.mu.Lock()
 | 
				
			||||||
	defer t.mu.Unlock()
 | 
						defer t.mu.Unlock()
 | 
				
			||||||
@@ -1397,11 +1370,11 @@ func (t *http2Server) ChannelzMetric() *channelz.SocketInternalMetric {
 | 
				
			|||||||
		LastMessageReceivedTimestamp:     time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgRecvTime)),
 | 
							LastMessageReceivedTimestamp:     time.Unix(0, atomic.LoadInt64(&t.czData.lastMsgRecvTime)),
 | 
				
			||||||
		LocalFlowControlWindow:           int64(t.fc.getSize()),
 | 
							LocalFlowControlWindow:           int64(t.fc.getSize()),
 | 
				
			||||||
		SocketOptions:                    channelz.GetSocketOption(t.conn),
 | 
							SocketOptions:                    channelz.GetSocketOption(t.conn),
 | 
				
			||||||
		LocalAddr:                        t.localAddr,
 | 
							LocalAddr:                        t.peer.LocalAddr,
 | 
				
			||||||
		RemoteAddr:                       t.remoteAddr,
 | 
							RemoteAddr:                       t.peer.Addr,
 | 
				
			||||||
		// RemoteName :
 | 
							// RemoteName :
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if au, ok := t.authInfo.(credentials.ChannelzSecurityInfo); ok {
 | 
						if au, ok := t.peer.AuthInfo.(credentials.ChannelzSecurityInfo); ok {
 | 
				
			||||||
		s.Security = au.GetSecurityValue()
 | 
							s.Security = au.GetSecurityValue()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.RemoteFlowControlWindow = t.getOutFlowWindow()
 | 
						s.RemoteFlowControlWindow = t.getOutFlowWindow()
 | 
				
			||||||
@@ -1433,10 +1406,12 @@ func (t *http2Server) getOutFlowWindow() int64 {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t *http2Server) getPeer() *peer.Peer {
 | 
					// Peer returns the peer of the transport.
 | 
				
			||||||
 | 
					func (t *http2Server) Peer() *peer.Peer {
 | 
				
			||||||
	return &peer.Peer{
 | 
						return &peer.Peer{
 | 
				
			||||||
		Addr:     t.remoteAddr,
 | 
							Addr:      t.peer.Addr,
 | 
				
			||||||
		AuthInfo: t.authInfo, // Can be nil
 | 
							LocalAddr: t.peer.LocalAddr,
 | 
				
			||||||
 | 
							AuthInfo:  t.peer.AuthInfo, // Can be nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1461,6 +1436,6 @@ func GetConnection(ctx context.Context) net.Conn {
 | 
				
			|||||||
// SetConnection adds the connection to the context to be able to get
 | 
					// SetConnection adds the connection to the context to be able to get
 | 
				
			||||||
// information about the destination ip and port for an incoming RPC. This also
 | 
					// information about the destination ip and port for an incoming RPC. This also
 | 
				
			||||||
// allows any unary or streaming interceptors to see the connection.
 | 
					// allows any unary or streaming interceptors to see the connection.
 | 
				
			||||||
func setConnection(ctx context.Context, conn net.Conn) context.Context {
 | 
					func SetConnection(ctx context.Context, conn net.Conn) context.Context {
 | 
				
			||||||
	return context.WithValue(ctx, connectionKey{}, conn)
 | 
						return context.WithValue(ctx, connectionKey{}, conn)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								vendor/google.golang.org/grpc/internal/transport/proxy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/google.golang.org/grpc/internal/transport/proxy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -28,6 +28,8 @@ import (
 | 
				
			|||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"net/http/httputil"
 | 
						"net/http/httputil"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"google.golang.org/grpc/internal"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const proxyAuthHeaderKey = "Proxy-Authorization"
 | 
					const proxyAuthHeaderKey = "Proxy-Authorization"
 | 
				
			||||||
@@ -112,7 +114,7 @@ func doHTTPConnectHandshake(ctx context.Context, conn net.Conn, backendAddr stri
 | 
				
			|||||||
// proxyDial dials, connecting to a proxy first if necessary. Checks if a proxy
 | 
					// proxyDial dials, connecting to a proxy first if necessary. Checks if a proxy
 | 
				
			||||||
// is necessary, dials, does the HTTP CONNECT handshake, and returns the
 | 
					// is necessary, dials, does the HTTP CONNECT handshake, and returns the
 | 
				
			||||||
// connection.
 | 
					// connection.
 | 
				
			||||||
func proxyDial(ctx context.Context, addr string, grpcUA string) (conn net.Conn, err error) {
 | 
					func proxyDial(ctx context.Context, addr string, grpcUA string) (net.Conn, error) {
 | 
				
			||||||
	newAddr := addr
 | 
						newAddr := addr
 | 
				
			||||||
	proxyURL, err := mapAddress(addr)
 | 
						proxyURL, err := mapAddress(addr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -122,15 +124,15 @@ func proxyDial(ctx context.Context, addr string, grpcUA string) (conn net.Conn,
 | 
				
			|||||||
		newAddr = proxyURL.Host
 | 
							newAddr = proxyURL.Host
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	conn, err = (&net.Dialer{}).DialContext(ctx, "tcp", newAddr)
 | 
						conn, err := internal.NetDialerWithTCPKeepalive().DialContext(ctx, "tcp", newAddr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if proxyURL != nil {
 | 
						if proxyURL == nil {
 | 
				
			||||||
		// proxy is disabled if proxyURL is nil.
 | 
							// proxy is disabled if proxyURL is nil.
 | 
				
			||||||
		conn, err = doHTTPConnectHandshake(ctx, conn, addr, proxyURL, grpcUA)
 | 
							return conn, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return doHTTPConnectHandshake(ctx, conn, addr, proxyURL, grpcUA)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error {
 | 
					func sendHTTPRequest(ctx context.Context, req *http.Request, conn net.Conn) error {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								vendor/google.golang.org/grpc/internal/transport/transport.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/google.golang.org/grpc/internal/transport/transport.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -37,6 +37,7 @@ import (
 | 
				
			|||||||
	"google.golang.org/grpc/internal/channelz"
 | 
						"google.golang.org/grpc/internal/channelz"
 | 
				
			||||||
	"google.golang.org/grpc/keepalive"
 | 
						"google.golang.org/grpc/keepalive"
 | 
				
			||||||
	"google.golang.org/grpc/metadata"
 | 
						"google.golang.org/grpc/metadata"
 | 
				
			||||||
 | 
						"google.golang.org/grpc/peer"
 | 
				
			||||||
	"google.golang.org/grpc/resolver"
 | 
						"google.golang.org/grpc/resolver"
 | 
				
			||||||
	"google.golang.org/grpc/stats"
 | 
						"google.golang.org/grpc/stats"
 | 
				
			||||||
	"google.golang.org/grpc/status"
 | 
						"google.golang.org/grpc/status"
 | 
				
			||||||
@@ -266,6 +267,7 @@ type Stream struct {
 | 
				
			|||||||
	// meaningful after headerChan is closed (always call waitOnHeader() before
 | 
						// meaningful after headerChan is closed (always call waitOnHeader() before
 | 
				
			||||||
	// reading its value).  Not valid on server side.
 | 
						// reading its value).  Not valid on server side.
 | 
				
			||||||
	headerValid      bool
 | 
						headerValid      bool
 | 
				
			||||||
 | 
						headerWireLength int // Only set on server side.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// hdrMu protects header and trailer metadata on the server-side.
 | 
						// hdrMu protects header and trailer metadata on the server-side.
 | 
				
			||||||
	hdrMu sync.Mutex
 | 
						hdrMu sync.Mutex
 | 
				
			||||||
@@ -425,6 +427,12 @@ func (s *Stream) Context() context.Context {
 | 
				
			|||||||
	return s.ctx
 | 
						return s.ctx
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetContext sets the context of the stream. This will be deleted once the
 | 
				
			||||||
 | 
					// stats handler callouts all move to gRPC layer.
 | 
				
			||||||
 | 
					func (s *Stream) SetContext(ctx context.Context) {
 | 
				
			||||||
 | 
						s.ctx = ctx
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Method returns the method for the stream.
 | 
					// Method returns the method for the stream.
 | 
				
			||||||
func (s *Stream) Method() string {
 | 
					func (s *Stream) Method() string {
 | 
				
			||||||
	return s.method
 | 
						return s.method
 | 
				
			||||||
@@ -437,6 +445,12 @@ func (s *Stream) Status() *status.Status {
 | 
				
			|||||||
	return s.status
 | 
						return s.status
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// HeaderWireLength returns the size of the headers of the stream as received
 | 
				
			||||||
 | 
					// from the wire. Valid only on the server.
 | 
				
			||||||
 | 
					func (s *Stream) HeaderWireLength() int {
 | 
				
			||||||
 | 
						return s.headerWireLength
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetHeader sets the header metadata. This can be called multiple times.
 | 
					// SetHeader sets the header metadata. This can be called multiple times.
 | 
				
			||||||
// Server side only.
 | 
					// Server side only.
 | 
				
			||||||
// This should not be called in parallel to other data writes.
 | 
					// This should not be called in parallel to other data writes.
 | 
				
			||||||
@@ -698,7 +712,7 @@ type ClientTransport interface {
 | 
				
			|||||||
// Write methods for a given Stream will be called serially.
 | 
					// Write methods for a given Stream will be called serially.
 | 
				
			||||||
type ServerTransport interface {
 | 
					type ServerTransport interface {
 | 
				
			||||||
	// HandleStreams receives incoming streams using the given handler.
 | 
						// HandleStreams receives incoming streams using the given handler.
 | 
				
			||||||
	HandleStreams(func(*Stream))
 | 
						HandleStreams(context.Context, func(*Stream))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// WriteHeader sends the header metadata for the given stream.
 | 
						// WriteHeader sends the header metadata for the given stream.
 | 
				
			||||||
	// WriteHeader may not be called on all streams.
 | 
						// WriteHeader may not be called on all streams.
 | 
				
			||||||
@@ -717,8 +731,8 @@ type ServerTransport interface {
 | 
				
			|||||||
	// handlers will be terminated asynchronously.
 | 
						// handlers will be terminated asynchronously.
 | 
				
			||||||
	Close(err error)
 | 
						Close(err error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// RemoteAddr returns the remote network address.
 | 
						// Peer returns the peer of the server transport.
 | 
				
			||||||
	RemoteAddr() net.Addr
 | 
						Peer() *peer.Peer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Drain notifies the client this ServerTransport stops accepting new RPCs.
 | 
						// Drain notifies the client this ServerTransport stops accepting new RPCs.
 | 
				
			||||||
	Drain(debugData string)
 | 
						Drain(debugData string)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								vendor/google.golang.org/grpc/metadata/metadata.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/google.golang.org/grpc/metadata/metadata.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -153,14 +153,16 @@ func Join(mds ...MD) MD {
 | 
				
			|||||||
type mdIncomingKey struct{}
 | 
					type mdIncomingKey struct{}
 | 
				
			||||||
type mdOutgoingKey struct{}
 | 
					type mdOutgoingKey struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewIncomingContext creates a new context with incoming md attached.
 | 
					// NewIncomingContext creates a new context with incoming md attached. md must
 | 
				
			||||||
 | 
					// not be modified after calling this function.
 | 
				
			||||||
func NewIncomingContext(ctx context.Context, md MD) context.Context {
 | 
					func NewIncomingContext(ctx context.Context, md MD) context.Context {
 | 
				
			||||||
	return context.WithValue(ctx, mdIncomingKey{}, md)
 | 
						return context.WithValue(ctx, mdIncomingKey{}, md)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewOutgoingContext creates a new context with outgoing md attached. If used
 | 
					// NewOutgoingContext creates a new context with outgoing md attached. If used
 | 
				
			||||||
// in conjunction with AppendToOutgoingContext, NewOutgoingContext will
 | 
					// in conjunction with AppendToOutgoingContext, NewOutgoingContext will
 | 
				
			||||||
// overwrite any previously-appended metadata.
 | 
					// overwrite any previously-appended metadata. md must not be modified after
 | 
				
			||||||
 | 
					// calling this function.
 | 
				
			||||||
func NewOutgoingContext(ctx context.Context, md MD) context.Context {
 | 
					func NewOutgoingContext(ctx context.Context, md MD) context.Context {
 | 
				
			||||||
	return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md})
 | 
						return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -203,7 +205,8 @@ func FromIncomingContext(ctx context.Context) (MD, bool) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ValueFromIncomingContext returns the metadata value corresponding to the metadata
 | 
					// ValueFromIncomingContext returns the metadata value corresponding to the metadata
 | 
				
			||||||
// key from the incoming metadata if it exists. Key must be lower-case.
 | 
					// key from the incoming metadata if it exists. Keys are matched in a case insensitive
 | 
				
			||||||
 | 
					// manner.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// # Experimental
 | 
					// # Experimental
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@@ -219,17 +222,16 @@ func ValueFromIncomingContext(ctx context.Context, key string) []string {
 | 
				
			|||||||
		return copyOf(v)
 | 
							return copyOf(v)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for k, v := range md {
 | 
						for k, v := range md {
 | 
				
			||||||
		// We need to manually convert all keys to lower case, because MD is a
 | 
							// Case insenitive comparison: MD is a map, and there's no guarantee
 | 
				
			||||||
		// map, and there's no guarantee that the MD attached to the context is
 | 
							// that the MD attached to the context is created using our helper
 | 
				
			||||||
		// created using our helper functions.
 | 
							// functions.
 | 
				
			||||||
		if strings.ToLower(k) == key {
 | 
							if strings.EqualFold(k, key) {
 | 
				
			||||||
			return copyOf(v)
 | 
								return copyOf(v)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// the returned slice must not be modified in place
 | 
					 | 
				
			||||||
func copyOf(v []string) []string {
 | 
					func copyOf(v []string) []string {
 | 
				
			||||||
	vals := make([]string, len(v))
 | 
						vals := make([]string, len(v))
 | 
				
			||||||
	copy(vals, v)
 | 
						copy(vals, v)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/google.golang.org/grpc/peer/peer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/google.golang.org/grpc/peer/peer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -32,6 +32,8 @@ import (
 | 
				
			|||||||
type Peer struct {
 | 
					type Peer struct {
 | 
				
			||||||
	// Addr is the peer address.
 | 
						// Addr is the peer address.
 | 
				
			||||||
	Addr net.Addr
 | 
						Addr net.Addr
 | 
				
			||||||
 | 
						// LocalAddr is the local address.
 | 
				
			||||||
 | 
						LocalAddr net.Addr
 | 
				
			||||||
	// AuthInfo is the authentication information of the transport.
 | 
						// AuthInfo is the authentication information of the transport.
 | 
				
			||||||
	// It is nil if there is no transport security being used.
 | 
						// It is nil if there is no transport security being used.
 | 
				
			||||||
	AuthInfo credentials.AuthInfo
 | 
						AuthInfo credentials.AuthInfo
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								vendor/google.golang.org/grpc/picker_wrapper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/google.golang.org/grpc/picker_wrapper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -37,7 +37,6 @@ import (
 | 
				
			|||||||
type pickerWrapper struct {
 | 
					type pickerWrapper struct {
 | 
				
			||||||
	mu            sync.Mutex
 | 
						mu            sync.Mutex
 | 
				
			||||||
	done          bool
 | 
						done          bool
 | 
				
			||||||
	idle          bool
 | 
					 | 
				
			||||||
	blockingCh    chan struct{}
 | 
						blockingCh    chan struct{}
 | 
				
			||||||
	picker        balancer.Picker
 | 
						picker        balancer.Picker
 | 
				
			||||||
	statsHandlers []stats.Handler // to record blocking picker calls
 | 
						statsHandlers []stats.Handler // to record blocking picker calls
 | 
				
			||||||
@@ -53,11 +52,7 @@ func newPickerWrapper(statsHandlers []stats.Handler) *pickerWrapper {
 | 
				
			|||||||
// updatePicker is called by UpdateBalancerState. It unblocks all blocked pick.
 | 
					// updatePicker is called by UpdateBalancerState. It unblocks all blocked pick.
 | 
				
			||||||
func (pw *pickerWrapper) updatePicker(p balancer.Picker) {
 | 
					func (pw *pickerWrapper) updatePicker(p balancer.Picker) {
 | 
				
			||||||
	pw.mu.Lock()
 | 
						pw.mu.Lock()
 | 
				
			||||||
	if pw.done || pw.idle {
 | 
						if pw.done {
 | 
				
			||||||
		// There is a small window where a picker update from the LB policy can
 | 
					 | 
				
			||||||
		// race with the channel going to idle mode. If the picker is idle here,
 | 
					 | 
				
			||||||
		// it is because the channel asked it to do so, and therefore it is sage
 | 
					 | 
				
			||||||
		// to ignore the update from the LB policy.
 | 
					 | 
				
			||||||
		pw.mu.Unlock()
 | 
							pw.mu.Unlock()
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -210,23 +205,15 @@ func (pw *pickerWrapper) close() {
 | 
				
			|||||||
	close(pw.blockingCh)
 | 
						close(pw.blockingCh)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (pw *pickerWrapper) enterIdleMode() {
 | 
					// reset clears the pickerWrapper and prepares it for being used again when idle
 | 
				
			||||||
	pw.mu.Lock()
 | 
					// mode is exited.
 | 
				
			||||||
	defer pw.mu.Unlock()
 | 
					func (pw *pickerWrapper) reset() {
 | 
				
			||||||
	if pw.done {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pw.idle = true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (pw *pickerWrapper) exitIdleMode() {
 | 
					 | 
				
			||||||
	pw.mu.Lock()
 | 
						pw.mu.Lock()
 | 
				
			||||||
	defer pw.mu.Unlock()
 | 
						defer pw.mu.Unlock()
 | 
				
			||||||
	if pw.done {
 | 
						if pw.done {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pw.blockingCh = make(chan struct{})
 | 
						pw.blockingCh = make(chan struct{})
 | 
				
			||||||
	pw.idle = false
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// dropError is a wrapper error that indicates the LB policy wishes to drop the
 | 
					// dropError is a wrapper error that indicates the LB policy wishes to drop the
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								vendor/google.golang.org/grpc/pickfirst.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/google.golang.org/grpc/pickfirst.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -25,7 +25,6 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"google.golang.org/grpc/balancer"
 | 
						"google.golang.org/grpc/balancer"
 | 
				
			||||||
	"google.golang.org/grpc/connectivity"
 | 
						"google.golang.org/grpc/connectivity"
 | 
				
			||||||
	"google.golang.org/grpc/internal/envconfig"
 | 
					 | 
				
			||||||
	internalgrpclog "google.golang.org/grpc/internal/grpclog"
 | 
						internalgrpclog "google.golang.org/grpc/internal/grpclog"
 | 
				
			||||||
	"google.golang.org/grpc/internal/grpcrand"
 | 
						"google.golang.org/grpc/internal/grpcrand"
 | 
				
			||||||
	"google.golang.org/grpc/internal/pretty"
 | 
						"google.golang.org/grpc/internal/pretty"
 | 
				
			||||||
@@ -65,19 +64,6 @@ type pfConfig struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (*pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {
 | 
					func (*pickfirstBuilder) ParseConfig(js json.RawMessage) (serviceconfig.LoadBalancingConfig, error) {
 | 
				
			||||||
	if !envconfig.PickFirstLBConfig {
 | 
					 | 
				
			||||||
		// Prior to supporting loadbalancing configuration, the pick_first LB
 | 
					 | 
				
			||||||
		// policy did not implement the balancer.ConfigParser interface. This
 | 
					 | 
				
			||||||
		// meant that if a non-empty configuration was passed to it, the service
 | 
					 | 
				
			||||||
		// config unmarshaling code would throw a warning log, but would
 | 
					 | 
				
			||||||
		// continue using the pick_first LB policy. The code below ensures the
 | 
					 | 
				
			||||||
		// same behavior is retained if the env var is not set.
 | 
					 | 
				
			||||||
		if string(js) != "{}" {
 | 
					 | 
				
			||||||
			logger.Warningf("Ignoring non-empty balancer configuration %q for the pick_first LB policy", string(js))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return nil, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var cfg pfConfig
 | 
						var cfg pfConfig
 | 
				
			||||||
	if err := json.Unmarshal(js, &cfg); err != nil {
 | 
						if err := json.Unmarshal(js, &cfg); err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("pickfirst: unable to unmarshal LB policy config: %s, error: %v", string(js), err)
 | 
							return nil, fmt.Errorf("pickfirst: unable to unmarshal LB policy config: %s, error: %v", string(js), err)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										36
									
								
								vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2018 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 dns implements a dns resolver to be installed as the default resolver
 | 
				
			||||||
 | 
					// in grpc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Deprecated: this package is imported by grpc and should not need to be
 | 
				
			||||||
 | 
					// imported directly by users.
 | 
				
			||||||
 | 
					package dns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"google.golang.org/grpc/internal/resolver/dns"
 | 
				
			||||||
 | 
						"google.golang.org/grpc/resolver"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewBuilder creates a dnsBuilder which is used to factory DNS resolvers.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Deprecated: import grpc and use resolver.Get("dns") instead.
 | 
				
			||||||
 | 
					func NewBuilder() resolver.Builder {
 | 
				
			||||||
 | 
						return dns.NewBuilder()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										113
									
								
								vendor/google.golang.org/grpc/resolver/map.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										113
									
								
								vendor/google.golang.org/grpc/resolver/map.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -136,3 +136,116 @@ func (a *AddressMap) Values() []any {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return ret
 | 
						return ret
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type endpointNode struct {
 | 
				
			||||||
 | 
						addrs map[string]struct{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Equal returns whether the unordered set of addrs are the same between the
 | 
				
			||||||
 | 
					// endpoint nodes.
 | 
				
			||||||
 | 
					func (en *endpointNode) Equal(en2 *endpointNode) bool {
 | 
				
			||||||
 | 
						if len(en.addrs) != len(en2.addrs) {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for addr := range en.addrs {
 | 
				
			||||||
 | 
							if _, ok := en2.addrs[addr]; !ok {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func toEndpointNode(endpoint Endpoint) endpointNode {
 | 
				
			||||||
 | 
						en := make(map[string]struct{})
 | 
				
			||||||
 | 
						for _, addr := range endpoint.Addresses {
 | 
				
			||||||
 | 
							en[addr.Addr] = struct{}{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return endpointNode{
 | 
				
			||||||
 | 
							addrs: en,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// EndpointMap is a map of endpoints to arbitrary values keyed on only the
 | 
				
			||||||
 | 
					// unordered set of address strings within an endpoint. This map is not thread
 | 
				
			||||||
 | 
					// safe, thus it is unsafe to access concurrently. Must be created via
 | 
				
			||||||
 | 
					// NewEndpointMap; do not construct directly.
 | 
				
			||||||
 | 
					type EndpointMap struct {
 | 
				
			||||||
 | 
						endpoints map[*endpointNode]any
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewEndpointMap creates a new EndpointMap.
 | 
				
			||||||
 | 
					func NewEndpointMap() *EndpointMap {
 | 
				
			||||||
 | 
						return &EndpointMap{
 | 
				
			||||||
 | 
							endpoints: make(map[*endpointNode]any),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get returns the value for the address in the map, if present.
 | 
				
			||||||
 | 
					func (em *EndpointMap) Get(e Endpoint) (value any, ok bool) {
 | 
				
			||||||
 | 
						en := toEndpointNode(e)
 | 
				
			||||||
 | 
						if endpoint := em.find(en); endpoint != nil {
 | 
				
			||||||
 | 
							return em.endpoints[endpoint], true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil, false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Set updates or adds the value to the address in the map.
 | 
				
			||||||
 | 
					func (em *EndpointMap) Set(e Endpoint, value any) {
 | 
				
			||||||
 | 
						en := toEndpointNode(e)
 | 
				
			||||||
 | 
						if endpoint := em.find(en); endpoint != nil {
 | 
				
			||||||
 | 
							em.endpoints[endpoint] = value
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						em.endpoints[&en] = value
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Len returns the number of entries in the map.
 | 
				
			||||||
 | 
					func (em *EndpointMap) Len() int {
 | 
				
			||||||
 | 
						return len(em.endpoints)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Keys returns a slice of all current map keys, as endpoints specifying the
 | 
				
			||||||
 | 
					// addresses present in the endpoint keys, in which uniqueness is determined by
 | 
				
			||||||
 | 
					// the unordered set of addresses. Thus, endpoint information returned is not
 | 
				
			||||||
 | 
					// the full endpoint data (drops duplicated addresses and attributes) but can be
 | 
				
			||||||
 | 
					// used for EndpointMap accesses.
 | 
				
			||||||
 | 
					func (em *EndpointMap) Keys() []Endpoint {
 | 
				
			||||||
 | 
						ret := make([]Endpoint, 0, len(em.endpoints))
 | 
				
			||||||
 | 
						for en := range em.endpoints {
 | 
				
			||||||
 | 
							var endpoint Endpoint
 | 
				
			||||||
 | 
							for addr := range en.addrs {
 | 
				
			||||||
 | 
								endpoint.Addresses = append(endpoint.Addresses, Address{Addr: addr})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ret = append(ret, endpoint)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Values returns a slice of all current map values.
 | 
				
			||||||
 | 
					func (em *EndpointMap) Values() []any {
 | 
				
			||||||
 | 
						ret := make([]any, 0, len(em.endpoints))
 | 
				
			||||||
 | 
						for _, val := range em.endpoints {
 | 
				
			||||||
 | 
							ret = append(ret, val)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// find returns a pointer to the endpoint node in em if the endpoint node is
 | 
				
			||||||
 | 
					// already present. If not found, nil is returned. The comparisons are done on
 | 
				
			||||||
 | 
					// the unordered set of addresses within an endpoint.
 | 
				
			||||||
 | 
					func (em EndpointMap) find(e endpointNode) *endpointNode {
 | 
				
			||||||
 | 
						for endpoint := range em.endpoints {
 | 
				
			||||||
 | 
							if e.Equal(endpoint) {
 | 
				
			||||||
 | 
								return endpoint
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Delete removes the specified endpoint from the map.
 | 
				
			||||||
 | 
					func (em *EndpointMap) Delete(e Endpoint) {
 | 
				
			||||||
 | 
						en := toEndpointNode(e)
 | 
				
			||||||
 | 
						if entry := em.find(en); entry != nil {
 | 
				
			||||||
 | 
							delete(em.endpoints, entry)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								vendor/google.golang.org/grpc/resolver/resolver.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/google.golang.org/grpc/resolver/resolver.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -240,11 +240,6 @@ type ClientConn interface {
 | 
				
			|||||||
	//
 | 
						//
 | 
				
			||||||
	// Deprecated: Use UpdateState instead.
 | 
						// Deprecated: Use UpdateState instead.
 | 
				
			||||||
	NewAddress(addresses []Address)
 | 
						NewAddress(addresses []Address)
 | 
				
			||||||
	// NewServiceConfig is called by resolver to notify ClientConn a new
 | 
					 | 
				
			||||||
	// service config. The service config should be provided as a json string.
 | 
					 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	// Deprecated: Use UpdateState instead.
 | 
					 | 
				
			||||||
	NewServiceConfig(serviceConfig string)
 | 
					 | 
				
			||||||
	// ParseServiceConfig parses the provided service config and returns an
 | 
						// ParseServiceConfig parses the provided service config and returns an
 | 
				
			||||||
	// object that provides the parsed config.
 | 
						// object that provides the parsed config.
 | 
				
			||||||
	ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult
 | 
						ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult
 | 
				
			||||||
@@ -286,6 +281,11 @@ func (t Target) Endpoint() string {
 | 
				
			|||||||
	return strings.TrimPrefix(endpoint, "/")
 | 
						return strings.TrimPrefix(endpoint, "/")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String returns a string representation of Target.
 | 
				
			||||||
 | 
					func (t Target) String() string {
 | 
				
			||||||
 | 
						return t.URL.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Builder creates a resolver that will be used to watch name resolution updates.
 | 
					// Builder creates a resolver that will be used to watch name resolution updates.
 | 
				
			||||||
type Builder interface {
 | 
					type Builder interface {
 | 
				
			||||||
	// Build creates a new resolver for the given target.
 | 
						// Build creates a new resolver for the given target.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										247
									
								
								vendor/google.golang.org/grpc/resolver_conn_wrapper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										247
									
								
								vendor/google.golang.org/grpc/resolver_conn_wrapper.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,247 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Copyright 2017 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 grpc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/balancer"
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/internal/channelz"
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/internal/grpcsync"
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/internal/pretty"
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/resolver"
 | 
					 | 
				
			||||||
	"google.golang.org/grpc/serviceconfig"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// resolverStateUpdater wraps the single method used by ccResolverWrapper to
 | 
					 | 
				
			||||||
// report a state update from the actual resolver implementation.
 | 
					 | 
				
			||||||
type resolverStateUpdater interface {
 | 
					 | 
				
			||||||
	updateResolverState(s resolver.State, err error) error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ccResolverWrapper is a wrapper on top of cc for resolvers.
 | 
					 | 
				
			||||||
// It implements resolver.ClientConn interface.
 | 
					 | 
				
			||||||
type ccResolverWrapper struct {
 | 
					 | 
				
			||||||
	// The following fields are initialized when the wrapper is created and are
 | 
					 | 
				
			||||||
	// read-only afterwards, and therefore can be accessed without a mutex.
 | 
					 | 
				
			||||||
	cc                  resolverStateUpdater
 | 
					 | 
				
			||||||
	channelzID          *channelz.Identifier
 | 
					 | 
				
			||||||
	ignoreServiceConfig bool
 | 
					 | 
				
			||||||
	opts                ccResolverWrapperOpts
 | 
					 | 
				
			||||||
	serializer          *grpcsync.CallbackSerializer // To serialize all incoming calls.
 | 
					 | 
				
			||||||
	serializerCancel    context.CancelFunc           // To close the serializer, accessed only from close().
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// All incoming (resolver --> gRPC) calls are guaranteed to execute in a
 | 
					 | 
				
			||||||
	// mutually exclusive manner as they are scheduled on the serializer.
 | 
					 | 
				
			||||||
	// Fields accessed *only* in these serializer callbacks, can therefore be
 | 
					 | 
				
			||||||
	// accessed without a mutex.
 | 
					 | 
				
			||||||
	curState resolver.State
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// mu guards access to the below fields.
 | 
					 | 
				
			||||||
	mu       sync.Mutex
 | 
					 | 
				
			||||||
	closed   bool
 | 
					 | 
				
			||||||
	resolver resolver.Resolver // Accessed only from outgoing calls.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ccResolverWrapperOpts wraps the arguments to be passed when creating a new
 | 
					 | 
				
			||||||
// ccResolverWrapper.
 | 
					 | 
				
			||||||
type ccResolverWrapperOpts struct {
 | 
					 | 
				
			||||||
	target     resolver.Target       // User specified dial target to resolve.
 | 
					 | 
				
			||||||
	builder    resolver.Builder      // Resolver builder to use.
 | 
					 | 
				
			||||||
	bOpts      resolver.BuildOptions // Resolver build options to use.
 | 
					 | 
				
			||||||
	channelzID *channelz.Identifier  // Channelz identifier for the channel.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// newCCResolverWrapper uses the resolver.Builder to build a Resolver and
 | 
					 | 
				
			||||||
// returns a ccResolverWrapper object which wraps the newly built resolver.
 | 
					 | 
				
			||||||
func newCCResolverWrapper(cc resolverStateUpdater, opts ccResolverWrapperOpts) (*ccResolverWrapper, error) {
 | 
					 | 
				
			||||||
	ctx, cancel := context.WithCancel(context.Background())
 | 
					 | 
				
			||||||
	ccr := &ccResolverWrapper{
 | 
					 | 
				
			||||||
		cc:                  cc,
 | 
					 | 
				
			||||||
		channelzID:          opts.channelzID,
 | 
					 | 
				
			||||||
		ignoreServiceConfig: opts.bOpts.DisableServiceConfig,
 | 
					 | 
				
			||||||
		opts:                opts,
 | 
					 | 
				
			||||||
		serializer:          grpcsync.NewCallbackSerializer(ctx),
 | 
					 | 
				
			||||||
		serializerCancel:    cancel,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Cannot hold the lock at build time because the resolver can send an
 | 
					 | 
				
			||||||
	// update or error inline and these incoming calls grab the lock to schedule
 | 
					 | 
				
			||||||
	// a callback in the serializer.
 | 
					 | 
				
			||||||
	r, err := opts.builder.Build(opts.target, ccr, opts.bOpts)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		cancel()
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Any error reported by the resolver at build time that leads to a
 | 
					 | 
				
			||||||
	// re-resolution request from the balancer is dropped by grpc until we
 | 
					 | 
				
			||||||
	// return from this function. So, we don't have to handle pending resolveNow
 | 
					 | 
				
			||||||
	// requests here.
 | 
					 | 
				
			||||||
	ccr.mu.Lock()
 | 
					 | 
				
			||||||
	ccr.resolver = r
 | 
					 | 
				
			||||||
	ccr.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return ccr, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOptions) {
 | 
					 | 
				
			||||||
	ccr.mu.Lock()
 | 
					 | 
				
			||||||
	defer ccr.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// ccr.resolver field is set only after the call to Build() returns. But in
 | 
					 | 
				
			||||||
	// the process of building, the resolver may send an error update which when
 | 
					 | 
				
			||||||
	// propagated to the balancer may result in a re-resolution request.
 | 
					 | 
				
			||||||
	if ccr.closed || ccr.resolver == nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ccr.resolver.ResolveNow(o)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ccr *ccResolverWrapper) close() {
 | 
					 | 
				
			||||||
	ccr.mu.Lock()
 | 
					 | 
				
			||||||
	if ccr.closed {
 | 
					 | 
				
			||||||
		ccr.mu.Unlock()
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	channelz.Info(logger, ccr.channelzID, "Closing the name resolver")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Close the serializer to ensure that no more calls from the resolver are
 | 
					 | 
				
			||||||
	// handled, before actually closing the resolver.
 | 
					 | 
				
			||||||
	ccr.serializerCancel()
 | 
					 | 
				
			||||||
	ccr.closed = true
 | 
					 | 
				
			||||||
	r := ccr.resolver
 | 
					 | 
				
			||||||
	ccr.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Give enqueued callbacks a chance to finish.
 | 
					 | 
				
			||||||
	<-ccr.serializer.Done()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Spawn a goroutine to close the resolver (since it may block trying to
 | 
					 | 
				
			||||||
	// cleanup all allocated resources) and return early.
 | 
					 | 
				
			||||||
	go r.Close()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// serializerScheduleLocked is a convenience method to schedule a function to be
 | 
					 | 
				
			||||||
// run on the serializer while holding ccr.mu.
 | 
					 | 
				
			||||||
func (ccr *ccResolverWrapper) serializerScheduleLocked(f func(context.Context)) {
 | 
					 | 
				
			||||||
	ccr.mu.Lock()
 | 
					 | 
				
			||||||
	ccr.serializer.Schedule(f)
 | 
					 | 
				
			||||||
	ccr.mu.Unlock()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UpdateState is called by resolver implementations to report new state to gRPC
 | 
					 | 
				
			||||||
// which includes addresses and service config.
 | 
					 | 
				
			||||||
func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error {
 | 
					 | 
				
			||||||
	errCh := make(chan error, 1)
 | 
					 | 
				
			||||||
	if s.Endpoints == nil {
 | 
					 | 
				
			||||||
		s.Endpoints = make([]resolver.Endpoint, 0, len(s.Addresses))
 | 
					 | 
				
			||||||
		for _, a := range s.Addresses {
 | 
					 | 
				
			||||||
			ep := resolver.Endpoint{Addresses: []resolver.Address{a}, Attributes: a.BalancerAttributes}
 | 
					 | 
				
			||||||
			ep.Addresses[0].BalancerAttributes = nil
 | 
					 | 
				
			||||||
			s.Endpoints = append(s.Endpoints, ep)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	ok := ccr.serializer.Schedule(func(context.Context) {
 | 
					 | 
				
			||||||
		ccr.addChannelzTraceEvent(s)
 | 
					 | 
				
			||||||
		ccr.curState = s
 | 
					 | 
				
			||||||
		if err := ccr.cc.updateResolverState(ccr.curState, nil); err == balancer.ErrBadResolverState {
 | 
					 | 
				
			||||||
			errCh <- balancer.ErrBadResolverState
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		errCh <- nil
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		// The only time when Schedule() fail to add the callback to the
 | 
					 | 
				
			||||||
		// serializer is when the serializer is closed, and this happens only
 | 
					 | 
				
			||||||
		// when the resolver wrapper is closed.
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return <-errCh
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ReportError is called by resolver implementations to report errors
 | 
					 | 
				
			||||||
// encountered during name resolution to gRPC.
 | 
					 | 
				
			||||||
func (ccr *ccResolverWrapper) ReportError(err error) {
 | 
					 | 
				
			||||||
	ccr.serializerScheduleLocked(func(_ context.Context) {
 | 
					 | 
				
			||||||
		channelz.Warningf(logger, ccr.channelzID, "ccResolverWrapper: reporting error to cc: %v", err)
 | 
					 | 
				
			||||||
		ccr.cc.updateResolverState(resolver.State{}, err)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewAddress is called by the resolver implementation to send addresses to
 | 
					 | 
				
			||||||
// gRPC.
 | 
					 | 
				
			||||||
func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
 | 
					 | 
				
			||||||
	ccr.serializerScheduleLocked(func(_ context.Context) {
 | 
					 | 
				
			||||||
		ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig})
 | 
					 | 
				
			||||||
		ccr.curState.Addresses = addrs
 | 
					 | 
				
			||||||
		ccr.cc.updateResolverState(ccr.curState, nil)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewServiceConfig is called by the resolver implementation to send service
 | 
					 | 
				
			||||||
// configs to gRPC.
 | 
					 | 
				
			||||||
func (ccr *ccResolverWrapper) NewServiceConfig(sc string) {
 | 
					 | 
				
			||||||
	ccr.serializerScheduleLocked(func(_ context.Context) {
 | 
					 | 
				
			||||||
		channelz.Infof(logger, ccr.channelzID, "ccResolverWrapper: got new service config: %s", sc)
 | 
					 | 
				
			||||||
		if ccr.ignoreServiceConfig {
 | 
					 | 
				
			||||||
			channelz.Info(logger, ccr.channelzID, "Service config lookups disabled; ignoring config")
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		scpr := parseServiceConfig(sc)
 | 
					 | 
				
			||||||
		if scpr.Err != nil {
 | 
					 | 
				
			||||||
			channelz.Warningf(logger, ccr.channelzID, "ccResolverWrapper: error parsing service config: %v", scpr.Err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		ccr.addChannelzTraceEvent(resolver.State{Addresses: ccr.curState.Addresses, ServiceConfig: scpr})
 | 
					 | 
				
			||||||
		ccr.curState.ServiceConfig = scpr
 | 
					 | 
				
			||||||
		ccr.cc.updateResolverState(ccr.curState, nil)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ParseServiceConfig is called by resolver implementations to parse a JSON
 | 
					 | 
				
			||||||
// representation of the service config.
 | 
					 | 
				
			||||||
func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.ParseResult {
 | 
					 | 
				
			||||||
	return parseServiceConfig(scJSON)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// addChannelzTraceEvent adds a channelz trace event containing the new
 | 
					 | 
				
			||||||
// state received from resolver implementations.
 | 
					 | 
				
			||||||
func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) {
 | 
					 | 
				
			||||||
	var updates []string
 | 
					 | 
				
			||||||
	var oldSC, newSC *ServiceConfig
 | 
					 | 
				
			||||||
	var oldOK, newOK bool
 | 
					 | 
				
			||||||
	if ccr.curState.ServiceConfig != nil {
 | 
					 | 
				
			||||||
		oldSC, oldOK = ccr.curState.ServiceConfig.Config.(*ServiceConfig)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if s.ServiceConfig != nil {
 | 
					 | 
				
			||||||
		newSC, newOK = s.ServiceConfig.Config.(*ServiceConfig)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if oldOK != newOK || (oldOK && newOK && oldSC.rawJSONString != newSC.rawJSONString) {
 | 
					 | 
				
			||||||
		updates = append(updates, "service config updated")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(ccr.curState.Addresses) > 0 && len(s.Addresses) == 0 {
 | 
					 | 
				
			||||||
		updates = append(updates, "resolver returned an empty address list")
 | 
					 | 
				
			||||||
	} else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 {
 | 
					 | 
				
			||||||
		updates = append(updates, "resolver returned new addresses")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	channelz.Infof(logger, ccr.channelzID, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; "))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										197
									
								
								vendor/google.golang.org/grpc/resolver_wrapper.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								vendor/google.golang.org/grpc/resolver_wrapper.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright 2017 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 grpc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"google.golang.org/grpc/internal/channelz"
 | 
				
			||||||
 | 
						"google.golang.org/grpc/internal/grpcsync"
 | 
				
			||||||
 | 
						"google.golang.org/grpc/internal/pretty"
 | 
				
			||||||
 | 
						"google.golang.org/grpc/resolver"
 | 
				
			||||||
 | 
						"google.golang.org/grpc/serviceconfig"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ccResolverWrapper is a wrapper on top of cc for resolvers.
 | 
				
			||||||
 | 
					// It implements resolver.ClientConn interface.
 | 
				
			||||||
 | 
					type ccResolverWrapper struct {
 | 
				
			||||||
 | 
						// The following fields are initialized when the wrapper is created and are
 | 
				
			||||||
 | 
						// read-only afterwards, and therefore can be accessed without a mutex.
 | 
				
			||||||
 | 
						cc                  *ClientConn
 | 
				
			||||||
 | 
						ignoreServiceConfig bool
 | 
				
			||||||
 | 
						serializer          *grpcsync.CallbackSerializer
 | 
				
			||||||
 | 
						serializerCancel    context.CancelFunc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resolver resolver.Resolver // only accessed within the serializer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The following fields are protected by mu.  Caller must take cc.mu before
 | 
				
			||||||
 | 
						// taking mu.
 | 
				
			||||||
 | 
						mu       sync.Mutex
 | 
				
			||||||
 | 
						curState resolver.State
 | 
				
			||||||
 | 
						closed   bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// newCCResolverWrapper initializes the ccResolverWrapper.  It can only be used
 | 
				
			||||||
 | 
					// after calling start, which builds the resolver.
 | 
				
			||||||
 | 
					func newCCResolverWrapper(cc *ClientConn) *ccResolverWrapper {
 | 
				
			||||||
 | 
						ctx, cancel := context.WithCancel(cc.ctx)
 | 
				
			||||||
 | 
						return &ccResolverWrapper{
 | 
				
			||||||
 | 
							cc:                  cc,
 | 
				
			||||||
 | 
							ignoreServiceConfig: cc.dopts.disableServiceConfig,
 | 
				
			||||||
 | 
							serializer:          grpcsync.NewCallbackSerializer(ctx),
 | 
				
			||||||
 | 
							serializerCancel:    cancel,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// start builds the name resolver using the resolver.Builder in cc and returns
 | 
				
			||||||
 | 
					// any error encountered.  It must always be the first operation performed on
 | 
				
			||||||
 | 
					// any newly created ccResolverWrapper, except that close may be called instead.
 | 
				
			||||||
 | 
					func (ccr *ccResolverWrapper) start() error {
 | 
				
			||||||
 | 
						errCh := make(chan error)
 | 
				
			||||||
 | 
						ccr.serializer.Schedule(func(ctx context.Context) {
 | 
				
			||||||
 | 
							if ctx.Err() != nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							opts := resolver.BuildOptions{
 | 
				
			||||||
 | 
								DisableServiceConfig: ccr.cc.dopts.disableServiceConfig,
 | 
				
			||||||
 | 
								DialCreds:            ccr.cc.dopts.copts.TransportCredentials,
 | 
				
			||||||
 | 
								CredsBundle:          ccr.cc.dopts.copts.CredsBundle,
 | 
				
			||||||
 | 
								Dialer:               ccr.cc.dopts.copts.Dialer,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							var err error
 | 
				
			||||||
 | 
							ccr.resolver, err = ccr.cc.resolverBuilder.Build(ccr.cc.parsedTarget, ccr, opts)
 | 
				
			||||||
 | 
							errCh <- err
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						return <-errCh
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ccr *ccResolverWrapper) resolveNow(o resolver.ResolveNowOptions) {
 | 
				
			||||||
 | 
						ccr.serializer.Schedule(func(ctx context.Context) {
 | 
				
			||||||
 | 
							if ctx.Err() != nil || ccr.resolver == nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ccr.resolver.ResolveNow(o)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// close initiates async shutdown of the wrapper.  To determine the wrapper has
 | 
				
			||||||
 | 
					// finished shutting down, the channel should block on ccr.serializer.Done()
 | 
				
			||||||
 | 
					// without cc.mu held.
 | 
				
			||||||
 | 
					func (ccr *ccResolverWrapper) close() {
 | 
				
			||||||
 | 
						channelz.Info(logger, ccr.cc.channelzID, "Closing the name resolver")
 | 
				
			||||||
 | 
						ccr.mu.Lock()
 | 
				
			||||||
 | 
						ccr.closed = true
 | 
				
			||||||
 | 
						ccr.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ccr.serializer.Schedule(func(context.Context) {
 | 
				
			||||||
 | 
							if ccr.resolver == nil {
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ccr.resolver.Close()
 | 
				
			||||||
 | 
							ccr.resolver = nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						ccr.serializerCancel()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UpdateState is called by resolver implementations to report new state to gRPC
 | 
				
			||||||
 | 
					// which includes addresses and service config.
 | 
				
			||||||
 | 
					func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error {
 | 
				
			||||||
 | 
						ccr.cc.mu.Lock()
 | 
				
			||||||
 | 
						ccr.mu.Lock()
 | 
				
			||||||
 | 
						if ccr.closed {
 | 
				
			||||||
 | 
							ccr.mu.Unlock()
 | 
				
			||||||
 | 
							ccr.cc.mu.Unlock()
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if s.Endpoints == nil {
 | 
				
			||||||
 | 
							s.Endpoints = make([]resolver.Endpoint, 0, len(s.Addresses))
 | 
				
			||||||
 | 
							for _, a := range s.Addresses {
 | 
				
			||||||
 | 
								ep := resolver.Endpoint{Addresses: []resolver.Address{a}, Attributes: a.BalancerAttributes}
 | 
				
			||||||
 | 
								ep.Addresses[0].BalancerAttributes = nil
 | 
				
			||||||
 | 
								s.Endpoints = append(s.Endpoints, ep)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ccr.addChannelzTraceEvent(s)
 | 
				
			||||||
 | 
						ccr.curState = s
 | 
				
			||||||
 | 
						ccr.mu.Unlock()
 | 
				
			||||||
 | 
						return ccr.cc.updateResolverStateAndUnlock(s, nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ReportError is called by resolver implementations to report errors
 | 
				
			||||||
 | 
					// encountered during name resolution to gRPC.
 | 
				
			||||||
 | 
					func (ccr *ccResolverWrapper) ReportError(err error) {
 | 
				
			||||||
 | 
						ccr.cc.mu.Lock()
 | 
				
			||||||
 | 
						ccr.mu.Lock()
 | 
				
			||||||
 | 
						if ccr.closed {
 | 
				
			||||||
 | 
							ccr.mu.Unlock()
 | 
				
			||||||
 | 
							ccr.cc.mu.Unlock()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ccr.mu.Unlock()
 | 
				
			||||||
 | 
						channelz.Warningf(logger, ccr.cc.channelzID, "ccResolverWrapper: reporting error to cc: %v", err)
 | 
				
			||||||
 | 
						ccr.cc.updateResolverStateAndUnlock(resolver.State{}, err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewAddress is called by the resolver implementation to send addresses to
 | 
				
			||||||
 | 
					// gRPC.
 | 
				
			||||||
 | 
					func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
 | 
				
			||||||
 | 
						ccr.cc.mu.Lock()
 | 
				
			||||||
 | 
						ccr.mu.Lock()
 | 
				
			||||||
 | 
						if ccr.closed {
 | 
				
			||||||
 | 
							ccr.mu.Unlock()
 | 
				
			||||||
 | 
							ccr.cc.mu.Unlock()
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s := resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig}
 | 
				
			||||||
 | 
						ccr.addChannelzTraceEvent(s)
 | 
				
			||||||
 | 
						ccr.curState = s
 | 
				
			||||||
 | 
						ccr.mu.Unlock()
 | 
				
			||||||
 | 
						ccr.cc.updateResolverStateAndUnlock(s, nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ParseServiceConfig is called by resolver implementations to parse a JSON
 | 
				
			||||||
 | 
					// representation of the service config.
 | 
				
			||||||
 | 
					func (ccr *ccResolverWrapper) ParseServiceConfig(scJSON string) *serviceconfig.ParseResult {
 | 
				
			||||||
 | 
						return parseServiceConfig(scJSON)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// addChannelzTraceEvent adds a channelz trace event containing the new
 | 
				
			||||||
 | 
					// state received from resolver implementations.
 | 
				
			||||||
 | 
					func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) {
 | 
				
			||||||
 | 
						var updates []string
 | 
				
			||||||
 | 
						var oldSC, newSC *ServiceConfig
 | 
				
			||||||
 | 
						var oldOK, newOK bool
 | 
				
			||||||
 | 
						if ccr.curState.ServiceConfig != nil {
 | 
				
			||||||
 | 
							oldSC, oldOK = ccr.curState.ServiceConfig.Config.(*ServiceConfig)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if s.ServiceConfig != nil {
 | 
				
			||||||
 | 
							newSC, newOK = s.ServiceConfig.Config.(*ServiceConfig)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if oldOK != newOK || (oldOK && newOK && oldSC.rawJSONString != newSC.rawJSONString) {
 | 
				
			||||||
 | 
							updates = append(updates, "service config updated")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(ccr.curState.Addresses) > 0 && len(s.Addresses) == 0 {
 | 
				
			||||||
 | 
							updates = append(updates, "resolver returned an empty address list")
 | 
				
			||||||
 | 
						} else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 {
 | 
				
			||||||
 | 
							updates = append(updates, "resolver returned new addresses")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						channelz.Infof(logger, ccr.cc.channelzID, "Resolver state updated: %s (%v)", pretty.ToJSON(s), strings.Join(updates, "; "))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										231
									
								
								vendor/google.golang.org/grpc/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										231
									
								
								vendor/google.golang.org/grpc/server.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -70,6 +70,10 @@ func init() {
 | 
				
			|||||||
	internal.GetServerCredentials = func(srv *Server) credentials.TransportCredentials {
 | 
						internal.GetServerCredentials = func(srv *Server) credentials.TransportCredentials {
 | 
				
			||||||
		return srv.opts.creds
 | 
							return srv.opts.creds
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						internal.IsRegisteredMethod = func(srv *Server, method string) bool {
 | 
				
			||||||
 | 
							return srv.isRegisteredMethod(method)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						internal.ServerFromContext = serverFromContext
 | 
				
			||||||
	internal.DrainServerTransports = func(srv *Server, addr string) {
 | 
						internal.DrainServerTransports = func(srv *Server, addr string) {
 | 
				
			||||||
		srv.drainServerTransports(addr)
 | 
							srv.drainServerTransports(addr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -81,6 +85,7 @@ func init() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	internal.BinaryLogger = binaryLogger
 | 
						internal.BinaryLogger = binaryLogger
 | 
				
			||||||
	internal.JoinServerOptions = newJoinServerOption
 | 
						internal.JoinServerOptions = newJoinServerOption
 | 
				
			||||||
 | 
						internal.RecvBufferPool = recvBufferPool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var statusOK = status.New(codes.OK, "")
 | 
					var statusOK = status.New(codes.OK, "")
 | 
				
			||||||
@@ -140,6 +145,7 @@ type Server struct {
 | 
				
			|||||||
	czData     *channelzData
 | 
						czData     *channelzData
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	serverWorkerChannel      chan func()
 | 
						serverWorkerChannel      chan func()
 | 
				
			||||||
 | 
						serverWorkerChannelClose func()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type serverOptions struct {
 | 
					type serverOptions struct {
 | 
				
			||||||
@@ -578,11 +584,13 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption {
 | 
				
			|||||||
// options are used: StatsHandler, EnableTracing, or binary logging. In such
 | 
					// options are used: StatsHandler, EnableTracing, or binary logging. In such
 | 
				
			||||||
// cases, the shared buffer pool will be ignored.
 | 
					// cases, the shared buffer pool will be ignored.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// # Experimental
 | 
					// Deprecated: use experimental.WithRecvBufferPool instead.  Will be deleted in
 | 
				
			||||||
//
 | 
					// v1.60.0 or later.
 | 
				
			||||||
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
 | 
					 | 
				
			||||||
// later release.
 | 
					 | 
				
			||||||
func RecvBufferPool(bufferPool SharedBufferPool) ServerOption {
 | 
					func RecvBufferPool(bufferPool SharedBufferPool) ServerOption {
 | 
				
			||||||
 | 
						return recvBufferPool(bufferPool)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func recvBufferPool(bufferPool SharedBufferPool) ServerOption {
 | 
				
			||||||
	return newFuncServerOption(func(o *serverOptions) {
 | 
						return newFuncServerOption(func(o *serverOptions) {
 | 
				
			||||||
		o.recvBufferPool = bufferPool
 | 
							o.recvBufferPool = bufferPool
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
@@ -616,15 +624,14 @@ func (s *Server) serverWorker() {
 | 
				
			|||||||
// connections to reduce the time spent overall on runtime.morestack.
 | 
					// connections to reduce the time spent overall on runtime.morestack.
 | 
				
			||||||
func (s *Server) initServerWorkers() {
 | 
					func (s *Server) initServerWorkers() {
 | 
				
			||||||
	s.serverWorkerChannel = make(chan func())
 | 
						s.serverWorkerChannel = make(chan func())
 | 
				
			||||||
 | 
						s.serverWorkerChannelClose = grpcsync.OnceFunc(func() {
 | 
				
			||||||
 | 
							close(s.serverWorkerChannel)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	for i := uint32(0); i < s.opts.numServerWorkers; i++ {
 | 
						for i := uint32(0); i < s.opts.numServerWorkers; i++ {
 | 
				
			||||||
		go s.serverWorker()
 | 
							go s.serverWorker()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Server) stopServerWorkers() {
 | 
					 | 
				
			||||||
	close(s.serverWorkerChannel)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewServer creates a gRPC server which has no service registered and has not
 | 
					// NewServer creates a gRPC server which has no service registered and has not
 | 
				
			||||||
// started to accept requests yet.
 | 
					// started to accept requests yet.
 | 
				
			||||||
func NewServer(opt ...ServerOption) *Server {
 | 
					func NewServer(opt ...ServerOption) *Server {
 | 
				
			||||||
@@ -806,6 +813,18 @@ func (l *listenSocket) Close() error {
 | 
				
			|||||||
// Serve returns when lis.Accept fails with fatal errors.  lis will be closed when
 | 
					// Serve returns when lis.Accept fails with fatal errors.  lis will be closed when
 | 
				
			||||||
// this method returns.
 | 
					// this method returns.
 | 
				
			||||||
// Serve will return a non-nil error unless Stop or GracefulStop is called.
 | 
					// Serve will return a non-nil error unless Stop or GracefulStop is called.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Note: All supported releases of Go (as of December 2023) override the OS
 | 
				
			||||||
 | 
					// defaults for TCP keepalive time and interval to 15s. To enable TCP keepalive
 | 
				
			||||||
 | 
					// with OS defaults for keepalive time and interval, callers need to do the
 | 
				
			||||||
 | 
					// following two things:
 | 
				
			||||||
 | 
					//   - pass a net.Listener created by calling the Listen method on a
 | 
				
			||||||
 | 
					//     net.ListenConfig with the `KeepAlive` field set to a negative value. This
 | 
				
			||||||
 | 
					//     will result in the Go standard library not overriding OS defaults for TCP
 | 
				
			||||||
 | 
					//     keepalive interval and time. But this will also result in the Go standard
 | 
				
			||||||
 | 
					//     library not enabling TCP keepalives by default.
 | 
				
			||||||
 | 
					//   - override the Accept method on the passed in net.Listener and set the
 | 
				
			||||||
 | 
					//     SO_KEEPALIVE socket option to enable TCP keepalives, with OS defaults.
 | 
				
			||||||
func (s *Server) Serve(lis net.Listener) error {
 | 
					func (s *Server) Serve(lis net.Listener) error {
 | 
				
			||||||
	s.mu.Lock()
 | 
						s.mu.Lock()
 | 
				
			||||||
	s.printf("serving")
 | 
						s.printf("serving")
 | 
				
			||||||
@@ -917,7 +936,7 @@ func (s *Server) handleRawConn(lisAddr string, rawConn net.Conn) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		s.serveStreams(st)
 | 
							s.serveStreams(context.Background(), st, rawConn)
 | 
				
			||||||
		s.removeConn(lisAddr, st)
 | 
							s.removeConn(lisAddr, st)
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -971,18 +990,29 @@ func (s *Server) newHTTP2Transport(c net.Conn) transport.ServerTransport {
 | 
				
			|||||||
	return st
 | 
						return st
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Server) serveStreams(st transport.ServerTransport) {
 | 
					func (s *Server) serveStreams(ctx context.Context, st transport.ServerTransport, rawConn net.Conn) {
 | 
				
			||||||
	defer st.Close(errors.New("finished serving streams for the server transport"))
 | 
						ctx = transport.SetConnection(ctx, rawConn)
 | 
				
			||||||
	var wg sync.WaitGroup
 | 
						ctx = peer.NewContext(ctx, st.Peer())
 | 
				
			||||||
 | 
						for _, sh := range s.opts.statsHandlers {
 | 
				
			||||||
 | 
							ctx = sh.TagConn(ctx, &stats.ConnTagInfo{
 | 
				
			||||||
 | 
								RemoteAddr: st.Peer().Addr,
 | 
				
			||||||
 | 
								LocalAddr:  st.Peer().LocalAddr,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							sh.HandleConn(ctx, &stats.ConnBegin{})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							st.Close(errors.New("finished serving streams for the server transport"))
 | 
				
			||||||
 | 
							for _, sh := range s.opts.statsHandlers {
 | 
				
			||||||
 | 
								sh.HandleConn(ctx, &stats.ConnEnd{})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	streamQuota := newHandlerQuota(s.opts.maxConcurrentStreams)
 | 
						streamQuota := newHandlerQuota(s.opts.maxConcurrentStreams)
 | 
				
			||||||
	st.HandleStreams(func(stream *transport.Stream) {
 | 
						st.HandleStreams(ctx, func(stream *transport.Stream) {
 | 
				
			||||||
		wg.Add(1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		streamQuota.acquire()
 | 
							streamQuota.acquire()
 | 
				
			||||||
		f := func() {
 | 
							f := func() {
 | 
				
			||||||
			defer streamQuota.release()
 | 
								defer streamQuota.release()
 | 
				
			||||||
			defer wg.Done()
 | 
					 | 
				
			||||||
			s.handleStream(st, stream)
 | 
								s.handleStream(st, stream)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -996,7 +1026,6 @@ func (s *Server) serveStreams(st transport.ServerTransport) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		go f()
 | 
							go f()
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	wg.Wait()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var _ http.Handler = (*Server)(nil)
 | 
					var _ http.Handler = (*Server)(nil)
 | 
				
			||||||
@@ -1040,7 +1069,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer s.removeConn(listenerAddressForServeHTTP, st)
 | 
						defer s.removeConn(listenerAddressForServeHTTP, st)
 | 
				
			||||||
	s.serveStreams(st)
 | 
						s.serveStreams(r.Context(), st, nil)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Server) addConn(addr string, st transport.ServerTransport) bool {
 | 
					func (s *Server) addConn(addr string, st transport.ServerTransport) bool {
 | 
				
			||||||
@@ -1689,6 +1718,7 @@ func (s *Server) processStreamingRPC(ctx context.Context, t transport.ServerTran
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream) {
 | 
					func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream) {
 | 
				
			||||||
	ctx := stream.Context()
 | 
						ctx := stream.Context()
 | 
				
			||||||
 | 
						ctx = contextWithServer(ctx, s)
 | 
				
			||||||
	var ti *traceInfo
 | 
						var ti *traceInfo
 | 
				
			||||||
	if EnableTracing {
 | 
						if EnableTracing {
 | 
				
			||||||
		tr := trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method())
 | 
							tr := trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method())
 | 
				
			||||||
@@ -1697,7 +1727,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
 | 
				
			|||||||
			tr: tr,
 | 
								tr: tr,
 | 
				
			||||||
			firstLine: firstLine{
 | 
								firstLine: firstLine{
 | 
				
			||||||
				client:     false,
 | 
									client:     false,
 | 
				
			||||||
				remoteAddr: t.RemoteAddr(),
 | 
									remoteAddr: t.Peer().Addr,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if dl, ok := ctx.Deadline(); ok {
 | 
							if dl, ok := ctx.Deadline(); ok {
 | 
				
			||||||
@@ -1731,6 +1761,22 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
 | 
				
			|||||||
	service := sm[:pos]
 | 
						service := sm[:pos]
 | 
				
			||||||
	method := sm[pos+1:]
 | 
						method := sm[pos+1:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						md, _ := metadata.FromIncomingContext(ctx)
 | 
				
			||||||
 | 
						for _, sh := range s.opts.statsHandlers {
 | 
				
			||||||
 | 
							ctx = sh.TagRPC(ctx, &stats.RPCTagInfo{FullMethodName: stream.Method()})
 | 
				
			||||||
 | 
							sh.HandleRPC(ctx, &stats.InHeader{
 | 
				
			||||||
 | 
								FullMethod:  stream.Method(),
 | 
				
			||||||
 | 
								RemoteAddr:  t.Peer().Addr,
 | 
				
			||||||
 | 
								LocalAddr:   t.Peer().LocalAddr,
 | 
				
			||||||
 | 
								Compression: stream.RecvCompress(),
 | 
				
			||||||
 | 
								WireLength:  stream.HeaderWireLength(),
 | 
				
			||||||
 | 
								Header:      md,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// To have calls in stream callouts work. Will delete once all stats handler
 | 
				
			||||||
 | 
						// calls come from the gRPC layer.
 | 
				
			||||||
 | 
						stream.SetContext(ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	srv, knownService := s.services[service]
 | 
						srv, knownService := s.services[service]
 | 
				
			||||||
	if knownService {
 | 
						if knownService {
 | 
				
			||||||
		if md, ok := srv.methods[method]; ok {
 | 
							if md, ok := srv.methods[method]; ok {
 | 
				
			||||||
@@ -1820,62 +1866,68 @@ func ServerTransportStreamFromContext(ctx context.Context) ServerTransportStream
 | 
				
			|||||||
// pending RPCs on the client side will get notified by connection
 | 
					// pending RPCs on the client side will get notified by connection
 | 
				
			||||||
// errors.
 | 
					// errors.
 | 
				
			||||||
func (s *Server) Stop() {
 | 
					func (s *Server) Stop() {
 | 
				
			||||||
	s.quit.Fire()
 | 
						s.stop(false)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		s.serveWG.Wait()
 | 
					 | 
				
			||||||
		s.done.Fire()
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelzID) })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	s.mu.Lock()
 | 
					 | 
				
			||||||
	listeners := s.lis
 | 
					 | 
				
			||||||
	s.lis = nil
 | 
					 | 
				
			||||||
	conns := s.conns
 | 
					 | 
				
			||||||
	s.conns = nil
 | 
					 | 
				
			||||||
	// interrupt GracefulStop if Stop and GracefulStop are called concurrently.
 | 
					 | 
				
			||||||
	s.cv.Broadcast()
 | 
					 | 
				
			||||||
	s.mu.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for lis := range listeners {
 | 
					 | 
				
			||||||
		lis.Close()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, cs := range conns {
 | 
					 | 
				
			||||||
		for st := range cs {
 | 
					 | 
				
			||||||
			st.Close(errors.New("Server.Stop called"))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if s.opts.numServerWorkers > 0 {
 | 
					 | 
				
			||||||
		s.stopServerWorkers()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	s.mu.Lock()
 | 
					 | 
				
			||||||
	if s.events != nil {
 | 
					 | 
				
			||||||
		s.events.Finish()
 | 
					 | 
				
			||||||
		s.events = nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	s.mu.Unlock()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GracefulStop stops the gRPC server gracefully. It stops the server from
 | 
					// GracefulStop stops the gRPC server gracefully. It stops the server from
 | 
				
			||||||
// accepting new connections and RPCs and blocks until all the pending RPCs are
 | 
					// accepting new connections and RPCs and blocks until all the pending RPCs are
 | 
				
			||||||
// finished.
 | 
					// finished.
 | 
				
			||||||
func (s *Server) GracefulStop() {
 | 
					func (s *Server) GracefulStop() {
 | 
				
			||||||
 | 
						s.stop(true)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *Server) stop(graceful bool) {
 | 
				
			||||||
	s.quit.Fire()
 | 
						s.quit.Fire()
 | 
				
			||||||
	defer s.done.Fire()
 | 
						defer s.done.Fire()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelzID) })
 | 
						s.channelzRemoveOnce.Do(func() { channelz.RemoveEntry(s.channelzID) })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s.mu.Lock()
 | 
						s.mu.Lock()
 | 
				
			||||||
	if s.conns == nil {
 | 
						s.closeListenersLocked()
 | 
				
			||||||
 | 
						// Wait for serving threads to be ready to exit.  Only then can we be sure no
 | 
				
			||||||
 | 
						// new conns will be created.
 | 
				
			||||||
	s.mu.Unlock()
 | 
						s.mu.Unlock()
 | 
				
			||||||
		return
 | 
						s.serveWG.Wait()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s.mu.Lock()
 | 
				
			||||||
 | 
						defer s.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if graceful {
 | 
				
			||||||
 | 
							s.drainAllServerTransportsLocked()
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							s.closeServerTransportsLocked()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for lis := range s.lis {
 | 
						for len(s.conns) != 0 {
 | 
				
			||||||
		lis.Close()
 | 
							s.cv.Wait()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.lis = nil
 | 
						s.conns = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if s.opts.numServerWorkers > 0 {
 | 
				
			||||||
 | 
							// Closing the channel (only once, via grpcsync.OnceFunc) after all the
 | 
				
			||||||
 | 
							// connections have been closed above ensures that there are no
 | 
				
			||||||
 | 
							// goroutines executing the callback passed to st.HandleStreams (where
 | 
				
			||||||
 | 
							// the channel is written to).
 | 
				
			||||||
 | 
							s.serverWorkerChannelClose()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if s.events != nil {
 | 
				
			||||||
 | 
							s.events.Finish()
 | 
				
			||||||
 | 
							s.events = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// s.mu must be held by the caller.
 | 
				
			||||||
 | 
					func (s *Server) closeServerTransportsLocked() {
 | 
				
			||||||
 | 
						for _, conns := range s.conns {
 | 
				
			||||||
 | 
							for st := range conns {
 | 
				
			||||||
 | 
								st.Close(errors.New("Server.Stop called"))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// s.mu must be held by the caller.
 | 
				
			||||||
 | 
					func (s *Server) drainAllServerTransportsLocked() {
 | 
				
			||||||
	if !s.drain {
 | 
						if !s.drain {
 | 
				
			||||||
		for _, conns := range s.conns {
 | 
							for _, conns := range s.conns {
 | 
				
			||||||
			for st := range conns {
 | 
								for st := range conns {
 | 
				
			||||||
@@ -1884,22 +1936,14 @@ func (s *Server) GracefulStop() {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		s.drain = true
 | 
							s.drain = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Wait for serving threads to be ready to exit.  Only then can we be sure no
 | 
					 | 
				
			||||||
	// new conns will be created.
 | 
					 | 
				
			||||||
	s.mu.Unlock()
 | 
					 | 
				
			||||||
	s.serveWG.Wait()
 | 
					 | 
				
			||||||
	s.mu.Lock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for len(s.conns) != 0 {
 | 
					 | 
				
			||||||
		s.cv.Wait()
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
	s.conns = nil
 | 
					
 | 
				
			||||||
	if s.events != nil {
 | 
					// s.mu must be held by the caller.
 | 
				
			||||||
		s.events.Finish()
 | 
					func (s *Server) closeListenersLocked() {
 | 
				
			||||||
		s.events = nil
 | 
						for lis := range s.lis {
 | 
				
			||||||
 | 
							lis.Close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.mu.Unlock()
 | 
						s.lis = nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// contentSubtype must be lowercase
 | 
					// contentSubtype must be lowercase
 | 
				
			||||||
@@ -1913,11 +1957,50 @@ func (s *Server) getCodec(contentSubtype string) baseCodec {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	codec := encoding.GetCodec(contentSubtype)
 | 
						codec := encoding.GetCodec(contentSubtype)
 | 
				
			||||||
	if codec == nil {
 | 
						if codec == nil {
 | 
				
			||||||
 | 
							logger.Warningf("Unsupported codec %q. Defaulting to %q for now. This will start to fail in future releases.", contentSubtype, proto.Name)
 | 
				
			||||||
		return encoding.GetCodec(proto.Name)
 | 
							return encoding.GetCodec(proto.Name)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return codec
 | 
						return codec
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type serverKey struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// serverFromContext gets the Server from the context.
 | 
				
			||||||
 | 
					func serverFromContext(ctx context.Context) *Server {
 | 
				
			||||||
 | 
						s, _ := ctx.Value(serverKey{}).(*Server)
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// contextWithServer sets the Server in the context.
 | 
				
			||||||
 | 
					func contextWithServer(ctx context.Context, server *Server) context.Context {
 | 
				
			||||||
 | 
						return context.WithValue(ctx, serverKey{}, server)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// isRegisteredMethod returns whether the passed in method is registered as a
 | 
				
			||||||
 | 
					// method on the server. /service/method and service/method will match if the
 | 
				
			||||||
 | 
					// service and method are registered on the server.
 | 
				
			||||||
 | 
					func (s *Server) isRegisteredMethod(serviceMethod string) bool {
 | 
				
			||||||
 | 
						if serviceMethod != "" && serviceMethod[0] == '/' {
 | 
				
			||||||
 | 
							serviceMethod = serviceMethod[1:]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pos := strings.LastIndex(serviceMethod, "/")
 | 
				
			||||||
 | 
						if pos == -1 { // Invalid method name syntax.
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						service := serviceMethod[:pos]
 | 
				
			||||||
 | 
						method := serviceMethod[pos+1:]
 | 
				
			||||||
 | 
						srv, knownService := s.services[service]
 | 
				
			||||||
 | 
						if knownService {
 | 
				
			||||||
 | 
							if _, ok := srv.methods[method]; ok {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if _, ok := srv.streams[method]; ok {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetHeader sets the header metadata to be sent from the server to the client.
 | 
					// SetHeader sets the header metadata to be sent from the server to the client.
 | 
				
			||||||
// The context provided must be the context passed to the server's handler.
 | 
					// The context provided must be the context passed to the server's handler.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								vendor/google.golang.org/grpc/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/google.golang.org/grpc/version.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -19,4 +19,4 @@
 | 
				
			|||||||
package grpc
 | 
					package grpc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Version is the current grpc version.
 | 
					// Version is the current grpc version.
 | 
				
			||||||
const Version = "1.59.0"
 | 
					const Version = "1.60.1"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										164
									
								
								vendor/google.golang.org/grpc/vet.sh
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										164
									
								
								vendor/google.golang.org/grpc/vet.sh
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -35,7 +35,6 @@ if [[ "$1" = "-install" ]]; then
 | 
				
			|||||||
  # Install the pinned versions as defined in module tools.
 | 
					  # Install the pinned versions as defined in module tools.
 | 
				
			||||||
  pushd ./test/tools
 | 
					  pushd ./test/tools
 | 
				
			||||||
  go install \
 | 
					  go install \
 | 
				
			||||||
    golang.org/x/lint/golint \
 | 
					 | 
				
			||||||
    golang.org/x/tools/cmd/goimports \
 | 
					    golang.org/x/tools/cmd/goimports \
 | 
				
			||||||
    honnef.co/go/tools/cmd/staticcheck \
 | 
					    honnef.co/go/tools/cmd/staticcheck \
 | 
				
			||||||
    github.com/client9/misspell/cmd/misspell
 | 
					    github.com/client9/misspell/cmd/misspell
 | 
				
			||||||
@@ -77,12 +76,16 @@ fi
 | 
				
			|||||||
not grep 'func Test[^(]' *_test.go
 | 
					not grep 'func Test[^(]' *_test.go
 | 
				
			||||||
not grep 'func Test[^(]' test/*.go
 | 
					not grep 'func Test[^(]' test/*.go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# - Check for typos in test function names
 | 
				
			||||||
 | 
					git grep 'func (s) ' -- "*_test.go" | not grep -v 'func (s) Test'
 | 
				
			||||||
 | 
					git grep 'func [A-Z]' -- "*_test.go" | not grep -v 'func Test\|Benchmark\|Example'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# - Do not import x/net/context.
 | 
					# - Do not import x/net/context.
 | 
				
			||||||
not git grep -l 'x/net/context' -- "*.go"
 | 
					not git grep -l 'x/net/context' -- "*.go"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# - Do not import math/rand for real library code.  Use internal/grpcrand for
 | 
					# - Do not import math/rand for real library code.  Use internal/grpcrand for
 | 
				
			||||||
#   thread safety.
 | 
					#   thread safety.
 | 
				
			||||||
git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^stress\|grpcrand\|^benchmark\|wrr_test'
 | 
					git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^interop/stress\|grpcrand\|^benchmark\|wrr_test'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# - Do not use "interface{}"; use "any" instead.
 | 
					# - Do not use "interface{}"; use "any" instead.
 | 
				
			||||||
git grep -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc'
 | 
					git grep -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc'
 | 
				
			||||||
@@ -101,8 +104,7 @@ git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
misspell -error .
 | 
					misspell -error .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# - gofmt, goimports, golint (with exceptions for generated code), go vet,
 | 
					# - gofmt, goimports, go vet, go mod tidy.
 | 
				
			||||||
# go mod tidy.
 | 
					 | 
				
			||||||
# Perform these checks on each module inside gRPC.
 | 
					# Perform these checks on each module inside gRPC.
 | 
				
			||||||
for MOD_FILE in $(find . -name 'go.mod'); do
 | 
					for MOD_FILE in $(find . -name 'go.mod'); do
 | 
				
			||||||
  MOD_DIR=$(dirname ${MOD_FILE})
 | 
					  MOD_DIR=$(dirname ${MOD_FILE})
 | 
				
			||||||
@@ -110,7 +112,6 @@ for MOD_FILE in $(find . -name 'go.mod'); do
 | 
				
			|||||||
  go vet -all ./... | fail_on_output
 | 
					  go vet -all ./... | fail_on_output
 | 
				
			||||||
  gofmt -s -d -l . 2>&1 | fail_on_output
 | 
					  gofmt -s -d -l . 2>&1 | fail_on_output
 | 
				
			||||||
  goimports -l . 2>&1 | not grep -vE "\.pb\.go"
 | 
					  goimports -l . 2>&1 | not grep -vE "\.pb\.go"
 | 
				
			||||||
  golint ./... 2>&1 | not grep -vE "/grpc_testing_not_regenerate/.*\.pb\.go:"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  go mod tidy -compat=1.19
 | 
					  go mod tidy -compat=1.19
 | 
				
			||||||
  git status --porcelain 2>&1 | fail_on_output || \
 | 
					  git status --porcelain 2>&1 | fail_on_output || \
 | 
				
			||||||
@@ -119,94 +120,73 @@ for MOD_FILE in $(find . -name 'go.mod'); do
 | 
				
			|||||||
done
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# - Collection of static analysis checks
 | 
					# - Collection of static analysis checks
 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# TODO(dfawley): don't use deprecated functions in examples or first-party
 | 
					 | 
				
			||||||
# plugins.
 | 
					 | 
				
			||||||
# TODO(dfawley): enable ST1019 (duplicate imports) but allow for protobufs.
 | 
					 | 
				
			||||||
SC_OUT="$(mktemp)"
 | 
					SC_OUT="$(mktemp)"
 | 
				
			||||||
staticcheck -go 1.19 -checks 'inherit,-ST1015,-ST1019,-SA1019' ./... > "${SC_OUT}" || true
 | 
					staticcheck -go 1.19 -checks 'all' ./... > "${SC_OUT}" || true
 | 
				
			||||||
# Error if anything other than deprecation warnings are printed.
 | 
					
 | 
				
			||||||
not grep -v "is deprecated:.*SA1019" "${SC_OUT}"
 | 
					# Error for anything other than checks that need exclusions.
 | 
				
			||||||
# Only ignore the following deprecated types/fields/functions.
 | 
					grep -v "(ST1000)" "${SC_OUT}" | grep -v "(SA1019)" | grep -v "(ST1003)" | not grep -v "(ST1019)\|\(other import of\)"
 | 
				
			||||||
not grep -Fv '.CredsBundle
 | 
					
 | 
				
			||||||
.HeaderMap
 | 
					# Exclude underscore checks for generated code.
 | 
				
			||||||
.Metadata is deprecated: use Attributes
 | 
					grep "(ST1003)" "${SC_OUT}" | not grep -v '\(.pb.go:\)\|\(code_string_test.go:\)'
 | 
				
			||||||
.NewAddress
 | 
					
 | 
				
			||||||
.NewServiceConfig
 | 
					# Error for duplicate imports not including grpc protos.
 | 
				
			||||||
.Type is deprecated: use Attributes
 | 
					grep "(ST1019)\|\(other import of\)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused
 | 
				
			||||||
BuildVersion is deprecated
 | 
					channelz/grpc_channelz_v1"
 | 
				
			||||||
balancer.ErrTransientFailure
 | 
					go-control-plane/envoy
 | 
				
			||||||
balancer.Picker
 | 
					grpclb/grpc_lb_v1"
 | 
				
			||||||
extDesc.Filename is deprecated
 | 
					health/grpc_health_v1"
 | 
				
			||||||
github.com/golang/protobuf/jsonpb is deprecated
 | 
					interop/grpc_testing"
 | 
				
			||||||
grpc.CallCustomCodec
 | 
					orca/v3"
 | 
				
			||||||
grpc.Code
 | 
					proto/grpc_gcp"
 | 
				
			||||||
grpc.Compressor
 | 
					proto/grpc_lookup_v1"
 | 
				
			||||||
grpc.CustomCodec
 | 
					reflection/grpc_reflection_v1"
 | 
				
			||||||
grpc.Decompressor
 | 
					reflection/grpc_reflection_v1alpha"
 | 
				
			||||||
grpc.MaxMsgSize
 | 
					XXXXX PleaseIgnoreUnused'
 | 
				
			||||||
grpc.MethodConfig
 | 
					
 | 
				
			||||||
grpc.NewGZIPCompressor
 | 
					# Error for any package comments not in generated code.
 | 
				
			||||||
grpc.NewGZIPDecompressor
 | 
					grep "(ST1000)" "${SC_OUT}" | not grep -v "\.pb\.go:"
 | 
				
			||||||
grpc.RPCCompressor
 | 
					
 | 
				
			||||||
grpc.RPCDecompressor
 | 
					# Only ignore the following deprecated types/fields/functions and exclude
 | 
				
			||||||
grpc.ServiceConfig
 | 
					# generated code.
 | 
				
			||||||
grpc.WithCompressor
 | 
					grep "(SA1019)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused
 | 
				
			||||||
grpc.WithDecompressor
 | 
					XXXXX Protobuf related deprecation errors:
 | 
				
			||||||
grpc.WithDialer
 | 
					"github.com/golang/protobuf
 | 
				
			||||||
grpc.WithMaxMsgSize
 | 
					.pb.go:
 | 
				
			||||||
grpc.WithServiceConfig
 | 
					: ptypes.
 | 
				
			||||||
grpc.WithTimeout
 | 
					proto.RegisterType
 | 
				
			||||||
http.CloseNotifier
 | 
					XXXXX gRPC internal usage deprecation errors:
 | 
				
			||||||
info.SecurityVersion
 | 
					"google.golang.org/grpc
 | 
				
			||||||
proto is deprecated
 | 
					: grpc.
 | 
				
			||||||
proto.InternalMessageInfo is deprecated
 | 
					: v1alpha.
 | 
				
			||||||
proto.EnumName is deprecated
 | 
					: v1alphareflectionpb.
 | 
				
			||||||
proto.ErrInternalBadWireType is deprecated
 | 
					BalancerAttributes is deprecated:
 | 
				
			||||||
proto.FileDescriptor is deprecated
 | 
					CredsBundle is deprecated:
 | 
				
			||||||
proto.Marshaler is deprecated
 | 
					Metadata is deprecated: use Attributes instead.
 | 
				
			||||||
proto.MessageType is deprecated
 | 
					NewSubConn is deprecated:
 | 
				
			||||||
proto.RegisterEnum is deprecated
 | 
					OverrideServerName is deprecated:
 | 
				
			||||||
proto.RegisterFile is deprecated
 | 
					RemoveSubConn is deprecated:
 | 
				
			||||||
proto.RegisterType is deprecated
 | 
					SecurityVersion is deprecated:
 | 
				
			||||||
proto.RegisterExtension is deprecated
 | 
					 | 
				
			||||||
proto.RegisteredExtension is deprecated
 | 
					 | 
				
			||||||
proto.RegisteredExtensions is deprecated
 | 
					 | 
				
			||||||
proto.RegisterMapType is deprecated
 | 
					 | 
				
			||||||
proto.Unmarshaler is deprecated
 | 
					 | 
				
			||||||
Target is deprecated: Use the Target field in the BuildOptions instead.
 | 
					Target is deprecated: Use the Target field in the BuildOptions instead.
 | 
				
			||||||
xxx_messageInfo_
 | 
					UpdateAddresses is deprecated:
 | 
				
			||||||
' "${SC_OUT}"
 | 
					UpdateSubConnState is deprecated:
 | 
				
			||||||
 | 
					balancer.ErrTransientFailure is deprecated:
 | 
				
			||||||
# - special golint on package comments.
 | 
					grpc/reflection/v1alpha/reflection.proto
 | 
				
			||||||
lint_package_comment_per_package() {
 | 
					XXXXX xDS deprecated fields we support
 | 
				
			||||||
  # Number of files in this go package.
 | 
					.ExactMatch
 | 
				
			||||||
  fileCount=$(go list -f '{{len .GoFiles}}' $1)
 | 
					.PrefixMatch
 | 
				
			||||||
  if [ ${fileCount} -eq 0 ]; then
 | 
					.SafeRegexMatch
 | 
				
			||||||
    return 0
 | 
					.SuffixMatch
 | 
				
			||||||
  fi
 | 
					GetContainsMatch
 | 
				
			||||||
  # Number of package errors generated by golint.
 | 
					GetExactMatch
 | 
				
			||||||
  lintPackageCommentErrorsCount=$(golint --min_confidence 0 $1 | grep -c "should have a package comment")
 | 
					GetMatchSubjectAltNames
 | 
				
			||||||
  # golint complains about every file that's missing the package comment. If the
 | 
					GetPrefixMatch
 | 
				
			||||||
  # number of files for this package is greater than the number of errors, there's
 | 
					GetSafeRegexMatch
 | 
				
			||||||
  # at least one file with package comment, good. Otherwise, fail.
 | 
					GetSuffixMatch
 | 
				
			||||||
  if [ ${fileCount} -le ${lintPackageCommentErrorsCount} ]; then
 | 
					GetTlsCertificateCertificateProviderInstance
 | 
				
			||||||
    echo "Package $1 (with ${fileCount} files) is missing package comment"
 | 
					GetValidationContextCertificateProviderInstance
 | 
				
			||||||
    return 1
 | 
					XXXXX TODO: Remove the below deprecation usages:
 | 
				
			||||||
  fi
 | 
					CloseNotifier
 | 
				
			||||||
}
 | 
					Roots.Subjects
 | 
				
			||||||
lint_package_comment() {
 | 
					XXXXX PleaseIgnoreUnused'
 | 
				
			||||||
  set +ex
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  count=0
 | 
					 | 
				
			||||||
  for i in $(go list ./...); do
 | 
					 | 
				
			||||||
    lint_package_comment_per_package "$i"
 | 
					 | 
				
			||||||
    ((count += $?))
 | 
					 | 
				
			||||||
  done
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  set -ex
 | 
					 | 
				
			||||||
  return $count
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
lint_package_comment
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo SUCCESS
 | 
					echo SUCCESS
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							@@ -150,7 +150,7 @@ github.com/compose-spec/compose-go/v2/validation
 | 
				
			|||||||
# github.com/containerd/console v1.0.4
 | 
					# github.com/containerd/console v1.0.4
 | 
				
			||||||
## explicit; go 1.13
 | 
					## explicit; go 1.13
 | 
				
			||||||
github.com/containerd/console
 | 
					github.com/containerd/console
 | 
				
			||||||
# github.com/containerd/containerd v1.7.19
 | 
					# github.com/containerd/containerd v1.7.20
 | 
				
			||||||
## explicit; go 1.21
 | 
					## explicit; go 1.21
 | 
				
			||||||
github.com/containerd/containerd/archive/compression
 | 
					github.com/containerd/containerd/archive/compression
 | 
				
			||||||
github.com/containerd/containerd/content
 | 
					github.com/containerd/containerd/content
 | 
				
			||||||
@@ -219,7 +219,7 @@ github.com/davecgh/go-spew/spew
 | 
				
			|||||||
# github.com/distribution/reference v0.6.0
 | 
					# github.com/distribution/reference v0.6.0
 | 
				
			||||||
## explicit; go 1.20
 | 
					## explicit; go 1.20
 | 
				
			||||||
github.com/distribution/reference
 | 
					github.com/distribution/reference
 | 
				
			||||||
# github.com/docker/cli v27.0.3+incompatible
 | 
					# github.com/docker/cli v27.1.1+incompatible
 | 
				
			||||||
## explicit
 | 
					## explicit
 | 
				
			||||||
github.com/docker/cli/cli
 | 
					github.com/docker/cli/cli
 | 
				
			||||||
github.com/docker/cli/cli-plugins/hooks
 | 
					github.com/docker/cli/cli-plugins/hooks
 | 
				
			||||||
@@ -271,7 +271,7 @@ github.com/docker/distribution/registry/client/transport
 | 
				
			|||||||
github.com/docker/distribution/registry/storage/cache
 | 
					github.com/docker/distribution/registry/storage/cache
 | 
				
			||||||
github.com/docker/distribution/registry/storage/cache/memory
 | 
					github.com/docker/distribution/registry/storage/cache/memory
 | 
				
			||||||
github.com/docker/distribution/uuid
 | 
					github.com/docker/distribution/uuid
 | 
				
			||||||
# github.com/docker/docker v27.0.3+incompatible
 | 
					# github.com/docker/docker v27.1.1+incompatible
 | 
				
			||||||
## explicit
 | 
					## explicit
 | 
				
			||||||
github.com/docker/docker/api
 | 
					github.com/docker/docker/api
 | 
				
			||||||
github.com/docker/docker/api/types
 | 
					github.com/docker/docker/api/types
 | 
				
			||||||
@@ -516,7 +516,7 @@ github.com/mitchellh/go-wordwrap
 | 
				
			|||||||
github.com/mitchellh/hashstructure/v2
 | 
					github.com/mitchellh/hashstructure/v2
 | 
				
			||||||
# github.com/mitchellh/mapstructure v1.5.0
 | 
					# github.com/mitchellh/mapstructure v1.5.0
 | 
				
			||||||
## explicit; go 1.14
 | 
					## explicit; go 1.14
 | 
				
			||||||
# github.com/moby/buildkit v0.15.1
 | 
					# github.com/moby/buildkit v0.15.1-0.20240810140024-664c2b469f19
 | 
				
			||||||
## explicit; go 1.21.0
 | 
					## explicit; go 1.21.0
 | 
				
			||||||
github.com/moby/buildkit/api/services/control
 | 
					github.com/moby/buildkit/api/services/control
 | 
				
			||||||
github.com/moby/buildkit/api/types
 | 
					github.com/moby/buildkit/api/types
 | 
				
			||||||
@@ -531,6 +531,7 @@ github.com/moby/buildkit/client/llb
 | 
				
			|||||||
github.com/moby/buildkit/client/llb/sourceresolver
 | 
					github.com/moby/buildkit/client/llb/sourceresolver
 | 
				
			||||||
github.com/moby/buildkit/client/ociindex
 | 
					github.com/moby/buildkit/client/ociindex
 | 
				
			||||||
github.com/moby/buildkit/cmd/buildkitd/config
 | 
					github.com/moby/buildkit/cmd/buildkitd/config
 | 
				
			||||||
 | 
					github.com/moby/buildkit/errdefs
 | 
				
			||||||
github.com/moby/buildkit/executor/resources/types
 | 
					github.com/moby/buildkit/executor/resources/types
 | 
				
			||||||
github.com/moby/buildkit/exporter/containerimage/exptypes
 | 
					github.com/moby/buildkit/exporter/containerimage/exptypes
 | 
				
			||||||
github.com/moby/buildkit/exporter/exptypes
 | 
					github.com/moby/buildkit/exporter/exptypes
 | 
				
			||||||
@@ -620,7 +621,7 @@ github.com/moby/sys/sequential
 | 
				
			|||||||
# github.com/moby/sys/signal v0.7.0
 | 
					# github.com/moby/sys/signal v0.7.0
 | 
				
			||||||
## explicit; go 1.16
 | 
					## explicit; go 1.16
 | 
				
			||||||
github.com/moby/sys/signal
 | 
					github.com/moby/sys/signal
 | 
				
			||||||
# github.com/moby/sys/user v0.1.0
 | 
					# github.com/moby/sys/user v0.3.0
 | 
				
			||||||
## explicit; go 1.17
 | 
					## explicit; go 1.17
 | 
				
			||||||
github.com/moby/sys/user
 | 
					github.com/moby/sys/user
 | 
				
			||||||
# github.com/moby/term v0.5.0
 | 
					# github.com/moby/term v0.5.0
 | 
				
			||||||
@@ -779,10 +780,7 @@ go.opentelemetry.io/otel/internal/global
 | 
				
			|||||||
go.opentelemetry.io/otel/propagation
 | 
					go.opentelemetry.io/otel/propagation
 | 
				
			||||||
go.opentelemetry.io/otel/semconv/v1.17.0
 | 
					go.opentelemetry.io/otel/semconv/v1.17.0
 | 
				
			||||||
go.opentelemetry.io/otel/semconv/v1.21.0
 | 
					go.opentelemetry.io/otel/semconv/v1.21.0
 | 
				
			||||||
# go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0
 | 
					# go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0
 | 
				
			||||||
## explicit; go 1.20
 | 
					 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric
 | 
					 | 
				
			||||||
# go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.42.0
 | 
					 | 
				
			||||||
## explicit; go 1.20
 | 
					## explicit; go 1.20
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal
 | 
				
			||||||
@@ -790,7 +788,7 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/envco
 | 
				
			|||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/oconf
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/retry
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal/transform
 | 
				
			||||||
# go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0
 | 
					# go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0
 | 
				
			||||||
## explicit; go 1.20
 | 
					## explicit; go 1.20
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp
 | 
				
			||||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal
 | 
					go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal
 | 
				
			||||||
@@ -886,7 +884,7 @@ golang.org/x/net/internal/socks
 | 
				
			|||||||
golang.org/x/net/internal/timeseries
 | 
					golang.org/x/net/internal/timeseries
 | 
				
			||||||
golang.org/x/net/proxy
 | 
					golang.org/x/net/proxy
 | 
				
			||||||
golang.org/x/net/trace
 | 
					golang.org/x/net/trace
 | 
				
			||||||
# golang.org/x/oauth2 v0.11.0
 | 
					# golang.org/x/oauth2 v0.13.0
 | 
				
			||||||
## explicit; go 1.18
 | 
					## explicit; go 1.18
 | 
				
			||||||
golang.org/x/oauth2
 | 
					golang.org/x/oauth2
 | 
				
			||||||
golang.org/x/oauth2/internal
 | 
					golang.org/x/oauth2/internal
 | 
				
			||||||
@@ -949,17 +947,17 @@ google.golang.org/appengine/internal/log
 | 
				
			|||||||
google.golang.org/appengine/internal/remote_api
 | 
					google.golang.org/appengine/internal/remote_api
 | 
				
			||||||
google.golang.org/appengine/internal/urlfetch
 | 
					google.golang.org/appengine/internal/urlfetch
 | 
				
			||||||
google.golang.org/appengine/urlfetch
 | 
					google.golang.org/appengine/urlfetch
 | 
				
			||||||
# google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b
 | 
					# google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3
 | 
				
			||||||
## explicit; go 1.19
 | 
					## explicit; go 1.19
 | 
				
			||||||
google.golang.org/genproto/protobuf/field_mask
 | 
					google.golang.org/genproto/protobuf/field_mask
 | 
				
			||||||
# google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b
 | 
					# google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f
 | 
				
			||||||
## explicit; go 1.19
 | 
					## explicit; go 1.19
 | 
				
			||||||
google.golang.org/genproto/googleapis/api/httpbody
 | 
					google.golang.org/genproto/googleapis/api/httpbody
 | 
				
			||||||
# google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b
 | 
					# google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0
 | 
				
			||||||
## explicit; go 1.19
 | 
					## explicit; go 1.19
 | 
				
			||||||
google.golang.org/genproto/googleapis/rpc/errdetails
 | 
					google.golang.org/genproto/googleapis/rpc/errdetails
 | 
				
			||||||
google.golang.org/genproto/googleapis/rpc/status
 | 
					google.golang.org/genproto/googleapis/rpc/status
 | 
				
			||||||
# google.golang.org/grpc v1.59.0
 | 
					# google.golang.org/grpc v1.60.1
 | 
				
			||||||
## explicit; go 1.19
 | 
					## explicit; go 1.19
 | 
				
			||||||
google.golang.org/grpc
 | 
					google.golang.org/grpc
 | 
				
			||||||
google.golang.org/grpc/attributes
 | 
					google.golang.org/grpc/attributes
 | 
				
			||||||
@@ -998,6 +996,7 @@ google.golang.org/grpc/internal/metadata
 | 
				
			|||||||
google.golang.org/grpc/internal/pretty
 | 
					google.golang.org/grpc/internal/pretty
 | 
				
			||||||
google.golang.org/grpc/internal/resolver
 | 
					google.golang.org/grpc/internal/resolver
 | 
				
			||||||
google.golang.org/grpc/internal/resolver/dns
 | 
					google.golang.org/grpc/internal/resolver/dns
 | 
				
			||||||
 | 
					google.golang.org/grpc/internal/resolver/dns/internal
 | 
				
			||||||
google.golang.org/grpc/internal/resolver/passthrough
 | 
					google.golang.org/grpc/internal/resolver/passthrough
 | 
				
			||||||
google.golang.org/grpc/internal/resolver/unix
 | 
					google.golang.org/grpc/internal/resolver/unix
 | 
				
			||||||
google.golang.org/grpc/internal/serviceconfig
 | 
					google.golang.org/grpc/internal/serviceconfig
 | 
				
			||||||
@@ -1009,6 +1008,7 @@ google.golang.org/grpc/keepalive
 | 
				
			|||||||
google.golang.org/grpc/metadata
 | 
					google.golang.org/grpc/metadata
 | 
				
			||||||
google.golang.org/grpc/peer
 | 
					google.golang.org/grpc/peer
 | 
				
			||||||
google.golang.org/grpc/resolver
 | 
					google.golang.org/grpc/resolver
 | 
				
			||||||
 | 
					google.golang.org/grpc/resolver/dns
 | 
				
			||||||
google.golang.org/grpc/serviceconfig
 | 
					google.golang.org/grpc/serviceconfig
 | 
				
			||||||
google.golang.org/grpc/stats
 | 
					google.golang.org/grpc/stats
 | 
				
			||||||
google.golang.org/grpc/status
 | 
					google.golang.org/grpc/status
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user