Merge branch 'master' into fix_alarm

pull/11579/head
Sree Kuchibhotla 7 years ago
commit 34989fdaae
  1. 1
      BUILD
  2. 6
      CMakeLists.txt
  3. 6
      Makefile
  4. 1
      binding.gyp
  5. 1
      build.yaml
  6. 1
      config.m4
  7. 1
      config.w32
  8. 412
      etc/roots.pem
  9. 1
      gRPC-Core.podspec
  10. 1
      grpc.gemspec
  11. 5
      include/grpc++/impl/codegen/async_unary_call.h
  12. 1
      package.xml
  13. 1
      src/core/ext/transport/chttp2/transport/bin_decoder.c
  14. 211
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  15. 369
      src/core/ext/transport/chttp2/transport/flow_control.c
  16. 10
      src/core/ext/transport/chttp2/transport/frame_settings.c
  17. 10
      src/core/ext/transport/chttp2/transport/frame_window_update.c
  18. 281
      src/core/ext/transport/chttp2/transport/internal.h
  19. 84
      src/core/ext/transport/chttp2/transport/parsing.c
  20. 19
      src/core/ext/transport/chttp2/transport/stream_lists.c
  21. 4
      src/core/ext/transport/chttp2/transport/varint.c
  22. 72
      src/core/ext/transport/chttp2/transport/writing.c
  23. 1
      src/core/lib/json/json_reader.c
  24. 2
      src/core/lib/security/transport/security_handshaker.c
  25. 2
      src/core/lib/support/murmur_hash.c
  26. 2
      src/core/tsi/fake_transport_security.c
  27. 2
      src/core/tsi/transport_security.c
  28. 3
      src/core/tsi/transport_security.h
  29. 2
      src/core/tsi/transport_security_adapter.c
  30. 2
      src/core/tsi/transport_security_interface.h
  31. 2
      src/node/src/credentials.js
  32. 2
      src/objective-c/GRPCClient/GRPCCall.h
  33. 1
      src/python/grpcio/grpc_core_dependencies.py
  34. 14
      test/cpp/microbenchmarks/bm_chttp2_transport.cc
  35. 27
      test/cpp/microbenchmarks/bm_fullstack_trickle.cc
  36. 1
      tools/doxygen/Doxyfile.core.internal
  37. 4
      tools/internal_ci/helper_scripts/prepare_build_linux_rc
  38. 25
      tools/internal_ci/linux/grpc_bazel.sh
  39. 23
      tools/internal_ci/linux/grpc_bazel_build.cfg
  40. 23
      tools/internal_ci/linux/grpc_bazel_test.cfg
  41. 2
      tools/internal_ci/macos/grpc_basictests.cfg
  42. 31
      tools/internal_ci/macos/grpc_basictests_dbg.cfg
  43. 31
      tools/internal_ci/macos/grpc_basictests_opt.cfg
  44. 2
      tools/internal_ci/macos/pull_request/grpc_basictests_dbg.cfg
  45. 31
      tools/internal_ci/macos/pull_request/grpc_basictests_opt.cfg
  46. 1
      tools/run_tests/generated/sources_and_headers.json
  47. 2
      tools/run_tests/run_tests.py
  48. 2
      vsprojects/vcxproj/grpc/grpc.vcxproj
  49. 3
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  50. 2
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
  51. 3
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
  52. 2
      vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
  53. 3
      vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
  54. 2
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  55. 3
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters

@ -1218,6 +1218,7 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/bin_encoder.c", "src/core/ext/transport/chttp2/transport/bin_encoder.c",
"src/core/ext/transport/chttp2/transport/chttp2_plugin.c", "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
"src/core/ext/transport/chttp2/transport/chttp2_transport.c", "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
"src/core/ext/transport/chttp2/transport/flow_control.c",
"src/core/ext/transport/chttp2/transport/frame_data.c", "src/core/ext/transport/chttp2/transport/frame_data.c",
"src/core/ext/transport/chttp2/transport/frame_goaway.c", "src/core/ext/transport/chttp2/transport/frame_goaway.c",
"src/core/ext/transport/chttp2/transport/frame_ping.c", "src/core/ext/transport/chttp2/transport/frame_ping.c",

@ -1079,6 +1079,7 @@ add_library(grpc
src/core/ext/transport/chttp2/transport/bin_encoder.c src/core/ext/transport/chttp2/transport/bin_encoder.c
src/core/ext/transport/chttp2/transport/chttp2_plugin.c src/core/ext/transport/chttp2/transport/chttp2_plugin.c
src/core/ext/transport/chttp2/transport/chttp2_transport.c src/core/ext/transport/chttp2/transport/chttp2_transport.c
src/core/ext/transport/chttp2/transport/flow_control.c
src/core/ext/transport/chttp2/transport/frame_data.c src/core/ext/transport/chttp2/transport/frame_data.c
src/core/ext/transport/chttp2/transport/frame_goaway.c src/core/ext/transport/chttp2/transport/frame_goaway.c
src/core/ext/transport/chttp2/transport/frame_ping.c src/core/ext/transport/chttp2/transport/frame_ping.c
@ -1425,6 +1426,7 @@ add_library(grpc_cronet
src/core/ext/transport/chttp2/transport/bin_encoder.c src/core/ext/transport/chttp2/transport/bin_encoder.c
src/core/ext/transport/chttp2/transport/chttp2_plugin.c src/core/ext/transport/chttp2/transport/chttp2_plugin.c
src/core/ext/transport/chttp2/transport/chttp2_transport.c src/core/ext/transport/chttp2/transport/chttp2_transport.c
src/core/ext/transport/chttp2/transport/flow_control.c
src/core/ext/transport/chttp2/transport/frame_data.c src/core/ext/transport/chttp2/transport/frame_data.c
src/core/ext/transport/chttp2/transport/frame_goaway.c src/core/ext/transport/chttp2/transport/frame_goaway.c
src/core/ext/transport/chttp2/transport/frame_ping.c src/core/ext/transport/chttp2/transport/frame_ping.c
@ -1753,6 +1755,7 @@ add_library(grpc_test_util
src/core/ext/transport/chttp2/transport/bin_encoder.c src/core/ext/transport/chttp2/transport/bin_encoder.c
src/core/ext/transport/chttp2/transport/chttp2_plugin.c src/core/ext/transport/chttp2/transport/chttp2_plugin.c
src/core/ext/transport/chttp2/transport/chttp2_transport.c src/core/ext/transport/chttp2/transport/chttp2_transport.c
src/core/ext/transport/chttp2/transport/flow_control.c
src/core/ext/transport/chttp2/transport/frame_data.c src/core/ext/transport/chttp2/transport/frame_data.c
src/core/ext/transport/chttp2/transport/frame_goaway.c src/core/ext/transport/chttp2/transport/frame_goaway.c
src/core/ext/transport/chttp2/transport/frame_ping.c src/core/ext/transport/chttp2/transport/frame_ping.c
@ -2009,6 +2012,7 @@ add_library(grpc_test_util_unsecure
src/core/ext/transport/chttp2/transport/bin_encoder.c src/core/ext/transport/chttp2/transport/bin_encoder.c
src/core/ext/transport/chttp2/transport/chttp2_plugin.c src/core/ext/transport/chttp2/transport/chttp2_plugin.c
src/core/ext/transport/chttp2/transport/chttp2_transport.c src/core/ext/transport/chttp2/transport/chttp2_transport.c
src/core/ext/transport/chttp2/transport/flow_control.c
src/core/ext/transport/chttp2/transport/frame_data.c src/core/ext/transport/chttp2/transport/frame_data.c
src/core/ext/transport/chttp2/transport/frame_goaway.c src/core/ext/transport/chttp2/transport/frame_goaway.c
src/core/ext/transport/chttp2/transport/frame_ping.c src/core/ext/transport/chttp2/transport/frame_ping.c
@ -2232,6 +2236,7 @@ add_library(grpc_unsecure
src/core/ext/transport/chttp2/transport/bin_encoder.c src/core/ext/transport/chttp2/transport/bin_encoder.c
src/core/ext/transport/chttp2/transport/chttp2_plugin.c src/core/ext/transport/chttp2/transport/chttp2_plugin.c
src/core/ext/transport/chttp2/transport/chttp2_transport.c src/core/ext/transport/chttp2/transport/chttp2_transport.c
src/core/ext/transport/chttp2/transport/flow_control.c
src/core/ext/transport/chttp2/transport/frame_data.c src/core/ext/transport/chttp2/transport/frame_data.c
src/core/ext/transport/chttp2/transport/frame_goaway.c src/core/ext/transport/chttp2/transport/frame_goaway.c
src/core/ext/transport/chttp2/transport/frame_ping.c src/core/ext/transport/chttp2/transport/frame_ping.c
@ -2774,6 +2779,7 @@ add_library(grpc++_cronet
src/core/ext/transport/chttp2/transport/bin_encoder.c src/core/ext/transport/chttp2/transport/bin_encoder.c
src/core/ext/transport/chttp2/transport/chttp2_plugin.c src/core/ext/transport/chttp2/transport/chttp2_plugin.c
src/core/ext/transport/chttp2/transport/chttp2_transport.c src/core/ext/transport/chttp2/transport/chttp2_transport.c
src/core/ext/transport/chttp2/transport/flow_control.c
src/core/ext/transport/chttp2/transport/frame_data.c src/core/ext/transport/chttp2/transport/frame_data.c
src/core/ext/transport/chttp2/transport/frame_goaway.c src/core/ext/transport/chttp2/transport/frame_goaway.c
src/core/ext/transport/chttp2/transport/frame_ping.c src/core/ext/transport/chttp2/transport/frame_ping.c

@ -3026,6 +3026,7 @@ LIBGRPC_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.c \ src/core/ext/transport/chttp2/transport/bin_encoder.c \
src/core/ext/transport/chttp2/transport/chttp2_plugin.c \ src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
src/core/ext/transport/chttp2/transport/chttp2_transport.c \ src/core/ext/transport/chttp2/transport/chttp2_transport.c \
src/core/ext/transport/chttp2/transport/flow_control.c \
src/core/ext/transport/chttp2/transport/frame_data.c \ src/core/ext/transport/chttp2/transport/frame_data.c \
src/core/ext/transport/chttp2/transport/frame_goaway.c \ src/core/ext/transport/chttp2/transport/frame_goaway.c \
src/core/ext/transport/chttp2/transport/frame_ping.c \ src/core/ext/transport/chttp2/transport/frame_ping.c \
@ -3370,6 +3371,7 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.c \ src/core/ext/transport/chttp2/transport/bin_encoder.c \
src/core/ext/transport/chttp2/transport/chttp2_plugin.c \ src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
src/core/ext/transport/chttp2/transport/chttp2_transport.c \ src/core/ext/transport/chttp2/transport/chttp2_transport.c \
src/core/ext/transport/chttp2/transport/flow_control.c \
src/core/ext/transport/chttp2/transport/frame_data.c \ src/core/ext/transport/chttp2/transport/frame_data.c \
src/core/ext/transport/chttp2/transport/frame_goaway.c \ src/core/ext/transport/chttp2/transport/frame_goaway.c \
src/core/ext/transport/chttp2/transport/frame_ping.c \ src/core/ext/transport/chttp2/transport/frame_ping.c \
@ -3695,6 +3697,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.c \ src/core/ext/transport/chttp2/transport/bin_encoder.c \
src/core/ext/transport/chttp2/transport/chttp2_plugin.c \ src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
src/core/ext/transport/chttp2/transport/chttp2_transport.c \ src/core/ext/transport/chttp2/transport/chttp2_transport.c \
src/core/ext/transport/chttp2/transport/flow_control.c \
src/core/ext/transport/chttp2/transport/frame_data.c \ src/core/ext/transport/chttp2/transport/frame_data.c \
src/core/ext/transport/chttp2/transport/frame_goaway.c \ src/core/ext/transport/chttp2/transport/frame_goaway.c \
src/core/ext/transport/chttp2/transport/frame_ping.c \ src/core/ext/transport/chttp2/transport/frame_ping.c \
@ -3940,6 +3943,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.c \ src/core/ext/transport/chttp2/transport/bin_encoder.c \
src/core/ext/transport/chttp2/transport/chttp2_plugin.c \ src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
src/core/ext/transport/chttp2/transport/chttp2_transport.c \ src/core/ext/transport/chttp2/transport/chttp2_transport.c \
src/core/ext/transport/chttp2/transport/flow_control.c \
src/core/ext/transport/chttp2/transport/frame_data.c \ src/core/ext/transport/chttp2/transport/frame_data.c \
src/core/ext/transport/chttp2/transport/frame_goaway.c \ src/core/ext/transport/chttp2/transport/frame_goaway.c \
src/core/ext/transport/chttp2/transport/frame_ping.c \ src/core/ext/transport/chttp2/transport/frame_ping.c \
@ -4139,6 +4143,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.c \ src/core/ext/transport/chttp2/transport/bin_encoder.c \
src/core/ext/transport/chttp2/transport/chttp2_plugin.c \ src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
src/core/ext/transport/chttp2/transport/chttp2_transport.c \ src/core/ext/transport/chttp2/transport/chttp2_transport.c \
src/core/ext/transport/chttp2/transport/flow_control.c \
src/core/ext/transport/chttp2/transport/frame_data.c \ src/core/ext/transport/chttp2/transport/frame_data.c \
src/core/ext/transport/chttp2/transport/frame_goaway.c \ src/core/ext/transport/chttp2/transport/frame_goaway.c \
src/core/ext/transport/chttp2/transport/frame_ping.c \ src/core/ext/transport/chttp2/transport/frame_ping.c \
@ -4664,6 +4669,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.c \ src/core/ext/transport/chttp2/transport/bin_encoder.c \
src/core/ext/transport/chttp2/transport/chttp2_plugin.c \ src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
src/core/ext/transport/chttp2/transport/chttp2_transport.c \ src/core/ext/transport/chttp2/transport/chttp2_transport.c \
src/core/ext/transport/chttp2/transport/flow_control.c \
src/core/ext/transport/chttp2/transport/frame_data.c \ src/core/ext/transport/chttp2/transport/frame_data.c \
src/core/ext/transport/chttp2/transport/frame_goaway.c \ src/core/ext/transport/chttp2/transport/frame_goaway.c \
src/core/ext/transport/chttp2/transport/frame_ping.c \ src/core/ext/transport/chttp2/transport/frame_ping.c \

@ -788,6 +788,7 @@
'src/core/ext/transport/chttp2/transport/bin_encoder.c', 'src/core/ext/transport/chttp2/transport/bin_encoder.c',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.c', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.c',
'src/core/ext/transport/chttp2/transport/chttp2_transport.c', 'src/core/ext/transport/chttp2/transport/chttp2_transport.c',
'src/core/ext/transport/chttp2/transport/flow_control.c',
'src/core/ext/transport/chttp2/transport/frame_data.c', 'src/core/ext/transport/chttp2/transport/frame_data.c',
'src/core/ext/transport/chttp2/transport/frame_goaway.c', 'src/core/ext/transport/chttp2/transport/frame_goaway.c',
'src/core/ext/transport/chttp2/transport/frame_ping.c', 'src/core/ext/transport/chttp2/transport/frame_ping.c',

@ -783,6 +783,7 @@ filegroups:
- src/core/ext/transport/chttp2/transport/bin_encoder.c - src/core/ext/transport/chttp2/transport/bin_encoder.c
- src/core/ext/transport/chttp2/transport/chttp2_plugin.c - src/core/ext/transport/chttp2/transport/chttp2_plugin.c
- src/core/ext/transport/chttp2/transport/chttp2_transport.c - src/core/ext/transport/chttp2/transport/chttp2_transport.c
- src/core/ext/transport/chttp2/transport/flow_control.c
- src/core/ext/transport/chttp2/transport/frame_data.c - src/core/ext/transport/chttp2/transport/frame_data.c
- src/core/ext/transport/chttp2/transport/frame_goaway.c - src/core/ext/transport/chttp2/transport/frame_goaway.c
- src/core/ext/transport/chttp2/transport/frame_ping.c - src/core/ext/transport/chttp2/transport/frame_ping.c

@ -217,6 +217,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/chttp2/transport/bin_encoder.c \ src/core/ext/transport/chttp2/transport/bin_encoder.c \
src/core/ext/transport/chttp2/transport/chttp2_plugin.c \ src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
src/core/ext/transport/chttp2/transport/chttp2_transport.c \ src/core/ext/transport/chttp2/transport/chttp2_transport.c \
src/core/ext/transport/chttp2/transport/flow_control.c \
src/core/ext/transport/chttp2/transport/frame_data.c \ src/core/ext/transport/chttp2/transport/frame_data.c \
src/core/ext/transport/chttp2/transport/frame_goaway.c \ src/core/ext/transport/chttp2/transport/frame_goaway.c \
src/core/ext/transport/chttp2/transport/frame_ping.c \ src/core/ext/transport/chttp2/transport/frame_ping.c \

@ -194,6 +194,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\transport\\chttp2\\transport\\bin_encoder.c " + "src\\core\\ext\\transport\\chttp2\\transport\\bin_encoder.c " +
"src\\core\\ext\\transport\\chttp2\\transport\\chttp2_plugin.c " + "src\\core\\ext\\transport\\chttp2\\transport\\chttp2_plugin.c " +
"src\\core\\ext\\transport\\chttp2\\transport\\chttp2_transport.c " + "src\\core\\ext\\transport\\chttp2\\transport\\chttp2_transport.c " +
"src\\core\\ext\\transport\\chttp2\\transport\\flow_control.c " +
"src\\core\\ext\\transport\\chttp2\\transport\\frame_data.c " + "src\\core\\ext\\transport\\chttp2\\transport\\frame_data.c " +
"src\\core\\ext\\transport\\chttp2\\transport\\frame_goaway.c " + "src\\core\\ext\\transport\\chttp2\\transport\\frame_goaway.c " +
"src\\core\\ext\\transport\\chttp2\\transport\\frame_ping.c " + "src\\core\\ext\\transport\\chttp2\\transport\\frame_ping.c " +

@ -155,38 +155,6 @@ ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
# Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
# Label: "AddTrust Low-Value Services Root"
# Serial: 1
# MD5 Fingerprint: 1e:42:95:02:33:92:6b:b9:5f:c0:7f:da:d6:b2:4b:fc
# SHA1 Fingerprint: cc:ab:0e:a0:4c:23:01:d6:69:7b:dd:37:9f:cd:12:eb:24:e3:94:9d
# SHA256 Fingerprint: 8c:72:09:27:9a:c0:4e:27:5e:16:d0:7f:d3:b7:75:e8:01:54:b5:96:80:46:e3:1f:52:dd:25:76:63:24:e9:a7
-----BEGIN CERTIFICATE-----
MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
-----END CERTIFICATE-----
# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network # Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network # Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
# Label: "AddTrust External Root" # Label: "AddTrust External Root"
@ -220,71 +188,6 @@ c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
# Subject: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
# Label: "AddTrust Public Services Root"
# Serial: 1
# MD5 Fingerprint: c1:62:3e:23:c5:82:73:9c:03:59:4b:2b:e9:77:49:7f
# SHA1 Fingerprint: 2a:b6:28:48:5e:78:fb:f3:ad:9e:79:10:dd:6b:df:99:72:2c:96:e5
# SHA256 Fingerprint: 07:91:ca:07:49:b2:07:82:aa:d3:c7:d7:bd:0c:df:c9:48:58:35:84:3e:b2:d7:99:60:09:ce:43:ab:6c:69:27
-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx
MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB
ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV
BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV
6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX
GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP
dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH
1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF
62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW
BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL
MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv
b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6
IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/
iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh
4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm
XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
-----END CERTIFICATE-----
# Issuer: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
# Subject: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
# Label: "AddTrust Qualified Certificates Root"
# Serial: 1
# MD5 Fingerprint: 27:ec:39:47:cd:da:5a:af:e2:9a:01:65:21:a9:4c:bb
# SHA1 Fingerprint: 4d:23:78:ec:91:95:39:b5:00:7f:75:8f:03:3b:21:1e:c5:4d:8b:cf
# SHA256 Fingerprint: 80:95:21:08:05:db:4b:bc:35:5e:44:28:d8:fd:6e:c2:cd:e3:ab:5f:b9:7a:99:42:98:8e:b8:f4:dc:d0:60:16
-----BEGIN CERTIFICATE-----
MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1
MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK
EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh
BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq
xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G
87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i
2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U
WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1
0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G
A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T
AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr
pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm
aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv
hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm
hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3
P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y
iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no
xqE=
-----END CERTIFICATE-----
# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
# Label: "Entrust Root Certification Authority" # Label: "Entrust Root Certification Authority"
@ -348,35 +251,6 @@ hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
# Subject: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
# Label: "GeoTrust Global CA 2"
# Serial: 1
# MD5 Fingerprint: 0e:40:a7:6c:de:03:5d:8f:d1:0f:e4:d1:8d:f9:6c:a9
# SHA1 Fingerprint: a9:e9:78:08:14:37:58:88:f2:05:19:b0:6d:2b:0d:2b:60:16:90:7d
# SHA256 Fingerprint: ca:2d:82:a0:86:77:07:2f:8a:b6:76:4f:f0:35:67:6c:fe:3e:5e:32:5e:01:21:72:df:3f:92:09:6d:b7:9b:85
-----BEGIN CERTIFICATE-----
MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW
MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs
IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A
PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8
Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL
TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL
5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7
S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe
2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap
EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td
EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv
/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN
A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0
abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF
I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz
4iIprn2DQKi6bA==
-----END CERTIFICATE-----
# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. # Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc.
# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. # Subject: CN=GeoTrust Universal CA O=GeoTrust Inc.
# Label: "GeoTrust Universal CA" # Label: "GeoTrust Universal CA"
@ -545,72 +419,6 @@ l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=Secure Certificate Services O=Comodo CA Limited
# Subject: CN=Secure Certificate Services O=Comodo CA Limited
# Label: "Comodo Secure Services root"
# Serial: 1
# MD5 Fingerprint: d3:d9:bd:ae:9f:ac:67:24:b3:c8:1b:52:e1:b9:a9:bd
# SHA1 Fingerprint: 4a:65:d5:f4:1d:ef:39:b8:b8:90:4a:4a:d3:64:81:33:cf:c7:a1:d1
# SHA256 Fingerprint: bd:81:ce:3b:4f:65:91:d1:1a:67:b5:fc:7a:47:fd:ef:25:52:1b:f9:aa:4e:18:b9:e3:df:2e:34:a7:80:3b:e8
-----BEGIN CERTIFICATE-----
MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
-----END CERTIFICATE-----
# Issuer: CN=Trusted Certificate Services O=Comodo CA Limited
# Subject: CN=Trusted Certificate Services O=Comodo CA Limited
# Label: "Comodo Trusted Services root"
# Serial: 1
# MD5 Fingerprint: 91:1b:3f:6e:cd:9e:ab:ee:07:fe:1f:71:d2:b3:61:27
# SHA1 Fingerprint: e1:9f:e3:0e:8b:84:60:9e:80:9b:17:0d:72:a8:c5:ba:6e:14:09:bd
# SHA256 Fingerprint: 3f:06:e5:56:81:d4:96:f5:be:16:9e:b5:38:9f:9f:2b:8f:f6:1e:17:08:df:68:81:72:48:49:cd:5d:27:cb:69
-----BEGIN CERTIFICATE-----
MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
-----END CERTIFICATE-----
# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority # Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority # Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
# Label: "QuoVadis Root CA" # Label: "QuoVadis Root CA"
@ -795,40 +603,6 @@ Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
# Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
# Label: "UTN USERFirst Hardware Root CA"
# Serial: 91374294542884704022267039221184531197
# MD5 Fingerprint: 4c:56:41:e5:0d:bb:2b:e8:ca:a3:ed:18:08:ad:43:39
# SHA1 Fingerprint: 04:83:ed:33:99:ac:36:08:05:87:22:ed:bc:5e:46:00:e3:be:f9:d7
# SHA256 Fingerprint: 6e:a5:47:41:d0:04:66:7e:ed:1b:48:16:63:4a:a3:a7:9e:6e:4b:96:95:0f:82:79:da:fc:8d:9b:d8:81:21:37
-----BEGIN CERTIFICATE-----
MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
-----END CERTIFICATE-----
# Issuer: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org # Issuer: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
# Subject: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org # Subject: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
# Label: "Camerfirma Chambers of Commerce Root" # Label: "Camerfirma Chambers of Commerce Root"
@ -1090,48 +864,6 @@ LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl
pYYsfPQS pYYsfPQS
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services
# Subject: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services
# Label: "Swisscom Root CA 1"
# Serial: 122348795730808398873664200247279986742
# MD5 Fingerprint: f8:38:7c:77:88:df:2c:16:68:2e:c2:e2:52:4b:b8:f9
# SHA1 Fingerprint: 5f:3a:fc:0a:8b:64:f6:86:67:34:74:df:7e:a9:a2:fe:f9:fa:7a:51
# SHA256 Fingerprint: 21:db:20:12:36:60:bb:2e:d4:18:20:5d:a1:1e:e7:a8:5a:65:e2:bc:6e:55:b5:af:7e:78:99:c8:a2:66:d9:2e
-----BEGIN CERTIFICATE-----
MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk
MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT
AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9
m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih
FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/
TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F
EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco
kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu
HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF
vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo
19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC
L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW
bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX
JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc
K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf
ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik
Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB
sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e
3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR
ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip
mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH
b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf
rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms
hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y
zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6
MBr1mmz0DlP5OlvRHA==
-----END CERTIFICATE-----
# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
# Label: "DigiCert Assured ID Root CA" # Label: "DigiCert Assured ID Root CA"
@ -1899,34 +1631,6 @@ i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
9u6wWk5JRFRYX0KD 9u6wWk5JRFRYX0KD
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=CNNIC ROOT O=CNNIC
# Subject: CN=CNNIC ROOT O=CNNIC
# Label: "CNNIC ROOT"
# Serial: 1228079105
# MD5 Fingerprint: 21:bc:82:ab:49:c4:13:3b:4b:b2:2b:5c:6b:90:9c:19
# SHA1 Fingerprint: 8b:af:4c:9b:1d:f0:2a:92:f7:da:12:8e:b9:1b:ac:f4:98:60:4b:6f
# SHA256 Fingerprint: e2:83:93:77:3d:a8:45:a6:79:f2:08:0c:c7:fb:44:a3:b7:a1:c3:79:2c:b7:eb:77:29:fd:cb:6a:8d:99:ae:a7
-----BEGIN CERTIFICATE-----
MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD
TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2
MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF
Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh
IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6
dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO
V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC
GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN
v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB
AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB
Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO
76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK
OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH
ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi
yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL
buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj
2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=
-----END CERTIFICATE-----
# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only # Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only # Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
# Label: "GeoTrust Primary Certification Authority - G3" # Label: "GeoTrust Primary Certification Authority - G3"
@ -3393,122 +3097,6 @@ opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3YeMLEYC/H
YvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km YvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km
-----END CERTIFICATE----- -----END CERTIFICATE-----
# Issuer: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center
# Subject: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center
# Label: "China Internet Network Information Center EV Certificates Root"
# Serial: 1218379777
# MD5 Fingerprint: 55:5d:63:00:97:bd:6a:97:f5:67:ab:4b:fb:6e:63:15
# SHA1 Fingerprint: 4f:99:aa:93:fb:2b:d1:37:26:a1:99:4a:ce:7f:f0:05:f2:93:5d:1e
# SHA256 Fingerprint: 1c:01:c6:f4:db:b2:fe:fc:22:55:8b:2b:ca:32:56:3f:49:84:4a:cf:c3:2b:7b:e4:b0:ff:59:9f:9e:8c:7a:f7
-----BEGIN CERTIFICATE-----
MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g
Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0
aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa
Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg
SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo
aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp
ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z
7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//
DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx
zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8
hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs
4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u
gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY
NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3
j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG
52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB
echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI
zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
wy39FCqQmbkHzJ8=
-----END CERTIFICATE-----
# Issuer: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services
# Subject: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services
# Label: "Swisscom Root CA 2"
# Serial: 40698052477090394928831521023204026294
# MD5 Fingerprint: 5b:04:69:ec:a5:83:94:63:18:a7:86:d0:e4:f2:6e:19
# SHA1 Fingerprint: 77:47:4f:c6:30:e4:0f:4c:47:64:3f:84:ba:b8:c6:95:4a:8a:41:ec
# SHA256 Fingerprint: f0:9b:12:2c:71:14:f4:a0:9b:d4:ea:4f:4a:99:d5:58:b4:6e:4c:25:cd:81:14:0d:29:c0:56:13:91:4c:38:41
-----BEGIN CERTIFICATE-----
MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk
MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT
AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr
jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r
0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f
2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP
ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF
y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA
tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL
6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0
uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL
acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh
k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q
VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh
b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R
fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv
/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI
REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx
srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv
aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT
woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n
Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W
t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N
8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2
9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5
wSsSnqaeG8XmDtkx2Q==
-----END CERTIFICATE-----
# Issuer: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services
# Subject: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services
# Label: "Swisscom Root EV CA 2"
# Serial: 322973295377129385374608406479535262296
# MD5 Fingerprint: 7b:30:34:9f:dd:0a:4b:6b:35:ca:31:51:28:5d:ae:ec
# SHA1 Fingerprint: e7:a1:90:29:d3:d5:52:dc:0d:0f:c6:92:d3:ea:88:0d:15:2e:1a:6b
# SHA256 Fingerprint: d9:5f:ea:3c:a4:ee:dc:e7:4c:d7:6e:75:fc:6d:1f:f6:2c:44:1f:0f:a8:bc:77:f0:34:b1:9e:5d:b2:58:01:5d
-----BEGIN CERTIFICATE-----
MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw
ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp
dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290
IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD
VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy
dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg
MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx
UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD
1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH
oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR
HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/
5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv
idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL
OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC
NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f
46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB
UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth
7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G
A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED
MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB
bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x
XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T
PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0
Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70
WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL
Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm
7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S
nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN
vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB
WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI
fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb
I+2ksx0WckNLIOFZfsLorSa/ovc=
-----END CERTIFICATE-----
# Issuer: CN=CA Disig Root R1 O=Disig a.s. # Issuer: CN=CA Disig Root R1 O=Disig a.s.
# Subject: CN=CA Disig Root R1 O=Disig a.s. # Subject: CN=CA Disig Root R1 O=Disig a.s.
# Label: "CA Disig Root R1" # Label: "CA Disig Root R1"

@ -594,6 +594,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_encoder.c', 'src/core/ext/transport/chttp2/transport/bin_encoder.c',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.c', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.c',
'src/core/ext/transport/chttp2/transport/chttp2_transport.c', 'src/core/ext/transport/chttp2/transport/chttp2_transport.c',
'src/core/ext/transport/chttp2/transport/flow_control.c',
'src/core/ext/transport/chttp2/transport/frame_data.c', 'src/core/ext/transport/chttp2/transport/frame_data.c',
'src/core/ext/transport/chttp2/transport/frame_goaway.c', 'src/core/ext/transport/chttp2/transport/frame_goaway.c',
'src/core/ext/transport/chttp2/transport/frame_ping.c', 'src/core/ext/transport/chttp2/transport/frame_ping.c',

@ -526,6 +526,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.c ) s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.c )
s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_plugin.c ) s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_plugin.c )
s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.c ) s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.c )
s.files += %w( src/core/ext/transport/chttp2/transport/flow_control.c )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.c ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.c )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_goaway.c ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_goaway.c )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_ping.c ) s.files += %w( src/core/ext/transport/chttp2/transport/frame_ping.c )

@ -307,6 +307,11 @@ class default_delete<grpc::ClientAsyncResponseReader<R>> {
public: public:
void operator()(void* p) {} void operator()(void* p) {}
}; };
template <class R>
class default_delete<grpc::ClientAsyncResponseReaderInterface<R>> {
public:
void operator()(void* p) {}
};
} }
#endif // GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H #endif // GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H

@ -540,6 +540,7 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/bin_encoder.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/bin_encoder.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_plugin.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_plugin.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_transport.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_transport.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/flow_control.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_data.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_data.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_goaway.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_goaway.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_ping.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_ping.c" role="src" />

@ -118,6 +118,7 @@ bool grpc_base64_decode_partial(struct grpc_base64_decode_context *ctx) {
switch (input_tail) { switch (input_tail) {
case 3: case 3:
ctx->output_cur[1] = COMPOSE_OUTPUT_BYTE_1(ctx->input_cur); ctx->output_cur[1] = COMPOSE_OUTPUT_BYTE_1(ctx->input_cur);
/* fallthrough */
case 2: case 2:
ctx->output_cur[0] = COMPOSE_OUTPUT_BYTE_0(ctx->input_cur); ctx->output_cur[0] = COMPOSE_OUTPUT_BYTE_0(ctx->input_cur);
} }

@ -114,11 +114,6 @@ static void connectivity_state_set(grpc_exec_ctx *exec_ctx,
grpc_connectivity_state state, grpc_connectivity_state state,
grpc_error *error, const char *reason); grpc_error *error, const char *reason);
static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s,
size_t max_size_hint,
size_t have_already);
static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx, static void incoming_byte_stream_destroy_locked(grpc_exec_ctx *exec_ctx,
void *byte_stream, void *byte_stream,
grpc_error *error_ignored); grpc_error *error_ignored);
@ -270,8 +265,9 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->endpoint_reading = 1; t->endpoint_reading = 1;
t->next_stream_id = is_client ? 1 : 2; t->next_stream_id = is_client ? 1 : 2;
t->is_client = is_client; t->is_client = is_client;
t->outgoing_window = DEFAULT_WINDOW; t->flow_control.remote_window = DEFAULT_WINDOW;
t->incoming_window = DEFAULT_WINDOW; t->flow_control.announced_window = DEFAULT_WINDOW;
t->flow_control.t = t;
t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; t->deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
t->is_first_frame = true; t->is_first_frame = true;
grpc_connectivity_state_init( grpc_connectivity_state_init(
@ -710,6 +706,7 @@ static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
post_destructive_reclaimer(exec_ctx, t); post_destructive_reclaimer(exec_ctx, t);
} }
s->flow_control.s = s;
GPR_TIMER_END("init_stream", 0); GPR_TIMER_END("init_stream", 0);
return 0; return 0;
@ -766,13 +763,7 @@ static void destroy_stream_locked(grpc_exec_ctx *exec_ctx, void *sp,
GRPC_ERROR_UNREF(s->write_closed_error); GRPC_ERROR_UNREF(s->write_closed_error);
GRPC_ERROR_UNREF(s->byte_stream_error); GRPC_ERROR_UNREF(s->byte_stream_error);
if (s->incoming_window_delta > 0) { grpc_chttp2_flowctl_destroy_stream(&t->flow_control, &s->flow_control);
GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA(
"destroy", t, s, s->incoming_window_delta);
} else if (s->incoming_window_delta < 0) {
GRPC_CHTTP2_FLOW_CREDIT_STREAM_INCOMING_WINDOW_DELTA(
"destroy", t, s, -s->incoming_window_delta);
}
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "stream"); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "stream");
@ -1476,9 +1467,16 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx, void *stream_op,
s->recv_message_ready = op_payload->recv_message.recv_message_ready; s->recv_message_ready = op_payload->recv_message.recv_message_ready;
s->recv_message = op_payload->recv_message.recv_message; s->recv_message = op_payload->recv_message.recv_message;
if (s->id != 0) { if (s->id != 0) {
if (!s->read_closed) {
already_received = s->frame_storage.length; already_received = s->frame_storage.length;
incoming_byte_stream_update_flow_control( grpc_chttp2_flowctl_incoming_bs_update(
exec_ctx, t, s, GRPC_HEADER_SIZE_IN_BYTES, already_received); &t->flow_control, &s->flow_control, GRPC_HEADER_SIZE_IN_BYTES,
already_received);
grpc_chttp2_act_on_flowctl_action(
exec_ctx,
grpc_chttp2_flowctl_get_action(&t->flow_control, &s->flow_control),
t, s);
}
} }
grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s); grpc_chttp2_maybe_complete_recv_message(exec_ctx, t, s);
} }
@ -2228,6 +2226,37 @@ static void end_all_the_calls(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
* INPUT PROCESSING - PARSING * INPUT PROCESSING - PARSING
*/ */
void grpc_chttp2_act_on_flowctl_action(grpc_exec_ctx *exec_ctx,
grpc_chttp2_flowctl_action action,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
switch (action.send_stream_update) {
case GRPC_CHTTP2_FLOWCTL_NO_ACTION_NEEDED:
break;
case GRPC_CHTTP2_FLOWCTL_UPDATE_IMMEDIATELY:
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED,
"immediate stream flowctl");
break;
case GRPC_CHTTP2_FLOWCTL_QUEUE_UPDATE:
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK,
"queue stream flowctl");
break;
}
switch (action.send_transport_update) {
case GRPC_CHTTP2_FLOWCTL_NO_ACTION_NEEDED:
break;
case GRPC_CHTTP2_FLOWCTL_UPDATE_IMMEDIATELY:
grpc_chttp2_initiate_write(exec_ctx, t, "immediate transport flowctl");
break;
// this is the same as no action b/c every time the transport enters the
// writing path it will maybe do an update
case GRPC_CHTTP2_FLOWCTL_QUEUE_UPDATE:
break;
}
}
static void update_bdp(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, static void update_bdp(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
double bdp_dbl) { double bdp_dbl) {
// initial window size bounded [1,2^31-1], but we set the min to 128. // initial window size bounded [1,2^31-1], but we set the min to 128.
@ -2239,9 +2268,10 @@ static void update_bdp(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
if (delta == 0 || (delta > -bdp / 10 && delta < bdp / 10)) { if (delta == 0 || (delta > -bdp / 10 && delta < bdp / 10)) {
return; return;
} }
if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) { if (GRPC_TRACER_ON(grpc_bdp_estimator_trace) ||
gpr_log(GPR_DEBUG, "%s: update initial window size to %d", t->peer_string, GRPC_TRACER_ON(grpc_flowctl_trace)) {
(int)bdp); gpr_log(GPR_DEBUG, "%s | %p[%s] | update initial window size to %d",
t->peer_string, t, t->is_client ? "cli" : "svr", (int)bdp);
} }
queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, queue_setting_update(exec_ctx, t, GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE,
(uint32_t)bdp); (uint32_t)bdp);
@ -2341,8 +2371,8 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
GPR_TIMER_END("reading_action.parse", 0); GPR_TIMER_END("reading_action.parse", 0);
GPR_TIMER_BEGIN("post_parse_locked", 0); GPR_TIMER_BEGIN("post_parse_locked", 0);
if (t->initial_window_update != 0) { if (t->flow_control.initial_window_update != 0) {
if (t->initial_window_update > 0) { if (t->flow_control.initial_window_update > 0) {
grpc_chttp2_stream *s; grpc_chttp2_stream *s;
while (grpc_chttp2_list_pop_stalled_by_stream(t, &s)) { while (grpc_chttp2_list_pop_stalled_by_stream(t, &s)) {
grpc_chttp2_become_writable( grpc_chttp2_become_writable(
@ -2350,7 +2380,7 @@ static void read_action_locked(grpc_exec_ctx *exec_ctx, void *tp,
"unstalled"); "unstalled");
} }
} }
t->initial_window_update = 0; t->flow_control.initial_window_update = 0;
} }
GPR_TIMER_END("post_parse_locked", 0); GPR_TIMER_END("post_parse_locked", 0);
} }
@ -2624,54 +2654,6 @@ static void incoming_byte_stream_unref(grpc_exec_ctx *exec_ctx,
} }
} }
static void incoming_byte_stream_update_flow_control(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s,
size_t max_size_hint,
size_t have_already) {
uint32_t max_recv_bytes;
uint32_t initial_window_size =
t->settings[GRPC_SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
/* clamp max recv hint to an allowable size */
if (max_size_hint >= UINT32_MAX - initial_window_size) {
max_recv_bytes = UINT32_MAX - initial_window_size;
} else {
max_recv_bytes = (uint32_t)max_size_hint;
}
/* account for bytes already received but unknown to higher layers */
if (max_recv_bytes >= have_already) {
max_recv_bytes -= (uint32_t)have_already;
} else {
max_recv_bytes = 0;
}
/* add some small lookahead to keep pipelines flowing */
GPR_ASSERT(max_recv_bytes <= UINT32_MAX - initial_window_size);
if (s->incoming_window_delta < max_recv_bytes && !s->read_closed) {
uint32_t add_max_recv_bytes =
(uint32_t)(max_recv_bytes - s->incoming_window_delta);
grpc_chttp2_stream_write_type write_type =
GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED;
if (s->incoming_window_delta + initial_window_size <
(int64_t)have_already) {
write_type = GRPC_CHTTP2_STREAM_WRITE_INITIATE_COVERED;
}
GRPC_CHTTP2_FLOW_CREDIT_STREAM_INCOMING_WINDOW_DELTA("op", t, s,
add_max_recv_bytes);
GRPC_CHTTP2_FLOW_CREDIT_STREAM("op", t, s, announce_window,
add_max_recv_bytes);
if ((int64_t)s->incoming_window_delta + (int64_t)initial_window_size -
(int64_t)s->announce_window >
(int64_t)initial_window_size / 2) {
write_type = GRPC_CHTTP2_STREAM_WRITE_PIGGYBACK;
}
grpc_chttp2_become_writable(exec_ctx, t, s, write_type,
"read_incoming_stream");
}
}
static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx, static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
void *argp, void *argp,
grpc_error *error_ignored) { grpc_error *error_ignored) {
@ -2680,9 +2662,15 @@ static void incoming_byte_stream_next_locked(grpc_exec_ctx *exec_ctx,
grpc_chttp2_stream *s = bs->stream; grpc_chttp2_stream *s = bs->stream;
size_t cur_length = s->frame_storage.length; size_t cur_length = s->frame_storage.length;
incoming_byte_stream_update_flow_control( if (!s->read_closed) {
exec_ctx, t, s, bs->next_action.max_size_hint, cur_length); grpc_chttp2_flowctl_incoming_bs_update(&t->flow_control, &s->flow_control,
bs->next_action.max_size_hint,
cur_length);
grpc_chttp2_act_on_flowctl_action(
exec_ctx,
grpc_chttp2_flowctl_get_action(&t->flow_control, &s->flow_control), t,
s);
}
GPR_ASSERT(s->unprocessed_incoming_frames_buffer.length == 0); GPR_ASSERT(s->unprocessed_incoming_frames_buffer.length == 0);
if (s->frame_storage.length > 0) { if (s->frame_storage.length > 0) {
grpc_slice_buffer_swap(&s->frame_storage, grpc_slice_buffer_swap(&s->frame_storage,
@ -2991,83 +2979,6 @@ static void destructive_reclaimer_locked(grpc_exec_ctx *exec_ctx, void *arg,
GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destructive_reclaimer"); GRPC_CHTTP2_UNREF_TRANSPORT(exec_ctx, t, "destructive_reclaimer");
} }
/*******************************************************************************
* TRACING
*/
static char *format_flowctl_context_var(const char *context, const char *var,
int64_t val, uint32_t id) {
char *name;
if (context == NULL) {
name = gpr_strdup(var);
} else if (0 == strcmp(context, "t")) {
GPR_ASSERT(id == 0);
gpr_asprintf(&name, "TRANSPORT:%s", var);
} else if (0 == strcmp(context, "s")) {
GPR_ASSERT(id != 0);
gpr_asprintf(&name, "STREAM[%d]:%s", id, var);
} else {
gpr_asprintf(&name, "BAD_CONTEXT[%s][%d]:%s", context, id, var);
}
char *name_fld = gpr_leftpad(name, ' ', 64);
char *value;
gpr_asprintf(&value, "%" PRId64, val);
char *value_fld = gpr_leftpad(value, ' ', 8);
char *result;
gpr_asprintf(&result, "%s %s", name_fld, value_fld);
gpr_free(name);
gpr_free(name_fld);
gpr_free(value);
gpr_free(value_fld);
return result;
}
void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
grpc_chttp2_flowctl_op op, const char *context1,
const char *var1, const char *context2,
const char *var2, int is_client,
uint32_t stream_id, int64_t val1, int64_t val2) {
char *tmp_phase;
char *label1 = format_flowctl_context_var(context1, var1, val1, stream_id);
char *label2 = format_flowctl_context_var(context2, var2, val2, stream_id);
char *clisvr = is_client ? "client" : "server";
char *prefix;
tmp_phase = gpr_leftpad(phase, ' ', 8);
gpr_asprintf(&prefix, "FLOW %s: %s ", tmp_phase, clisvr);
gpr_free(tmp_phase);
switch (op) {
case GRPC_CHTTP2_FLOWCTL_MOVE:
if (val2 != 0) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"%sMOVE %s <- %s giving %" PRId64, prefix, label1, label2,
val1 + val2);
}
break;
case GRPC_CHTTP2_FLOWCTL_CREDIT:
GPR_ASSERT(val2 >= 0);
if (val2 != 0) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"%sCREDIT %s by %s giving %" PRId64, prefix, label1, label2,
val1 + val2);
}
break;
case GRPC_CHTTP2_FLOWCTL_DEBIT:
GPR_ASSERT(val2 >= 0);
if (val2 != 0) {
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
"%sDEBIT %s by %s giving %" PRId64, prefix, label1, label2,
val1 - val2);
}
break;
}
gpr_free(label1);
gpr_free(label2);
gpr_free(prefix);
}
/******************************************************************************* /*******************************************************************************
* INTEGRATION GLUE * INTEGRATION GLUE
*/ */

@ -0,0 +1,369 @@
/*
*
* 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.
*
*/
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/useful.h>
#include "src/core/lib/support/string.h"
static uint32_t grpc_chttp2_target_announced_window(
const grpc_chttp2_transport_flowctl* tfc);
#ifndef NDEBUG
typedef struct {
int64_t remote_window;
int64_t target_window;
int64_t announced_window;
int64_t remote_window_delta;
int64_t local_window_delta;
int64_t announced_window_delta;
} shadow_flow_control;
static void pretrace(shadow_flow_control* shadow_fc,
grpc_chttp2_transport_flowctl* tfc,
grpc_chttp2_stream_flowctl* sfc) {
shadow_fc->remote_window = tfc->remote_window;
shadow_fc->target_window = grpc_chttp2_target_announced_window(tfc);
shadow_fc->announced_window = tfc->announced_window;
if (sfc != NULL) {
shadow_fc->remote_window_delta = sfc->remote_window_delta;
shadow_fc->local_window_delta = sfc->local_window_delta;
shadow_fc->announced_window_delta = sfc->announced_window_delta;
}
}
static char* fmt_str(int64_t old, int64_t new) {
char* str;
if (old != new) {
gpr_asprintf(&str, "%" PRId64 " -> %" PRId64 "", old, new);
} else {
gpr_asprintf(&str, "%" PRId64 "", old);
}
char* str_lp = gpr_leftpad(str, ' ', 30);
gpr_free(str);
return str_lp;
}
static void posttrace(shadow_flow_control* shadow_fc,
grpc_chttp2_transport_flowctl* tfc,
grpc_chttp2_stream_flowctl* sfc, char* reason) {
uint32_t acked_local_window =
tfc->t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
uint32_t remote_window =
tfc->t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
char* trw_str = fmt_str(shadow_fc->remote_window, tfc->remote_window);
char* tlw_str = fmt_str(shadow_fc->target_window,
grpc_chttp2_target_announced_window(tfc));
char* taw_str = fmt_str(shadow_fc->announced_window, tfc->announced_window);
char* srw_str;
char* slw_str;
char* saw_str;
if (sfc != NULL) {
srw_str = fmt_str(shadow_fc->remote_window_delta + remote_window,
sfc->remote_window_delta + remote_window);
slw_str = fmt_str(shadow_fc->local_window_delta + acked_local_window,
sfc->local_window_delta + acked_local_window);
saw_str = fmt_str(shadow_fc->announced_window_delta + acked_local_window,
sfc->announced_window_delta + acked_local_window);
} else {
srw_str = gpr_leftpad("", ' ', 30);
slw_str = gpr_leftpad("", ' ', 30);
saw_str = gpr_leftpad("", ' ', 30);
}
gpr_log(GPR_DEBUG,
"%p[%u][%s] | %s | trw:%s, ttw:%s, taw:%s, srw:%s, slw:%s, saw:%s",
tfc, sfc != NULL ? sfc->s->id : 0, tfc->t->is_client ? "cli" : "svr",
reason, trw_str, tlw_str, taw_str, srw_str, slw_str, saw_str);
gpr_free(trw_str);
gpr_free(tlw_str);
gpr_free(taw_str);
gpr_free(srw_str);
gpr_free(slw_str);
gpr_free(saw_str);
}
static char* urgency_to_string(grpc_chttp2_flowctl_urgency urgency) {
switch (urgency) {
case GRPC_CHTTP2_FLOWCTL_NO_ACTION_NEEDED:
return "no action";
case GRPC_CHTTP2_FLOWCTL_UPDATE_IMMEDIATELY:
return "update immediately";
case GRPC_CHTTP2_FLOWCTL_QUEUE_UPDATE:
return "queue update";
default:
GPR_UNREACHABLE_CODE(return "unknown");
}
GPR_UNREACHABLE_CODE(return "unknown");
}
static void trace_action(grpc_chttp2_flowctl_action action) {
gpr_log(GPR_DEBUG, "transport: %s, stream: %s",
urgency_to_string(action.send_transport_update),
urgency_to_string(action.send_stream_update));
}
#define PRETRACE(tfc, sfc) \
shadow_flow_control shadow_fc; \
GRPC_FLOW_CONTROL_IF_TRACING(pretrace(&shadow_fc, tfc, sfc))
#define POSTTRACE(tfc, sfc, reason) \
GRPC_FLOW_CONTROL_IF_TRACING(posttrace(&shadow_fc, tfc, sfc, reason))
#define TRACEACTION(action) GRPC_FLOW_CONTROL_IF_TRACING(trace_action(action))
#else
#define PRETRACE(tfc, sfc)
#define POSTTRACE(tfc, sfc, reason)
#define TRACEACTION(action)
#endif
/* How many bytes of incoming flow control would we like to advertise */
static uint32_t grpc_chttp2_target_announced_window(
const grpc_chttp2_transport_flowctl* tfc) {
return (uint32_t)GPR_MIN(
(int64_t)((1u << 31) - 1),
tfc->announced_stream_total_over_incoming_window +
tfc->t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
}
// we have sent data on the wire, we must track this in our bookkeeping for the
// remote peer's flow control.
void grpc_chttp2_flowctl_sent_data(grpc_chttp2_transport_flowctl* tfc,
grpc_chttp2_stream_flowctl* sfc,
int64_t size) {
PRETRACE(tfc, sfc);
tfc->remote_window -= size;
sfc->remote_window_delta -= size;
POSTTRACE(tfc, sfc, " data sent");
}
static void announced_window_delta_preupdate(grpc_chttp2_transport_flowctl* tfc,
grpc_chttp2_stream_flowctl* sfc) {
if (sfc->announced_window_delta > 0) {
tfc->announced_stream_total_over_incoming_window -=
sfc->announced_window_delta;
} else {
tfc->announced_stream_total_under_incoming_window +=
-sfc->announced_window_delta;
}
}
static void announced_window_delta_postupdate(
grpc_chttp2_transport_flowctl* tfc, grpc_chttp2_stream_flowctl* sfc) {
if (sfc->announced_window_delta > 0) {
tfc->announced_stream_total_over_incoming_window +=
sfc->announced_window_delta;
} else {
tfc->announced_stream_total_under_incoming_window -=
-sfc->announced_window_delta;
}
}
// We have received data from the wire. We must track this in our own flow
// control bookkeeping.
// Returns an error if the incoming frame violates our flow control.
grpc_error* grpc_chttp2_flowctl_recv_data(grpc_chttp2_transport_flowctl* tfc,
grpc_chttp2_stream_flowctl* sfc,
int64_t incoming_frame_size) {
uint32_t sent_init_window =
tfc->t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
uint32_t acked_init_window =
tfc->t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
PRETRACE(tfc, sfc);
if (incoming_frame_size > tfc->announced_window) {
char* msg;
gpr_asprintf(&msg,
"frame of size %" PRId64 " overflows local window of %" PRId64,
incoming_frame_size, tfc->announced_window);
grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
return err;
}
if (sfc != NULL) {
int64_t acked_stream_window =
sfc->announced_window_delta + acked_init_window;
int64_t sent_stream_window = sfc->announced_window_delta + sent_init_window;
if (incoming_frame_size > acked_stream_window) {
if (incoming_frame_size <= sent_stream_window) {
gpr_log(
GPR_ERROR,
"Incoming frame of size %" PRId64
" exceeds local window size of %" PRId64
".\n"
"The (un-acked, future) window size would be %" PRId64
" which is not exceeded.\n"
"This would usually cause a disconnection, but allowing it due to"
"broken HTTP2 implementations in the wild.\n"
"See (for example) https://github.com/netty/netty/issues/6520.",
incoming_frame_size, acked_stream_window, sent_stream_window);
} else {
char* msg;
gpr_asprintf(&msg, "frame of size %" PRId64
" overflows local window of %" PRId64,
incoming_frame_size, acked_stream_window);
grpc_error* err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
return err;
}
}
announced_window_delta_preupdate(tfc, sfc);
sfc->announced_window_delta -= incoming_frame_size;
announced_window_delta_postupdate(tfc, sfc);
sfc->local_window_delta -= incoming_frame_size;
}
tfc->announced_window -= incoming_frame_size;
POSTTRACE(tfc, sfc, " data recv");
return GRPC_ERROR_NONE;
}
// Returns a non zero announce integer if we should send a transport window
// update
uint32_t grpc_chttp2_flowctl_maybe_send_transport_update(
grpc_chttp2_transport_flowctl* tfc) {
PRETRACE(tfc, NULL);
uint32_t target_announced_window = grpc_chttp2_target_announced_window(tfc);
uint32_t threshold_to_send_transport_window_update =
tfc->t->outbuf.count > 0 ? 3 * target_announced_window / 4
: target_announced_window / 2;
if (tfc->announced_window <= threshold_to_send_transport_window_update &&
tfc->announced_window != target_announced_window) {
uint32_t announce = (uint32_t)GPR_CLAMP(
target_announced_window - tfc->announced_window, 0, UINT32_MAX);
tfc->announced_window += announce;
POSTTRACE(tfc, NULL, "t updt sent");
return announce;
}
GRPC_FLOW_CONTROL_IF_TRACING(
gpr_log(GPR_DEBUG, "%p[0][%s] will not send transport update", tfc,
tfc->t->is_client ? "cli" : "svr"));
return 0;
}
// Returns a non zero announce integer if we should send a stream window update
uint32_t grpc_chttp2_flowctl_maybe_send_stream_update(
grpc_chttp2_transport_flowctl* tfc, grpc_chttp2_stream_flowctl* sfc) {
PRETRACE(tfc, sfc);
if (sfc->local_window_delta > sfc->announced_window_delta) {
uint32_t announce = (uint32_t)GPR_CLAMP(
sfc->local_window_delta - sfc->announced_window_delta, 0, UINT32_MAX);
announced_window_delta_preupdate(tfc, sfc);
sfc->announced_window_delta += announce;
announced_window_delta_postupdate(tfc, sfc);
POSTTRACE(tfc, sfc, "s updt sent");
return announce;
}
GRPC_FLOW_CONTROL_IF_TRACING(
gpr_log(GPR_DEBUG, "%p[%u][%s] will not send stream update", tfc,
sfc->s->id, tfc->t->is_client ? "cli" : "svr"));
return 0;
}
// we have received a WINDOW_UPDATE frame for a transport
void grpc_chttp2_flowctl_recv_transport_update(
grpc_chttp2_transport_flowctl* tfc, uint32_t size) {
PRETRACE(tfc, NULL);
tfc->remote_window += size;
POSTTRACE(tfc, NULL, "t updt recv");
}
// we have received a WINDOW_UPDATE frame for a stream
void grpc_chttp2_flowctl_recv_stream_update(grpc_chttp2_transport_flowctl* tfc,
grpc_chttp2_stream_flowctl* sfc,
uint32_t size) {
PRETRACE(tfc, sfc);
sfc->remote_window_delta += size;
POSTTRACE(tfc, sfc, "s updt recv");
}
void grpc_chttp2_flowctl_incoming_bs_update(grpc_chttp2_transport_flowctl* tfc,
grpc_chttp2_stream_flowctl* sfc,
size_t max_size_hint,
size_t have_already) {
PRETRACE(tfc, sfc);
uint32_t max_recv_bytes;
uint32_t sent_init_window =
tfc->t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
/* clamp max recv hint to an allowable size */
if (max_size_hint >= UINT32_MAX - sent_init_window) {
max_recv_bytes = UINT32_MAX - sent_init_window;
} else {
max_recv_bytes = (uint32_t)max_size_hint;
}
/* account for bytes already received but unknown to higher layers */
if (max_recv_bytes >= have_already) {
max_recv_bytes -= (uint32_t)have_already;
} else {
max_recv_bytes = 0;
}
/* add some small lookahead to keep pipelines flowing */
GPR_ASSERT(max_recv_bytes <= UINT32_MAX - sent_init_window);
if (sfc->local_window_delta < max_recv_bytes) {
uint32_t add_max_recv_bytes =
(uint32_t)(max_recv_bytes - sfc->local_window_delta);
sfc->local_window_delta += add_max_recv_bytes;
}
POSTTRACE(tfc, sfc, "app st recv");
}
void grpc_chttp2_flowctl_destroy_stream(grpc_chttp2_transport_flowctl* tfc,
grpc_chttp2_stream_flowctl* sfc) {
announced_window_delta_preupdate(tfc, sfc);
}
grpc_chttp2_flowctl_action grpc_chttp2_flowctl_get_action(
const grpc_chttp2_transport_flowctl* tfc,
const grpc_chttp2_stream_flowctl* sfc) {
grpc_chttp2_flowctl_action action;
memset(&action, 0, sizeof(action));
uint32_t target_announced_window = grpc_chttp2_target_announced_window(tfc);
if (tfc->announced_window < target_announced_window / 2) {
action.send_transport_update = GRPC_CHTTP2_FLOWCTL_UPDATE_IMMEDIATELY;
}
if (sfc != NULL && !sfc->s->read_closed) {
uint32_t sent_init_window =
tfc->t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
if ((int64_t)sfc->local_window_delta >
(int64_t)sfc->announced_window_delta &&
(int64_t)sfc->announced_window_delta + sent_init_window <=
sent_init_window / 2) {
action.send_stream_update = GRPC_CHTTP2_FLOWCTL_UPDATE_IMMEDIATELY;
} else if (sfc->local_window_delta > sfc->announced_window_delta) {
action.send_stream_update = GRPC_CHTTP2_FLOWCTL_QUEUE_UPDATE;
}
}
TRACEACTION(action);
return action;
}

@ -201,11 +201,13 @@ grpc_error *grpc_chttp2_settings_parser_parse(grpc_exec_ctx *exec_ctx, void *p,
} }
if (id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE && if (id == GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE &&
parser->incoming_settings[id] != parser->value) { parser->incoming_settings[id] != parser->value) {
t->initial_window_update += t->flow_control.initial_window_update +=
(int64_t)parser->value - parser->incoming_settings[id]; (int64_t)parser->value - parser->incoming_settings[id];
if (GRPC_TRACER_ON(grpc_http_trace)) { if (GRPC_TRACER_ON(grpc_http_trace) ||
gpr_log(GPR_DEBUG, "adding %d for initial_window change", GRPC_TRACER_ON(grpc_flowctl_trace)) {
(int)t->initial_window_update); gpr_log(GPR_DEBUG, "%p[%s] adding %d for initial_window change",
t, t->is_client ? "cli" : "svr",
(int)t->flow_control.initial_window_update);
} }
} }
parser->incoming_settings[id] = parser->value; parser->incoming_settings[id] = parser->value;

@ -95,8 +95,8 @@ grpc_error *grpc_chttp2_window_update_parser_parse(
if (t->incoming_stream_id != 0) { if (t->incoming_stream_id != 0) {
if (s != NULL) { if (s != NULL) {
GRPC_CHTTP2_FLOW_CREDIT_STREAM("parse", t, s, outgoing_window_delta, grpc_chttp2_flowctl_recv_stream_update(
received_update); &t->flow_control, &s->flow_control, received_update);
if (grpc_chttp2_list_remove_stalled_by_stream(t, s)) { if (grpc_chttp2_list_remove_stalled_by_stream(t, s)) {
grpc_chttp2_become_writable( grpc_chttp2_become_writable(
exec_ctx, t, s, GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED, exec_ctx, t, s, GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
@ -104,10 +104,10 @@ grpc_error *grpc_chttp2_window_update_parser_parse(
} }
} }
} else { } else {
bool was_zero = t->outgoing_window <= 0; bool was_zero = t->flow_control.remote_window <= 0;
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("parse", t, outgoing_window, grpc_chttp2_flowctl_recv_transport_update(&t->flow_control,
received_update); received_update);
bool is_zero = t->outgoing_window <= 0; bool is_zero = t->flow_control.remote_window <= 0;
if (was_zero && !is_zero) { if (was_zero && !is_zero) {
grpc_chttp2_initiate_write(exec_ctx, t, "new_global_flow_control"); grpc_chttp2_initiate_write(exec_ctx, t, "new_global_flow_control");
} }

@ -213,6 +213,35 @@ typedef enum {
GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED, GRPC_CHTTP2_KEEPALIVE_STATE_DISABLED,
} grpc_chttp2_keepalive_state; } grpc_chttp2_keepalive_state;
typedef struct {
/** initial window change. This is tracked as we parse settings frames from
* the remote peer. If there is a positive delta, then we will make all
* streams readable since they may have become unstalled */
int64_t initial_window_update;
/** Our bookkeeping for the remote peer's available window */
int64_t remote_window;
/** calculating what we should give for local window:
we track the total amount of flow control over initial window size
across all streams: this is data that we want to receive right now (it
has an outstanding read)
and the total amount of flow control under initial window size across all
streams: this is data we've read early
we want to adjust incoming_window such that:
incoming_window = total_over - max(bdp - total_under, 0) */
int64_t announced_stream_total_over_incoming_window;
int64_t announced_stream_total_under_incoming_window;
/** This is out window according to what we have sent to our remote peer. The
* difference between this and target window is what we use to decide when
* to send WINDOW_UPDATE frames. */
int64_t announced_window;
// read only pointer back to transport for certain data
const grpc_chttp2_transport *t;
} grpc_chttp2_transport_flowctl;
struct grpc_chttp2_transport { struct grpc_chttp2_transport {
grpc_transport base; /* must be first */ grpc_transport base; /* must be first */
gpr_refcount refs; gpr_refcount refs;
@ -271,7 +300,6 @@ struct grpc_chttp2_transport {
grpc_slice_buffer outbuf; grpc_slice_buffer outbuf;
/** hpack encoding */ /** hpack encoding */
grpc_chttp2_hpack_compressor hpack_compressor; grpc_chttp2_hpack_compressor hpack_compressor;
int64_t outgoing_window;
/** is this a client? */ /** is this a client? */
uint8_t is_client; uint8_t is_client;
@ -328,21 +356,14 @@ struct grpc_chttp2_transport {
/** parser for goaway frames */ /** parser for goaway frames */
grpc_chttp2_goaway_parser goaway_parser; grpc_chttp2_goaway_parser goaway_parser;
/** initial window change */ grpc_chttp2_transport_flowctl flow_control;
int64_t initial_window_update;
/** window available for peer to send to us */ /* bdp estimation */
int64_t incoming_window; grpc_bdp_estimator bdp_estimator;
/** calculating what we should give for incoming window:
we track the total amount of flow control over initial window size /* pid controller */
across all streams: this is data that we want to receive right now (it grpc_pid_controller pid_controller;
has an outstanding read) gpr_timespec last_pid_update;
and the total amount of flow control under initial window size across all
streams: this is data we've read early
we want to adjust incoming_window such that:
incoming_window = total_over - max(bdp - total_under, 0) */
int64_t stream_total_over_incoming_window;
int64_t stream_total_under_incoming_window;
/* deframing */ /* deframing */
grpc_chttp2_deframe_transport_state deframe_state; grpc_chttp2_deframe_transport_state deframe_state;
@ -369,11 +390,8 @@ struct grpc_chttp2_transport {
grpc_chttp2_write_cb *write_cb_pool; grpc_chttp2_write_cb *write_cb_pool;
/* bdp estimator */ /* bdp estimator */
grpc_bdp_estimator bdp_estimator;
grpc_pid_controller pid_controller;
grpc_closure start_bdp_ping_locked; grpc_closure start_bdp_ping_locked;
grpc_closure finish_bdp_ping_locked; grpc_closure finish_bdp_ping_locked;
gpr_timespec last_pid_update;
/* if non-NULL, close the transport with this error when writes are finished /* if non-NULL, close the transport with this error when writes are finished
*/ */
@ -422,6 +440,25 @@ typedef enum {
GPRC_METADATA_PUBLISHED_AT_CLOSE GPRC_METADATA_PUBLISHED_AT_CLOSE
} grpc_published_metadata_method; } grpc_published_metadata_method;
typedef struct {
/** window available for us to send to peer, over or under the initial window
* size of the transport... ie:
* remote_window = remote_window_delta + transport.initial_window_size */
int64_t remote_window_delta;
/** window available for peer to send to us (as a delta on
* transport.initial_window_size)
* local_window = local_window_delta + transport.initial_window_size */
int64_t local_window_delta;
/** window available for peer to send to us over this stream that we have
* announced to the peer */
int64_t announced_window_delta;
// read only pointer back to stream for data
const grpc_chttp2_stream *s;
} grpc_chttp2_stream_flowctl;
struct grpc_chttp2_stream { struct grpc_chttp2_stream {
grpc_chttp2_transport *t; grpc_chttp2_transport *t;
grpc_stream_refcount *refcount; grpc_stream_refcount *refcount;
@ -435,10 +472,6 @@ struct grpc_chttp2_stream {
/** HTTP2 stream id for this stream, or zero if one has not been assigned */ /** HTTP2 stream id for this stream, or zero if one has not been assigned */
uint32_t id; uint32_t id;
/** window available for us to send to peer, over or under the initial window
* size of the transport... ie:
* outgoing_window = outgoing_window_delta + transport.initial_window_size */
int64_t outgoing_window_delta;
/** things the upper layers would like to send */ /** things the upper layers would like to send */
grpc_metadata_batch *send_initial_metadata; grpc_metadata_batch *send_initial_metadata;
grpc_closure *send_initial_metadata_finished; grpc_closure *send_initial_metadata_finished;
@ -505,10 +538,6 @@ struct grpc_chttp2_stream {
grpc_error *forced_close_error; grpc_error *forced_close_error;
/** how many header frames have we received? */ /** how many header frames have we received? */
uint8_t header_frames_received; uint8_t header_frames_received;
/** window available for peer to send to us (as a delta on
* transport.initial_window_size)
* incoming_window = incoming_window_delta + transport.initial_window_size */
int64_t incoming_window_delta;
/** parsing state for data frames */ /** parsing state for data frames */
/* Accessed only by transport thread when stream->pending_byte_stream == false /* Accessed only by transport thread when stream->pending_byte_stream == false
* Accessed only by application thread when stream->pending_byte_stream == * Accessed only by application thread when stream->pending_byte_stream ==
@ -519,8 +548,9 @@ struct grpc_chttp2_stream {
bool sent_initial_metadata; bool sent_initial_metadata;
bool sent_trailing_metadata; bool sent_trailing_metadata;
/** how much window should we announce? */
uint32_t announce_window; grpc_chttp2_stream_flowctl flow_control;
grpc_slice_buffer flow_controlled_buffer; grpc_slice_buffer flow_controlled_buffer;
grpc_chttp2_write_cb *on_write_finished_cbs; grpc_chttp2_write_cb *on_write_finished_cbs;
@ -621,6 +651,75 @@ bool grpc_chttp2_list_pop_stalled_by_stream(grpc_chttp2_transport *t,
bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t, bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s); grpc_chttp2_stream *s);
/********* Flow Control ***************/
// we have sent data on the wire
void grpc_chttp2_flowctl_sent_data(grpc_chttp2_transport_flowctl *tfc,
grpc_chttp2_stream_flowctl *sfc,
int64_t size);
// we have received data from the wire
grpc_error *grpc_chttp2_flowctl_recv_data(grpc_chttp2_transport_flowctl *tfc,
grpc_chttp2_stream_flowctl *sfc,
int64_t incoming_frame_size);
// returns an announce if we should send a transport update to our peer,
// else returns zero
uint32_t grpc_chttp2_flowctl_maybe_send_transport_update(
grpc_chttp2_transport_flowctl *tfc);
// returns an announce if we should send a stream update to our peer, else
// returns zero
uint32_t grpc_chttp2_flowctl_maybe_send_stream_update(
grpc_chttp2_transport_flowctl *tfc, grpc_chttp2_stream_flowctl *sfc);
// we have received a WINDOW_UPDATE frame for a transport
void grpc_chttp2_flowctl_recv_transport_update(
grpc_chttp2_transport_flowctl *tfc, uint32_t size);
// we have received a WINDOW_UPDATE frame for a stream
void grpc_chttp2_flowctl_recv_stream_update(grpc_chttp2_transport_flowctl *tfc,
grpc_chttp2_stream_flowctl *sfc,
uint32_t size);
// the application is asking for a certain amount of bytes
void grpc_chttp2_flowctl_incoming_bs_update(grpc_chttp2_transport_flowctl *tfc,
grpc_chttp2_stream_flowctl *sfc,
size_t max_size_hint,
size_t have_already);
void grpc_chttp2_flowctl_destroy_stream(grpc_chttp2_transport_flowctl *tfc,
grpc_chttp2_stream_flowctl *sfc);
typedef enum {
// Nothing to be done.
GRPC_CHTTP2_FLOWCTL_NO_ACTION_NEEDED = 0,
// Initiate a write to update the initial window immediately.
GRPC_CHTTP2_FLOWCTL_UPDATE_IMMEDIATELY,
// Push the flow control update into a send buffer, to be sent
// out the next time a write is initiated.
GRPC_CHTTP2_FLOWCTL_QUEUE_UPDATE,
} grpc_chttp2_flowctl_urgency;
typedef struct {
grpc_chttp2_flowctl_urgency send_stream_update;
grpc_chttp2_flowctl_urgency send_transport_update;
} grpc_chttp2_flowctl_action;
// Reads the flow control data and returns and actionable struct that will tell
// chttp2 exactly what it needs to do
grpc_chttp2_flowctl_action grpc_chttp2_flowctl_get_action(
const grpc_chttp2_transport_flowctl *tfc,
const grpc_chttp2_stream_flowctl *sfc);
// Takes in a flow control action and performs all the needed operations.
void grpc_chttp2_act_on_flowctl_action(grpc_exec_ctx *exec_ctx,
grpc_chttp2_flowctl_action action,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s);
/********* End of Flow Control ***************/
grpc_chttp2_stream *grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport *t, grpc_chttp2_stream *grpc_chttp2_parsing_lookup_stream(grpc_chttp2_transport *t,
uint32_t id); uint32_t id);
grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_stream *grpc_chttp2_parsing_accept_stream(grpc_exec_ctx *exec_ctx,
@ -651,126 +750,22 @@ void grpc_chttp2_complete_closure_step(grpc_exec_ctx *exec_ctx,
extern grpc_tracer_flag grpc_http_trace; extern grpc_tracer_flag grpc_http_trace;
extern grpc_tracer_flag grpc_flowctl_trace; extern grpc_tracer_flag grpc_flowctl_trace;
#ifndef NDEBUG
#define GRPC_FLOW_CONTROL_IF_TRACING(stmt) \
if (!(GRPC_TRACER_ON(grpc_flowctl_trace))) \
; \
else \
stmt
#else
#define GRPC_FLOW_CONTROL_IF_TRACING(stmt)
#endif
#define GRPC_CHTTP2_IF_TRACING(stmt) \ #define GRPC_CHTTP2_IF_TRACING(stmt) \
if (!(GRPC_TRACER_ON(grpc_http_trace))) \ if (!(GRPC_TRACER_ON(grpc_http_trace))) \
; \ ; \
else \ else \
stmt stmt
typedef enum {
GRPC_CHTTP2_FLOWCTL_MOVE,
GRPC_CHTTP2_FLOWCTL_CREDIT,
GRPC_CHTTP2_FLOWCTL_DEBIT
} grpc_chttp2_flowctl_op;
#define GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, transport, id1, id2, dst_context, \
dst_var, src_context, src_var) \
do { \
assert(id1 == id2); \
if (GRPC_TRACER_ON(grpc_flowctl_trace)) { \
grpc_chttp2_flowctl_trace( \
__FILE__, __LINE__, phase, GRPC_CHTTP2_FLOWCTL_MOVE, #dst_context, \
#dst_var, #src_context, #src_var, transport->is_client, id1, \
dst_context->dst_var, src_context->src_var); \
} \
dst_context->dst_var += src_context->src_var; \
src_context->src_var = 0; \
} while (0)
#define GRPC_CHTTP2_FLOW_MOVE_STREAM(phase, transport, dst_context, dst_var, \
src_context, src_var) \
GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, transport, dst_context->id, \
src_context->id, dst_context, dst_var, \
src_context, src_var)
#define GRPC_CHTTP2_FLOW_MOVE_TRANSPORT(phase, dst_context, dst_var, \
src_context, src_var) \
GRPC_CHTTP2_FLOW_MOVE_COMMON(phase, dst_context, 0, 0, dst_context, dst_var, \
src_context, src_var)
#define GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, transport, id, dst_context, \
dst_var, amount) \
do { \
if (GRPC_TRACER_ON(grpc_flowctl_trace)) { \
grpc_chttp2_flowctl_trace(__FILE__, __LINE__, phase, \
GRPC_CHTTP2_FLOWCTL_CREDIT, #dst_context, \
#dst_var, NULL, #amount, transport->is_client, \
id, dst_context->dst_var, amount); \
} \
dst_context->dst_var += amount; \
} while (0)
#define GRPC_CHTTP2_FLOW_CREDIT_STREAM(phase, transport, dst_context, dst_var, \
amount) \
GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, transport, dst_context->id, \
dst_context, dst_var, amount)
#define GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT(phase, dst_context, dst_var, amount) \
GRPC_CHTTP2_FLOW_CREDIT_COMMON(phase, dst_context, 0, dst_context, dst_var, \
amount)
#define GRPC_CHTTP2_FLOW_STREAM_INCOMING_WINDOW_DELTA_PREUPDATE( \
phase, transport, dst_context) \
if (dst_context->incoming_window_delta < 0) { \
transport->stream_total_under_incoming_window += \
dst_context->incoming_window_delta; \
} else if (dst_context->incoming_window_delta > 0) { \
transport->stream_total_over_incoming_window -= \
dst_context->incoming_window_delta; \
}
#define GRPC_CHTTP2_FLOW_STREAM_INCOMING_WINDOW_DELTA_POSTUPDATE( \
phase, transport, dst_context) \
if (dst_context->incoming_window_delta < 0) { \
transport->stream_total_under_incoming_window -= \
dst_context->incoming_window_delta; \
} else if (dst_context->incoming_window_delta > 0) { \
transport->stream_total_over_incoming_window += \
dst_context->incoming_window_delta; \
}
#define GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA( \
phase, transport, dst_context, amount) \
GRPC_CHTTP2_FLOW_STREAM_INCOMING_WINDOW_DELTA_PREUPDATE(phase, transport, \
dst_context); \
GRPC_CHTTP2_FLOW_DEBIT_STREAM(phase, transport, dst_context, \
incoming_window_delta, amount); \
GRPC_CHTTP2_FLOW_STREAM_INCOMING_WINDOW_DELTA_POSTUPDATE(phase, transport, \
dst_context);
#define GRPC_CHTTP2_FLOW_CREDIT_STREAM_INCOMING_WINDOW_DELTA( \
phase, transport, dst_context, amount) \
GRPC_CHTTP2_FLOW_STREAM_INCOMING_WINDOW_DELTA_PREUPDATE(phase, transport, \
dst_context); \
GRPC_CHTTP2_FLOW_CREDIT_STREAM(phase, transport, dst_context, \
incoming_window_delta, amount); \
GRPC_CHTTP2_FLOW_STREAM_INCOMING_WINDOW_DELTA_POSTUPDATE(phase, transport, \
dst_context);
#define GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, transport, id, dst_context, \
dst_var, amount) \
do { \
if (GRPC_TRACER_ON(grpc_flowctl_trace)) { \
grpc_chttp2_flowctl_trace(__FILE__, __LINE__, phase, \
GRPC_CHTTP2_FLOWCTL_DEBIT, #dst_context, \
#dst_var, NULL, #amount, transport->is_client, \
id, dst_context->dst_var, amount); \
} \
dst_context->dst_var -= amount; \
} while (0)
#define GRPC_CHTTP2_FLOW_DEBIT_STREAM(phase, transport, dst_context, dst_var, \
amount) \
GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, transport, dst_context->id, \
dst_context, dst_var, amount)
#define GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT(phase, dst_context, dst_var, amount) \
GRPC_CHTTP2_FLOW_DEBIT_COMMON(phase, dst_context, 0, dst_context, dst_var, \
amount)
void grpc_chttp2_flowctl_trace(const char *file, int line, const char *phase,
grpc_chttp2_flowctl_op op, const char *context1,
const char *var1, const char *context2,
const char *var2, int is_client,
uint32_t stream_id, int64_t val1, int64_t val2);
void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, void grpc_chttp2_fake_status(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
grpc_chttp2_stream *stream, grpc_error *error); grpc_chttp2_stream *stream, grpc_error *error);
void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx, void grpc_chttp2_mark_stream_closed(grpc_exec_ctx *exec_ctx,
@ -872,8 +867,6 @@ void grpc_chttp2_fail_pending_writes(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t, grpc_chttp2_transport *t,
grpc_chttp2_stream *s, grpc_error *error); grpc_chttp2_stream *s, grpc_error *error);
uint32_t grpc_chttp2_target_incoming_window(grpc_chttp2_transport *t);
/** Set the default keepalive configurations, must only be called at /** Set the default keepalive configurations, must only be called at
initialization */ initialization */
void grpc_chttp2_config_default_keepalive_args(grpc_channel_args *args, void grpc_chttp2_config_default_keepalive_args(grpc_channel_args *args,

@ -349,93 +349,25 @@ void grpc_chttp2_parsing_become_skip_parser(grpc_exec_ctx *exec_ctx,
t->parser == grpc_chttp2_header_parser_parse); t->parser == grpc_chttp2_header_parser_parse);
} }
static grpc_error *update_incoming_window(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
uint32_t incoming_frame_size = t->incoming_frame_size;
if (incoming_frame_size > t->incoming_window) {
char *msg;
gpr_asprintf(&msg, "frame of size %d overflows incoming window of %" PRId64,
t->incoming_frame_size, t->incoming_window);
grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
return err;
}
if (s != NULL) {
if (incoming_frame_size >
s->incoming_window_delta +
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
if (incoming_frame_size <=
s->incoming_window_delta +
t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]) {
gpr_log(
GPR_ERROR,
"Incoming frame of size %d exceeds incoming window size of %" PRId64
".\n"
"The (un-acked, future) window size would be %" PRId64
" which is not exceeded.\n"
"This would usually cause a disconnection, but allowing it due to "
"broken HTTP2 implementations in the wild.\n"
"See (for example) https://github.com/netty/netty/issues/6520.",
t->incoming_frame_size,
s->incoming_window_delta +
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
s->incoming_window_delta +
t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
} else {
char *msg;
gpr_asprintf(&msg,
"frame of size %d overflows incoming window of %" PRId64,
t->incoming_frame_size,
s->incoming_window_delta +
t->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
grpc_error *err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
return err;
}
}
GRPC_CHTTP2_FLOW_DEBIT_STREAM_INCOMING_WINDOW_DELTA("parse", t, s,
incoming_frame_size);
if ((int64_t)s->incoming_window_delta - (int64_t)s->announce_window <=
-(int64_t)t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] /
2) {
grpc_chttp2_become_writable(exec_ctx, t, s,
GRPC_CHTTP2_STREAM_WRITE_INITIATE_UNCOVERED,
"window-update-required");
}
s->received_bytes += incoming_frame_size;
}
uint32_t target_incoming_window = grpc_chttp2_target_incoming_window(t);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("parse", t, incoming_window,
incoming_frame_size);
if (t->incoming_window <= target_incoming_window / 2) {
grpc_chttp2_initiate_write(exec_ctx, t, "flow_control");
}
return GRPC_ERROR_NONE;
}
static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx, static grpc_error *init_data_frame_parser(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport *t) { grpc_chttp2_transport *t) {
grpc_chttp2_stream *s = grpc_chttp2_stream *s =
grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id); grpc_chttp2_parsing_lookup_stream(t, t->incoming_stream_id);
grpc_error *err = GRPC_ERROR_NONE; grpc_error *err = GRPC_ERROR_NONE;
err = update_incoming_window(exec_ctx, t, s); err = grpc_chttp2_flowctl_recv_data(&t->flow_control,
s == NULL ? NULL : &s->flow_control,
t->incoming_frame_size);
grpc_chttp2_act_on_flowctl_action(
exec_ctx, grpc_chttp2_flowctl_get_action(
&t->flow_control, s == NULL ? NULL : &s->flow_control),
t, s);
if (err != GRPC_ERROR_NONE) { if (err != GRPC_ERROR_NONE) {
goto error_handler; goto error_handler;
} }
if (s == NULL) { if (s == NULL) {
return init_skip_frame_parser(exec_ctx, t, 0); return init_skip_frame_parser(exec_ctx, t, 0);
} }
s->received_bytes += t->incoming_frame_size;
s->stats.incoming.framing_bytes += 9; s->stats.incoming.framing_bytes += 9;
if (err == GRPC_ERROR_NONE && s->read_closed) { if (err == GRPC_ERROR_NONE && s->read_closed) {
return init_skip_frame_parser(exec_ctx, t, 0); return init_skip_frame_parser(exec_ctx, t, 0);

@ -150,12 +150,17 @@ void grpc_chttp2_list_remove_waiting_for_concurrency(grpc_chttp2_transport *t,
void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t, void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) { grpc_chttp2_stream *s) {
GRPC_FLOW_CONTROL_IF_TRACING(
gpr_log(GPR_DEBUG, "stream %u stalled by transport", s->id));
stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
} }
bool grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t, bool grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) { grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT); bool ret = stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
GRPC_FLOW_CONTROL_IF_TRACING(if (ret) gpr_log(
GPR_DEBUG, "stream %u un-stalled by transport", (*s)->id));
return ret;
} }
void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t, void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t,
@ -165,15 +170,23 @@ void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t,
void grpc_chttp2_list_add_stalled_by_stream(grpc_chttp2_transport *t, void grpc_chttp2_list_add_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) { grpc_chttp2_stream *s) {
GRPC_FLOW_CONTROL_IF_TRACING(
gpr_log(GPR_DEBUG, "stream %u stalled by stream", s->id));
stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM); stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
} }
bool grpc_chttp2_list_pop_stalled_by_stream(grpc_chttp2_transport *t, bool grpc_chttp2_list_pop_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) { grpc_chttp2_stream **s) {
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM); bool ret = stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
GRPC_FLOW_CONTROL_IF_TRACING(
if (ret) gpr_log(GPR_DEBUG, "stream %u un-stalled by stream", (*s)->id));
return ret;
} }
bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t, bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) { grpc_chttp2_stream *s) {
return stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM); bool ret = stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
GRPC_FLOW_CONTROL_IF_TRACING(
if (ret) gpr_log(GPR_DEBUG, "stream %u un-stalled by stream", s->id));
return ret;
} }

@ -37,12 +37,16 @@ void grpc_chttp2_hpack_write_varint_tail(uint32_t tail_value, uint8_t* target,
switch (tail_length) { switch (tail_length) {
case 5: case 5:
target[4] = (uint8_t)((tail_value >> 28) | 0x80); target[4] = (uint8_t)((tail_value >> 28) | 0x80);
/* fallthrough */
case 4: case 4:
target[3] = (uint8_t)((tail_value >> 21) | 0x80); target[3] = (uint8_t)((tail_value >> 21) | 0x80);
/* fallthrough */
case 3: case 3:
target[2] = (uint8_t)((tail_value >> 14) | 0x80); target[2] = (uint8_t)((tail_value >> 14) | 0x80);
/* fallthrough */
case 2: case 2:
target[1] = (uint8_t)((tail_value >> 7) | 0x80); target[1] = (uint8_t)((tail_value >> 7) | 0x80);
/* fallthrough */
case 1: case 1:
target[0] = (uint8_t)((tail_value) | 0x80); target[0] = (uint8_t)((tail_value) | 0x80);
} }

@ -148,15 +148,6 @@ static bool stream_ref_if_not_destroyed(gpr_refcount *r) {
return true; return true;
} }
/* How many bytes of incoming flow control would we like to advertise */
uint32_t grpc_chttp2_target_incoming_window(grpc_chttp2_transport *t) {
return (uint32_t)GPR_MIN(
(int64_t)((1u << 31) - 1),
t->stream_total_over_incoming_window +
t->settings[GRPC_SENT_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
}
/* How many bytes would we like to put on the wire during a single syscall */ /* How many bytes would we like to put on the wire during a single syscall */
static uint32_t target_write_size(grpc_chttp2_transport *t) { static uint32_t target_write_size(grpc_chttp2_transport *t) {
return 1024 * 1024; return 1024 * 1024;
@ -201,7 +192,7 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
&t->hpack_compressor, &t->hpack_compressor,
t->settings[GRPC_PEER_SETTINGS][GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]); t->settings[GRPC_PEER_SETTINGS][GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]);
if (t->outgoing_window > 0) { if (t->flow_control.remote_window > 0) {
while (grpc_chttp2_list_pop_stalled_by_transport(t, &s)) { while (grpc_chttp2_list_pop_stalled_by_transport(t, &s)) {
if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s) && if (!t->closed && grpc_chttp2_list_add_writable_stream(t, s) &&
stream_ref_if_not_destroyed(&s->refcount->refs)) { stream_ref_if_not_destroyed(&s->refcount->refs)) {
@ -227,10 +218,12 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
bool sent_initial_metadata = s->sent_initial_metadata; bool sent_initial_metadata = s->sent_initial_metadata;
bool now_writing = false; bool now_writing = false;
GRPC_CHTTP2_IF_TRACING(gpr_log( GRPC_CHTTP2_IF_TRACING(
GPR_DEBUG, "W:%p %s[%d] im-(sent,send)=(%d,%d) announce=%d", t, gpr_log(GPR_DEBUG, "W:%p %s[%d] im-(sent,send)=(%d,%d) announce=%d", t,
t->is_client ? "CLIENT" : "SERVER", s->id, sent_initial_metadata, t->is_client ? "CLIENT" : "SERVER", s->id,
s->send_initial_metadata != NULL, s->announce_window)); sent_initial_metadata, s->send_initial_metadata != NULL,
(int)(s->flow_control.local_window_delta -
s->flow_control.announced_window_delta)));
grpc_mdelem *extra_headers_for_trailing_metadata[2]; grpc_mdelem *extra_headers_for_trailing_metadata[2];
size_t num_extra_headers_for_trailing_metadata = 0; size_t num_extra_headers_for_trailing_metadata = 0;
@ -287,11 +280,12 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
sent_initial_metadata = true; sent_initial_metadata = true;
} }
/* send any window updates */ /* send any window updates */
if (s->announce_window > 0) { uint32_t stream_announce = grpc_chttp2_flowctl_maybe_send_stream_update(
uint32_t announce = s->announce_window; &t->flow_control, &s->flow_control);
grpc_slice_buffer_add(&t->outbuf, if (stream_announce > 0) {
grpc_chttp2_window_update_create( grpc_slice_buffer_add(
s->id, s->announce_window, &s->stats.outgoing)); &t->outbuf, grpc_chttp2_window_update_create(s->id, stream_announce,
&s->stats.outgoing));
t->ping_state.pings_before_data_required = t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data; t->ping_policy.max_pings_without_data;
if (!t->is_client) { if (!t->is_client) {
@ -299,22 +293,21 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
gpr_inf_past(GPR_CLOCK_MONOTONIC); gpr_inf_past(GPR_CLOCK_MONOTONIC);
t->ping_recv_state.ping_strikes = 0; t->ping_recv_state.ping_strikes = 0;
} }
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, announce_window, announce);
} }
if (sent_initial_metadata) { if (sent_initial_metadata) {
/* send any body bytes, if allowed by flow control */ /* send any body bytes, if allowed by flow control */
if (s->flow_controlled_buffer.length > 0 || if (s->flow_controlled_buffer.length > 0 ||
(s->stream_compression_send_enabled && (s->stream_compression_send_enabled &&
s->compressed_data_buffer->length > 0)) { s->compressed_data_buffer->length > 0)) {
uint32_t stream_outgoing_window = (uint32_t)GPR_MAX( uint32_t stream_remote_window = (uint32_t)GPR_MAX(
0, 0,
s->outgoing_window_delta + s->flow_control.remote_window_delta +
(int64_t)t->settings[GRPC_PEER_SETTINGS] (int64_t)t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]); [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE]);
uint32_t max_outgoing = (uint32_t)GPR_MIN( uint32_t max_outgoing = (uint32_t)GPR_MIN(
t->settings[GRPC_PEER_SETTINGS] t->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE], [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE],
GPR_MIN(stream_outgoing_window, t->outgoing_window)); GPR_MIN(stream_remote_window, t->flow_control.remote_window));
if (max_outgoing > 0) { if (max_outgoing > 0) {
bool is_last_data_frame = false; bool is_last_data_frame = false;
bool is_last_frame = false; bool is_last_frame = false;
@ -335,10 +328,8 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
grpc_chttp2_encode_data(s->id, s->compressed_data_buffer, grpc_chttp2_encode_data(s->id, s->compressed_data_buffer,
send_bytes, is_last_frame, send_bytes, is_last_frame,
&s->stats.outgoing, &t->outbuf); &s->stats.outgoing, &t->outbuf);
GRPC_CHTTP2_FLOW_DEBIT_STREAM( grpc_chttp2_flowctl_sent_data(&t->flow_control,
"write", t, s, outgoing_window_delta, send_bytes); &s->flow_control, send_bytes);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window,
send_bytes);
max_outgoing -= send_bytes; max_outgoing -= send_bytes;
if (s->compressed_data_buffer->length == 0) { if (s->compressed_data_buffer->length == 0) {
s->sending_bytes += s->uncompressed_data_size; s->sending_bytes += s->uncompressed_data_size;
@ -367,9 +358,7 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer, grpc_chttp2_encode_data(s->id, &s->flow_controlled_buffer,
send_bytes, is_last_frame, send_bytes, is_last_frame,
&s->stats.outgoing, &t->outbuf); &s->stats.outgoing, &t->outbuf);
GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", t, s, outgoing_window_delta, grpc_chttp2_flowctl_sent_data(&t->flow_control, &s->flow_control,
send_bytes);
GRPC_CHTTP2_FLOW_DEBIT_TRANSPORT("write", t, outgoing_window,
send_bytes); send_bytes);
s->sending_bytes += send_bytes; s->sending_bytes += send_bytes;
} }
@ -396,10 +385,10 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:fork"); GRPC_CHTTP2_STREAM_REF(s, "chttp2_writing:fork");
grpc_chttp2_list_add_writable_stream(t, s); grpc_chttp2_list_add_writable_stream(t, s);
} }
} else if (t->outgoing_window == 0) { } else if (t->flow_control.remote_window == 0) {
grpc_chttp2_list_add_stalled_by_transport(t, s); grpc_chttp2_list_add_stalled_by_transport(t, s);
now_writing = true; now_writing = true;
} else if (stream_outgoing_window == 0) { } else if (stream_remote_window == 0) {
grpc_chttp2_list_add_stalled_by_stream(t, s); grpc_chttp2_list_add_stalled_by_stream(t, s);
now_writing = true; now_writing = true;
} }
@ -453,22 +442,15 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
} }
} }
/* if the grpc_chttp2_transport is ready to send a window update, do so here uint32_t transport_announce =
also; 3/4 is a magic number that will likely get tuned soon */ grpc_chttp2_flowctl_maybe_send_transport_update(&t->flow_control);
uint32_t target_incoming_window = grpc_chttp2_target_incoming_window(t); if (transport_announce) {
uint32_t threshold_to_send_transport_window_update =
t->outbuf.count > 0 ? 3 * target_incoming_window / 4
: target_incoming_window / 2;
if (t->incoming_window <= threshold_to_send_transport_window_update &&
t->incoming_window != target_incoming_window) {
maybe_initiate_ping(exec_ctx, t, maybe_initiate_ping(exec_ctx, t,
GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE); GRPC_CHTTP2_PING_BEFORE_TRANSPORT_WINDOW_UPDATE);
uint32_t announced = (uint32_t)GPR_CLAMP(
target_incoming_window - t->incoming_window, 0, UINT32_MAX);
GRPC_CHTTP2_FLOW_CREDIT_TRANSPORT("write", t, incoming_window, announced);
grpc_transport_one_way_stats throwaway_stats; grpc_transport_one_way_stats throwaway_stats;
grpc_slice_buffer_add(&t->outbuf, grpc_chttp2_window_update_create( grpc_slice_buffer_add(
0, announced, &throwaway_stats)); &t->outbuf, grpc_chttp2_window_update_create(0, transport_announce,
&throwaway_stats));
t->ping_state.pings_before_data_required = t->ping_state.pings_before_data_required =
t->ping_policy.max_pings_without_data; t->ping_policy.max_pings_without_data;
if (!t->is_client) { if (!t->is_client) {

@ -178,6 +178,7 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) {
json_reader_string_clear(reader); json_reader_string_clear(reader);
reader->state = GRPC_JSON_STATE_VALUE_END; reader->state = GRPC_JSON_STATE_VALUE_END;
/* The missing break here is intentional. */ /* The missing break here is intentional. */
/* fallthrough */
case GRPC_JSON_STATE_VALUE_END: case GRPC_JSON_STATE_VALUE_END:
case GRPC_JSON_STATE_OBJECT_KEY_BEGIN: case GRPC_JSON_STATE_OBJECT_KEY_BEGIN:

@ -147,7 +147,7 @@ static void on_peer_checked(grpc_exec_ctx *exec_ctx, void *arg,
goto done; goto done;
} }
// Get unused bytes. // Get unused bytes.
unsigned char *unused_bytes = NULL; const unsigned char *unused_bytes = NULL;
size_t unused_bytes_size = 0; size_t unused_bytes_size = 0;
result = tsi_handshaker_result_get_unused_bytes( result = tsi_handshaker_result_get_unused_bytes(
h->handshaker_result, &unused_bytes, &unused_bytes_size); h->handshaker_result, &unused_bytes, &unused_bytes_size);

@ -62,8 +62,10 @@ uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed) {
switch (len & 3) { switch (len & 3) {
case 3: case 3:
k1 ^= ((uint32_t)tail[2]) << 16; k1 ^= ((uint32_t)tail[2]) << 16;
/* fallthrough */
case 2: case 2:
k1 ^= ((uint32_t)tail[1]) << 8; k1 ^= ((uint32_t)tail[1]) << 8;
/* fallthrough */
case 1: case 1:
k1 ^= tail[0]; k1 ^= tail[0];
k1 *= c1; k1 *= c1;

@ -391,7 +391,7 @@ static tsi_result fake_handshaker_result_create_frame_protector(
} }
static tsi_result fake_handshaker_result_get_unused_bytes( static tsi_result fake_handshaker_result_get_unused_bytes(
const tsi_handshaker_result *self, unsigned char **bytes, const tsi_handshaker_result *self, const unsigned char **bytes,
size_t *bytes_size) { size_t *bytes_size) {
fake_handshaker_result *result = (fake_handshaker_result *)self; fake_handshaker_result *result = (fake_handshaker_result *)self;
*bytes_size = result->unused_bytes_size; *bytes_size = result->unused_bytes_size;

@ -240,7 +240,7 @@ tsi_result tsi_handshaker_result_create_frame_protector(
} }
tsi_result tsi_handshaker_result_get_unused_bytes( tsi_result tsi_handshaker_result_get_unused_bytes(
const tsi_handshaker_result *self, unsigned char **bytes, const tsi_handshaker_result *self, const unsigned char **bytes,
size_t *bytes_size) { size_t *bytes_size) {
if (self == NULL || bytes == NULL || bytes_size == NULL) { if (self == NULL || bytes == NULL || bytes_size == NULL) {
return TSI_INVALID_ARGUMENT; return TSI_INVALID_ARGUMENT;

@ -90,7 +90,8 @@ typedef struct {
size_t *max_output_protected_frame_size, size_t *max_output_protected_frame_size,
tsi_frame_protector **protector); tsi_frame_protector **protector);
tsi_result (*get_unused_bytes)(const tsi_handshaker_result *self, tsi_result (*get_unused_bytes)(const tsi_handshaker_result *self,
unsigned char **bytes, size_t *bytes_size); const unsigned char **bytes,
size_t *bytes_size);
void (*destroy)(tsi_handshaker_result *self); void (*destroy)(tsi_handshaker_result *self);
} tsi_handshaker_result_vtable; } tsi_handshaker_result_vtable;

@ -50,7 +50,7 @@ static tsi_result adapter_result_create_frame_protector(
} }
static tsi_result adapter_result_get_unused_bytes( static tsi_result adapter_result_get_unused_bytes(
const tsi_handshaker_result *self, unsigned char **bytes, const tsi_handshaker_result *self, const unsigned char **bytes,
size_t *byte_size) { size_t *byte_size) {
tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self; tsi_adapter_handshaker_result *impl = (tsi_adapter_handshaker_result *)self;
*bytes = impl->unused_bytes; *bytes = impl->unused_bytes;

@ -221,7 +221,7 @@ tsi_result tsi_handshaker_result_create_frame_protector(
Ownership of the bytes is retained by the handshaker result. As a Ownership of the bytes is retained by the handshaker result. As a
consequence, the caller must not free the bytes. */ consequence, the caller must not free the bytes. */
tsi_result tsi_handshaker_result_get_unused_bytes( tsi_result tsi_handshaker_result_get_unused_bytes(
const tsi_handshaker_result *self, unsigned char **bytes, const tsi_handshaker_result *self, const unsigned char **bytes,
size_t *byte_size); size_t *byte_size);
/* This method releases the tsi_handshaker_handshaker object. After this method /* This method releases the tsi_handshaker_handshaker object. After this method

@ -82,7 +82,7 @@ var _ = require('lodash');
* @memberof grpc.credentials * @memberof grpc.credentials
* @alias grpc.credentials.createSsl * @alias grpc.credentials.createSsl
* @kind function * @kind function
* @param {Buffer} root_certs The root certificate data * @param {Buffer=} root_certs The root certificate data
* @param {Buffer=} private_key The client certificate private key, if * @param {Buffer=} private_key The client certificate private key, if
* applicable * applicable
* @param {Buffer=} cert_chain The client certificate cert chain, if applicable * @param {Buffer=} cert_chain The client certificate cert chain, if applicable

@ -167,7 +167,7 @@ extern id const kGRPCTrailersKey;
* The authority for the RPC. If nil, the default authority will be used. This property must be nil * The authority for the RPC. If nil, the default authority will be used. This property must be nil
* when Cronet transport is enabled. * when Cronet transport is enabled.
*/ */
@property (atomic, readwrite) NSString *serverName; @property (atomic, copy, readwrite) NSString *serverName;
/** /**
* The container of the request headers of an RPC conforms to this protocol, which is a subset of * The container of the request headers of an RPC conforms to this protocol, which is a subset of

@ -193,6 +193,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/transport/chttp2/transport/bin_encoder.c', 'src/core/ext/transport/chttp2/transport/bin_encoder.c',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.c', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.c',
'src/core/ext/transport/chttp2/transport/chttp2_transport.c', 'src/core/ext/transport/chttp2/transport/chttp2_transport.c',
'src/core/ext/transport/chttp2/transport/flow_control.c',
'src/core/ext/transport/chttp2/transport/frame_data.c', 'src/core/ext/transport/chttp2/transport/frame_data.c',
'src/core/ext/transport/chttp2/transport/frame_goaway.c', 'src/core/ext/transport/chttp2/transport/frame_goaway.c',
'src/core/ext/transport/chttp2/transport/frame_ping.c', 'src/core/ext/transport/chttp2/transport/frame_ping.c',

@ -391,8 +391,9 @@ static void BM_TransportStreamSend(benchmark::State &state) {
MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) { MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
if (!state.KeepRunning()) return; if (!state.KeepRunning()) return;
// force outgoing window to be yuge // force outgoing window to be yuge
s.chttp2_stream()->outgoing_window_delta = 1024 * 1024 * 1024; s.chttp2_stream()->flow_control.remote_window_delta =
f.chttp2_transport()->outgoing_window = 1024 * 1024 * 1024; 1024 * 1024 * 1024;
f.chttp2_transport()->flow_control.remote_window = 1024 * 1024 * 1024;
grpc_slice_buffer_stream_init(&send_stream, &send_buffer, 0); grpc_slice_buffer_stream_init(&send_stream, &send_buffer, 0);
reset_op(); reset_op();
op.on_complete = c.get(); op.on_complete = c.get();
@ -517,12 +518,13 @@ static void BM_TransportStreamRecv(benchmark::State &state) {
std::unique_ptr<Closure> drain_continue; std::unique_ptr<Closure> drain_continue;
grpc_slice recv_slice; grpc_slice recv_slice;
std::unique_ptr<Closure> c = std::unique_ptr<Closure> c = MakeClosure([&](grpc_exec_ctx *exec_ctx,
MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) { grpc_error *error) {
if (!state.KeepRunning()) return; if (!state.KeepRunning()) return;
// force outgoing window to be yuge // force outgoing window to be yuge
s.chttp2_stream()->incoming_window_delta = 1024 * 1024 * 1024; s.chttp2_stream()->flow_control.local_window_delta = 1024 * 1024 * 1024;
f.chttp2_transport()->incoming_window = 1024 * 1024 * 1024; s.chttp2_stream()->flow_control.announced_window_delta = 1024 * 1024 * 1024;
f.chttp2_transport()->flow_control.announced_window = 1024 * 1024 * 1024;
received = 0; received = 0;
reset_op(); reset_op();
op.on_complete = do_nothing.get(); op.on_complete = do_nothing.get();

@ -73,11 +73,11 @@ class TrickledCHTTP2 : public EndpointPairFixture {
log_.reset(new std::ofstream(fn.str().c_str())); log_.reset(new std::ofstream(fn.str().c_str()));
write_csv(log_.get(), "t", "iteration", "client_backlog", write_csv(log_.get(), "t", "iteration", "client_backlog",
"server_backlog", "client_t_stall", "client_s_stall", "server_backlog", "client_t_stall", "client_s_stall",
"server_t_stall", "server_s_stall", "client_t_outgoing", "server_t_stall", "server_s_stall", "client_t_remote",
"server_t_outgoing", "client_t_incoming", "server_t_incoming", "server_t_remote", "client_t_announced", "server_t_announced",
"client_s_outgoing_delta", "server_s_outgoing_delta", "client_s_remote_delta", "server_s_remote_delta",
"client_s_incoming_delta", "server_s_incoming_delta", "client_s_local_delta", "server_s_local_delta",
"client_s_announce_window", "server_s_announce_window", "client_s_announced_delta", "server_s_announced_delta",
"client_peer_iws", "client_local_iws", "client_sent_iws", "client_peer_iws", "client_local_iws", "client_sent_iws",
"client_acked_iws", "server_peer_iws", "server_local_iws", "client_acked_iws", "server_peer_iws", "server_local_iws",
"server_sent_iws", "server_acked_iws", "client_queued_bytes", "server_sent_iws", "server_acked_iws", "client_queued_bytes",
@ -127,14 +127,15 @@ class TrickledCHTTP2 : public EndpointPairFixture {
client->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != nullptr, client->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != nullptr,
server->lists[GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT].head != nullptr, server->lists[GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT].head != nullptr,
server->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != nullptr, server->lists[GRPC_CHTTP2_LIST_STALLED_BY_STREAM].head != nullptr,
client->outgoing_window, server->outgoing_window, client->flow_control.remote_window, server->flow_control.remote_window,
client->incoming_window, server->incoming_window, client->flow_control.announced_window,
client_stream ? client_stream->outgoing_window_delta : -1, server->flow_control.announced_window,
server_stream ? server_stream->outgoing_window_delta : -1, client_stream ? client_stream->flow_control.remote_window_delta : -1,
client_stream ? client_stream->incoming_window_delta : -1, server_stream ? server_stream->flow_control.remote_window_delta : -1,
server_stream ? server_stream->incoming_window_delta : -1, client_stream ? client_stream->flow_control.local_window_delta : -1,
client_stream ? client_stream->announce_window : -1, server_stream ? server_stream->flow_control.local_window_delta : -1,
server_stream ? server_stream->announce_window : -1, client_stream ? client_stream->flow_control.announced_window_delta : -1,
server_stream ? server_stream->flow_control.announced_window_delta : -1,
client->settings[GRPC_PEER_SETTINGS] client->settings[GRPC_PEER_SETTINGS]
[GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE], [GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE],
client->settings[GRPC_LOCAL_SETTINGS] client->settings[GRPC_LOCAL_SETTINGS]

@ -1014,6 +1014,7 @@ src/core/ext/transport/chttp2/transport/bin_encoder.h \
src/core/ext/transport/chttp2/transport/chttp2_plugin.c \ src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
src/core/ext/transport/chttp2/transport/chttp2_transport.c \ src/core/ext/transport/chttp2/transport/chttp2_transport.c \
src/core/ext/transport/chttp2/transport/chttp2_transport.h \ src/core/ext/transport/chttp2/transport/chttp2_transport.h \
src/core/ext/transport/chttp2/transport/flow_control.c \
src/core/ext/transport/chttp2/transport/frame.h \ src/core/ext/transport/chttp2/transport/frame.h \
src/core/ext/transport/chttp2/transport/frame_data.c \ src/core/ext/transport/chttp2/transport/frame_data.c \
src/core/ext/transport/chttp2/transport/frame_data.h \ src/core/ext/transport/chttp2/transport/frame_data.h \

@ -24,6 +24,10 @@ ulimit -n 32768
echo 'DOCKER_OPTS="${DOCKER_OPTS} --graph=/tmpfs/docker"' | sudo tee --append /etc/default/docker echo 'DOCKER_OPTS="${DOCKER_OPTS} --graph=/tmpfs/docker"' | sudo tee --append /etc/default/docker
sudo service docker restart sudo service docker restart
# Populate xdg-cache-home to workaround https://github.com/grpc/grpc/issues/11968
sudo mkdir -p /tmp/xdg-cache-home
PYTHONWARNINGS=ignore XDG_CACHE_HOME=/tmp/xdg-cache-home sudo -E pip install coverage==4.4 pylint==1.6.5
# Download Docker images from DockerHub # Download Docker images from DockerHub
export DOCKERHUB_ORGANIZATION=grpctesting export DOCKERHUB_ORGANIZATION=grpctesting

@ -0,0 +1,25 @@
#!/usr/bin/env bash
# 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.
set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
source tools/internal_ci/helper_scripts/prepare_build_linux_rc
export DOCKERFILE_DIR=tools/dockerfile/test/bazel
export DOCKER_RUN_SCRIPT=$BAZEL_SCRIPT
exec tools/run_tests/dockerize/build_and_run_docker.sh

@ -0,0 +1,23 @@
# 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.
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/linux/grpc_bazel.sh"
timeout_mins: 60
env_vars {
key: "BAZEL_SCRIPT"
value: "tools/jenkins/run_bazel_basic_in_docker.sh"
}

@ -0,0 +1,23 @@
# 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.
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/linux/grpc_bazel.sh"
timeout_mins: 240
env_vars {
key: "BAZEL_SCRIPT"
value: "tools/jenkins/run_bazel_full_in_docker.sh"
}

@ -27,5 +27,5 @@ action {
env_vars { env_vars {
key: "RUN_TESTS_FLAGS" key: "RUN_TESTS_FLAGS"
value: "-f basictests macos --internal_ci -j 2 --inner_jobs 4 --bq_result_table aggregate_results" value: "-f basictests macos --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results"
} }

@ -0,0 +1,31 @@
# 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.
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh"
gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json"
timeout_mins: 240
action {
define_artifacts {
regex: "**/*sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
env_vars {
key: "RUN_TESTS_FLAGS"
value: "-f basictests macos dbg --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results"
}

@ -0,0 +1,31 @@
# 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.
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh"
gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json"
timeout_mins: 240
action {
define_artifacts {
regex: "**/*sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
env_vars {
key: "RUN_TESTS_FLAGS"
value: "-f basictests macos opt --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results"
}

@ -27,5 +27,5 @@ action {
env_vars { env_vars {
key: "RUN_TESTS_FLAGS" key: "RUN_TESTS_FLAGS"
value: "-f basictests macos --internal_ci -j 2 --inner_jobs 4" value: "-f basictests macos dbg --internal_ci -j 1 --inner_jobs 4"
} }

@ -0,0 +1,31 @@
# 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.
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh"
gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json"
timeout_mins: 240
action {
define_artifacts {
regex: "**/*sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
env_vars {
key: "RUN_TESTS_FLAGS"
value: "-f basictests macos opt --internal_ci -j 1 --inner_jobs 4"
}

@ -8810,6 +8810,7 @@
"src/core/ext/transport/chttp2/transport/chttp2_plugin.c", "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
"src/core/ext/transport/chttp2/transport/chttp2_transport.c", "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
"src/core/ext/transport/chttp2/transport/chttp2_transport.h", "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
"src/core/ext/transport/chttp2/transport/flow_control.c",
"src/core/ext/transport/chttp2/transport/frame.h", "src/core/ext/transport/chttp2/transport/frame.h",
"src/core/ext/transport/chttp2/transport/frame_data.c", "src/core/ext/transport/chttp2/transport/frame_data.c",
"src/core/ext/transport/chttp2/transport/frame_data.h", "src/core/ext/transport/chttp2/transport/frame_data.h",

@ -144,7 +144,7 @@ class Config(object):
cpu_cost=cpu_cost, cpu_cost=cpu_cost,
timeout_seconds=(self.timeout_multiplier * timeout_seconds if timeout_seconds else None), timeout_seconds=(self.timeout_multiplier * timeout_seconds if timeout_seconds else None),
flake_retries=5 if flaky or args.allow_flakes else 0, flake_retries=5 if flaky or args.allow_flakes else 0,
timeout_retries=3 if args.allow_flakes else 0) timeout_retries=3 if flaky or args.allow_flakes else 0)
def get_c_tests(travis, test_lang) : def get_c_tests(travis, test_lang) :

@ -785,6 +785,8 @@
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\flow_control.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_goaway.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_goaway.c">

@ -397,6 +397,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter> <Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\flow_control.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter> <Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile> </ClCompile>

@ -571,6 +571,8 @@
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\flow_control.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_goaway.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_goaway.c">

@ -514,6 +514,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter> <Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\flow_control.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter> <Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile> </ClCompile>

@ -559,6 +559,8 @@
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\flow_control.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_goaway.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_goaway.c">

@ -499,6 +499,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter> <Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\flow_control.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter> <Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile> </ClCompile>

@ -753,6 +753,8 @@
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\flow_control.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_goaway.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_goaway.c">

@ -403,6 +403,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_transport.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter> <Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\flow_control.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\frame_data.c">
<Filter>src\core\ext\transport\chttp2\transport</Filter> <Filter>src\core\ext\transport\chttp2\transport</Filter>
</ClCompile> </ClCompile>

Loading…
Cancel
Save